/** * @throws \RuntimeException */ public function loadConfig() { if (!file_exists(OLDSTYLE_WORKING_DIR . '.Oldstyle')) { throw new \RuntimeException("Directory is not a Oldstyle directory: " . OLDSTYLE_WORKING_DIR); } $config = Oldstyle::fromYAML(file_get_contents(OLDSTYLE_WORKING_DIR . '.Oldstyle')); if (!$config || !is_array($config)) { throw new \RuntimeException("Error: " . OLDSTYLE_WORKING_DIR . ".Oldstyle file is not valid YAML, or is empty."); } $this->config = $config; return $config; }
/** * Loops over an object folder and parses the files to pass to buildSingleObject * * @param $folder * @param $type */ public function buildObjects($folder, $type) { if (!file_exists(OLDSTYLE_WORKING_DIR . $folder)) { $this->output->writeln('> Skipping ' . $type['class'] . ', ' . $folder . ' does not exist.'); return; } $criteria = $this->getPartitionCriteria($type['folder']); if (is_null($criteria)) { $criteria = array(); } if ($this->isForce) { $this->modx->removeCollection($type['class'], $criteria); if (isset($type['truncate_on_force'])) { foreach ($type['truncate_on_force'] as $class) { $this->output->writeln('> Truncating ' . $class . ' before force building ' . $type['class'] . '...'); $this->modx->removeCollection($class, array()); } } /** * @deprecated 2015-03-30 * * Deprecated in favour of specifying truncate_on_force in the .oldstyle file. */ switch ($type['class']) { // $modx->removeCollection does not automatically remove related objects, which in the case // of modCategory results in orphaned modCategoryClosure objects. Normally, this is okay, because // Oldstyle recreates the objects with the same ID. But Categories automatically add the closure on // save, which then throws a bunch of errors about duplicate IDs. Worst of all, it _removes_ the // category object if it can't save the closure, causing the IDs to go all over the place. // So in this case, we make sure all category closures are wiped too. case 'modCategory': $this->modx->removeCollection('modCategoryClosure', array()); break; } } $directory = new \DirectoryIterator(OLDSTYLE_WORKING_DIR . $folder); // Reset the conflicts so we're good to go on new ones $this->resetConflicts(); $this->getExistingObjects($type['class'], $criteria); foreach ($directory as $file) { /** @var \SplFileInfo $file */ $name = $file->getBasename(); // Ignore dotfiles/folders if (substr($name, 0, 1) == '.') { continue; } if (!$file->isFile()) { $this->output->writeln('- Skipping ' . $file->getType() . ': ' . $name); continue; } // Load the file contents $file = file_get_contents($file->getRealPath()); // Normalize line-endings to \n to ensure consistency $file = str_replace("\r\n", "\n", $file); $file = str_replace("\r", "\n", $file); // Get the raw data, and the content list($rawData, $content) = explode(Oldstyle::$contentSeparator, $file); // Turn the raw YAML data into an array $data = Oldstyle::fromYAML($rawData); if (!empty($content)) { $data['content'] = $content; } $this->buildSingleObject($data, $type); } $this->removeOrphans($type); $this->resolveConflicts($folder, $type); }
/** * Runs the command. * * @param InputInterface $input * @param OutputInterface $output * @return int */ protected function execute(InputInterface $input, OutputInterface $output) { /** * @var $database_type * @var $database_server * @var $database_user * @var $database_password * @var $dbase * @var */ include MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php'; if ($database_type !== 'mysql') { $output->writeln('<error>Sorry, only MySQL is supported as database driver currently.</error>'); return 1; } // Grab the directory to place the backup $backupDirectory = isset($this->config['backup_directory']) ? $this->config['backup_directory'] : '_backup/'; $targetDirectory = OLDSTYLE_WORKING_DIR . $backupDirectory; // Make sure the directory exists if (!is_dir($targetDirectory)) { mkdir($targetDirectory); if (!is_dir($targetDirectory)) { $output->writeln('<error>Could not create {$backupDirectory} folder</error>'); return 1; } } // Compute the name $file = $input->getArgument('name'); if (!empty($file)) { $file = $this->modx->filterPathSegment($file); } else { $file = strftime('%Y-%m-%d-%H%M%S-%z'); } if (substr($file, -4) != '.sql') { $file .= '.sql'; } // Full target directory and file $targetFile = $targetDirectory . $file; if (file_exists($targetFile)) { $output->writeln('<error>A file with the name {$file} already exists in {$backupDirectory}.</error>'); return 1; } $output->writeln('Writing database backup to <info>' . $file . '</info>...'); $database_password = str_replace("'", '\'', $database_password); $password_parameter = ''; if ($database_password != '') { $password_parameter = "-p'{$database_password}'"; } if ($input->getOption("exclude-tables")) { $tables = $config = Oldstyle::fromYAML(file_get_contents(OLDSTYLE_WORKING_DIR . $this->config['backup_ignore_table_file'])); $exclude_tables = ""; foreach ($tables as $table) { $exclude_tables .= " "; $exclude_tables .= "--ignore-table={$dbase}.{$table}"; } exec("mysqldump -u {$database_user} {$password_parameter} -h {$database_server} {$dbase} {$exclude_tables}> {$targetFile} "); } else { exec("mysqldump -u {$database_user} {$password_parameter} -h {$database_server} {$dbase} > {$targetFile} "); } return 0; }