[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/installation/src/Model/ -> ConfigurationModel.php (source)

   1  <?php
   2  
   3  /**
   4   * @package     Joomla.Installation
   5   * @subpackage  Model
   6   *
   7   * @copyright   (C) 2009 Open Source Matters, Inc. <https://www.joomla.org>
   8   * @license     GNU General Public License version 2 or later; see LICENSE.txt
   9   */
  10  
  11  namespace Joomla\CMS\Installation\Model;
  12  
  13  use Joomla\CMS\Factory;
  14  use Joomla\CMS\Installation\Helper\DatabaseHelper;
  15  use Joomla\CMS\Installer\Installer;
  16  use Joomla\CMS\Language\Text;
  17  use Joomla\CMS\User\UserHelper;
  18  use Joomla\CMS\Version;
  19  use Joomla\Database\DatabaseDriver;
  20  use Joomla\Filesystem\File;
  21  use Joomla\Filesystem\Folder;
  22  use Joomla\Registry\Registry;
  23  use Joomla\Utilities\ArrayHelper;
  24  
  25  // phpcs:disable PSR1.Files.SideEffects
  26  \defined('_JEXEC') or die;
  27  // phpcs:enable PSR1.Files.SideEffects
  28  
  29  /**
  30   * Configuration setup model for the Joomla Core Installer.
  31   *
  32   * @since  3.1
  33   */
  34  class ConfigurationModel extends BaseInstallationModel
  35  {
  36      /**
  37       * The generated user ID.
  38       *
  39       * @var    integer
  40       * @since  4.0.0
  41       */
  42      protected static $userId = 0;
  43  
  44      /**
  45       * Method to setup the configuration file
  46       *
  47       * @param   array  $options  The session options
  48       *
  49       * @return  boolean  True on success
  50       *
  51       * @since   3.1
  52       */
  53      public function setup($options)
  54      {
  55          // Get the options as an object for easier handling.
  56          $options = ArrayHelper::toObject($options);
  57  
  58          // Get a database object.
  59          try {
  60              $db = DatabaseHelper::getDbo(
  61                  $options->db_type,
  62                  $options->db_host,
  63                  $options->db_user,
  64                  $options->db_pass_plain,
  65                  $options->db_name,
  66                  $options->db_prefix,
  67                  true,
  68                  DatabaseHelper::getEncryptionSettings($options)
  69              );
  70          } catch (\RuntimeException $e) {
  71              Factory::getApplication()->enqueueMessage(Text::sprintf('INSTL_ERROR_CONNECT_DB', $e->getMessage()), 'error');
  72  
  73              return false;
  74          }
  75  
  76          // Attempt to create the configuration.
  77          if (!$this->createConfiguration($options)) {
  78              return false;
  79          }
  80  
  81          $serverType = $db->getServerType();
  82  
  83          // Attempt to update the table #__schema.
  84          $pathPart = JPATH_ADMINISTRATOR . '/components/com_admin/sql/updates/' . $serverType . '/';
  85  
  86          $files = Folder::files($pathPart, '\.sql$');
  87  
  88          if (empty($files)) {
  89              Factory::getApplication()->enqueueMessage(Text::_('INSTL_ERROR_INITIALISE_SCHEMA'), 'error');
  90  
  91              return false;
  92          }
  93  
  94          $version = '';
  95  
  96          foreach ($files as $file) {
  97              if (version_compare($version, File::stripExt($file)) < 0) {
  98                  $version = File::stripExt($file);
  99              }
 100          }
 101  
 102          $query = $db->getQuery(true)
 103              ->select('extension_id')
 104              ->from($db->quoteName('#__extensions'))
 105              ->where($db->quoteName('name') . ' = ' . $db->quote('files_joomla'));
 106          $db->setQuery($query);
 107          $eid = $db->loadResult();
 108  
 109          $query->clear()
 110              ->insert($db->quoteName('#__schemas'))
 111              ->columns(
 112                  array(
 113                      $db->quoteName('extension_id'),
 114                      $db->quoteName('version_id')
 115                  )
 116              )
 117              ->values($eid . ', ' . $db->quote($version));
 118          $db->setQuery($query);
 119  
 120          try {
 121              $db->execute();
 122          } catch (\RuntimeException $e) {
 123              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 124  
 125              return false;
 126          }
 127  
 128          // Attempt to refresh manifest caches.
 129          $query->clear()
 130              ->select('*')
 131              ->from('#__extensions');
 132          $db->setQuery($query);
 133  
 134          $return = true;
 135  
 136          try {
 137              $extensions = $db->loadObjectList();
 138          } catch (\RuntimeException $e) {
 139              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 140              $return = false;
 141          }
 142  
 143          // This is needed because the installer loads the extension table in constructor, needs to be refactored in 5.0
 144          Factory::$database = $db;
 145          $installer = Installer::getInstance();
 146  
 147          foreach ($extensions as $extension) {
 148              if (!$installer->refreshManifestCache($extension->extension_id)) {
 149                  Factory::getApplication()->enqueueMessage(
 150                      Text::sprintf('INSTL_DATABASE_COULD_NOT_REFRESH_MANIFEST_CACHE', $extension->name),
 151                      'error'
 152                  );
 153  
 154                  return false;
 155              }
 156          }
 157  
 158          // Handle default backend language setting. This feature is available for localized versions of Joomla.
 159          $languages = Factory::getApplication()->getLocaliseAdmin($db);
 160  
 161          if (in_array($options->language, $languages['admin']) || in_array($options->language, $languages['site'])) {
 162              // Build the language parameters for the language manager.
 163              $params = array();
 164  
 165              // Set default administrator/site language to sample data values.
 166              $params['administrator'] = 'en-GB';
 167              $params['site']          = 'en-GB';
 168  
 169              if (in_array($options->language, $languages['admin'])) {
 170                  $params['administrator'] = $options->language;
 171              }
 172  
 173              if (in_array($options->language, $languages['site'])) {
 174                  $params['site'] = $options->language;
 175              }
 176  
 177              $params = json_encode($params);
 178  
 179              // Update the language settings in the language manager.
 180              $query->clear()
 181                  ->update($db->quoteName('#__extensions'))
 182                  ->set($db->quoteName('params') . ' = ' . $db->quote($params))
 183                  ->where($db->quoteName('element') . ' = ' . $db->quote('com_languages'));
 184              $db->setQuery($query);
 185  
 186              try {
 187                  $db->execute();
 188              } catch (\RuntimeException $e) {
 189                  Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 190  
 191                  $return = false;
 192              }
 193          }
 194  
 195          // Attempt to create the root user.
 196          if (!$this->createRootUser($options, $db)) {
 197              $this->deleteConfiguration();
 198  
 199              return false;
 200          }
 201  
 202          // Update the cms data user ids.
 203          $this->updateUserIds($db);
 204  
 205          // Check for testing sampledata plugin.
 206          $this->checkTestingSampledata($db);
 207  
 208          return $return;
 209      }
 210  
 211      /**
 212       * Retrieves the default user ID and sets it if necessary.
 213       *
 214       * @return  integer  The user ID.
 215       *
 216       * @since   3.1
 217       */
 218      public static function getUserId()
 219      {
 220          if (!self::$userId) {
 221              self::$userId = self::generateRandUserId();
 222          }
 223  
 224          return self::$userId;
 225      }
 226  
 227      /**
 228       * Generates the user ID.
 229       *
 230       * @return  integer  The user ID.
 231       *
 232       * @since   3.1
 233       */
 234      protected static function generateRandUserId()
 235      {
 236          $session    = Factory::getSession();
 237          $randUserId = $session->get('randUserId');
 238  
 239          if (empty($randUserId)) {
 240              // Create the ID for the root user only once and store in session.
 241              $randUserId = mt_rand(1, 1000);
 242              $session->set('randUserId', $randUserId);
 243          }
 244  
 245          return $randUserId;
 246      }
 247  
 248      /**
 249       * Resets the user ID.
 250       *
 251       * @return  void
 252       *
 253       * @since   3.1
 254       */
 255      public static function resetRandUserId()
 256      {
 257          self::$userId = 0;
 258  
 259          Factory::getSession()->set('randUserId', self::$userId);
 260      }
 261  
 262      /**
 263       * Method to update the user id of sql data content to the new rand user id.
 264       *
 265       * @param   DatabaseDriver  $db  Database connector object $db*.
 266       *
 267       * @return  void
 268       *
 269       * @since   3.6.1
 270       */
 271      protected function updateUserIds($db)
 272      {
 273          // Create the ID for the root user.
 274          $userId = self::getUserId();
 275  
 276          // Update all core tables created_by fields of the tables with the random user id.
 277          $updatesArray = array(
 278              '#__categories'      => array('created_user_id', 'modified_user_id'),
 279              '#__tags'            => array('created_user_id', 'modified_user_id'),
 280              '#__workflows'       => array('created_by', 'modified_by'),
 281          );
 282  
 283          foreach ($updatesArray as $table => $fields) {
 284              foreach ($fields as $field) {
 285                  $query = $db->getQuery(true)
 286                      ->update($db->quoteName($table))
 287                      ->set($db->quoteName($field) . ' = ' . $db->quote($userId))
 288                      ->where($db->quoteName($field) . ' != 0')
 289                      ->where($db->quoteName($field) . ' IS NOT NULL');
 290  
 291                  $db->setQuery($query);
 292  
 293                  try {
 294                      $db->execute();
 295                  } catch (\RuntimeException $e) {
 296                      Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 297                  }
 298              }
 299          }
 300      }
 301  
 302      /**
 303       * Method to check for the testing sampledata plugin.
 304       *
 305       * @param   DatabaseDriver  $db  Database connector object $db*.
 306       *
 307       * @return  void
 308       *
 309       * @since   4.0.0
 310       */
 311      public function checkTestingSampledata($db)
 312      {
 313          $version = new Version();
 314  
 315          if (!$version->isInDevelopmentState() || !is_file(JPATH_PLUGINS . '/sampledata/testing/testing.php')) {
 316              return;
 317          }
 318  
 319          $testingPlugin = new \stdClass();
 320          $testingPlugin->extension_id = null;
 321          $testingPlugin->name = 'plg_sampledata_testing';
 322          $testingPlugin->type = 'plugin';
 323          $testingPlugin->element = 'testing';
 324          $testingPlugin->folder = 'sampledata';
 325          $testingPlugin->client_id = 0;
 326          $testingPlugin->enabled = 1;
 327          $testingPlugin->access = 1;
 328          $testingPlugin->manifest_cache = '';
 329          $testingPlugin->params = '{}';
 330          $testingPlugin->custom_data = '';
 331  
 332          $db->insertObject('#__extensions', $testingPlugin, 'extension_id');
 333  
 334          $installer = new Installer();
 335          $installer->setDatabase($db);
 336  
 337          if (!$installer->refreshManifestCache($testingPlugin->extension_id)) {
 338              Factory::getApplication()->enqueueMessage(
 339                  Text::sprintf('INSTL_DATABASE_COULD_NOT_REFRESH_MANIFEST_CACHE', $testingPlugin->name),
 340                  'error'
 341              );
 342          }
 343      }
 344  
 345      /**
 346       * Method to create the configuration file
 347       *
 348       * @param   \stdClass  $options  The session options
 349       *
 350       * @return  boolean  True on success
 351       *
 352       * @since   3.1
 353       */
 354      public function createConfiguration($options)
 355      {
 356          // Create a new registry to build the configuration options.
 357          $registry = new Registry();
 358  
 359          // Site settings.
 360          $registry->set('offline', false);
 361          $registry->set('offline_message', Text::_('INSTL_STD_OFFLINE_MSG'));
 362          $registry->set('display_offline_message', 1);
 363          $registry->set('offline_image', '');
 364          $registry->set('sitename', $options->site_name);
 365          $registry->set('editor', 'tinymce');
 366          $registry->set('captcha', '0');
 367          $registry->set('list_limit', 20);
 368          $registry->set('access', 1);
 369  
 370          // Debug settings.
 371          $registry->set('debug', false);
 372          $registry->set('debug_lang', false);
 373          $registry->set('debug_lang_const', true);
 374  
 375          // Database settings.
 376          $registry->set('dbtype', $options->db_type);
 377          $registry->set('host', $options->db_host);
 378          $registry->set('user', $options->db_user);
 379          $registry->set('password', $options->db_pass_plain);
 380          $registry->set('db', $options->db_name);
 381          $registry->set('dbprefix', $options->db_prefix);
 382          $registry->set('dbencryption', $options->db_encryption);
 383          $registry->set('dbsslverifyservercert', $options->db_sslverifyservercert);
 384          $registry->set('dbsslkey', $options->db_sslkey);
 385          $registry->set('dbsslcert', $options->db_sslcert);
 386          $registry->set('dbsslca', $options->db_sslca);
 387          $registry->set('dbsslcipher', $options->db_sslcipher);
 388  
 389          // Server settings.
 390          $registry->set('force_ssl', 0);
 391          $registry->set('live_site', '');
 392          $registry->set('secret', UserHelper::genRandomPassword(16));
 393          $registry->set('gzip', false);
 394          $registry->set('error_reporting', 'default');
 395          $registry->set('helpurl', $options->helpurl);
 396  
 397          // Locale settings.
 398          $registry->set('offset', 'UTC');
 399  
 400          // Mail settings.
 401          $registry->set('mailonline', true);
 402          $registry->set('mailer', 'mail');
 403          $registry->set('mailfrom', $options->admin_email);
 404          $registry->set('fromname', $options->site_name);
 405          $registry->set('sendmail', '/usr/sbin/sendmail');
 406          $registry->set('smtpauth', false);
 407          $registry->set('smtpuser', '');
 408          $registry->set('smtppass', '');
 409          $registry->set('smtphost', 'localhost');
 410          $registry->set('smtpsecure', 'none');
 411          $registry->set('smtpport', 25);
 412  
 413          // Cache settings.
 414          $registry->set('caching', 0);
 415          $registry->set('cache_handler', 'file');
 416          $registry->set('cachetime', 15);
 417          $registry->set('cache_platformprefix', false);
 418  
 419          // Meta settings.
 420          $registry->set('MetaDesc', '');
 421          $registry->set('MetaAuthor', true);
 422          $registry->set('MetaVersion', false);
 423          $registry->set('robots', '');
 424  
 425          // SEO settings.
 426          $registry->set('sef', true);
 427          $registry->set('sef_rewrite', false);
 428          $registry->set('sef_suffix', false);
 429          $registry->set('unicodeslugs', false);
 430  
 431          // Feed settings.
 432          $registry->set('feed_limit', 10);
 433          $registry->set('feed_email', 'none');
 434  
 435          $registry->set('log_path', JPATH_ADMINISTRATOR . '/logs');
 436          $registry->set('tmp_path', JPATH_ROOT . '/tmp');
 437  
 438          // Session setting.
 439          $registry->set('lifetime', 15);
 440          $registry->set('session_handler', 'database');
 441          $registry->set('shared_session', false);
 442          $registry->set('session_metadata', true);
 443  
 444          // Generate the configuration class string buffer.
 445          $buffer = $registry->toString('PHP', array('class' => 'JConfig', 'closingtag' => false));
 446  
 447          // Build the configuration file path.
 448          $path = JPATH_CONFIGURATION . '/configuration.php';
 449  
 450          // Determine if the configuration file path is writable.
 451          if (file_exists($path)) {
 452              $canWrite = is_writable($path);
 453          } else {
 454              $canWrite = is_writable(JPATH_CONFIGURATION . '/');
 455          }
 456  
 457          /*
 458           * If the file exists but isn't writable OR if the file doesn't exist and the parent directory
 459           * is not writable the user needs to fix this.
 460           */
 461          if ((file_exists($path) && !is_writable($path)) || (!file_exists($path) && !is_writable(dirname($path) . '/'))) {
 462              return false;
 463          }
 464  
 465          // Get the session
 466          $session = Factory::getSession();
 467  
 468          if ($canWrite) {
 469              file_put_contents($path, $buffer);
 470              $session->set('setup.config', null);
 471          } else {
 472              // If we cannot write the configuration.php, setup fails!
 473              return false;
 474          }
 475  
 476          return true;
 477      }
 478  
 479      /**
 480       * Method to create the root user for the site.
 481       *
 482       * @param   object          $options  The session options.
 483       * @param   DatabaseDriver  $db       Database connector object $db*.
 484       *
 485       * @return  boolean  True on success.
 486       *
 487       * @since   3.1
 488       */
 489      private function createRootUser($options, $db)
 490      {
 491          $cryptpass = UserHelper::hashPassword($options->admin_password_plain);
 492  
 493          // Take the admin user id - we'll need to leave this in the session for sample data install later on.
 494          $userId = self::getUserId();
 495  
 496          // Create the admin user.
 497          date_default_timezone_set('UTC');
 498          $installdate = date('Y-m-d H:i:s');
 499  
 500          $query = $db->getQuery(true)
 501              ->select($db->quoteName('id'))
 502              ->from($db->quoteName('#__users'))
 503              ->where($db->quoteName('id') . ' = ' . $db->quote($userId));
 504  
 505          $db->setQuery($query);
 506  
 507          try {
 508              $result = $db->loadResult();
 509          } catch (\RuntimeException $e) {
 510              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 511  
 512              return false;
 513          }
 514  
 515          if ($result) {
 516              $query->clear()
 517                  ->update($db->quoteName('#__users'))
 518                  ->set($db->quoteName('name') . ' = ' . $db->quote(trim($options->admin_user)))
 519                  ->set($db->quoteName('username') . ' = ' . $db->quote(trim($options->admin_username)))
 520                  ->set($db->quoteName('email') . ' = ' . $db->quote($options->admin_email))
 521                  ->set($db->quoteName('password') . ' = ' . $db->quote($cryptpass))
 522                  ->set($db->quoteName('block') . ' = 0')
 523                  ->set($db->quoteName('sendEmail') . ' = 1')
 524                  ->set($db->quoteName('registerDate') . ' = ' . $db->quote($installdate))
 525                  ->set($db->quoteName('lastvisitDate') . ' = NULL')
 526                  ->set($db->quoteName('activation') . ' = ' . $db->quote('0'))
 527                  ->set($db->quoteName('params') . ' = ' . $db->quote(''))
 528                  ->where($db->quoteName('id') . ' = ' . $db->quote($userId));
 529          } else {
 530              $columns = array(
 531                  $db->quoteName('id'),
 532                  $db->quoteName('name'),
 533                  $db->quoteName('username'),
 534                  $db->quoteName('email'),
 535                  $db->quoteName('password'),
 536                  $db->quoteName('block'),
 537                  $db->quoteName('sendEmail'),
 538                  $db->quoteName('registerDate'),
 539                  $db->quoteName('lastvisitDate'),
 540                  $db->quoteName('activation'),
 541                  $db->quoteName('params')
 542              );
 543              $query->clear()
 544                  ->insert('#__users', true)
 545                  ->columns($columns)
 546                  ->values(
 547                      $db->quote($userId) . ', ' . $db->quote(trim($options->admin_user)) . ', ' . $db->quote(trim($options->admin_username)) . ', ' .
 548                      $db->quote($options->admin_email) . ', ' . $db->quote($cryptpass) . ', ' .
 549                      $db->quote('0') . ', ' . $db->quote('1') . ', ' . $db->quote($installdate) . ', NULL, ' .
 550                      $db->quote('0') . ', ' . $db->quote('')
 551                  );
 552          }
 553  
 554          $db->setQuery($query);
 555  
 556          try {
 557              $db->execute();
 558          } catch (\RuntimeException $e) {
 559              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 560  
 561              return false;
 562          }
 563  
 564          // Map the super user to the Super Users group
 565          $query->clear()
 566              ->select($db->quoteName('user_id'))
 567              ->from($db->quoteName('#__user_usergroup_map'))
 568              ->where($db->quoteName('user_id') . ' = ' . $db->quote($userId));
 569  
 570          $db->setQuery($query);
 571  
 572          if ($db->loadResult()) {
 573              $query->clear()
 574                  ->update($db->quoteName('#__user_usergroup_map'))
 575                  ->set($db->quoteName('user_id') . ' = ' . $db->quote($userId))
 576                  ->set($db->quoteName('group_id') . ' = 8');
 577          } else {
 578              $query->clear()
 579                  ->insert($db->quoteName('#__user_usergroup_map'), false)
 580                  ->columns(array($db->quoteName('user_id'), $db->quoteName('group_id')))
 581                  ->values($db->quote($userId) . ', 8');
 582          }
 583  
 584          $db->setQuery($query);
 585  
 586          try {
 587              $db->execute();
 588          } catch (\RuntimeException $e) {
 589              Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
 590  
 591              return false;
 592          }
 593  
 594          return true;
 595      }
 596  
 597      /**
 598       * Method to erase the configuration file.
 599       *
 600       * @return  void
 601       *
 602       * @since   4.0.0
 603       */
 604      private function deleteConfiguration()
 605      {
 606          // The configuration file path.
 607          $path = JPATH_CONFIGURATION . '/configuration.php';
 608  
 609          if (file_exists($path)) {
 610              File::delete($path);
 611          }
 612      }
 613  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer