3) { $dirParts = array_splice($dirParts, 0, -3); $myDir = implode(DIRECTORY_SEPARATOR, $dirParts); } if (@file_exists(__DIR__ . '/../../helpers/integration.php')) { require_once __DIR__ . '/../../helpers/integration.php'; } elseif (@file_exists('../../helpers/integration.php')) { require_once '../../helpers/integration.php'; } elseif (@file_exists($myDir . '/helpers/integration.php')) { require_once $myDir . '/helpers/integration.php'; } // Load the platform defines if (!defined('APATH_BASE')) { require_once __DIR__ . '/../defines.php'; } // Load the version file if (@file_exists(__DIR__ . '/../version.php')) { require_once __DIR__ . '/../version.php'; } // Add our app to the autoloader, if it's not already set $prefixes = Autoloader::getInstance()->getPrefixes(); if (!array_key_exists('Solo\\', $prefixes)) { Autoloader::getInstance()->addMap('Solo\\', APATH_BASE . '/Solo'); } // Include the Akeeba Engine factory if (!defined('AKEEBAENGINE')) { define('AKEEBAENGINE', 1); $factoryPath = __DIR__ . '/../Solo/engine/Factory.php'; // Load the engine if (!file_exists($factoryPath)) { echo "ERROR!\n"; echo "Could not load the backup engine; file does not exist. Technical information:\n"; echo "Path to " . basename(__FILE__) . ": " . __DIR__ . "\n"; echo "Path to factory file: $factoryPath\n"; die("\n"); } else { try { require_once $factoryPath; } catch (\Exception $e) { echo "ERROR!\n"; echo "Backup engine returned an error. Technical information:\n"; echo "Error message:\n\n"; echo $e->getMessage() . "\n\n"; echo "Path to " . basename(__FILE__) . ":" . __DIR__ . "\n"; echo "Path to factory file: $factoryPath\n"; die("\n"); } } Platform::addPlatform('Solo', __DIR__ . '/../Solo/Platform/Solo'); Platform::getInstance()->load_version_defines(); Platform::getInstance()->apply_quirk_definitions(); } class BackupApplication extends \Awf\Application\Cli { const secretKeyRelativePath = '/engine/secretkey.php'; public function __construct(\Awf\Container\Container $container = null) { parent::__construct($container); if (empty($this->container->basePath)) { $this->container->basePath = APATH_BASE . '/Solo'; } } public function initialise() { // Load the extra language files Text::loadLanguage(null, 'akeeba', '.com_akeeba.ini', true, $this->container->languagePath); // Halt if the configuration does not exist yet $configPath = $this->getContainer()->appConfig->getDefaultPath(); if (!@file_exists($configPath)) { $this->out('Configuration not found; aborting'); $this->close(254); } // Load the configuration if it's present if (@file_exists($configPath)) { // Load the application's configuration $this->container->appConfig->loadConfiguration($configPath); // Load Akeeba Engine's settings encryption preferences $secretKeyFile = $this->getContainer()->basePath . static::secretKeyRelativePath; if (@file_exists($secretKeyFile)) { require_once $secretKeyFile; } // Load Akeeba Engine's configuration Platform::getInstance()->load_configuration(); } return $this; } /** * Language file processing callback. It converts _QQ_ to " and replaces the product name in the legacy INI files * imported from Akeeba Backup for Joomla!. * * @param string $filename The full path to the file being loaded * @param array $strings The key/value array of the translations * * @return boolean|array False to prevent loading the file, or array of processed language string, or true to * ignore this processing callback. */ public function processLanguageIniFile($filename, $strings) { foreach ($strings as $k => $v) { $v = str_replace('_QQ_', '"', $v); $v = str_replace('Akeeba Backup', 'Akeeba Solo', $v); $strings[$k] = $v; } return $strings; } /** * Method to run the application routines. Most likely you will want to instantiate a controller * and execute it, or perform some sort of task directly. * * @return void */ protected function doExecute() { // Get the backup profile and description $profile = $this->getContainer()->input->get('profile', 1, 'int'); if($profile <= 0) { $profile = 1; } $debugmessage = ''; if ($this->getContainer()->input->get('debug', -1, 'int') != -1) { if (!defined('AKEEBADEBUG')) { define('AKEEBADEBUG', 1); } $debugmessage = "*** DEBUG MODE ENABLED ***\n"; } $version = AKEEBA_VERSION; $date = AKEEBA_DATE; $start_backup = time(); $memusage = $this->memUsage(); $phpversion = PHP_VERSION; $phpenvironment = PHP_SAPI; $phpos = PHP_OS; if ($this->getContainer()->input->get('quiet', -1, 'int') == -1) { $year = gmdate('Y'); echo <<getContainer()->input->get('quiet', -1, 'int') == -1) { echo "Unsetting time limit restrictions.\n"; } @set_time_limit(0); } elseif (!$safe_mode) { if ($this->getContainer()->input->get('quiet', -1, 'int') == -1) { echo "Could not unset time limit restrictions; you may get a timeout error\n"; } } else { if ($this->getContainer()->input->get('quiet', -1, 'int') == -1) { echo "You are using PHP's Safe Mode; you may get a timeout error\n"; } } if ($this->getContainer()->input->get('quiet', -1, 'int') == -1) { echo "\n"; } // Log some paths if ($this->getContainer()->input->get('quiet', -1, 'int') == -1) { echo "Site paths determined by this script:\n"; echo "APATH_BASE : " . APATH_BASE . "\n"; } $startup_check = true; $url = Platform::getInstance()->get_platform_configuration_option('siteurl', ''); if (empty($url)) { echo <<get_platform_configuration_option('frontend_enable', ''); $secret = Platform::getInstance()->get_platform_configuration_option('frontend_secret_word', ''); if (!$frontend_enabled) { echo <<getContainer()->input->get('method', '', 'cmd'); if (!empty($overridemethod)) { $method = $overridemethod; } if (empty($method)) { echo <<close(255); } echo <<fetchURL($url, $method); echo "[{$timestamp}] Got $result\n"; if (empty($result) || ($result === false)) { echo "[{$timestamp}] No message received\n"; echo <<timeago($start_backup, time(), '', false) . "\n"; echo "Peak memory usage: " . $this->peakMemUsage() . "\n\n"; } elseif (strpos($result, '500 ERROR -- ') !== false) { // Backup error echo "[{$timestamp}] Error signal received\n"; echo <<fetchURL($headers['location'], $method); } else { return ($body); } break; case 'fopen': $opts = array( 'http' => array( 'method' => "GET", 'header' => "Accept-language: en\r\n" ) ); $context = stream_context_create($opts); $result = @file_get_contents($url, false, $context); break; } return $result; } /** * Returns a fancy formatted time lapse code * * @param integer $referenceDateTime Timestamp of the reference date/time * @param string|integer $currentDateTime Timestamp of the current date/time * @param string $measureBy One of s, m, h, d, or y (time unit) * @param boolean $autoText Append text automatically? * * @return string */ private function timeago($referenceDateTime = 0, $currentDateTime = '', $measureBy = '', $autoText = true) { if ($currentDateTime == '') { $currentDateTime = time(); } // Raw time difference $Raw = $currentDateTime - $referenceDateTime; $Clean = abs($Raw); $calcNum = array( array('s', 60), array('m', 60 * 60), array('h', 60 * 60 * 60), array('d', 60 * 60 * 60 * 24), array('y', 60 * 60 * 60 * 24 * 365) ); $calc = array( 's' => array(1, 'second'), 'm' => array(60, 'minute'), 'h' => array(60 * 60, 'hour'), 'd' => array(60 * 60 * 24, 'day'), 'y' => array(60 * 60 * 24 * 365, 'year') ); if ($measureBy == '') { $usemeasure = 's'; for ($i = 0; $i < count($calcNum); $i++) { if ($Clean <= $calcNum[$i][1]) { $usemeasure = $calcNum[$i][0]; $i = count($calcNum); } } } else { $usemeasure = $measureBy; } $datedifference = floor($Clean / $calc[$usemeasure][0]); if ($autoText == true && ($currentDateTime == time())) { if ($Raw < 0) { $prospect = ' from now'; } else { $prospect = ' ago'; } } else { $prospect = ''; } if ($referenceDateTime != 0) { if ($datedifference == 1) { return $datedifference . ' ' . $calc[$usemeasure][1] . ' ' . $prospect; } else { return $datedifference . ' ' . $calc[$usemeasure][1] . 's ' . $prospect; } } else { return 'No input time referenced.'; } } /** * Returns the current memory usage * * @return string */ private function memUsage() { if (function_exists('memory_get_usage')) { $size = memory_get_usage(); $unit = array('b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'); return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; } else { return "(unknown)"; } } /** * Returns the peak memory usage * * @return string */ private function peakMemUsage() { if (function_exists('memory_get_peak_usage')) { $size = memory_get_peak_usage(); $unit = array('b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'); return @round($size / pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $unit[$i]; } else { return "(unknown)"; } } /** * Parses POSIX command line options and returns them as an associative array. Each array item contains * a single dimensional array of values. Arguments without a dash are silently ignored. * * @return array */ private function parseOptions() { global $argc, $argv; // Workaround for PHP-CGI if (!isset($argc) && !isset($argv)) { $query = ""; if (!empty($_GET)) { foreach ($_GET as $k => $v) { $query .= " $k"; if ($v != "") { $query .= "=$v"; } } } $query = ltrim($query); $argv = explode(' ', $query); $argc = count($argv); } $currentName = ""; $options = array(); for ($i = 1; $i < $argc; $i++) { $argument = $argv[$i]; if (strpos($argument, "-") === 0) { $argument = ltrim($argument, '-'); if (strstr($argument, '=')) { list($name, $value) = explode('=', $argument, 2); } else { $name = $argument; $value = null; } $currentName = $name; if (!isset($options[$currentName]) || ($options[$currentName] == null)) { $options[$currentName] = array(); } } else { $value = $argument; } if ((!is_null($value)) && (!is_null($currentName))) { if (strstr($value, '=')) { $parts = explode('=', $value, 2); $key = $parts[0]; $value = $parts[1]; } else { $key = null; } $values = $options[$currentName]; if (is_null($values)) { $values = array(); } if (is_null($key)) { array_push($values, $value); } else { $values[$key] = $value; } $options[$currentName] = $values; } } return $options; } /** * Returns the value of a command line option * * @param string $key The full name of the option, e.g. "foobar" * @param mixed $default The default value to return * @param boolean $first_item_only Return only the first value specified (default = true) * * @return mixed */ private function getOption($key, $default = null, $first_item_only = true) { static $options = null; if (is_null($options)) { $options = $this->parseOptions(); } if (!array_key_exists($key, $options)) { return $default; } else { if ($first_item_only) { return $options[$key][0]; } else { return $options[$key]; } } } } if (!isset($container)) { $container = new \Solo\Container(); } $app = new BackupApplication($container); $app->initialise()->execute();