Example #1
0
     $app->downloadPackage($_REQUEST['id']);
     return array(CONTROLLER_STATUS_REDIRECT, 'upgrade_center.manage');
 }
 if ($mode == 'upload') {
     $upgrade_pack = fn_filter_uploaded_data('upgrade_pack', Registry::get('config.allowed_pack_exts'));
     if (empty($upgrade_pack[0])) {
         fn_set_notification('E', __('error'), __('text_allowed_to_upload_file_extension', array('[ext]' => implode(',', Registry::get('config.allowed_pack_exts')))));
     } else {
         $upgrade_pack = $upgrade_pack[0];
         $app->uploadUpgradePack($upgrade_pack);
     }
     return array(CONTROLLER_STATUS_REDIRECT, 'upgrade_center.manage');
 }
 if ($mode == 'install') {
     if (!empty($_REQUEST['change_ftp_settings'])) {
         Log::instance($_REQUEST['id'])->add('Update FTP connection settings');
         foreach ($_REQUEST['change_ftp_settings'] as $setting_name => $value) {
             Settings::instance()->updateValue($setting_name, $value, '', true);
             Registry::set('settings.Upgrade_center.' . $setting_name, $value);
         }
     }
     fn_delete_notification('uc.timeout_check_success');
     list($result, $data) = $app->install($_REQUEST['id'], $_REQUEST);
     if ($result === UpgradeCenter::PACKAGE_INSTALL_RESULT_FAIL) {
         $view = Tygh::$app['view'];
         $view->assign('validation_result', $result);
         $view->assign('validation_data', $data);
         $view->assign('id', str_replace('.', '_', $_REQUEST['id']));
         $view->assign('type', $_REQUEST['type']);
         $view->assign('caption', __('continue'));
         $view->assign('show_pre_upgrade_notice', false);
Example #2
0
 /**
  * Validates and installs package
  *
  * @todo Implement language installer
  * @todo Additional migrations validation
  *
  * @param string $package_id Package id like "core", "access_restrictions", etc
  * @return array($result, $data) Installation result
  */
 public function install($package_id, $request)
 {
     $result = true;
     $logger = Log::instance($package_id);
     $logger->add('');
     $logger->add(str_replace('[package_id]', $package_id, 'Start installation of the "[package_id]" upgrade package'));
     $logger->add('================================================');
     $logger->add('Get all available validators');
     Output::steps(5);
     // Validators, Backups (database/files), Copying Files, Migrations, Languages
     Output::display(__('uc_title_validators'), __('uc_upgrade_progress'), false);
     $validators = $this->getValidators();
     $schema = $this->getSchema($package_id, true);
     $information_schema = $this->getSchema($package_id, false);
     $package_validators = $this->getPackageValidators($package_id, $schema);
     if (!empty($package_validators)) {
         $validators = array_merge($package_validators, $validators);
     }
     foreach ($validators as $validator) {
         $logger->add(str_replace('[validator]', $validator->getName(), 'Execute "[validator]" validator'));
         Output::display(__('uc_execute_validator', array('[validator]' => $validator->getName())), '', false);
         list($result, $data) = $validator->check($schema, $request);
         if (!$result) {
             break;
         }
     }
     if (!$result) {
         $logger->add('Upgrade stopped: Awaiting resolving validation errors: ' . $validator->getName());
         return array($result, array($validator->getName() => $data));
     } else {
         $backup_filename = "upg_{$package_id}_{$information_schema['from_version']}-{$information_schema['to_version']}_" . date('dMY_His', TIME);
         // Prepare restore.php file. Paste necessary data and access information
         $restore_key = $this->prepareRestore($backup_filename . '.zip');
         if (empty($restore_key)) {
             $logger->add('Upgrade stopped: Unable to prepare restore file. restore.php was locally modified/removed or renamed.');
             return array(false, array(__('restore') => __('upgrade_center.unable_to_prepare_restore')));
         }
         $content_path = $this->getPackagesDir() . $package_id . '/content/';
         // Run pre script
         if (!empty($schema['scripts']['pre'])) {
             include_once $content_path . 'scripts/' . $schema['scripts']['pre'];
         }
         $this->closeStore();
         $logger->add('Backup files and Database');
         Output::display(__('backup_data'), '', true);
         $backup_file = DataKeeper::backup(array('pack_name' => $backup_filename, 'compress' => 'zip', 'set_comet_steps' => false, 'move_progress' => false));
         if (empty($backup_file) || !file_exists($backup_file)) {
             $logger->add('Upgrade stopped: Failed to backup DB/Files');
             return array(false, array(__('backup') => __('text_uc_failed_to_backup_tables')));
         }
         // Send mail to admin e-mail with information about backup
         Mailer::sendMail(array('to' => 'company_site_administrator', 'from' => 'default_company_site_administrator', 'data' => array('backup_file' => $backup_file, 'settings_section_url' => fn_url('settings.manage'), 'restore_link' => Registry::get('config.http_location') . '/var/upgrade/restore.php?uak=' . $restore_key), 'tpl' => 'upgrade/backup_info.tpl'), 'A', Registry::get('settings.Appearance.backend_default_language'));
         $logger->add('Copy package files');
         Output::display(__('uc_copy_files'), '', true);
         // Move files from package
         $this->applyPackageFiles($content_path . 'package', $this->config['dir']['root']);
         $this->cleanupOldFiles($schema, $this->config['dir']['root']);
         // Copy files from themes_repository to design folder
         $this->processThemesFiles($schema);
         Output::display(__('uc_run_migrations'), '', true);
         // Run migrations
         if (!empty($schema['migrations'])) {
             $logger->add('Run migrations');
             $minimal_date = 0;
             foreach ($schema['migrations'] as $migration) {
                 preg_match('/^[0-9]+/', $migration, $matches);
                 if (!empty($matches[0])) {
                     $date = $matches[0];
                     if ($date < $minimal_date || empty($minimal_date)) {
                         $minimal_date = $date;
                     }
                 }
             }
             $config = array('migration_dir' => $content_path . 'migrations/', 'package_id' => $package_id);
             Migration::instance($config)->migrate($minimal_date);
         }
         // Install languages
         Output::display(__('uc_install_languages'), '', true);
         if (!empty($schema['languages'])) {
             $logger->add('Install langauges from the upgrade package');
             $avail_languages = Languages::getAvailable('A', true);
             foreach ($avail_languages as $lang_code => $language) {
                 if (in_array($lang_code, $schema['languages'])) {
                     $logger->add(str_replace('[lang_code]', $lang_code, 'Install the \\"[lang_code]\\" language'));
                     Output::display(__('install') . ': ' . $lang_code, '', false);
                     Languages::installCrowdinPack($content_path . 'languages/' . $lang_code, array('install_newly_added' => true, 'validate_lang_code' => true, 'reinstall' => true));
                 } else {
                     $pack_code = '';
                     if (in_array(CART_LANGUAGE, $schema['languages'])) {
                         $pack_code = CART_LANGUAGE;
                     } elseif (in_array('en', $schema['languages'])) {
                         $pack_code = 'en';
                     }
                     if (file_exists($content_path . 'languages/' . $pack_code)) {
                         // Fill the unknown language by the Default/EN language variables
                         Languages::installCrowdinPack($content_path . 'languages/' . $pack_code, array('reinstall' => true, 'force_lang_code' => $lang_code, 'install_newly_added' => true));
                     }
                 }
             }
         }
     }
     // Run post script
     if (!empty($schema['scripts']['post'])) {
         include_once $content_path . 'scripts/' . $schema['scripts']['post'];
     }
     Output::display(__('text_uc_upgrade_completed'), '', true);
     $logger->add('Upgrade completed');
     $this->deletePackage($package_id);
     // Clear obsolete files
     fn_clear_cache();
     fn_rm(Registry::get('config.dir.cache_templates'));
     return array(true, array());
 }
Example #3
0
 public function doWrite($message, $newline)
 {
     Log::instance($this->config['package_id'])->add($message);
     $this->buffer .= $message . ($newline ? PHP_EOL : '');
 }
Example #4
0
 /**
  * Prepares restore.php file.
  *
  * @return bool if all necessary information was added to restore.php
  */
 protected function prepareRestore($package_id, $content_schema, $information_schema, $backup_filename)
 {
     $logger = Log::instance($package_id);
     $logger->add('Preparing restore script');
     $upgrades_dir = $this->config['dir']['root'] . '/upgrades';
     $source_restore_file_path = $upgrades_dir . '/source_restore.php';
     $target_restore_dir_name = "{$package_id}_{$information_schema['from_version']}-{$information_schema['to_version']}";
     $target_restore_file_name = 'restore_' . date('Y-m-d_H:i:s', TIME) . '.php';
     $target_restore_dir_path = $upgrades_dir . "/{$target_restore_dir_name}/";
     $target_restore_file_path = $target_restore_dir_path . $target_restore_file_name;
     $target_restore_http_path = Registry::get('config.http_location') . "/upgrades/{$target_restore_dir_name}/{$target_restore_file_name}";
     $target_restore_dir_perms = 0755;
     $target_restore_file_perms = 0644;
     if (is_dir($upgrades_dir)) {
         $logger->add(sprintf('Upgrades directory permissions: %s', fn_get_file_perms_info($upgrades_dir)));
     } else {
         $logger->add(sprintf('Upgrades directory not found at "%s"', $upgrades_dir));
         return false;
     }
     if (file_exists($source_restore_file_path)) {
         $logger->add(sprintf('Source restore script permissions: %s', fn_get_file_perms_info($source_restore_file_path)));
         if (!is_readable($source_restore_file_path)) {
             $logger->add('Source restore script is not readable');
             return false;
         }
     } else {
         $logger->add(sprintf('Source restore script not found at "%s"', $source_restore_file_path));
         return false;
     }
     if (fn_mkdir($target_restore_dir_path, $target_restore_dir_perms)) {
         $logger->add(array(sprintf('Created directory for restore script at "%s"', $target_restore_dir_path), sprintf('Directory permissions: %s', fn_get_file_perms_info($target_restore_dir_path))));
     } else {
         $logger->add(sprintf('Unable to create directory for restore script at "%s"', $target_restore_dir_path));
         return false;
     }
     $content = fn_get_contents($source_restore_file_path);
     $restore_key = md5(uniqid()) . md5(uniqid('', true));
     $stats_data = $this->getStatsData($package_id);
     $restore_data = array('backup' => array('filename' => $backup_filename, 'created_at' => date('Y-m-d H:i:s', TIME), 'created_on_version' => PRODUCT_VERSION));
     $content = str_replace(array("'%UC_SETTINGS%'", "'%CONFIG%'", "'%BACKUP_FILENAME%'", "'%RESTORE_KEY%'", "'%STATS_DATA%'", "'%RESTORE_DATA%'"), array(var_export($this->settings, true), var_export(Registry::get('config'), true), var_export($backup_filename, true), var_export($restore_key, true), var_export($stats_data, true), var_export($restore_data, true)), $content);
     if (fn_put_contents($target_restore_file_path, $content, '', $target_restore_file_perms)) {
         $logger->add(array(sprintf('Created restore script at "%s"', $target_restore_file_path), sprintf('Restore script permissions: %s', fn_get_file_perms_info($target_restore_file_path))));
     } else {
         $logger->add(sprintf('Unable to create restore script at "%s"', $target_restore_file_path));
         return false;
     }
     // Ensure that target restore script directory has correct permissions (0755)
     $logger->add('Correcting target restore script directory permissions...');
     $this->chmod($target_restore_dir_path, $target_restore_dir_perms, $logger);
     $logger->add(sprintf('Target restore script directory permissions: %s', fn_get_file_perms_info($target_restore_dir_path)));
     // Restore validator could change permissions for upgrades directory to "0777" if it wasn't writable.
     // "0777" are not acceptable permissions for that directory because some servers restrict execution of
     // PHP scripts located at directory with "0777" permissions.
     $logger->add('Correcting upgrades directory permissions...');
     $this->chmod($upgrades_dir, $target_restore_dir_perms, $logger);
     $logger->add(sprintf('Upgrades directory permissions: %s', fn_get_file_perms_info($upgrades_dir)));
     // Check if restore is available through the HTTP
     $result = Http::get($target_restore_http_path);
     if ($result != 'Access denied') {
         $logger->add(sprintf('Restore script is not available via HTTP at "%s".', $target_restore_http_path));
         return false;
     }
     return array($restore_key, $target_restore_file_path, $target_restore_http_path);
 }