/home/suroeste/public_html/wp-content/plugins/akeebabackupwp/app/Solo
NameSizeModeActions
Application/-0755rm
assets/-0777rm
Cli/-0755rm
Controller/-0755rm
Dependencies/-0777rm
Exception/-0777rm
Helper/-0755rm
Model/-0755rm
Platform/-0777rm
Pythia/-0755rm
View/-0777rm
ViewTemplates/-0777rm
.htaccess1660644editdlrm
Application.php128540644editdlrm
Container.php12950644editdlrm
Dispatcher.php18820644editdlrm
PostUpgradeScript.php339130644editdlrm
web.config1850644editdlrm
Edit: /home/suroeste/public_html/wp-content/plugins/akeebabackupwp/app/Solo/PostUpgradeScript.php (33913B)
container = $container; } /** * Execute the post-upgrade actions */ public function execute() { // Do not execute the post-upgrade script in the development environment $realPath = realpath(__DIR__); if (@file_exists($realPath . '/../../.nopostupgrade')) { return; } // Invalidate the Composer files' OPCache. if (function_exists('opcache_invalidate')) { @opcache_invalidate(APATH_BASE . '/../vendor/autoload.php', true); @opcache_invalidate(APATH_BASE . '/../vendor/composer/autoload_classmap.php', true); @opcache_invalidate(APATH_BASE . '/../vendor/composer/autoload_namespaces.php', true); @opcache_invalidate(APATH_BASE . '/../vendor/composer/autoload_psr4.php', true); @opcache_invalidate(APATH_BASE . '/../vendor/composer/autoload_real.php', true); @opcache_invalidate(APATH_BASE . '/../vendor/composer/autoload_static.php', true); } // Migrate secretkey.php $this->migrateSecretKeyFile(); // Special handling for running the Solo application inside WordPress. if ($this->container->segment->get('insideCMS', false)) { if (defined('WPINC')) { $this->WordPressActions(); } } // Remove obsolete files $this->processRemoveFiles(); // Remove obsolete folders $this->processRemoveFolders(); // Migrate profiles $this->migrateProfiles(); // Migrate front-end API activation options $this->upgradeFrontendEnable(); } /** * Upgrades the frontend_enable option into the two separate legacyapi_enabled and jsonapi_enabled options. * * Before version 7 we had a single option to control both frontend backup APIs. Starting version 7 we can enable * and disable them separately. */ public function upgradeFrontendEnable() { $currentValue = $this->container->appConfig->get('options.frontend_enable', null); if (is_null($currentValue)) { return; } $this->container->appConfig->set('options.frontend_enable', null); $this->container->appConfig->set('options.legacyapi_enabled', $currentValue); $this->container->appConfig->set('options.jsonapi_enabled', $currentValue); $this->container->appConfig->saveConfiguration(); } /** * Removes obsolete files, depending on the edition (core or pro) */ protected function processRemoveFiles() { if (defined('WPINC')) { $basePath = rtrim($this->container->filesystemBase, '/' . DIRECTORY_SEPARATOR) . '/../'; foreach ($this->removeWordPressOnlyFilesAll as $file) { $filePath = $basePath . $file; if (file_exists($filePath)) { @unlink($filePath); } } } $removeFiles = $this->removeFilesAllVersions; if (defined('AKEEBABACKUP_PRO') && AKEEBABACKUP_PRO) { $removeFiles = array_merge($removeFiles, $this->removeFilesPro); } else { $removeFiles = array_merge($removeFiles, $this->removeFilesCore); } $this->_removeFiles($removeFiles); } /** * Removes obsolete folders, depending on the edition (core or pro) */ protected function processRemoveFolders() { $removeFolders = $this->removeFoldersAllVersions; if (defined('AKEEBABACKUP_PRO') && AKEEBABACKUP_PRO) { $removeFolders = array_merge($removeFolders, $this->removeFoldersPro); } else { $removeFolders = array_merge($removeFolders, $this->removeFoldersCore); } $this->_removeFolders($removeFolders); } /** * Specific actions to execute when we are running inside WordPress */ private function WordPressActions() { $this->WordPressUpgradeToUtf8mb4(); $this->WordPressRemoveFolders(); $this->WordPressRemoveFiles(); } /** * Remove obsolete folders from the WordPress installation * * @return void */ private function WordPressRemoveFolders() { $removeFolders = [ // Standalone platform 'app/Solo/Platform', // Obsolete folders after the introduction of Akeeba Engine 2 'helpers/platform/solowp', ]; // Remove WordPress-specific features from the Core release if (defined('AKEEBABACKUP_PRO') && !AKEEBABACKUP_PRO) { $removeFolders = array_merge( [ 'helpers/assets/mu-plugins', 'wpcli', ], $removeFolders ); } $fsBase = rtrim($this->container->filesystemBase, '/' . DIRECTORY_SEPARATOR) . '/../'; $fs = $this->container->fileSystem; foreach ($removeFolders as $folder) { $fs->rmdir($fsBase . $folder, true); } } /** * Remove obsolete files from the WordPress installation * * @return void */ private function WordPressRemoveFiles() { $removeFiles = [ // Migrating INI files to .json files "helpers/Platform/Wordpress/Config/04.quota.ini", "helpers/Platform/Wordpress/Config/02.advanced.ini", "helpers/Platform/Wordpress/Config/Pro/04.quota.ini", "helpers/Platform/Wordpress/Config/Pro/02.advanced.ini", "helpers/Platform/Wordpress/Config/Pro/01.basic.ini", "helpers/Platform/Wordpress/Config/Pro/02.platform.ini", "helpers/Platform/Wordpress/Config/Pro/03.filters.ini", "helpers/Platform/Wordpress/Config/Pro/05.tuning.ini", "helpers/Platform/Wordpress/Config/01.basic.ini", "helpers/Platform/Wordpress/Config/02.platform.ini", "helpers/Platform/Wordpress/Config/05.tuning.ini", ]; // Remove WordPress-specific features from the Core release if (defined('AKEEBABACKUP_PRO') && !AKEEBABACKUP_PRO) { $additionalFiles = [ 'helpers/boot_wpcli.php', ]; $removeFiles = array_merge($removeFiles, $additionalFiles); } if (empty($removeFiles)) { return; } $fsBase = rtrim($this->container->filesystemBase, '/' . DIRECTORY_SEPARATOR) . '/../'; $fs = $this->container->fileSystem; foreach ($removeFiles as $file) { $fs->delete($fsBase . $file); } } /** * Update WordPress tables to utf8mb4 if required */ private function WordPressUpgradeToUtf8mb4() { /** @var wpdb $wpdb */ global $wpdb; // Is it really WordPress? if (!is_object($wpdb)) { return; } // Is it really WordPress? if (!method_exists($wpdb, 'has_cap')) { return; } // Does the database support utf8mb4 at all? if (!$wpdb->has_cap('utf8mb4')) { return; } // Is the actual charset set to utf8mb4? $charset = strtolower($wpdb->charset); if ($charset != 'utf8mb4') { return; } // OK, all conditions met, let's upgrade the tables to utf8mb4 $dbInstaller = new Installer($this->container); $dbInstaller->setForcedFile($this->container->basePath . '/assets/sql/xml/utf8mb4_update.xml'); $dbInstaller->updateSchema(); return; } /** * Removes obsolete files given on a list * * @param array $removeFiles List of files to remove * * @return void */ private function _removeFiles(array $removeFiles) { if (empty($removeFiles)) { return; } $fsBase = rtrim($this->container->filesystemBase, '/' . DIRECTORY_SEPARATOR) . '/'; $fs = $this->container->fileSystem; foreach ($removeFiles as $file) { $fs->delete($fsBase . $file); } } /** * Removes obsolete folders given on a list * * @param array $removeFolders List of folders to remove * * @return void */ private function _removeFolders(array $removeFolders) { if (empty($removeFolders)) { return; } $fsBase = rtrim($this->container->filesystemBase, '/' . DIRECTORY_SEPARATOR) . '/'; $fs = $this->container->fileSystem; foreach ($removeFolders as $folder) { $fs->rmdir($fsBase . $folder, true); } } /** * Migrates existing backup profiles. The changes currently made are: * * Change post-processing from "s3" (legacy) to "amazons3" (current version). * * Fix profiles with invalid embedded installer settings. * * Migrate to separate local and remote quota settings. * * @return void */ private function migrateProfiles() { // Get a list of backup profiles $db = $this->container->db; $query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__ak_profiles')); $profiles = $db->setQuery($query)->loadColumn(); // Normally this should never happen as we're supposed to have at least profile #1 if (empty($profiles)) { return; } // Migrate each profile foreach ($profiles as $profile) { // Initialization $dirty = false; // Load the profile configuration Platform::getInstance()->load_configuration($profile); $config = Factory::getConfiguration(); // Remove key protection $protected = $config->getProtectedKeys(); $config->setProtectedKeys([]); // -- Migrate obsolete "s3" engine to "amazons3" if ($config->get('akeeba.advanced.postproc_engine', '') == 's3') { $dirty = true; $config->setKeyProtection('akeeba.advanced.postproc_engine', false); $config->setKeyProtection('engine.postproc.amazons3.signature', false); $config->setKeyProtection('engine.postproc.amazons3.accesskey', false); $config->setKeyProtection('engine.postproc.amazons3.secretkey', false); $config->setKeyProtection('engine.postproc.amazons3.usessl', false); $config->setKeyProtection('engine.postproc.amazons3.bucket', false); $config->setKeyProtection('engine.postproc.amazons3.directory', false); $config->setKeyProtection('engine.postproc.amazons3.rrs', false); $config->setKeyProtection('engine.postproc.amazons3.customendpoint', false); $config->setKeyProtection('engine.postproc.amazons3.legacy', false); $config->set('akeeba.advanced.postproc_engine', 'amazons3'); $config->set('engine.postproc.amazons3.signature', 's3'); $config->set('engine.postproc.amazons3.accesskey', $config->get('engine.postproc.s3.accesskey')); $config->set('engine.postproc.amazons3.secretkey', $config->get('engine.postproc.s3.secretkey')); $config->set('engine.postproc.amazons3.usessl', $config->get('engine.postproc.s3.usessl')); $config->set('engine.postproc.amazons3.bucket', $config->get('engine.postproc.s3.bucket')); $config->set('engine.postproc.amazons3.directory', $config->get('engine.postproc.s3.directory')); $config->set('engine.postproc.amazons3.rrs', $config->get('engine.postproc.s3.rrs')); $config->set( 'engine.postproc.amazons3.customendpoint', $config->get('engine.postproc.s3.customendpoint') ); $config->set('engine.postproc.amazons3.legacy', $config->get('engine.postproc.s3.legacy')); } // Fix profiles with invalid embedded installer settings $embeddedInstaller = $config->get('akeeba.advanced.embedded_installer'); if (empty($embeddedInstaller) || ($embeddedInstaller == 'angie-joomla') || ((substr( $embeddedInstaller, 0, 5 ) != 'angie') && ($embeddedInstaller != 'none'))) { $dirty = true; $config->setKeyProtection('akeeba.advanced.embedded_installer', false); $config->set('akeeba.advanced.embedded_installer', 'angie'); } // Transcribe the local quota to remote quota settings if the legacy "Enable remote quotas" option is on. if ($config->get('akeeba.quota.remote', 0) == 1) { $dirty = true; $config->set('akeeba.quota.remote', null); $config->set('akeeba.quota.remotely.maxage.enable', $config->get('akeeba.quota.maxage.enable', 0)); $config->set('akeeba.quota.remotely.maxage.maxdays', $config->get('akeeba.quota.maxage.maxdays', 31)); $config->set('akeeba.quota.remotely.maxage.keepday', $config->get('akeeba.quota.maxage.keepday', 1)); $config->set('akeeba.quota.remotely.enable_size_quota', $config->get('akeeba.quota.enable_size_quota', 0)); $config->set('akeeba.quota.remotely.size_quota', $config->get('akeeba.quota.size_quota', 15728640)); $config->set('akeeba.quota.remotely.enable_count_quota', $config->get('akeeba.quota.enable_count_quota', 1)); $config->set('akeeba.quota.remotely.count_quota', $config->get('akeeba.quota.count_quota', 3)); } // Restore key protection $config->setProtectedKeys($protected); // Save dirty records if ($dirty) { Platform::getInstance()->save_configuration($profile); } } } /** * Migrate the settings encryption key file, if needed * * @return void * @since 8.0.0 */ private function migrateSecretKeyFile(): void { $oldFile = $this->findBestSecretKeyFile(); $newFile = APATH_BASE . '/Solo/secretkey.php'; // Different secretkey.php when using WordPress if (defined('ABSPATH')) { $newFile = rtrim( (defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : (rtrim(ABSPATH, '/') . '/wp-content')), '/' ) . '/akeebabackup_secretkey.php'; } if (empty($oldFile) || !file_exists($oldFile)) { return; } if ($oldFile !== $newFile) { if (@copy($oldFile, $newFile)) { @unlink($oldFile); } } Factory::getSecureSettings()->setKeyFilename($newFile); } /** * Find the secret key file which decrypts the most backup profiles. * * @return string|null The path the best key file. NULL if there's no file, or encryption is disabled. * @since 8.1.0 */ private function findBestSecretKeyFile(): ?string { // If encryption is not supported, or disabled, there's nothing I need to do. Right? $secureSettings = Factory::getSecureSettings(); if (!$secureSettings->supportsEncryption()) { return null; } // Extract the keys from the different possible files $files = [ APATH_BASE . '/Solo/engine/secretkey.php', APATH_BASE . '/Solo/secretkey.php', ]; // Different secretkey.php when using WordPress if (defined('ABSPATH')) { $files[] = rtrim( (defined('WP_CONTENT_DIR') ? WP_CONTENT_DIR : (rtrim(ABSPATH, '/') . '/wp-content')), '/' ) . '/akeebabackup_secretkey.php'; } $keys = array_combine( $files, array_map([$this, 'getSecretKeyFromFile'], $files) ); // Remove empty keys (file cannot be read, or does not exist). $keys = array_filter($keys); // Get the backup profile configuration from the database $platform = Platform::getInstance(); $db = $this->container->db; try { $sql = $db->getQuery(true) ->select([ $db->quoteName('id'), $db->quoteName('configuration'), ]) ->from($db->qn($platform->tableNameProfiles)); $encryptedProfiles = $db->setQuery($sql)->loadAssocList('id', 'configuration'); } catch (\Throwable $e) { return false; } // For each key file, try to decrypt the backup profiles and assign it the number of profiles it decrypted $keys = array_map(function ($key) use ($encryptedProfiles, $secureSettings) { $test = array_map(function($data) use ($secureSettings, $key) { $data = $secureSettings->decryptSettings($data, $key); try { $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR); if (!is_array($data) || empty($data)) { return 0; } } catch (\JsonException $e) { return 0; } return 1; }, $encryptedProfiles); return array_sum($test); }, $keys); // Rank key files by number of decrypted profiles, ascending (best key file is last) asort($keys); // Remove key files which failed to decrypt anything $keys = array_filter($keys, fn($x) => $x > 0); // No key files succeeded. Oof. if (empty($keys)) { return null; } // Get and return the highest ranking key file. $files = array_keys($keys); return array_pop($files); } /** * Extract the secret key from a key file without including it (since we cannot redeclare constants) * * @param string $filePath * * @return string|null The key, or NULL if the file is missing, unreadable, or of an invalid format. * @since 8.1.0 */ private function getSecretKeyFromFile(string $filePath): ?string { // Make sure there is a file, and we can read its contents. if (!@file_exists($filePath) || !@is_file($filePath) || !@is_readable($filePath)) { return null; } $fileContents = @file_get_contents($filePath); if ($fileContents === false) { return null; } // Try to locate the key value using a RegEx $pattern = '/define\s*\(\s*(\'AKEEBA_SERVERKEY\'|"AKEEBA_SERVERKEY")\s*,\s*(\'.*\'|".*")\s*\)/'; if (!preg_match($pattern, $fileContents, $matches)) { return null; } if (!isset($matches[2]) || !is_string($matches[2]) || empty($matches[2])) { return null; } // The matched string is either `'SOMETHING'` or `"SOMETHING"`. We need to find the quote type and remove it. $quote = substr($matches[2], 0, 1); $encodedKey = trim($matches[2], $quote); return base64_decode($encodedKey); } }