[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |