%PDF- %PDF-
Direktori : /home/lightco1/upgrade.lightco.com.au/administrator/components/com_akeeba/Model/ |
Current File : /home/lightco1/upgrade.lightco.com.au/administrator/components/com_akeeba/Model/ControlPanel.php |
<?php /** * @package AkeebaBackup * @copyright Copyright (c)2006-2017 Nicholas K. Dionysopoulos / Akeeba Ltd * @license GNU General Public License version 3, or later */ namespace Akeeba\Backup\Admin\Model; // Protect from unauthorized access defined('_JEXEC') or die(); use Akeeba\Backup\Admin\Helper\SecretWord; use Akeeba\Backup\Admin\Model\Mixin\Chmod; use Akeeba\Engine\Factory; use Akeeba\Engine\Platform; use Akeeba\Engine\Util\RandomValue; use FOF30\Database\Installer; use FOF30\Model\Model; use JFactory; use JFile; use JFolder; use JHtml; use JLoader; use JUri; use RuntimeException; /** * ControlPanel model. Generic maintenance tasks used mainly from the ControlPanel page. */ class ControlPanel extends Model { use Chmod; /** * Gets a list of profiles which will be displayed as quick icons in the interface * * @return \stdClass[] Array of objects; each has the properties `id` and `description` */ public function getQuickIconProfiles() { $db = $this->container->db; $query = $db->getQuery(true) ->select(array( $db->qn('id'), $db->qn('description') ))->from($db->qn('#__ak_profiles')) ->where($db->qn('quickicon') . ' = ' . $db->q(1)) ->order($db->qn('id') . " ASC"); $db->setQuery($query); $ret = $db->loadObjectList(); if (empty($ret)) { $ret = array(); } return $ret; } /** * Creates an icon definition entry * * @param string $iconFile The filename of the icon on the GUI button * @param string $label The label below the GUI button * @param string $view The view to fire up when the button is clicked * * @return array The icon definition array */ public function _makeIconDefinition($iconFile, $label, $view = null, $task = null) { return array( 'icon' => $iconFile, 'label' => $label, 'view' => $view, 'task' => $task ); } /** * Was the last backup a failed one? Used to apply magic settings as a means of troubleshooting. * * @return bool */ public function isLastBackupFailed() { // Get the last backup record ID $list = Platform::getInstance()->get_statistics_list(array('limitstart' => 0, 'limit' => 1)); if (empty($list)) { return false; } $id = $list[0]; $record = Platform::getInstance()->get_statistics($id); return ($record['status'] == 'fail'); } /** * Checks that the media permissions are oh seven double five for directories and oh six double four for files and * fixes them if they are incorrect. * * @param bool $force Forcibly check subresources, even if the parent has correct permissions * * @return bool False if we couldn't figure out what's going on */ public function fixMediaPermissions($force = false) { // Are we on Windows? $isWindows = (DIRECTORY_SEPARATOR == '\\'); if (function_exists('php_uname')) { $isWindows = stristr(php_uname(), 'windows'); } // No point changing permissions on Windows, as they have ACLs if ($isWindows) { return true; } // Check the parent permissions $parent = JPATH_ROOT . '/media/com_akeeba'; $parentPerms = fileperms($parent); // If we can't determine the parent's permissions, bail out if ($parentPerms === false) { return false; } // Fooling some broken file scanners. $ohSevenFiveFive = 500 - 7; $ohFourOhSevenFiveFive = 16000 + 900 - 23; $ohSixFourFour = 450 - 30; $ohOneDoubleOhSixFourFour = 33000 + 200 - 12; // Fix the parent's permissions if required if (($parentPerms != $ohSevenFiveFive) && ($parentPerms != $ohFourOhSevenFiveFive)) { $this->chmod($parent, $ohSevenFiveFive); } elseif (!$force) { return true; } // During development we use symlinks and we don't wanna see that big fat warning if (@is_link($parent)) { return true; } JLoader::import('joomla.filesystem.folder'); $result = true; // Loop through subdirectories $folders = JFolder::folders($parent, '.', 3, true); foreach ($folders as $folder) { $perms = fileperms($folder); if (($perms != $ohSevenFiveFive) && ($perms != $ohFourOhSevenFiveFive)) { $result &= $this->chmod($folder, $ohSevenFiveFive); } } // Loop through files $files = JFolder::files($parent, '.', 3, true); foreach ($files as $file) { $perms = fileperms($file); if (($perms != $ohSixFourFour) && ($perms != $ohOneDoubleOhSixFourFour)) { $result &= $this->chmod($file, $ohSixFourFour); } } return $result; } /** * Checks if we should enable settings encryption and applies the change * * @return void */ public function checkSettingsEncryption() { // Do we have a key file? JLoader::import('joomla.filesystem.file'); $filename = JPATH_COMPONENT_ADMINISTRATOR . '/BackupEngine/serverkey.php'; if (JFile::exists($filename)) { // We have a key file. Do we need to disable it? if ($this->container->params->get('useencryption', -1) == 0) { // User asked us to disable encryption. Let's do it. $this->disableSettingsEncryption(); } return; } if (!Factory::getSecureSettings()->supportsEncryption()) { return; } if ($this->container->params->get('useencryption', -1) != 0) { // User asked us to enable encryption (or he left us with the default setting!). Let's do it. $this->enableSettingsEncryption(); } } /** * Disables the encryption of profile settings. If the settings were already encrypted they are automatically * decrypted. * * @return void */ private function disableSettingsEncryption() { // Load the server key file if necessary $filename = JPATH_COMPONENT_ADMINISTRATOR . '/BackupEngine/serverkey.php'; $key = Factory::getSecureSettings()->getKey(); // Loop all profiles and decrypt their settings /** @var Profiles $profilesModel */ $profilesModel = $this->container->factory->model('Profiles')->tmpInstance(); $profiles = $profilesModel->get(true); $db = $this->container->db; /** @var Profiles $profile */ foreach ($profiles as $profile) { $id = $profile->getId(); $config = Factory::getSecureSettings()->decryptSettings($profile->configuration, $key); $sql = $db->getQuery(true) ->update($db->qn('#__ak_profiles')) ->set($db->qn('configuration') . ' = ' . $db->q($config)) ->where($db->qn('id') . ' = ' . $db->q($id)); $db->setQuery($sql); $db->execute(); } // Decrypt the Secret Word settings in the database $params = $this->container->params; SecretWord::enforceDecrypted($params, 'frontend_secret_word', $key); // Finally, remove the key file if (!@unlink($filename)) { JLoader::import('joomla.filesystem.file'); JFile::delete($filename); } } /** * Enabled the encryption of profile settings. Existing settings are automatically encrypted. * * @return void */ private function enableSettingsEncryption() { $key = $this->createSettingsKey(); if (empty($key) || ($key == false)) { return; } // Loop all profiles and encrypt their settings /** @var \Akeeba\Backup\Admin\Model\Profiles $profilesModel */ $profilesModel = $this->container->factory->model('Profiles')->tmpInstance(); $profiles = $profilesModel->get(true); $db = $this->container->db; if (!empty($profiles)) { foreach ($profiles as $profile) { $id = $profile->id; $config = Factory::getSecureSettings()->encryptSettings($profile->configuration, $key); $sql = $db->getQuery(true) ->update($db->qn('#__ak_profiles')) ->set($db->qn('configuration') . ' = ' . $db->q($config)) ->where($db->qn('id') . ' = ' . $db->q($id)); $db->setQuery($sql); $db->execute(); } } } /** * Creates an encryption key for the settings and saves it in the <component>/BackupEngine/serverkey.php path * * @return bool|string FALSE on failure, the encryptions key otherwise */ private function createSettingsKey() { $randVal = new RandomValue(); $rawKey = $randVal->generate(64); $key = base64_encode($rawKey); $filecontents = "<?php defined('AKEEBAENGINE') or die(); define('AKEEBA_SERVERKEY', '$key'); ?>"; $filename = $this->container->backEndPath . '/BackupEngine/serverkey.php'; JLoader::import('joomla.filesystem.file'); $result = JFile::write($filename, $filecontents); if (!$result) { return false; } return $rawKey; } /** * Updates some internal settings: * * - The stored URL of the site, used for the front-end backup feature (altbackup.php) * - The detected Joomla! libraries path * - Marks all existing profiles as configured, if necessary */ public function updateMagicParameters() { if (!$this->container->params->get('confwiz_upgrade', 0)) { $this->markOldProfilesConfigured(); } $this->container->params->set('confwiz_upgrade', 1); $this->container->params->set('siteurl', str_replace('/administrator', '', JUri::base())); $this->container->params->set('jlibrariesdir', Factory::getFilesystemTools()->TranslateWinPath(JPATH_LIBRARIES)); $this->container->params->set('jversion', '1.6'); $this->container->params->save(); } /** * Do you have to issue a warning that setting the Download ID in the CORE edition has no effect? * * @return bool True if you need to show the warning */ public function mustWarnAboutDownloadIDInCore() { $ret = false; $isPro = AKEEBA_PRO; if ($isPro) { return $ret; } $dlid = $this->container->params->get('update_dlid', ''); if (preg_match('/^([0-9]{1,}:)?[0-9a-f]{32}$/i', $dlid)) { $ret = true; } return $ret; } /** * Does the user need to enter a Download ID in the component's Options page? * * @return bool */ public function needsDownloadID() { // Do I need a Download ID? $ret = true; $isPro = AKEEBA_PRO; if (!$isPro) { $ret = false; } else { $dlid = $this->container->params->get('update_dlid', ''); if (preg_match('/^([0-9]{1,}:)?[0-9a-f]{32}$/i', $dlid)) { $ret = false; } } return $ret; } /** * Checks the database for missing / outdated tables and runs the appropriate SQL scripts if necessary. * * @throws RuntimeException If the previous database update is stuck * * @return $this */ public function checkAndFixDatabase() { $params = $this->container->params; // First of all let's check if we are already updating $stuck = $params->get('updatedb', 0); if ($stuck) { throw new RuntimeException('Previous database update is flagged as stuck'); } // Then set the flag $params->set('updatedb', 1); $params->save(); // Install or update database $dbInstaller = new Installer( $this->container->db, JPATH_ADMINISTRATOR . '/components/com_akeeba/sql/xml' ); $dbInstaller->updateSchema(); // And finally remove the flag if everything went fine $params->set('updatedb', null); $params->save(); return $this; } /** * Akeeba Backup 4.3.2 displays a popup if your profile is not already configured by Configuration Wizard, the * Configuration page or imported from the Profiles page. This bit of code makes sure that existing profiles will * be marked as already configured just the FIRST time you upgrade to the new version from an old version. * * @return void */ public function markOldProfilesConfigured() { // Get all profiles $db = $this->container->db; $query = $db->getQuery(true) ->select(array( $db->qn('id'), ))->from($db->qn('#__ak_profiles')) ->order($db->qn('id') . " ASC"); $db->setQuery($query); $profiles = $db->loadColumn(); // Save the current profile number $oldProfile = $this->container->platform->getSessionVar('profile', 1, 'akeeba'); // Update all profiles foreach ($profiles as $profile_id) { Factory::nuke(); Platform::getInstance()->load_configuration($profile_id); $config = Factory::getConfiguration(); $config->set('akeeba.flag.confwiz', 1); Platform::getInstance()->save_configuration($profile_id); } // Restore the old profile Factory::nuke(); Platform::getInstance()->load_configuration($oldProfile); } /** * Check the strength of the Secret Word for front-end and remote backups. If it is insecure return the reason it * is insecure as a string. If the Secret Word is secure return an empty string. * * @return string */ public function getFrontendSecretWordError() { // Is frontend backup enabled? $febEnabled = Platform::getInstance()->get_platform_configuration_option('frontend_enable', 0) != 0; if (!$febEnabled) { return ''; } $secretWord = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', ''); try { \Akeeba\Engine\Util\Complexify::isStrongEnough($secretWord); } catch (RuntimeException $e) { // Ah, the current Secret Word is bad. Create a new one if necessary. $newSecret = $this->container->platform->getSessionVar('newSecretWord', null, 'akeeba.cpanel'); if (empty($newSecret)) { $random = new \Akeeba\Engine\Util\RandomValue(); $newSecret = $random->generateString(32); $this->container->platform->setSessionVar('newSecretWord', $newSecret, 'akeeba.cpanel'); } return $e->getMessage(); } return ''; } /** * Checks if the mbstring extension is installed and enabled * * @return bool */ public function checkMbstring() { return function_exists('mb_strlen') && function_exists('mb_convert_encoding') && function_exists('mb_substr') && function_exists('mb_convert_case'); } }