MODX Revolution PHP Cross Reference Content Management Systems

Source: /setup/includes/request/modinstallclirequest.class.php - 374 lines - 13343 bytes - Summary - Text - Print

Description: modInstallCLIRequest

   1  <?php
   2  /*
   3   * MODX Revolution
   4   *
   5   * Copyright 2006-2014 by MODX, LLC.
   6   * All rights reserved.
   7   *
   8   * This program is free software; you can redistribute it and/or modify it under
   9   * the terms of the GNU General Public License as published by the Free Software
  10   * Foundation; either version 2 of the License, or (at your option) any later
  11   * version.
  12   *
  13   * This program is distributed in the hope that it will be useful, but WITHOUT
  14   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  16   * details.
  17   *
  18   * You should have received a copy of the GNU General Public License along with
  19   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
  20   * Place, Suite 330, Boston, MA 02111-1307 USA
  21   */
  22  require_once strtr(realpath(MODX_SETUP_PATH.'includes/request/modinstallrequest.class.php'),'\\','/');
  23  /**
  24   * modInstallCLIRequest
  25   *
  26   * @package setup
  27   */
  28  /**
  29   * Handles CLI installs.
  30   *
  31   * @package setup
  32   */
  33  class modInstallCLIRequest extends modInstallRequest {
  34      /** @var modInstall $install */
  35      public $install;
  36      /** @var int $timeStart */
  37      public $timeStart = 0;
  38      /** @var string $timeTotal */
  39      public $timeTotal = '';
  40      
  41      /**
  42       * Constructor for modInstallConnector object.
  43       *
  44       * @constructor
  45       * @param modInstall &$modInstall A reference to the modInstall object.
  46       */
  47      function __construct(modInstall &$modInstall) {
  48          $this->install =& $modInstall;
  49          $this->install->loadSettings();
  50          $this->settings =& $this->install->settings;
  51      }
  52  
  53      /**
  54       * Parse the install mode from a string or int
  55       * @param string|int $mode
  56       * @return int
  57       */
  58      public function getInstallMode($mode) {
  59          if (!is_int($mode)) {
  60              switch ($mode) {
  61                  case 'new':
  62                      $mode = modInstall::MODE_NEW;
  63                      break;
  64                  case 'upgrade-evo':
  65                      $mode = modInstall::MODE_UPGRADE_EVO;
  66                      break;
  67                  case 'upgrade-revo-advanced':
  68                  case 'upgrade-advanced':
  69                      $mode = modInstall::MODE_UPGRADE_REVO_ADVANCED;
  70                      break;
  71                  case 'upgrade-revo':
  72                  case 'upgrade':
  73                  default:
  74                      $mode = modInstall::MODE_UPGRADE_REVO;
  75                      break;
  76              }
  77          }
  78          return $mode;
  79      }
  80  
  81      /**
  82       * Handles connector requests.
  83       *
  84       * @param string $action
  85       */
  86      public function handle($action = '') {
  87          $this->beginTimer();
  88          /* prepare the settings */
  89          $settings = $_REQUEST;
  90          if (empty($settings['installmode'])) $settings['installmode'] = modInstall::MODE_NEW;
  91          $settings['installmode'] = $this->getInstallMode($settings['installmode']);
  92          $this->settings->fromArray($settings); /* load CLI args into settings */
  93  
  94          /* load the config.xml file */
  95          $config = $this->getConfig($settings['installmode']);
  96          if (empty($config)) {
  97              $this->end($this->install->lexicon('cli_no_config_file'));
  98          }
  99          $this->settings->fromArray($config);
 100          $this->settings->fromArray($settings); /* do again to allow CLI-based overrides of config.xml */
 101  
 102          /* load the driver */
 103          $this->install->loadDriver();
 104  
 105          /* Run tests */
 106          $mode = (int)$this->install->settings->get('installmode');
 107          $results= $this->install->test($mode);
 108          if (!$this->install->test->success) {
 109              $msg = "\n";
 110              foreach ($results['fail'] as $field => $result) {
 111                  $msg .= $field.': '.$result['title'].' - '.$result['message'];
 112              }
 113              $msg = $this->install->lexicon('cli_tests_failed',array(
 114                  'errors' => $msg,
 115              ));
 116              $this->end($msg);
 117          }
 118  
 119          /** Attempt to create the database */
 120          $this->checkDatabase();
 121  
 122          /* Run installer */
 123          $this->install->getService('runner','runner.modInstallRunnerWeb');
 124          $failed = true;
 125          $errors = array();
 126          if ($this->install->runner) {
 127              $success = $this->install->runner->run($mode);
 128              $results = $this->install->runner->getResults();
 129  
 130              $failed= false;
 131              foreach ($results as $item) {
 132                  if ($item['class'] === 'failed') {
 133                      $failed= true;
 134                      $this->install->xpdo->log(xPDO::LOG_LEVEL_ERROR,$item['msg']);
 135                      $errors[] = $item;
 136                      break;
 137                  }
 138              }
 139          }
 140  
 141          if ($failed) {
 142              $msg = "\n";
 143              foreach ($errors as $field => $result) {
 144                  $msg .= $result['msg'];
 145              }
 146              $msg = $this->install->lexicon('cli_install_failed',array(
 147                  'errors' => $msg,
 148              ));
 149              $this->end($msg);
 150          }
 151  
 152          /* cleanup */
 153          $errors= $this->install->verify();
 154          foreach ($errors as $error) {
 155              $this->install->xpdo->log(xPDO::LOG_LEVEL_ERROR,$error);
 156          }
 157          $cleanupErrors = $this->install->cleanup();
 158          foreach ($cleanupErrors as $key => $error) {
 159              $this->install->xpdo->log(xPDO::LOG_LEVEL_ERROR,$error);
 160          }
 161  
 162          if ($this->settings->get('remove_setup_directory')) {
 163              $this->install->removeSetupDirectory();
 164          }
 165          $this->endTimer();
 166          $this->end(''.$this->install->lexicon('installation_finished',array(
 167              'time' => $this->timeTotal,
 168          )));
 169      }
 170  
 171      /**
 172       * {@inheritDoc}
 173       * @param int $mode
 174       * @param array $config
 175       * @return array
 176       */
 177      public function getConfig($mode = 0, array $config = array()) {
 178          /* load the config file */
 179          $config = array_merge($this->loadConfigFile(), $config);
 180          $config = parent::getConfig($mode, $config);
 181          $this->prepareSettings($config);
 182          return $config;
 183      }
 184  
 185      /**
 186       * Attempt to load the config.xml (or other config file) to use when installing. One must be present to run
 187       * MODX Setup in CLI mode.
 188       * 
 189       * @return array
 190       */
 191      public function loadConfigFile() {
 192          $settings = array();
 193          $configFile = $this->settings->get('config');
 194          if (empty($configFile)) $configFile = MODX_INSTALL_PATH.'setup/config.xml';
 195          if (!empty($configFile)) {
 196              if (!file_exists($configFile) && file_exists(MODX_SETUP_PATH.$configFile)) {
 197                  $configFile = MODX_SETUP_PATH.$configFile;
 198              }
 199          } elseif (file_exists(MODX_SETUP_PATH.'config.xml')) {
 200              $configFile = MODX_SETUP_PATH.'config.xml';
 201          }
 202          if (!empty($configFile) && file_exists($configFile)) {
 203              $settings = $this->parseConfigFile($configFile);
 204          }
 205          return $settings;
 206      }
 207  
 208      /**
 209       * Prepares settings for installation, including setting of defaults
 210       * 
 211       * @param array $settings
 212       * @return void
 213       */
 214      public function prepareSettings(array &$settings) {
 215          if (empty($settings['site_sessionname'])) {
 216              $settings['site_sessionname'] = 'SN' . uniqid('');
 217          }
 218          if (empty($settings['config_options'])) {
 219              $settings['config_options'] = array();
 220          }
 221          if (empty($settings['database']) && !empty($settings['dbase'])) {
 222              $settings['database'] = $settings['dbase'];
 223          }
 224          $settings['database_dsn'] = $this->getDatabaseDSN($settings['database_type'],$settings['database_server'],$settings['database'],$settings['database_connection_charset']);
 225          if (!empty($settings['database'])) {
 226              $settings['dbase'] = $settings['database'];
 227          }
 228          $this->settings->fromArray($settings);
 229  
 230          $this->setDefaultSetting('processors_path',$this->settings->get('core_path').'model/modx/processors/');
 231          $this->setDefaultSetting('connectors_path',$this->settings->get('context_connectors_path'));
 232          $this->setDefaultSetting('connectors_url',$this->settings->get('context_connectors_url'));
 233          $this->setDefaultSetting('mgr_path',$this->settings->get('context_mgr_path'));
 234          $this->setDefaultSetting('mgr_url',$this->settings->get('context_mgr_url'));
 235          $this->setDefaultSetting('web_path',$this->settings->get('context_web_path'));
 236          $this->setDefaultSetting('web_url',$this->settings->get('context_web_url'));
 237          $this->setDefaultSetting('assets_path',$this->settings->get('context_assets_path',$this->settings->get('context_web_path').'assets/'));
 238          $this->setDefaultSetting('assets_url',$this->settings->get('context_assets_url',$this->settings->get('context_web_url').'assets/'));
 239      }
 240  
 241      /**
 242       * Sets a default for a setting if not set
 243       * @param string $key
 244       * @param mixed $default
 245       * @return void
 246       */
 247      public function setDefaultSetting($key,$default) {
 248          $value = $this->settings->get($key,null);
 249          if ($value === null) {
 250              $this->settings->set($key,$default);
 251          }
 252      }
 253  
 254      /**
 255       * Parse the config XML file
 256       *
 257       * @param string $file
 258       * @return array
 259       */
 260      public function parseConfigFile($file) {
 261          $contents = file_get_contents($file);
 262          $xml = new SimpleXMLElement($contents);
 263  
 264          $settings = array();
 265          foreach ($xml as $k => $v) {
 266              $settings[(string)$k] = (string)$v;
 267          }
 268  
 269          return $settings;
 270      }
 271  
 272      /**
 273       * Check database settings
 274       * @return void
 275       */
 276      public function checkDatabase() {
 277          $mode = $this->settings->get('installmode');
 278  
 279          /* get an instance of xPDO using the install settings */
 280          $xpdo = $this->install->getConnection($mode);
 281          if (!is_object($xpdo) || !($xpdo instanceof xPDO)) {
 282              $this->end($this->install->lexicon('xpdo_err_ins'));
 283          }
 284  
 285          /* try to get a connection to the actual database */
 286          $dbExists = $xpdo->connect();
 287          if (!$dbExists) {
 288              if ($mode == modInstall::MODE_NEW && $xpdo->getManager()) {
 289                  /* otherwise try to create the database */
 290                  $dbExists = $xpdo->manager->createSourceContainer(
 291                      array(
 292                          'dbname' => $this->settings->get('dbase')
 293                          ,'host' => $this->settings->get('database_server')
 294                      )
 295                      ,$this->settings->get('database_user')
 296                      ,$this->settings->get('database_password')
 297                      ,array(
 298                          'charset' => $this->settings->get('database_connection_charset')
 299                          ,'collation' => $this->settings->get('database_collation')
 300                      )
 301                  );
 302                  if (!$dbExists) {
 303                      $this->end($this->install->lexicon('db_err_create_database'));
 304                  } else {
 305                      $xpdo = $this->install->getConnection($mode);
 306                      if (!is_object($xpdo) || !($xpdo instanceof xPDO)) {
 307                          $this->end($this->install->lexicon('xpdo_err_ins'));
 308                      }
 309                  }
 310              } elseif ($mode == modInstall::MODE_NEW) {
 311                  $this->end($this->install->lexicon('db_err_connect_server'));
 312              }
 313          }
 314          if (!$xpdo->connect()) {
 315              $this->end($this->install->lexicon('db_err_connect'));
 316          }
 317  
 318          /* test table prefix */
 319          if ($mode == modInstall::MODE_NEW || $mode == modInstall::MODE_UPGRADE_REVO_ADVANCED) {
 320              $count = null;
 321              $database = $this->settings->get('dbase');
 322              $prefix = $this->settings->get('table_prefix');
 323              $stmt = $xpdo->query($this->install->driver->testTablePrefix($database,$prefix));
 324              if ($stmt) {
 325                  $row = $stmt->fetch(PDO::FETCH_ASSOC);
 326                  if ($row) {
 327                      $count = (integer) $row['ct'];
 328                  }
 329                  $stmt->closeCursor();
 330              }
 331              if ($mode == modInstall::MODE_NEW && $count !== null) {
 332                  $this->end($this->install->lexicon('test_table_prefix_inuse'));
 333              } elseif ($mode == modInstall::MODE_UPGRADE_REVO_ADVANCED && $count === null) {
 334                  $this->end($this->install->lexicon('test_table_prefix_nf'));
 335              }
 336          }
 337      }
 338  
 339      /**
 340       * End the PHP session and output a message
 341       *
 342       * @param string $message
 343       * @return void
 344       */
 345      public function end($message = '') {
 346          @session_write_close();
 347          die($message."\n");
 348      }
 349  
 350      /**
 351       * Start the debugging timer
 352       * @return int
 353       */
 354      protected function beginTimer() {
 355          $mtime = microtime();
 356          $mtime = explode(" ", $mtime);
 357          $mtime = $mtime[1] + $mtime[0];
 358          $this->timeStart = $mtime;
 359          return $this->timeStart;
 360      }
 361      /**
 362       * End the debugging timer
 363       * @return string
 364       */
 365      protected function endTimer() {
 366          $mtime = microtime();
 367          $mtime = explode(" ", $mtime);
 368          $mtime = $mtime[1] + $mtime[0];
 369          $tend = $mtime;
 370          $this->timeTotal = ($tend - $this->timeStart);
 371          $this->timeTotal = sprintf("%2.4f s", $this->timeTotal);
 372          return $this->timeTotal;
 373      }
 374  }

title

Description

title

Description

title

Description

title

title

Body