Пример #1
0
 /**
  * Execute the JSON API task
  *
  * @param   array $parameters The parameters to this task
  *
  * @return  mixed
  *
  * @throws  \RuntimeException  In case of an error
  */
 public function execute(array $parameters = array())
 {
     // Get the passed configuration values
     $defConfig = array('profile' => -1, 'engineconfig' => array());
     $defConfig = array_merge($defConfig, $parameters);
     $profile = (int) $defConfig['profile'];
     $data = $defConfig['engineconfig'];
     if (empty($profile)) {
         throw new \RuntimeException('Invalid profile ID', 404);
     }
     // Forbid stupidly selecting the site's root as the output or temporary directory
     if (array_key_exists('akeeba.basic.output_directory', $data)) {
         $folder = $data['akeeba.basic.output_directory'];
         $folder = Factory::getFilesystemTools()->translateStockDirs($folder, true, true);
         $check = Factory::getFilesystemTools()->translateStockDirs('[SITEROOT]', true, true);
         if ($check == $folder) {
             $data['akeeba.basic.output_directory'] = '[DEFAULT_OUTPUT]';
         }
     }
     // Merge it
     $config = Factory::getConfiguration();
     $protectedKeys = $config->getProtectedKeys();
     $config->resetProtectedKeys();
     $config->mergeArray($data, false, false);
     $config->setProtectedKeys($protectedKeys);
     // Save configuration
     return Platform::getInstance()->save_configuration($profile);
 }
Пример #2
0
 public function __construct()
 {
     $this->object = 'dir';
     $this->subtype = 'inclusion';
     $this->method = 'direct';
     $this->filter_name = 'Libraries';
     // FIXME This filter doesn't work very well on many live hosts. Disabled for now.
     parent::__construct();
     return;
     if (empty($this->filter_name)) {
         $this->filter_name = strtolower(basename(__FILE__, '.php'));
     }
     // Get the saved library path and compare it to the default
     $jlibdir = Platform::getInstance()->get_platform_configuration_option('jlibrariesdir', '');
     if (empty($jlibdir)) {
         if (defined('JPATH_LIBRARIES')) {
             $jlibdir = JPATH_LIBRARIES;
         } elseif (defined('JPATH_PLATFORM')) {
             $jlibdir = JPATH_PLATFORM;
         } else {
             $jlibdir = false;
         }
     }
     if ($jlibdir !== false) {
         $jlibdir = Factory::getFilesystemTools()->TranslateWinPath($jlibdir);
         $defaultLibraries = Factory::getFilesystemTools()->TranslateWinPath(JPATH_SITE . '/libraries');
         if ($defaultLibraries != $jlibdir) {
             // The path differs, add it here
             $this->filter_data['JPATH_LIBRARIES'] = $jlibdir;
         }
     } else {
         $this->filter_data = array();
     }
     parent::__construct();
 }
Пример #3
0
 protected function scanFolder($folder, &$position, $forFolders = true, $threshold_key = 'dir', $threshold_default = 50)
 {
     $registry = Factory::getConfiguration();
     // Initialize variables
     $arr = array();
     $false = false;
     if (!is_dir($folder) && !is_dir($folder . '/')) {
         return $false;
     }
     try {
         $di = new \DirectoryIterator($folder);
     } catch (\Exception $e) {
         $this->setWarning('Unreadable directory ' . $folder);
         return $false;
     }
     if (!$di->valid()) {
         $this->setWarning('Unreadable directory ' . $folder);
         return $false;
     }
     if (!empty($position)) {
         $di->seek($position);
         if ($di->key() != $position) {
             $position = null;
             return $arr;
         }
     }
     $counter = 0;
     $maxCounter = $registry->get("engine.scan.large.{$threshold_key}_threshold", $threshold_default);
     while ($di->valid()) {
         if ($di->isDot()) {
             $di->next();
             continue;
         }
         if ($di->isDir() != $forFolders) {
             $di->next();
             continue;
         }
         $ds = $folder == '' || $folder == '/' || @substr($folder, -1) == '/' || @substr($folder, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
         $dir = $folder . $ds . $di->getFilename();
         $data = _AKEEBA_IS_WINDOWS ? Factory::getFilesystemTools()->TranslateWinPath($dir) : $dir;
         if ($data) {
             $counter++;
             $arr[] = $data;
         }
         if ($counter == $maxCounter) {
             break;
         } else {
             $di->next();
         }
     }
     // Determine the new value for the position
     $di->next();
     if ($di->valid()) {
         $position = $di->key() - 1;
     } else {
         $position = null;
     }
     return $arr;
 }
Пример #4
0
 /**
  * Common code which gets called on instance creation or wake-up (unserialization)
  *
  * @codeCoverageIgnore
  *
  * @return  void
  */
 protected function __bootstrap_code()
 {
     if (!defined('AKEEBA_CHUNK')) {
         // Cache chunk override as a constant
         $registry = Factory::getConfiguration();
         $chunk_override = $registry->get('engine.archiver.common.chunk_size', 0);
         define('AKEEBA_CHUNK', $chunk_override > 0 ? $chunk_override : 1048756);
     }
     $this->fsUtils = Factory::getFilesystemTools();
 }
Пример #5
0
 /**
  * Unregister and delete a temporary file
  *
  * @param   string  $fileName      The filename to unregister and delete
  * @param   bool    $removePrefix  The prefix to remove
  *
  * @return  bool  True on success
  */
 public function unregisterAndDeleteTempFile($fileName, $removePrefix = false)
 {
     $configuration = Factory::getConfiguration();
     if ($removePrefix) {
         $fileName = str_replace(Factory::getFilesystemTools()->TranslateWinPath($configuration->get('akeeba.basic.output_directory')), '', $fileName);
         if (substr($fileName, 0, 1) == '/' || substr($fileName, 0, 1) == '\\') {
             $fileName = substr($fileName, 1);
         }
         if (substr($fileName, -1) == '/' || substr($fileName, -1) == '\\') {
             $fileName = substr($fileName, 0, -1);
         }
     }
     // Make sure this file is registered
     $configuration = Factory::getConfiguration();
     $serialised = $configuration->get('volatile.tempfiles', false);
     $tempFiles = array();
     if ($serialised !== false) {
         $tempFiles = @unserialize($serialised);
     }
     if (!is_array($tempFiles)) {
         return false;
     }
     if (!in_array($fileName, $tempFiles)) {
         return false;
     }
     $file = $configuration->get('akeeba.basic.output_directory') . '/' . $fileName;
     Factory::getLog()->log(LogLevel::DEBUG, "-- Removing temporary file {$fileName}");
     $platform = strtoupper(PHP_OS);
     // TODO What exactly are we doing here? chown won't work on Windows. Huh...?
     if (substr($platform, 0, 6) == 'CYGWIN' || substr($platform, 0, 3) == 'WIN') {
         // On Windows we have to chown() the file first to make it owned by Nobody
         Factory::getLog()->log(LogLevel::DEBUG, "-- Windows hack: chowning {$fileName}");
         @chown($file, 600);
     }
     $result = @$this->nullifyAndDelete($file);
     // Make sure the file is removed before unregistering it
     if (!@file_exists($file)) {
         $aPos = array_search($fileName, $tempFiles);
         if ($aPos !== false) {
             unset($tempFiles[$aPos]);
             $configuration->set('volatile.tempfiles', serialize($tempFiles));
         }
     }
     return $result;
 }
Пример #6
0
 /**
  * Save the engine configuration
  *
  * @return  void
  */
 public function saveEngineConfig()
 {
     $data = $this->getState('engineconfig', array());
     // Forbid stupidly selecting the site's root as the output or temporary directory
     if (array_key_exists('akeeba.basic.output_directory', $data)) {
         $folder = $data['akeeba.basic.output_directory'];
         $folder = Factory::getFilesystemTools()->translateStockDirs($folder, true, true);
         $check = Factory::getFilesystemTools()->translateStockDirs('[SITEROOT]', true, true);
         if ($check == $folder) {
             $data['akeeba.basic.output_directory'] = '[DEFAULT_OUTPUT]';
         }
     }
     // Unprotect the configuration and merge it
     $config = Factory::getConfiguration();
     $protectedKeys = $config->getProtectedKeys();
     $config->resetProtectedKeys();
     $config->mergeArray($data, false, false);
     $config->setProtectedKeys($protectedKeys);
     // Save configuration
     Platform::getInstance()->save_configuration();
 }
Пример #7
0
 /**
  * Initialise the logger properties with parameters from the backup profile and the platform
  *
  * @return  void
  */
 protected function initialiseWithProfileParameters()
 {
     // Get the site's translated and untranslated root
     $this->site_root_untranslated = Platform::getInstance()->get_site_root();
     $this->site_root = Factory::getFilesystemTools()->TranslateWinPath($this->site_root_untranslated);
     // Load the registry and fetch log level
     $registry = Factory::getConfiguration();
     $this->configuredLoglevel = $registry->get('akeeba.basic.log_level');
     $this->configuredLoglevel = $this->configuredLoglevel * 1;
 }
Пример #8
0
 /**
  * Initialises the Google Drive connector object
  *
  * @return  bool  True on success, false if we cannot proceed
  */
 protected function initialiseConnector()
 {
     // Retrieve engine configuration data
     $config = Factory::getConfiguration();
     $access_token = trim($config->get('engine.postproc.googledrive.access_token', ''));
     $refresh_token = trim($config->get('engine.postproc.googledrive.refresh_token', ''));
     $this->chunked = $config->get('engine.postproc.googledrive.chunk_upload', true);
     $this->chunk_size = $config->get('engine.postproc.googledrive.chunk_upload_size', 10) * 1024 * 1024;
     $this->directory = $config->get('volatile.postproc.directory', null);
     if (empty($this->directory)) {
         $this->directory = $config->get('engine.postproc.googledrive.directory', '');
     }
     // Sanity checks
     if (empty($refresh_token)) {
         $this->setError('You have not linked Akeeba Backup with your Google Drive account');
         return false;
     }
     if (!function_exists('curl_init')) {
         $this->setWarning('cURL is not enabled, please enable it in order to post-process your archives');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($this->directory)) {
         $this->directory = trim($this->directory);
         $this->directory = ltrim(Factory::getFilesystemTools()->TranslateWinPath($this->directory), '/');
     } else {
         $this->directory = '';
     }
     // Parse tags
     $this->directory = Factory::getFilesystemTools()->replace_archive_name_variables($this->directory);
     $config->set('volatile.postproc.directory', $this->directory);
     $this->googleDrive = new ConnectorGoogleDrive($access_token, $refresh_token);
     // Validate the tokens
     Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::' . __METHOD__ . " - Validating the Google Drive tokens");
     $pingResult = $this->googleDrive->ping();
     // Save new configuration if there was a refresh
     if ($pingResult['needs_refresh']) {
         Factory::getLog()->log(LogLevel::DEBUG, __CLASS__ . '::' . __METHOD__ . " - Google Drive tokens were refreshed");
         $config->set('engine.postproc.googledrive.access_token', $pingResult['access_token'], false);
         $profile_id = Platform::getInstance()->get_active_profile();
         Platform::getInstance()->save_configuration($profile_id);
     }
     return true;
 }
Пример #9
0
 /**
  * Sends an email to the administrators
  *
  * @return bool True on success
  */
 protected function mail_administrators()
 {
     $this->setStep('Processing emails to administrators');
     $this->setSubstep('');
     // Skip email for back-end backups
     if (Platform::getInstance()->get_backup_origin() == 'backend') {
         return true;
     }
     $must_email = Platform::getInstance()->get_platform_configuration_option('frontend_email_on_finish', 0) != 0;
     if (!$must_email) {
         return true;
     }
     Factory::getLog()->log(LogLevel::DEBUG, "Preparing to send e-mail to administrators");
     $email = Platform::getInstance()->get_platform_configuration_option('frontend_email_address', '');
     $email = trim($email);
     if (!empty($email)) {
         Factory::getLog()->log(LogLevel::DEBUG, "Using pre-defined list of emails");
         $emails = explode(',', $email);
     } else {
         Factory::getLog()->log(LogLevel::DEBUG, "Fetching list of Super Administrator emails");
         $emails = Platform::getInstance()->get_administrator_emails();
     }
     if (!empty($emails)) {
         Factory::getLog()->log(LogLevel::DEBUG, "Creating email subject and body");
         // Fetch user's preferences
         $subject = trim(Platform::getInstance()->get_platform_configuration_option('frontend_email_subject', ''));
         $body = trim(Platform::getInstance()->get_platform_configuration_option('frontend_email_body', ''));
         // Get the statistics
         $statistics = Factory::getStatistics();
         $stat = $statistics->getRecord();
         $parts = Factory::getStatistics()->get_all_filenames($stat, false);
         $profile_number = Platform::getInstance()->get_active_profile();
         $profile_name = Platform::getInstance()->get_profile_name($profile_number);
         $parts = Factory::getStatistics()->get_all_filenames($stat, false);
         $stat = (object) $stat;
         $num_parts = $stat->multipart;
         // Non-split archives have a part count of 0
         if ($num_parts == 0) {
             $num_parts = 1;
         }
         $parts_list = '';
         if (!empty($parts)) {
             foreach ($parts as $file) {
                 $parts_list .= "\t" . basename($file) . "\n";
             }
         }
         // Get the remote storage status
         $remote_status = '';
         $post_proc_engine = Factory::getConfiguration()->get('akeeba.advanced.postproc_engine');
         if (!empty($post_proc_engine) && $post_proc_engine != 'none') {
             if (empty($stat->remote_filename)) {
                 $remote_status = Platform::getInstance()->translate('COM_AKEEBA_EMAIL_POSTPROCESSING_FAILED');
             } else {
                 $remote_status = Platform::getInstance()->translate('COM_AKEEBA_EMAIL_POSTPROCESSING_SUCCESS');
             }
         }
         // Do we need a default subject?
         if (empty($subject)) {
             // Get the default subject
             $subject = Platform::getInstance()->translate('EMAIL_SUBJECT_OK');
         } else {
             // Post-process the subject
             $subject = Factory::getFilesystemTools()->replace_archive_name_variables($subject);
         }
         // Do we need a default body?
         if (empty($body)) {
             $body = Platform::getInstance()->translate('EMAIL_BODY_OK');
             $info_source = Platform::getInstance()->translate('EMAIL_BODY_INFO');
             $body .= "\n\n" . sprintf($info_source, $profile_number, $num_parts) . "\n\n";
             $body .= $parts_list;
         } else {
             // Post-process the body
             $body = Factory::getFilesystemTools()->replace_archive_name_variables($body);
             $body = str_replace('[PROFILENUMBER]', $profile_number, $body);
             $body = str_replace('[PROFILENAME]', $profile_name, $body);
             $body = str_replace('[PARTCOUNT]', $num_parts, $body);
             $body = str_replace('[FILELIST]', $parts_list, $body);
             $body = str_replace('[REMOTESTATUS]', $remote_status, $body);
         }
         // Sometimes $body contains literal \n instead of newlines
         $body = str_replace('\\n', "\n", $body);
         foreach ($emails as $email) {
             Factory::getLog()->log(LogLevel::DEBUG, "Sending email to {$email}");
             Platform::getInstance()->send_email($email, $subject, $body);
         }
     } else {
         Factory::getLog()->log(LogLevel::DEBUG, "No email recipients found! Skipping email.");
     }
     return true;
 }
Пример #10
0
 /**
  * Update the cached live site's URL for the front-end backup feature (altbackup.php)
  * and the detected Joomla! libraries path
  */
 public function updateMagicParameters()
 {
     $component = JComponentHelper::getComponent('com_akeeba');
     if (is_object($component->params) && $component->params instanceof JRegistry) {
         $params = $component->params;
     } else {
         $params = new JRegistry($component->params);
     }
     if (!$params->get('confwiz_upgrade', 0)) {
         $this->markOldProfilesConfigured();
     }
     $params->set('confwiz_upgrade', 1);
     $params->set('siteurl', str_replace('/administrator', '', JUri::base()));
     if (defined('JPATH_LIBRARIES')) {
         $params->set('jlibrariesdir', Factory::getFilesystemTools()->TranslateWinPath(JPATH_LIBRARIES));
     } elseif (defined("JPATH_PLATFORM")) {
         $params->set('jlibrariesdir', Factory::getFilesystemTools()->TranslateWinPath(JPATH_PLATFORM));
     }
     $params->set('jversion', '1.6');
     $db = F0FPlatform::getInstance()->getDbo();
     $data = $params->toString();
     $sql = $db->getQuery(true)->update($db->qn('#__extensions'))->set($db->qn('params') . ' = ' . $db->q($data))->where($db->qn('element') . ' = ' . $db->q('com_akeeba'))->where($db->qn('type') . ' = ' . $db->q('component'));
     $db->setQuery($sql);
     $db->execute();
 }
Пример #11
0
 /**
  * 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();
 }
Пример #12
0
 /**
  * Initialises the OneDrive connector object
  *
  * @return  bool  True on success, false if we cannot proceed
  */
 protected function initialiseConnector()
 {
     // Retrieve engine configuration data
     $config = Factory::getConfiguration();
     $access_token = trim($config->get('engine.postproc.dropbox2.access_token', ''));
     $this->chunked = $config->get('engine.postproc.dropbox2.chunk_upload', true);
     $this->chunk_size = $config->get('engine.postproc.dropbox2.chunk_upload_size', 10) * 1024 * 1024;
     $this->directory = $config->get('volatile.postproc.directory', null);
     if (empty($this->directory)) {
         $this->directory = $config->get('engine.postproc.dropbox2.directory', '');
     }
     // Sanity checks
     if (empty($access_token)) {
         $this->setError('You have not linked Akeeba Backup with your Dropbox account');
         return false;
     }
     if (!function_exists('curl_init')) {
         $this->setWarning('cURL is not enabled, please enable it in order to post-process your archives');
         return false;
     }
     // Fix the directory name, if required
     if (!empty($this->directory)) {
         $this->directory = trim($this->directory);
         $this->directory = ltrim(Factory::getFilesystemTools()->TranslateWinPath($this->directory), '/');
     } else {
         $this->directory = '';
     }
     // Parse tags
     $this->directory = Factory::getFilesystemTools()->replace_archive_name_variables($this->directory);
     $config->set('volatile.postproc.directory', $this->directory);
     $this->dropbox2 = new ConnectorDropboxV2($access_token);
     return true;
 }
Пример #13
0
 public function &getFolders($folder, &$position)
 {
     // Was the breakflag set BEFORE starting? -- This workaround is required due to PHP5 defaulting to assigning variables by reference
     $registry = Factory::getConfiguration();
     $breakflag_before_process = $registry->get('volatile.breakflag', false);
     // Reset break flag before continuing
     $breakflag = false;
     // Initialize variables
     $arr = array();
     $false = false;
     if (!is_dir($folder) && !is_dir($folder . '/')) {
         return $false;
     }
     $counter = 0;
     $registry = Factory::getConfiguration();
     $maxCounter = $registry->get('engine.scan.smart.large_dir_threshold', 100);
     $allowBreakflag = $registry->get('volatile.operation_counter', 0) != 0 && !$breakflag_before_process;
     if (!@is_readable($folder)) {
         $this->setWarning('Unreadable directory ' . $folder);
         return $false;
     }
     $di = new \DirectoryIterator($folder);
     $ds = $folder == '' || $folder == '/' || @substr($folder, -1) == '/' || @substr($folder, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
     /** @var \DirectoryIterator $file */
     foreach ($di as $file) {
         if ($breakflag) {
             break;
         }
         if ($file->isDot()) {
             continue;
         }
         if (!$file->isDir()) {
             continue;
         }
         $dir = $folder . $ds . $file->getFilename();
         $data = $dir;
         if (_AKEEBA_IS_WINDOWS) {
             $data = Factory::getFilesystemTools()->TranslateWinPath($dir);
         }
         if ($data) {
             $arr[] = $data;
         }
         $counter++;
         if ($counter >= $maxCounter) {
             $breakflag = $allowBreakflag;
         }
     }
     // Save break flag status
     $registry->set('volatile.breakflag', $breakflag);
     return $arr;
 }
Пример #14
0
    /**
     * Send an email notification for failed backups
     *
     * @return  array  See the CLI script
     */
    public function notifyFailed()
    {
        // Invalidate stale backups
        Factory::resetState(array('global' => true, 'log' => false, 'maxrun' => $this->container->params->get('failure_timeout', 180)));
        // Get the last execution and search for failed backups AFTER that date
        $last = $this->getLastCheck();
        // Get failed backups
        $filters[] = array('field' => 'status', 'operand' => '=', 'value' => 'fail');
        $filters[] = array('field' => 'origin', 'operand' => '<>', 'value' => 'restorepoint');
        $filters[] = array('field' => 'backupstart', 'operand' => '>', 'value' => $last);
        $failed = Platform::getInstance()->get_statistics_list(array('filters' => $filters));
        // Well, everything went ok.
        if (!$failed) {
            return array('message' => array("No need to run: no failed backups or notifications were already sent."), 'result' => true);
        }
        // Whops! Something went wrong, let's start notifing
        $superAdmins = array();
        $superAdminEmail = $this->container->params->get('failure_email_address', '');
        if (!empty($superAdminEmail)) {
            $superAdmins = $this->getSuperUsers($superAdminEmail);
        }
        if (empty($superAdmins)) {
            $superAdmins = $this->getSuperUsers();
        }
        if (empty($superAdmins)) {
            return array('message' => array("WARNING! Failed backup(s) detected, but there are no configured Super Administrators to receive notifications"), 'result' => false);
        }
        $failedReport = array();
        foreach ($failed as $fail) {
            $string = "Description : " . $fail['description'] . "\n";
            $string .= "Start time  : " . $fail['backupstart'] . "\n";
            $string .= "Origin      : " . $fail['origin'] . "\n";
            $string .= "Type        : " . $fail['type'] . "\n";
            $string .= "Profile ID  : " . $fail['profile_id'];
            $failedReport[] = $string;
        }
        $failedReport = implode("\n#-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+#\n", $failedReport);
        $email_subject = $this->container->params->get('failure_email_subject', '');
        if (!$email_subject) {
            $email_subject = <<<ENDSUBJECT
THIS EMAIL IS SENT FROM YOUR SITE "[SITENAME]" - Failed backup(s) detected
ENDSUBJECT;
        }
        $email_body = $this->container->params->get('failure_email_body', '');
        if (!$email_body) {
            $email_body = <<<ENDBODY
================================================================================
FAILED BACKUP ALERT
================================================================================

Your site has determined that there are failed backups.

The following backups are found to be failing:

[FAILEDLIST]

================================================================================
WHY AM I RECEIVING THIS EMAIL?
================================================================================

This email has been automatically sent by scritp you, or the person who built
or manages your site, has installed and explicitly configured. This script looks
for failed backups and sends an email notification to all Super Users.

If you do not understand what this means, please do not contact the authors of
the software. They are NOT sending you this email and they cannot help you.
Instead, please contact the person who built or manages your site.

================================================================================
WHO SENT ME THIS EMAIL?
================================================================================

This email is sent to you by your own site, [SITENAME]

ENDBODY;
        }
        $jconfig = JFactory::getConfig();
        $mailfrom = $jconfig->get('mailfrom');
        $fromname = $jconfig->get('fromname');
        $email_subject = Factory::getFilesystemTools()->replace_archive_name_variables($email_subject);
        $email_body = Factory::getFilesystemTools()->replace_archive_name_variables($email_body);
        $email_body = str_replace('[FAILEDLIST]', $failedReport, $email_body);
        foreach ($superAdmins as $sa) {
            try {
                $mailer = JFactory::getMailer();
                $mailer->setSender(array($mailfrom, $fromname));
                $mailer->addRecipient($sa->email);
                $mailer->setSubject($email_subject);
                $mailer->setBody($email_body);
                $mailer->Send();
            } catch (\Exception $e) {
                // Joomla! 3.5 is written by incompetent bonobos
            }
        }
        // Let's update the last time we check, so we will avoid to send
        // the same notification several times
        $this->updateLastCheck(intval($last));
        return array('message' => array("WARNING! Found " . count($failed) . " failed backup(s)", "Sent " . count($superAdmins) . " notifications"), 'result' => true);
    }
Пример #15
0
 public function &getFolders($folder, $fullpath = false)
 {
     // Initialize variables
     $arr = array();
     $false = false;
     if (!is_dir($folder) && !is_dir($folder . '/')) {
         return $false;
     }
     $handle = @opendir($folder);
     if ($handle === false) {
         $handle = @opendir($folder . '/');
     }
     // If directory is not accessible, just return FALSE
     if ($handle === false) {
         return $false;
     }
     $registry = Factory::getConfiguration();
     $dereferencesymlinks = $registry->get('engine.archiver.common.dereference_symlinks');
     while (($file = @readdir($handle)) !== false) {
         if ($file != '.' && $file != '..') {
             $dir = "{$folder}/{$file}";
             $isDir = @is_dir($dir);
             $isLink = @is_link($dir);
             if ($isDir) {
                 //if(!$dereferencesymlinks && $isLink) continue;
                 if ($fullpath) {
                     $data = _AKEEBA_IS_WINDOWS ? Factory::getFilesystemTools()->TranslateWinPath($dir) : $dir;
                 } else {
                     $data = _AKEEBA_IS_WINDOWS ? Factory::getFilesystemTools()->TranslateWinPath($file) : $file;
                 }
                 if ($data) {
                     $arr[] = $data;
                 }
             }
         }
     }
     @closedir($handle);
     return $arr;
 }
Пример #16
0
 /**
  * Get the paths for a specific section
  *
  * @param   string $section The section to get the path list for (engine, installer, gui, filter)
  *
  * @return  array
  */
 public function getEnginePartPaths($section = 'gui')
 {
     // Create the key if it's not already present
     if (!array_key_exists($section, $this->enginePartPaths)) {
         $this->enginePartPaths[$section] = array();
     }
     // Add the defaults if the list is empty
     if (empty($this->enginePartPaths[$section])) {
         switch ($section) {
             case 'engine':
                 $this->enginePartPaths[$section] = array(Factory::getFilesystemTools()->TranslateWinPath(Factory::getAkeebaRoot()));
                 break;
             case 'installer':
                 $this->enginePartPaths[$section] = array(Factory::getFilesystemTools()->TranslateWinPath(Platform::getInstance()->get_installer_images_path()));
                 break;
             case 'gui':
                 // Add core GUI definitions
                 $this->enginePartPaths[$section] = array(Factory::getFilesystemTools()->TranslateWinPath(Factory::getAkeebaRoot() . '/Core'));
                 // Add platform GUI definition files
                 $platform_paths = Platform::getInstance()->getPlatformDirectories();
                 foreach ($platform_paths as $p) {
                     $this->enginePartPaths[$section][] = Factory::getFilesystemTools()->TranslateWinPath($p . '/Config');
                     if (defined('AKEEBA_PRO') && AKEEBA_PRO) {
                         $this->enginePartPaths[$section][] = Factory::getFilesystemTools()->TranslateWinPath($p . '/Config/Pro');
                     }
                 }
                 break;
             case 'filter':
                 $this->enginePartPaths[$section] = array(Factory::getFilesystemTools()->TranslateWinPath(Factory::getAkeebaRoot() . '/Platform/Filter/Stack'), Factory::getFilesystemTools()->TranslateWinPath(Factory::getAkeebaRoot() . '/Filter/Stack'));
                 $platform_paths = Platform::getInstance()->getPlatformDirectories();
                 foreach ($platform_paths as $p) {
                     $this->enginePartPaths[$section][] = Factory::getFilesystemTools()->TranslateWinPath($p . '/Filter/Stack');
                 }
                 break;
         }
     }
     return $this->enginePartPaths[$section];
 }
Пример #17
0
 /**
  * Common code which gets called on instance creation or wake-up (unserialization)
  *
  * @codeCoverageIgnore
  *
  * @return  void
  */
 protected function __bootstrap_code()
 {
     $this->fsUtils = Factory::getFilesystemTools();
 }
Пример #18
0
 /**
  * Returns a listing of contained directories and files, as well as their
  * exclusion status
  * @param string $root The root directory
  * @param string $node The subdirectory to scan
  * @return array
  */
 private function &get_listing($root, $node)
 {
     // Initialize the absolute directory root
     $directory = substr($root, 0);
     // Replace stock directory tags, like [SITEROOT]
     $stock_dirs = Platform::getInstance()->get_stock_directories();
     if (!empty($stock_dirs)) {
         foreach ($stock_dirs as $key => $replacement) {
             $directory = str_replace($key, $replacement, $directory);
         }
     }
     $directory = Factory::getFilesystemTools()->TranslateWinPath($directory);
     // Clean and add the node
     $node = Factory::getFilesystemTools()->TranslateWinPath($node);
     if ($node == '/') {
         $node = '';
     }
     // Just a dir. sep. is treated as no dir at all
     // Trim leading and trailing slashes
     $node = trim($node, '/');
     // Add node to directory
     if (!empty($node)) {
         $directory .= '/' . $node;
     }
     // Add any required trailing slash to the node to be used below
     if (!empty($node)) {
         $node .= '/';
     }
     // Get a filters instance
     $filters = Factory::getFilters();
     // Get a listing of folders and process it
     $folders = Factory::getFileLister()->getFolders($directory);
     asort($folders);
     $folders_out = array();
     if (!empty($folders)) {
         foreach ($folders as $folder) {
             $folder = Factory::getFilesystemTools()->TranslateWinPath($folder);
             // Filter out files whose names result to an empty JSON representation
             $json_folder = json_encode($folder);
             $folder = json_decode($json_folder);
             if (empty($folder)) {
                 continue;
             }
             $test = $node . $folder;
             $status = array();
             // Check dir/all filter (exclude)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'all', $byFilter);
             $status['directories'] = !$result ? 0 : ($byFilter == 'directories' ? 1 : 2);
             // Check dir/content filter (skip_files)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'content', $byFilter);
             $status['skipfiles'] = !$result ? 0 : ($byFilter == 'skipfiles' ? 1 : 2);
             // Check dir/children filter (skip_dirs)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'children', $byFilter);
             $status['skipdirs'] = !$result ? 0 : ($byFilter == 'skipdirs' ? 1 : 2);
             // Add to output array
             $folders_out[$folder] = $status;
         }
     }
     unset($folders);
     $folders = $folders_out;
     // Get a listing of files and process it
     $files = Factory::getFileLister()->getFiles($directory);
     asort($files);
     $files_out = array();
     if (!empty($files)) {
         foreach ($files as $file) {
             // Filter out files whose names result to an empty JSON representation
             $json_file = json_encode($file);
             $file = json_decode($json_file);
             if (empty($file)) {
                 continue;
             }
             $test = $node . $file;
             $status = array();
             // Check file/all filter (exclude)
             $result = $filters->isFilteredExtended($test, $root, 'file', 'all', $byFilter);
             $status['files'] = !$result ? 0 : ($byFilter == 'files' ? 1 : 2);
             $status['size'] = @filesize($directory . '/' . $file);
             // Add to output array
             $files_out[$file] = $status;
         }
     }
     unset($files);
     $files = $files_out;
     // Return a compiled array
     $retarray = array('folders' => $folders, 'files' => $files);
     return $retarray;
     /* Return array format
      * [array] :
      * 		'folders' [array] :
      * 			(folder_name) => [array]:
      *				'directories'	=> 0|1|2
      *				'skipfiles'		=> 0|1|2
      *				'skipdirs'		=> 0|1|2
      *		'files' [array] :
      *			(file_name) => [array]:
      *				'files'			=> 0|1|2
      *
      * Legend:
      * 0 -> Not excluded
      * 1 -> Excluded by the direct filter
      * 2 -> Excluded by another filter (regex, api, an unknown plugin filter...)
      */
 }
Пример #19
0
 /**
  * Q203 - MED  - Default output directory in use
  *
  * @return  bool
  */
 private function q203()
 {
     $stock_dirs = Platform::getInstance()->get_stock_directories();
     $registry = Factory::getConfiguration();
     $outdir = $registry->get('akeeba.basic.output_directory');
     foreach ($stock_dirs as $macro => $replacement) {
         $outdir = str_replace($macro, $replacement, $outdir);
     }
     $default = $stock_dirs['[DEFAULT_OUTPUT]'];
     $outdir = Factory::getFilesystemTools()->TranslateWinPath($outdir);
     $default = Factory::getFilesystemTools()->TranslateWinPath($default);
     return $outdir == $default;
 }
Пример #20
0
 /**
  * Returns the relative and absolute path to the archive
  */
 protected function getArchiveName()
 {
     $registry = Factory::getConfiguration();
     // Import volatile scripting keys to the registry
     Factory::getEngineParamsProvider()->importScriptingToRegistry();
     // Determine the extension
     $force_extension = Factory::getEngineParamsProvider()->getScriptingParameter('core.forceextension', null);
     if (is_null($force_extension)) {
         $archiver = Factory::getArchiverEngine();
         $extension = $archiver->getExtension();
     } else {
         $extension = $force_extension;
     }
     // Get the template name
     $templateName = $registry->get('akeeba.basic.archive_name');
     Factory::getLog()->log(LogLevel::DEBUG, "Archive template name: {$templateName}");
     // Parse all tags
     $fsUtils = Factory::getFilesystemTools();
     $templateName = $fsUtils->replace_archive_name_variables($templateName);
     Factory::getLog()->log(LogLevel::DEBUG, "Expanded template name: {$templateName}");
     $ds = DIRECTORY_SEPARATOR;
     $relative_path = $templateName . $extension;
     $absolute_path = $fsUtils->TranslateWinPath($registry->get('akeeba.basic.output_directory') . $ds . $relative_path);
     return array($relative_path, $absolute_path);
 }
Пример #21
0
 /**
  * Returns a listing of contained directories and files, as well as their
  * exclusion status
  * @param string $root The root directory
  * @param string $node The subdirectory to scan
  * @return array
  */
 private function &get_listing($root, $node)
 {
     // Initialize the absolute directory root
     $directory = substr($root, 0);
     // Replace stock directory tags, like [SITEROOT]
     $stock_dirs = Platform::getInstance()->get_stock_directories();
     if (!empty($stock_dirs)) {
         foreach ($stock_dirs as $key => $replacement) {
             $directory = str_replace($key, $replacement, $directory);
         }
     }
     $directory = Factory::getFilesystemTools()->TranslateWinPath($directory);
     // Clean and add the node
     $node = Factory::getFilesystemTools()->TranslateWinPath($node);
     if ($node == '/') {
         $node = '';
     }
     // Just a dir. sep. is treated as no dir at all
     // Trim leading and trailing slashes
     $node = trim($node, '/');
     // Add node to directory
     if (!empty($node)) {
         $directory .= '/' . $node;
     }
     // Add any required trailing slash to the node to be used below
     if (!empty($node)) {
         $node .= '/';
     }
     // Get a filters instance
     $filters = Factory::getFilters();
     // Detect PHP 5.2.5or earlier, with broken json_decode implementation
     $phpversion = PHP_VERSION;
     $vparts = explode('.', $phpversion);
     if ($vparts[0] == 5 && $vparts[1] == 2 && $vparts[2] <= 5 || $vparts[0] == 5 && $vparts[1] == 1) {
         define('AKEEBA_SAFE_JSON', false);
         require_once JPATH_COMPONENT_ADMINISTRATOR . '/helpers/jsonlib.php';
     } else {
         $test = '-test-';
         $tj = json_encode($test);
         $test = json_decode($test);
         if ($test == '-test-') {
             define('AKEEBA_SAFE_JSON', true);
         } else {
             define('AKEEBA_SAFE_JSON', false);
             require_once JPATH_COMPONENT_ADMINISTRATOR . '/helpers/jsonlib.php';
         }
     }
     // Get a listing of folders and process it
     $folders = Factory::getFileLister()->getFolders($directory);
     asort($folders);
     $folders_out = array();
     if (!empty($folders)) {
         foreach ($folders as $folder) {
             $folder = Factory::getFilesystemTools()->TranslateWinPath($folder);
             // Filter out files whose names result to an empty JSON representation
             if (AKEEBA_SAFE_JSON) {
                 $json_folder = json_encode($folder);
                 $folder = json_decode($json_folder);
             } else {
                 $jsonobj = new Akeeba_Services_JSON(0);
                 $json_folder = $jsonobj->encode($folder);
                 $folder = $jsonobj->decode($json_folder);
             }
             if (empty($folder)) {
                 continue;
             }
             $test = $node . $folder;
             $status = array();
             // Check dir/all filter (exclude)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'all', $byFilter);
             $status['directories'] = !$result ? 0 : ($byFilter == 'directories' ? 1 : 2);
             // Check dir/content filter (skip_files)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'content', $byFilter);
             $status['skipfiles'] = !$result ? 0 : ($byFilter == 'skipfiles' ? 1 : 2);
             // Check dir/children filter (skip_dirs)
             $result = $filters->isFilteredExtended($test, $root, 'dir', 'children', $byFilter);
             $status['skipdirs'] = !$result ? 0 : ($byFilter == 'skipdirs' ? 1 : 2);
             // Add to output array
             $folders_out[$folder] = $status;
         }
     }
     unset($folders);
     $folders = $folders_out;
     // Get a listing of files and process it
     $files = Factory::getFileLister()->getFiles($directory);
     asort($files);
     $files_out = array();
     if (!empty($files)) {
         foreach ($files as $file) {
             // Filter out files whose names result to an empty JSON representation
             if (AKEEBA_SAFE_JSON) {
                 $json_file = json_encode($file);
                 $file = json_decode($json_file);
             } else {
                 $jsonobj = new Akeeba_Services_JSON(0);
                 $json_file = $jsonobj->encode($file);
                 $file = $jsonobj->decode($json_file);
             }
             if (empty($file)) {
                 continue;
             }
             $test = $node . $file;
             $status = array();
             // Check file/all filter (exclude)
             $result = $filters->isFilteredExtended($test, $root, 'file', 'all', $byFilter);
             $status['files'] = !$result ? 0 : ($byFilter == 'files' ? 1 : 2);
             $status['size'] = @filesize($directory . '/' . $file);
             // Add to output array
             $files_out[$file] = $status;
         }
     }
     unset($files);
     $files = $files_out;
     // Return a compiled array
     $retarray = array('folders' => $folders, 'files' => $files);
     return $retarray;
     /* Return array format
      * [array] :
      * 		'folders' [array] :
      * 			(folder_name) => [array]:
      *				'directories'	=> 0|1|2
      *				'skipfiles'		=> 0|1|2
      *				'skipdirs'		=> 0|1|2
      *		'files' [array] :
      *			(file_name) => [array]:
      *				'files'			=> 0|1|2
      *
      * Legend:
      * 0 -> Not excluded
      * 1 -> Excluded by the direct filter
      * 2 -> Excluded by another filter (regex, api, an unknown plugin filter...)
      */
 }
Пример #22
0
 /**
  * Steps the files scanning of the current directory
  *
  * @return  boolean  True on success, false on fatal error
  */
 protected function scanFiles()
 {
     $engine = Factory::getScanEngine();
     list($root, $translated_root, $dir) = $this->getCleanDirectoryComponents();
     // Get a filters instance
     $filters = Factory::getFilters();
     if (is_null($this->getFiles_position)) {
         Factory::getLog()->log(LogLevel::INFO, "Scanning files of " . $this->current_directory);
         $this->processed_files_counter = 0;
     } else {
         Factory::getLog()->log(LogLevel::INFO, "Resuming scanning files of " . $this->current_directory);
     }
     // Get file listing
     $fileList = $engine->getFiles($this->current_directory, $this->getFiles_position);
     // Error propagation
     $this->propagateFromObject($engine);
     // If the list contains "too many" items, please break this step!
     if (Factory::getConfiguration()->get('volatile.breakflag', false)) {
         // Log the step break decision, for debugging reasons
         Factory::getLog()->log(LogLevel::INFO, "Large directory " . $this->current_directory . " while scanning for files; I will resume scanning in next step.");
         // Return immediately, marking that we are not done yet!
         return true;
     }
     // Error control
     if ($this->getError()) {
         return false;
     }
     // Do I have an unreadable directory?
     if ($fileList === false) {
         $this->setWarning('Unreadable directory ' . $this->current_directory);
         $this->done_file_scanning = true;
     } else {
         if (is_array($fileList) && !empty($fileList)) {
             // Add required trailing slash to $dir
             if (!empty($dir)) {
                 $dir .= '/';
             }
             // Scan all directory entries
             foreach ($fileList as $fileName) {
                 $check = $dir . basename($fileName);
                 if (_AKEEBA_IS_WINDOWS) {
                     $check = Factory::getFilesystemTools()->TranslateWinPath($check);
                 }
                 // Do I need this? $dir contains a path relative to the root anyway...
                 $check = ltrim(str_replace($translated_root, '', $check), '/');
                 $byFilter = '';
                 $skipThisFile = $filters->isFilteredExtended($check, $root, 'file', 'all', $byFilter);
                 if ($skipThisFile) {
                     Factory::getLog()->log(LogLevel::INFO, "Skipping file {$fileName} (filter: {$byFilter})");
                 } else {
                     $this->file_list[] = $fileName;
                     $this->processed_files_counter++;
                     $this->progressAddFile();
                 }
             }
         }
     }
     // If the scanner engine nullified the next position we are done
     // scanning for files
     if (is_null($this->getFiles_position)) {
         $this->done_file_scanning = true;
     }
     // If the directory was genuinely empty we will have to add an empty
     // directory entry in the archive, otherwise this directory will never
     // be restored.
     if ($this->done_file_scanning && $this->processed_files_counter == 0) {
         Factory::getLog()->log(LogLevel::INFO, "Empty directory " . $this->current_directory);
         $archiver = Factory::getArchiverEngine();
         if ($this->current_directory != $this->remove_path_prefix) {
             $archiver->addFile($this->current_directory, $this->remove_path_prefix, $this->path_prefix);
         }
         // Error propagation
         $this->propagateFromObject($archiver);
         // Check for errors
         if ($this->getError()) {
             return false;
         }
         unset($archiver);
     }
     return true;
 }
Пример #23
0
 /**
  * Remove the root prefix from an absolute path
  *
  * @param   string  $directory  The absolute path
  *
  * @return  string  The translated path, relative to the root directory of the backup job
  */
 protected function treatDirectory($directory)
 {
     if (!is_object($this->fsTools)) {
         $this->fsTools = Factory::getFilesystemTools();
     }
     // Get the site's root
     $configuration = Factory::getConfiguration();
     if ($configuration->get('akeeba.platform.override_root', 0)) {
         $root = $configuration->get('akeeba.platform.newroot', '[SITEROOT]');
     } else {
         $root = '[SITEROOT]';
     }
     if (stristr($root, '[')) {
         $root = $this->fsTools->translateStockDirs($root);
     }
     $site_root = $this->fsTools->TrimTrailingSlash($this->fsTools->TranslateWinPath($root));
     $directory = $this->fsTools->TrimTrailingSlash($this->fsTools->TranslateWinPath($directory));
     // Trim site root from beginning of directory
     if (substr($directory, 0, strlen($site_root)) == $site_root) {
         $directory = substr($directory, strlen($site_root));
         if (substr($directory, 0, 1) == '/') {
             $directory = substr($directory, 1);
         }
     }
     return $directory;
 }