コード例 #1
0
 /**
  * Run migration
  *
  * @museDescription  Runs pending migrations according to options provided
  *
  * @return  void
  **/
 public function run()
 {
     // Direction, up or down
     $direction = 'up';
     if ($this->arguments->getOpt('d')) {
         if ($this->arguments->getOpt('d') == 'up' || $this->arguments->getOpt('d') == 'down') {
             $direction = $this->arguments->getOpt('d');
         } else {
             $this->output->error('Error: Direction must be one of "up" or "down"');
         }
     }
     // Overriding default document root?
     $directory = null;
     if ($this->arguments->getOpt('r')) {
         if (is_dir($this->arguments->getOpt('r')) && is_readable($this->arguments->getOpt('r'))) {
             $directory = rtrim($this->arguments->getOpt('r'), DS);
         } else {
             $this->output->error('Error: Provided directory is not valid');
         }
     }
     // Migrating a super group
     $alternativeDatabase = null;
     if ($this->arguments->getOpt('group')) {
         $cname = $this->arguments->getOpt('group');
         $group = \Hubzero\User\Group::getInstance($cname);
         if ($group && $group->isSuperGroup()) {
             // Get group config
             $groupsConfig = \Component::params('com_groups');
             // Path to group folder
             $directory = PATH_APP . DS . trim($groupsConfig->get('uploadpath', '/site/groups'), DS);
             $directory .= DS . $group->get('gidNumber');
             // make sure we have migrations dir
             if (!is_dir($directory . DS . 'migrations') || !is_readable($directory . DS . 'migrations')) {
                 $this->output->error('Error: Migrations directory does not exist.');
             }
             // Get group database
             $alternativeDatabase = \Hubzero\User\Group\Helper::getDBO(array(), $group->get('cn'));
             // make sure we have a group db
             if ($alternativeDatabase->getErrorNum() > 0) {
                 $this->output->error('Error: Could not connect to Group Database.');
             }
         } else {
             $this->output->error('Error: Provided group is not valid');
         }
     }
     // Forcing update
     $force = false;
     if ($this->arguments->getOpt('force')) {
         if (!$this->arguments->getOpt('e') && !$this->arguments->getOpt('file')) {
             $this->output->error('Error: You cannot specify the "force" option without specifying a specific extention or file');
         } else {
             $force = true;
         }
     }
     // Logging only - record migration
     $logOnly = false;
     if ($this->arguments->getOpt('m')) {
         if (!$this->arguments->getOpt('e') && !$this->arguments->getOpt('file')) {
             $this->output->error('Error: You cannot specify the "Log only (-m)" option without specifying a specific extention or file');
         } else {
             $logOnly = true;
         }
     }
     // Ignore dates
     $ignoreDates = false;
     if ($this->arguments->getOpt('i')) {
         $ignoreDates = true;
     }
     // Specific extension
     $extension = null;
     if ($this->arguments->getOpt('e')) {
         if (!preg_match('/^com_[[:alnum:]]+$|^mod_[[:alnum:]]+$|^plg_[[:alnum:]]+_[[:alnum:]]+$|^core$/i', $this->arguments->getOpt('e'))) {
             $this->output->error('Error: extension should match the pattern of com_*, mod_*, plg_*_*, or core');
         } else {
             $extension = $this->arguments->getOpt('e');
         }
     }
     // Specific file
     $file = null;
     if ($this->arguments->getOpt('file')) {
         if (!preg_match('/^Migration[0-9]{14}[[:alnum:]]+\\.php$/', $this->arguments->getOpt('file'))) {
             $this->output->error('Error: Provided filename does not appear to be valid');
         } else {
             $file = $this->arguments->getOpt('file');
             // Also force "ignore dates mode", as that's somewhat implied by giving a specific filename
             $ignoreDates = true;
         }
     }
     // Dryrun
     $dryrun = true;
     if ($this->arguments->getOpt('f')) {
         $dryrun = false;
     }
     // Email results
     $email = false;
     if ($this->arguments->getOpt('email')) {
         if (!preg_match('/^[a-zA-Z0-9\\.\\_\\-]+@[a-zA-Z0-9\\.]+\\.[a-zA-Z]{2,4}$/', $this->arguments->getOpt('email'))) {
             $this->output->error('Error: ' . $this->arguments->getOpt('email') . ' does not appear to be a valid email address');
         } else {
             $email = $this->arguments->getOpt('email');
         }
     }
     // Create migration object
     $migration = new \Hubzero\Content\Migration($directory, $alternativeDatabase);
     // Make sure we got a migration object
     if ($migration === false) {
         $this->output->error('Error: failed to instantiate new migration object.');
     }
     if ($this->output->isInteractive()) {
         // Register callback function for adding lines interactively
         $output = $this->output;
         $callback = function ($message, $type = null) use($output) {
             $output->addLine($message, $type);
         };
         $migration->registerCallback('message', $callback);
         // Add progress callback as well
         $progress = $this->output->getProgressOutput();
         $migration->registerCallback('progress', $progress);
     }
     // Find migration files
     if ($migration->find($extension, $file) === false) {
         // Find failed, do nothing
         $this->output->error('Migration find failed! See log messages for details.');
     } else {
         // Run migration itself
         if (!($result = $migration->migrate($direction, $force, $dryrun, $ignoreDates, $logOnly))) {
             $this->output->error('Migration failed! See log messages for details.');
         } else {
             if (!$this->output->isInteractive()) {
                 if ($this->output->getMode() == 'minimal') {
                     if (count($migration->get('log')) > 0) {
                         $missed = array();
                         $pending = array();
                         $complete = array();
                         foreach ($migration->get('log') as $log) {
                             if (preg_match('/would run up\\(\\) (Migration[0-9]{14}[[:alnum:]_]*\\.php)/i', $log['message'], $matches)) {
                                 $pending[] = $matches[1];
                             }
                             if (preg_match('/completed up\\(\\) in (Migration[0-9]{14}[[:alnum:]_]*\\.php)/i', $log['message'], $matches) || preg_match('/would ignore up\\(\\) (Migration[0-9]{14}[[:alnum:]_]*\\.php)/i', $log['message'], $matches)) {
                                 $complete[] = $matches[1];
                             }
                             if (preg_match('/migration up\\(\\) in (Migration[0-9]{14}[[:alnum:]_]*\\.php) has not been run/i', $log['message'], $matches)) {
                                 $missed[] = $matches[1];
                             }
                         }
                         if (count($pending) > 0) {
                             $this->output->addLine(array('pending' => $pending));
                         }
                         if (count($missed) > 0) {
                             $this->output->addLine(array('missed' => $missed));
                         }
                         if (count($complete) > 0) {
                             $this->output->addLine(array('complete' => $complete));
                         }
                     }
                 } else {
                     $this->output->addLinesFromArray($migration->get('log'));
                 }
             }
             // Final success message
             if ($this->output->getMode() != 'minimal') {
                 $this->output->addLine('Success: ' . ucfirst($direction) . ' migration complete!', 'success');
             }
         }
     }
     // Email results if requested (only do so if there's something to report)
     if ($email && count($migration->get('affectedFiles')) > 0) {
         $this->output->addLine("Emailing results to: {$email}");
         $headers = "From: Migrations <automator@" . php_uname("n") . ">";
         $subject = "Migration output - " . php_uname("n") . " [" . date("d-M-Y H:i:s") . "]";
         $message = "";
         foreach ($migration->get('log') as $line) {
             $message .= $line['message'] . "\n";
         }
         // Send the message
         if (!mail($email, $subject, $message, $headers)) {
             $this->output->addLine("Error: failed to send message!", 'warning');
         }
     } elseif ($email) {
         $this->output->addLine('Ignoring email as no files were affected in this run.', 'info');
     }
 }