4 * Note that this installer has been based of the SilverStripe installer.
5 * You can get more information from the SilverStripe Website at
6 * http://www.silverstripe.com/.
8 * Copyright (c) 2006-7, SilverStripe Limited - www.silverstripe.com
11 * License: BSD-3-clause
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are
16 * Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * Neither the name of SilverStripe nor the names of its contributors may
24 * be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
31 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * Changes and modifications (c) 2007-2015 by CiviCRM LLC
47 ini_set('max_execution_time', 3000);
49 if (stristr(PHP_OS
, 'WIN')) {
50 define('CIVICRM_DIRECTORY_SEPARATOR', '/');
51 define('CIVICRM_WINDOWS', 1);
54 define('CIVICRM_DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR
);
55 define('CIVICRM_WINDOWS', 0);
58 // set installation type - drupal
63 // unset civicrm session if any
64 if (array_key_exists('CiviCRM', $_SESSION)) {
65 unset($_SESSION['CiviCRM']);
68 if (isset($_GET['civicrm_install_type'])) {
69 $_SESSION['civicrm_install_type'] = $_GET['civicrm_install_type'];
72 if (!isset($_SESSION['civicrm_install_type'])) {
73 $_SESSION['civicrm_install_type'] = "drupal";
80 global $installDirPath;
81 global $installURLPath;
83 $installType = strtolower($_SESSION['civicrm_install_type']);
85 if ($installType == 'drupal') {
86 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
87 $installDirPath = $installURLPath = '';
89 elseif ($installType == 'wordpress') {
90 $crmPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
;
91 $installDirPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
92 $installURLPath = WP_PLUGIN_URL
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
95 $errorTitle = "Oops! Unsupported installation mode";
96 $errorMsg = sprintf('%s: unknown installation mode. Please refer to the online documentation for more information.', $installType);
97 errorDisplayPage($errorTitle, $errorMsg, FALSE);
100 $pkgPath = $crmPath . DIRECTORY_SEPARATOR
. 'packages';
102 require_once $crmPath . '/CRM/Core/ClassLoader.php';
103 CRM_Core_ClassLoader
::singleton()->register();
105 // Load civicrm database config
106 if (isset($_REQUEST['mysql'])) {
107 $databaseConfig = $_REQUEST['mysql'];
110 $databaseConfig = array(
111 "server" => "localhost",
112 "username" => "civicrm",
114 "database" => "civicrm",
118 if ($installType == 'drupal') {
119 // Load drupal database config
120 if (isset($_REQUEST['drupal'])) {
121 $drupalConfig = $_REQUEST['drupal'];
124 $drupalConfig = array(
125 "server" => "localhost",
126 "username" => "drupal",
128 "database" => "drupal",
134 if (isset($_REQUEST['loadGenerated'])) {
138 require_once dirname(__FILE__
) . CIVICRM_DIRECTORY_SEPARATOR
. 'langs.php';
139 foreach ($langs as $locale => $_) {
140 if ($locale == 'en_US') {
143 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR
, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
144 unset($langs[$locale]);
148 // Set the locale (required by CRM_Core_Config)
149 // This is mostly sympbolic, since nothing we do during the install
150 // really requires CIVICRM_UF to be defined.
151 $installTypeToUF = array(
152 'wordpress' => 'WordPress',
153 'drupal' => 'Drupal',
156 $uf = (isset($installTypeToUF[$installType]) ?
$installTypeToUF[$installType] : 'Drupal');
157 define('CIVICRM_UF', $uf);
162 $seedLanguage = 'en_US';
164 if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
165 $seedLanguage = $_REQUEST['seedLanguage'];
166 $tsLocale = $_REQUEST['seedLanguage'];
169 $config = CRM_Core_Config
::singleton(FALSE);
170 $GLOBALS['civicrm_default_error_scope'] = NULL;
172 // The translation files are in the parent directory (l10n)
173 $i18n = CRM_Core_I18n
::singleton();
176 if ($installType == 'drupal') {
177 //CRM-6840 -don't force to install in sites/all/modules/
178 $object = new CRM_Utils_System_Drupal();
179 $cmsPath = $object->cmsRootPath();
181 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
182 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
183 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
184 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
185 'civicrm.settings.php'
188 elseif ($installType == 'wordpress') {
189 $cmsPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm';
190 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
191 'civicrm.settings.php'
195 if ($installType == 'drupal') {
196 // Lets check only /modules/.
197 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR
. 'modules', CIVICRM_DIRECTORY_SEPARATOR
) . '/';
199 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
200 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array('sites', 'all', 'modules'));
201 $errorTitle = ts("Oops! Please correct your install location");
202 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
203 errorDisplayPage($errorTitle, $errorMsg);
207 // Exit with error if CiviCRM has already been installed.
208 if ($alreadyInstalled) {
209 $errorTitle = ts("Oops! CiviCRM is already installed");
210 $settings_directory = $cmsPath;
212 if ($installType == 'drupal') {
213 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array(
214 ts('[your Drupal root directory]'),
220 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
221 $errorMsg = ts("CiviCRM has already been installed. <ul><li>To <strong>start over</strong>, you must delete or rename the existing CiviCRM settings file - <strong>civicrm.settings.php</strong> - from <strong>%1</strong>.</li><li>To <strong>upgrade an existing installation</strong>, <a href='%2'>refer to the online documentation</a>.</li></ul>", array(1 => $settings_directory, 2 => $docLink));
222 errorDisplayPage($errorTitle, $errorMsg, FALSE);
225 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'civicrm-version.php';
226 if (file_exists($versionFile)) {
227 require_once $versionFile;
228 $civicrm_version = civicrmVersion();
231 $civicrm_version = 'unknown';
234 if ($installType == 'drupal') {
235 // Ensure that they have downloaded the correct version of CiviCRM
236 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
237 $errorTitle = ts("Oops! Incorrect CiviCRM version");
238 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
239 errorDisplayPage($errorTitle, $errorMsg);
242 define('DRUPAL_ROOT', $cmsPath);
243 $drupalVersionFiles = array(
245 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'modules', 'system', 'system.module')),
247 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'includes', 'bootstrap.inc')),
249 foreach ($drupalVersionFiles as $drupalVersionFile) {
250 if (file_exists($drupalVersionFile)) {
251 require_once $drupalVersionFile;
255 if (!defined('VERSION') or version_compare(VERSION
, '6.0') < 0) {
256 $errorTitle = ts("Oops! Incorrect Drupal version");
257 $errorMsg = ts("This version of CiviCRM can only be used with Drupal 6.x or 7.x. Please ensure that '%1' exists if you are running Drupal 7.0 and over.", array(1 => implode("' or '", $drupalVersionFiles)));
258 errorDisplayPage($errorTitle, $errorMsg);
261 elseif ($installType == 'wordpress') {
263 $civicrm_version['cms'] = 'WordPress';
265 // Ensure that they have downloaded the correct version of CiviCRM
266 if ($civicrm_version['cms'] != 'WordPress') {
267 $errorTitle = ts("Oops! Incorrect CiviCRM version");
268 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
269 errorDisplayPage($errorTitle, $errorMsg);
273 // Check requirements
274 $req = new InstallRequirements();
277 if ($req->hasErrors()) {
278 $hasErrorOtherThanDatabase = TRUE;
281 if ($databaseConfig) {
282 $dbReq = new InstallRequirements();
283 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
284 if ($installType == 'drupal') {
285 $dbReq->checkdatabase($drupalConfig, 'Drupal');
290 if (isset($_REQUEST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
291 // Confirm before reinstalling
292 if (!isset($_REQUEST['force_reinstall']) && $alreadyInstalled) {
293 include $installDirPath . 'template.html';
296 $inst = new Installer();
297 $inst->install($_REQUEST);
300 // Show the config form
303 include $installDirPath . 'template.html';
307 * This class checks requirements
308 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
310 * $description[0] - The test category
311 * $description[1] - The test title
312 * $description[2] - The test error to show, if it goes wrong
314 class InstallRequirements
{
315 var $errors, $warnings, $tests;
317 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
318 const MINIMUM_THREAD_STACK
= 192;
321 * Just check that the database configuration is okay.
322 * @param $databaseConfig
325 public function checkdatabase($databaseConfig, $dbName) {
326 if ($this->requireFunction('mysql_connect',
328 ts("PHP Configuration"),
330 ts("MySQL support not included in PHP."),
334 $this->requireMySQLServer($databaseConfig['server'],
336 ts("MySQL %1 Configuration", array(1 => $dbName)),
337 ts("Does the server exist?"),
338 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
339 $databaseConfig['server'],
342 if ($this->requireMysqlConnection($databaseConfig['server'],
343 $databaseConfig['username'],
344 $databaseConfig['password'],
346 ts("MySQL %1 Configuration", array(1 => $dbName)),
347 ts("Are the access credentials correct?"),
348 ts("That username/password doesn't work"),
352 @$this->requireMySQLVersion("5.1",
354 ts("MySQL %1 Configuration", array(1 => $dbName)),
355 ts("MySQL version at least %1", array(1 => '5.1')),
356 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
357 ts("MySQL %1", array(1 => mysql_get_server_info())),
360 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
361 $databaseConfig['username'],
362 $databaseConfig['password'],
364 ts("MySQL %1 Configuration", array(1 => $dbName)),
365 ts("Is auto_increment_increment set to 1"),
366 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
369 $this->requireMySQLThreadStack($databaseConfig['server'],
370 $databaseConfig['username'],
371 $databaseConfig['password'],
372 $databaseConfig['database'],
373 self
::MINIMUM_THREAD_STACK
,
375 ts("MySQL %1 Configuration", array(1 => $dbName)),
376 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self
::MINIMUM_THREAD_STACK
)),
378 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
382 $onlyRequire = ($dbName == 'Drupal') ?
TRUE : FALSE;
383 $this->requireDatabaseOrCreatePermissions(
384 $databaseConfig['server'],
385 $databaseConfig['username'],
386 $databaseConfig['password'],
387 $databaseConfig['database'],
389 ts("MySQL %1 Configuration", array(1 => $dbName)),
390 ts("Can I access/create the database?"),
391 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
395 if ($dbName != 'Drupal') {
396 $this->requireMySQLInnoDB($databaseConfig['server'],
397 $databaseConfig['username'],
398 $databaseConfig['password'],
399 $databaseConfig['database'],
401 ts("MySQL %1 Configuration", array(1 => $dbName)),
402 ts("Can I access/create InnoDB tables in the database?"),
403 ts("Unable to create InnoDB tables. MySQL InnoDB support is required for CiviCRM but is either not available or not enabled in this MySQL database server."),
406 $this->requireMySQLTempTables($databaseConfig['server'],
407 $databaseConfig['username'],
408 $databaseConfig['password'],
409 $databaseConfig['database'],
411 ts("MySQL %1 Configuration", array(1 => $dbName)),
412 ts('Can I create temporary tables in the database?'),
413 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
416 $this->requireMySQLLockTables($databaseConfig['server'],
417 $databaseConfig['username'],
418 $databaseConfig['password'],
419 $databaseConfig['database'],
421 ts("MySQL %1 Configuration", array(1 => $dbName)),
422 ts('Can I create lock tables in the database?'),
423 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
426 $this->requireMySQLTrigger($databaseConfig['server'],
427 $databaseConfig['username'],
428 $databaseConfig['password'],
429 $databaseConfig['database'],
431 ts("MySQL %1 Configuration", array(1 => $dbName)),
432 ts('Can I create triggers in the database?'),
433 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
441 * Check everything except the database.
443 public function check() {
444 global $crmPath, $installType;
446 $this->errors
= NULL;
448 $this->requirePHPVersion('5.3.3', array(
449 ts("PHP Configuration"),
450 ts("PHP5 installed"),
452 ts("PHP version %1", array(1 => phpversion())),
455 // Check that we can identify the root folder successfully
456 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'README.txt',
458 ts("File permissions"),
459 ts("Does the webserver know where files are stored?"),
460 ts("The webserver isn't letting me identify where files are stored."),
466 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
467 $this->requireNoPathSeparator(
469 ts("File permissions"),
470 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
471 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR
)),
476 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
477 foreach ($requiredDirectories as $dir) {
478 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. $dir,
480 ts("File permissions"),
481 ts("Folder '%1' exists?", array(1 => $dir)),
482 ts("There is no '%1' folder.", array(1 => $dir)),
487 $configIDSiniDir = NULL;
489 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
490 if ($installType == 'drupal') {
492 // make sure that we can write to sites/default and files/
493 $writableDirectories = array(
494 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
495 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
496 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
498 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
499 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
503 elseif ($installType == 'wordpress') {
504 // make sure that we can write to plugins/civicrm and plugins/files/
505 $writableDirectories = array(WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'files', $cmsPath);
508 foreach ($writableDirectories as $dir) {
509 $dirName = CIVICRM_WINDOWS ?
$dir : CIVICRM_DIRECTORY_SEPARATOR
. $dir;
510 $testDetails = array(
511 ts("File permissions"),
512 ts("Is the %1 folder writeable?", array(1 => $dir)),
515 $this->requireWriteable($dirName, $testDetails, TRUE);
518 //check for Config.IDS.ini, file may exist in re-install
519 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
521 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
522 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR
, $configIDSiniDir);
523 if (file_exists($configIDSiniFile)) {
524 unlink($configIDSiniFile);
528 // Check for rewriting
529 if (isset($_SERVER['SERVER_SOFTWARE'])) {
530 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
532 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
533 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
536 if ($webserver == '') {
537 $webserver = ts("I can't tell what webserver you are running");
540 // Check for $_SERVER configuration
541 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
542 ts("Webserver config"),
543 ts("Recognised webserver"),
544 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
547 // Check for MySQL support
548 $this->requireFunction('mysql_connect', array(
549 ts("PHP Configuration"),
551 ts("MySQL support not included in PHP."),
554 // Check for JSON support
555 $this->requireFunction('json_encode', array(
556 ts("PHP Configuration"),
558 ts("JSON support not included in PHP."),
561 // Check for xcache_isset and emit warning if exists
562 $this->checkXCache(array(
563 ts("PHP Configuration"),
564 ts("XCache compatibility"),
565 ts("XCache is installed and there are known compatibility issues between XCache and CiviCRM. Consider using an alternative PHP caching mechanism or disable PHP caching altogether."),
568 // Check memory allocation
569 $this->requireMemory(32 * 1024 * 1024,
572 ts("PHP Configuration"),
573 ts("Memory allocated (PHP config option 'memory_limit')"),
574 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
575 ini_get("memory_limit"),
579 return $this->errors
;
584 * @param $recommended
585 * @param $testDetails
587 public function requireMemory($min, $recommended, $testDetails) {
588 $this->testing($testDetails);
589 $mem = $this->getPHPMemory();
591 if ($mem < $min && $mem > 0) {
592 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
593 $this->error($testDetails);
595 elseif ($mem < $recommended && $mem > 0) {
596 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
597 $this->warning($testDetails);
600 $testDetails[2] .= " " . ts("We can't determine how much memory you have allocated. Install only if you're sure you've allocated at least %1 MB.", array(1 => 32));
601 $this->warning($testDetails);
608 public function getPHPMemory() {
609 $memString = ini_get("memory_limit");
611 switch (strtolower(substr($memString, -1))) {
613 return round(substr($memString, 0, -1) * 1024);
616 return round(substr($memString, 0, -1) * 1024 * 1024);
619 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
622 return round($memString);
626 public function listErrors() {
628 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
629 foreach ($this->errors
as $error) {
630 echo "<li>" . htmlentities($error) . "</li>";
636 * @param null $section
638 public function showTable($section = NULL) {
640 $tests = $this->tests
[$section];
641 echo "<table class=\"testResults\" width=\"100%\">";
642 foreach ($tests as $test => $result) {
643 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
648 foreach ($this->tests
as $section => $tests) {
649 echo "<h3>$section</h3>";
650 echo "<table class=\"testResults\" width=\"100%\">";
652 foreach ($tests as $test => $result) {
653 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
661 * @param string $funcName
662 * @param $testDetails
666 public function requireFunction($funcName, $testDetails) {
667 $this->testing($testDetails);
669 if (!function_exists($funcName)) {
670 $this->error($testDetails);
679 * @param $testDetails
681 public function checkXCache($testDetails) {
682 if (function_exists('xcache_isset') &&
683 ini_get('xcache.size') > 0
685 $this->testing($testDetails);
686 $this->warning($testDetails);
692 * @param $testDetails
693 * @param null $maxVersion
695 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
697 $this->testing($testDetails);
699 $phpVersion = phpversion();
700 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
701 $belowMaxVersion = $maxVersion ?
version_compare($phpVersion, $maxVersion) < 0 : TRUE;
703 if ($maxVersion && $aboveMinVersion && $belowMaxVersion) {
706 elseif (!$maxVersion && $aboveMinVersion) {
710 if (!$testDetails[2]) {
711 if (!$aboveMinVersion) {
712 $testDetails[2] = ts("You need PHP version %1 or later, only %2 is installed. Please upgrade your server, or ask your web-host to do so.", array(1 => $minVersion, 2 => $phpVersion));
715 $testDetails[2] = ts("PHP version %1 is not supported. PHP version earlier than %2 is required. You might want to downgrade your server, or ask your web-host to do so.", array(1 => $maxVersion, 2 => $phpVersion));
719 $this->error($testDetails);
723 * @param string $filename
724 * @param $testDetails
725 * @param bool $absolute
727 public function requireFile($filename, $testDetails, $absolute = FALSE) {
728 $this->testing($testDetails);
730 $filename = $this->getBaseDir() . $filename;
732 if (!file_exists($filename)) {
733 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
734 $this->error($testDetails);
739 * @param $testDetails
741 public function requireNoPathSeparator($testDetails) {
742 $this->testing($testDetails);
743 if (substr_count($this->getBaseDir(), PATH_SEPARATOR
)) {
744 $this->error($testDetails);
749 * @param string $filename
750 * @param $testDetails
752 public function requireNoFile($filename, $testDetails) {
753 $this->testing($testDetails);
754 $filename = $this->getBaseDir() . $filename;
755 if (file_exists($filename)) {
756 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
757 $this->error($testDetails);
762 * @param string $filename
763 * @param $testDetails
765 public function moveFileOutOfTheWay($filename, $testDetails) {
766 $this->testing($testDetails);
767 $filename = $this->getBaseDir() . $filename;
768 if (file_exists($filename)) {
769 if (file_exists("$filename.bak")) {
772 rename($filename, "$filename.bak");
777 * @param string $filename
778 * @param $testDetails
779 * @param bool $absolute
781 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
782 $this->testing($testDetails);
784 $filename = $this->getBaseDir() . $filename;
787 if (!is_writable($filename)) {
789 if (function_exists('posix_getpwuid')) {
790 $user = posix_getpwuid(posix_geteuid());
791 $name = '- ' . $user['name'] . ' -';
794 if (!isset($testDetails[2])) {
795 $testDetails[2] = NULL;
797 $testDetails[2] .= ts("The user account used by your web-server %1 needs to be granted write access to the following directory in order to configure the CiviCRM settings file:", array(1 => $name)) . "\n$filename";
798 $this->error($testDetails);
803 * @param string $moduleName
804 * @param $testDetails
806 public function requireApacheModule($moduleName, $testDetails) {
807 $this->testing($testDetails);
808 if (!in_array($moduleName, apache_get_modules())) {
809 $this->error($testDetails);
815 * @param string $username
817 * @param $testDetails
819 public function requireMysqlConnection($server, $username, $password, $testDetails) {
820 $this->testing($testDetails);
821 $conn = @mysql_connect
($server, $username, $password);
827 $testDetails[2] .= ": " . mysql_error();
828 $this->error($testDetails);
834 * @param $testDetails
836 public function requireMySQLServer($server, $testDetails) {
837 $this->testing($testDetails);
838 $conn = @mysql_connect
($server, NULL, NULL);
840 if ($conn ||
mysql_errno() < 2000) {
844 $testDetails[2] .= ": " . mysql_error();
845 $this->error($testDetails);
851 * @param $testDetails
853 public function requireMySQLVersion($version, $testDetails) {
854 $this->testing($testDetails);
856 if (!mysql_get_server_info()) {
857 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
858 $this->warning($testDetails);
861 list($majorRequested, $minorRequested) = explode('.', $version);
862 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
864 if (($majorHas > $majorRequested) ||
($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
868 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
869 $this->error($testDetails);
876 * @param string $username
879 * @param $testDetails
881 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
882 $this->testing($testDetails);
883 $conn = @mysql_connect
($server, $username, $password);
885 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
886 $this->error($testDetails);
890 $innodb_support = FALSE;
891 $result = mysql_query("SHOW ENGINES", $conn);
892 while ($values = mysql_fetch_array($result)) {
893 if ($values['Engine'] == 'InnoDB') {
894 if (strtolower($values['Support']) == 'yes' ||
895 strtolower($values['Support']) == 'default'
897 $innodb_support = TRUE;
901 if ($innodb_support) {
902 $testDetails[3] = ts('MySQL server does have InnoDB support');
905 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
911 * @param string $username
914 * @param $testDetails
916 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
917 $this->testing($testDetails);
918 $conn = @mysql_connect
($server, $username, $password);
920 $testDetails[2] = ts('Could not login to the database.');
921 $this->error($testDetails);
925 if (!@mysql_select_db
($database, $conn)) {
926 $testDetails[2] = ts('Could not select the database.');
927 $this->error($testDetails);
931 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
933 $testDetails[2] = ts('Could not create a temp table.');
934 $this->error($testDetails);
936 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
941 * @param string $username
944 * @param $testDetails
946 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
947 $this->testing($testDetails);
948 $conn = @mysql_connect
($server, $username, $password);
950 $testDetails[2] = ts('Could not login to the database.');
951 $this->error($testDetails);
955 if (!@mysql_select_db
($database, $conn)) {
956 $testDetails[2] = ts('Could not select the database.');
957 $this->error($testDetails);
961 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
963 $testDetails[2] = ts('Could not create a table in the database.');
964 $this->error($testDetails);
967 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
969 mysql_query('DROP TABLE civicrm_install_temp_table_test');
970 $testDetails[2] = ts('Could not create a database trigger.');
971 $this->error($testDetails);
974 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
975 mysql_query('DROP TABLE civicrm_install_temp_table_test');
981 * @param string $username
984 * @param $testDetails
986 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
987 $this->testing($testDetails);
988 $conn = @mysql_connect
($server, $username, $password);
990 $testDetails[2] = ts('Could not connect to the database server.');
991 $this->error($testDetails);
995 if (!@mysql_select_db
($database, $conn)) {
996 $testDetails[2] = ts('Could not select the database.');
997 $this->error($testDetails);
1001 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1003 $testDetails[2] = ts('Could not create a table in the database.');
1004 $this->error($testDetails);
1008 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1010 $testDetails[2] = ts('Could not obtain a write lock for the database table.');
1011 $this->error($testDetails);
1012 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1016 $result = mysql_query('UNLOCK TABLES', $conn);
1018 $testDetails[2] = ts('Could not release the lock for the database table.');
1019 $this->error($testDetails);
1020 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1024 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1029 * @param string $username
1031 * @param $testDetails
1033 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
1034 $this->testing($testDetails);
1035 $conn = @mysql_connect
($server, $username, $password);
1037 $testDetails[2] = ts('Could not connect to the database server.');
1038 $this->error($testDetails);
1042 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1044 $testDetails[2] = ts('Could not query database server variables.');
1045 $this->error($testDetails);
1049 $values = mysql_fetch_row($result);
1050 if ($values[1] == 1) {
1051 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
1054 $this->error($testDetails);
1061 * @param string $username
1064 * @param $minValueKB
1065 * @param $testDetails
1067 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1068 $this->testing($testDetails);
1069 $conn = @mysql_connect
($server, $username, $password);
1071 $testDetails[2] = ts('Could not connect to the database server.');
1072 $this->error($testDetails);
1076 if (!@mysql_select_db
($database, $conn)) {
1077 $testDetails[2] = ts('Could not select the database.');
1078 $this->error($testDetails);
1082 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1084 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
1085 $this->error($testDetails);
1088 $values = mysql_fetch_row($result);
1089 if ($values[1] < (1024 * $minValueKB)) {
1090 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
1091 $this->error($testDetails);
1098 * @param string $username
1101 * @param $testDetails
1102 * @param bool $onlyRequire
1104 public function requireDatabaseOrCreatePermissions(
1110 $onlyRequire = FALSE
1112 $this->testing($testDetails);
1113 $conn = @mysql_connect
($server, $username, $password);
1116 if (@mysql_select_db
($database)) {
1117 $okay = "Database '$database' exists";
1119 elseif ($onlyRequire) {
1120 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
1121 $this->error($testDetails);
1125 if (@mysql_query
("CREATE DATABASE $database")) {
1126 $okay = ts("Able to create a new database.");
1129 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
1130 $this->error($testDetails);
1136 $testDetails[3] = $okay;
1137 $this->testing($testDetails);
1143 * @param $errorMessage
1145 public function requireServerVariables($varNames, $errorMessage) {
1146 //$this->testing($testDetails);
1147 foreach ($varNames as $varName) {
1148 if (!$_SERVER[$varName]) {
1149 $missing[] = '$_SERVER[' . $varName . ']';
1152 if (!isset($missing)) {
1156 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
1157 $this->error($testDetails);
1162 * @param $testDetails
1166 public function isRunningApache($testDetails) {
1167 $this->testing($testDetails);
1168 if (function_exists('apache_get_modules') ||
stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1172 $this->warning($testDetails);
1179 public function getBaseDir() {
1180 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR
;
1184 * @param $testDetails
1186 public function testing($testDetails) {
1187 if (!$testDetails) {
1191 $section = $testDetails[0];
1192 $test = $testDetails[1];
1194 $message = ts("OK");
1195 if (isset($testDetails[3])) {
1196 $message .= " ($testDetails[3])";
1199 $this->tests
[$section][$test] = array("good", $message);
1203 * @param $testDetails
1205 public function error($testDetails) {
1206 $section = $testDetails[0];
1207 $test = $testDetails[1];
1209 $this->tests
[$section][$test] = array("error", $testDetails[2]);
1210 $this->errors
[] = $testDetails;
1214 * @param $testDetails
1216 public function warning($testDetails) {
1217 $section = $testDetails[0];
1218 $test = $testDetails[1];
1220 $this->tests
[$section][$test] = array("warning", $testDetails[2]);
1221 $this->warnings
[] = $testDetails;
1227 public function hasErrors() {
1228 return count($this->errors
);
1234 public function hasWarnings() {
1235 return count($this->warnings
);
1243 class Installer
extends InstallRequirements
{
1250 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1251 $conn = @mysql_connect
($server, $username, $password);
1253 if (@mysql_select_db
($database)) {
1254 // skip if database already present
1258 if (@mysql_query
("CREATE DATABASE $database")) {
1261 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1262 $errorMsg = ts("We encountered an error when attempting to create the database. Please check your MySQL server permissions and the database name and try again.");
1263 errorDisplayPage($errorTitle, $errorMsg);
1272 public function install($config) {
1273 global $installDirPath;
1275 // create database if does not exists
1276 $this->createDatabaseIfNotExists($config['mysql']['server'],
1277 $config['mysql']['username'],
1278 $config['mysql']['password'],
1279 $config['mysql']['database']
1282 global $installDirPath;
1285 require_once $installDirPath . 'civicrm.php';
1286 civicrm_main($config);
1288 if (!$this->errors
) {
1289 global $installType, $installURLPath;
1291 $registerSiteURL = "https://civicrm.org/register-site";
1292 $commonOutputMessage
1293 = "<li>" . ts("Have you registered this site at CiviCRM.org? If not, please help strengthen the CiviCRM ecosystem by taking a few minutes to <a %1>fill out the site registration form</a>. The information collected will help us prioritize improvements, target our communications and build the community. If you have a technical role for this site, be sure to check Keep in Touch to receive technical updates (a low volume mailing list).", array(1 => "href='$registerSiteURL' target='_blank'")) . "</li>"
1294 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
1299 $installType == 'drupal' &&
1300 version_compare(VERSION
, '7.0-rc1') >= 0
1306 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1307 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1308 $output .= '<head>';
1309 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1310 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1311 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1312 $output .= '</head>';
1313 $output .= '<body>';
1314 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1317 $drupalURL = civicrm_cms_base();
1318 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1319 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1321 $output .= "<li>" . ts("Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$drupalPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1322 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$drupalURL'")) . "</li>";
1323 $output .= $commonOutputMessage;
1325 // automatically enable CiviCRM module once it is installed successfully.
1326 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1327 global $cmsPath, $crmPath;
1329 // relative / abosolute paths are not working for drupal, hence using chdir()
1332 // Force the re-initialisation of the config singleton on the next call
1333 // since so far, we had used the Config object without loading the DB.
1334 $c = CRM_Core_Config
::singleton(FALSE);
1337 include_once "./includes/bootstrap.inc";
1338 include_once "./includes/unicode.inc";
1340 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1342 // prevent session information from being saved.
1343 drupal_save_session(FALSE);
1345 // Force the current user to anonymous.
1346 $original_user = $GLOBALS['user'];
1347 $GLOBALS['user'] = drupal_anonymous_user();
1349 // explicitly setting error reporting, since we cannot handle drupal related notices
1352 // rebuild modules, so that civicrm is added
1353 system_rebuild_module_data();
1355 // now enable civicrm module.
1356 module_enable(array('civicrm', 'civicrmtheme'));
1358 // clear block, page, theme, and hook caches
1359 drupal_flush_all_caches();
1361 //add basic drupal permissions
1362 civicrm_install_set_drupal_perms();
1364 // restore the user.
1365 $GLOBALS['user'] = $original_user;
1366 drupal_save_session(TRUE);
1368 //change the default language to one chosen
1369 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1370 // This ensures that defaults get set, otherwise the user will login
1371 // and most configurations will be empty, not set to en_US defaults.
1372 civicrm_api3('Setting', 'revert');
1374 civicrm_api3('Setting', 'create', array(
1375 'domain_id' => 'current_domain',
1376 'lcMessages' => $config['seedLanguage'],
1382 $output .= '</div>';
1383 $output .= '</body>';
1384 $output .= '</html>';
1387 elseif ($installType == 'drupal' && version_compare(VERSION
, '6.0') >= 0) {
1391 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1392 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1393 $output .= '<head>';
1394 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1395 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1396 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1397 $output .= '</head>';
1398 $output .= '<body>';
1399 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
1402 $drupalURL = civicrm_cms_base();
1403 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1404 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1406 $output .= "<li>" . ts("Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$drupalPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1407 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$drupalURL'")) . "</li>";
1408 $output .= $commonOutputMessage;
1410 // explicitly setting error reporting, since we cannot handle drupal related notices
1413 // automatically enable CiviCRM module once it is installed successfully.
1414 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1415 global $cmsPath, $crmPath;
1417 // relative / abosolute paths are not working for drupal, hence using chdir()
1420 // Force the re-initialisation of the config singleton on the next call
1421 // since so far, we had used the Config object without loading the DB.
1422 $c = CRM_Core_Config
::singleton(FALSE);
1425 include_once "./includes/bootstrap.inc";
1426 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1428 // rebuild modules, so that civicrm is added
1429 module_rebuild_cache();
1431 // now enable civicrm module.
1432 module_enable(array('civicrm'));
1434 // clear block, page, theme, and hook caches
1435 drupal_flush_all_caches();
1437 //add basic drupal permissions
1438 db_query('UPDATE {permission} SET perm = CONCAT( perm, \', access CiviMail subscribe/unsubscribe pages, access all custom data, access uploaded files, make online contributions, profile create, profile edit, profile view, register for events, view event info\') WHERE rid IN (1, 2)');
1442 elseif ($installType == 'wordpress') {
1443 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
1444 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
1447 $cmsURL = civicrm_cms_base();
1448 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1449 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1451 $output .= "<li>" . ts("WordPress user permissions have been automatically set - giving Anonymous and Subscribers access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$wpPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1452 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$cmsURL'")) . "</li>";
1453 $output .= $commonOutputMessage;
1458 $c = CRM_Core_Config
::singleton(FALSE);
1463 return $this->errors
;
1468 function civicrm_install_set_drupal_perms() {
1469 if (!function_exists('db_select')) {
1470 db_query('UPDATE {permission} SET perm = CONCAT( perm, \', access CiviMail subscribe/unsubscribe pages, access all custom data, access uploaded files, make online contributions, profile listings and forms, register for events, view event info, view event participants\') WHERE rid IN (1, 2)');
1474 'access all custom data',
1475 'access uploaded files',
1476 'make online contributions',
1480 'register for events',
1482 'view event participants',
1483 'access CiviMail subscribe/unsubscribe pages',
1486 // Adding a permission that has not yet been assigned to a module by
1487 // a hook_permission implementation results in a database error.
1489 $allPerms = array_keys(module_invoke_all('permission'));
1490 foreach (array_diff($perms, $allPerms) as $perm) {
1492 'Cannot grant the %perm permission because it does not yet exist.',
1493 array('%perm' => $perm),
1497 $perms = array_intersect($perms, $allPerms);
1498 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID
, $perms);
1499 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID
, $perms);
1509 function getSiteDir($cmsPath, $str) {
1510 static $siteDir = '';
1516 $sites = CIVICRM_DIRECTORY_SEPARATOR
. 'sites' . CIVICRM_DIRECTORY_SEPARATOR
;
1517 $modules = CIVICRM_DIRECTORY_SEPARATOR
. 'modules' . CIVICRM_DIRECTORY_SEPARATOR
;
1518 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR
) .
1519 "([\-a-zA-Z0-9_.]+)" .
1520 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR
) . "/",
1521 $_SERVER['SCRIPT_FILENAME'], $matches
1523 $siteDir = isset($matches[1]) ?
$matches[1] : 'default';
1525 if (strtolower($siteDir) == 'all') {
1526 // For this case - use drupal's way of finding out multi-site directory
1527 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR
, $_SERVER['SCRIPT_FILENAME']);
1528 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1529 for ($i = count($uri) - 1; $i > 0; $i--) {
1530 for ($j = count($server); $j > 0; $j--) {
1531 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1532 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
1533 'sites' . CIVICRM_DIRECTORY_SEPARATOR
. $dir
1540 $siteDir = 'default';
1547 * @param $errorTitle
1551 function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1553 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1555 if (function_exists('ts')) {
1556 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1559 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1563 include 'error.html';