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
60 if (defined('PANTHEON_ENVIRONMENT')) {
61 ini_set('session.save_handler', 'files');
66 // unset civicrm session if any
67 if (array_key_exists('CiviCRM', $_SESSION)) {
68 unset($_SESSION['CiviCRM']);
71 if (isset($_GET['civicrm_install_type'])) {
72 $_SESSION['civicrm_install_type'] = $_GET['civicrm_install_type'];
75 if (!isset($_SESSION['civicrm_install_type'])) {
76 $_SESSION['civicrm_install_type'] = "drupal";
83 global $installDirPath;
84 global $installURLPath;
86 $installType = strtolower($_SESSION['civicrm_install_type']);
88 if ($installType == 'drupal') {
89 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
90 $installDirPath = $installURLPath = '';
92 elseif ($installType == 'wordpress') {
93 $crmPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
;
94 $installDirPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
95 $installURLPath = WP_PLUGIN_URL
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
98 $errorTitle = "Oops! Unsupported installation mode";
99 $errorMsg = sprintf('%s: unknown installation mode. Please refer to the online documentation for more information.', $installType);
100 errorDisplayPage($errorTitle, $errorMsg, FALSE);
103 $pkgPath = $crmPath . DIRECTORY_SEPARATOR
. 'packages';
105 require_once $crmPath . '/CRM/Core/ClassLoader.php';
106 CRM_Core_ClassLoader
::singleton()->register();
108 // Load civicrm database config
109 if (isset($_POST['mysql'])) {
110 $databaseConfig = $_POST['mysql'];
113 $databaseConfig = array(
114 "server" => "localhost",
115 "username" => "civicrm",
117 "database" => "civicrm",
121 if ($installType == 'wordpress') {
123 $databaseConfig = array(
125 "username" => DB_USER
,
126 "password" => DB_PASSWORD
,
127 "database" => DB_NAME
,
131 if ($installType == 'drupal') {
132 // Load drupal database config
133 if (isset($_POST['drupal'])) {
134 $drupalConfig = $_POST['drupal'];
137 $drupalConfig = array(
138 "server" => "localhost",
139 "username" => "drupal",
141 "database" => "drupal",
147 if (isset($_POST['loadGenerated'])) {
151 require_once dirname(__FILE__
) . CIVICRM_DIRECTORY_SEPARATOR
. 'langs.php';
152 foreach ($langs as $locale => $_) {
153 if ($locale == 'en_US') {
156 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR
, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
157 unset($langs[$locale]);
161 // Set the locale (required by CRM_Core_Config)
162 // This is mostly sympbolic, since nothing we do during the install
163 // really requires CIVICRM_UF to be defined.
164 $installTypeToUF = array(
165 'wordpress' => 'WordPress',
166 'drupal' => 'Drupal',
169 $uf = (isset($installTypeToUF[$installType]) ?
$installTypeToUF[$installType] : 'Drupal');
170 define('CIVICRM_UF', $uf);
175 $seedLanguage = 'en_US';
177 // CRM-16801 This validates that seedLanguage is valid by looking in $langs.
178 // NB: the variable is initial a $_REQUEST for the initial page reload,
179 // then becomes a $_POST when the installation form is submitted.
180 if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
181 $seedLanguage = $_REQUEST['seedLanguage'];
182 $tsLocale = $_REQUEST['seedLanguage'];
185 $config = CRM_Core_Config
::singleton(FALSE);
186 $GLOBALS['civicrm_default_error_scope'] = NULL;
188 // The translation files are in the parent directory (l10n)
189 $i18n = CRM_Core_I18n
::singleton();
191 // Support for Arabic, Hebrew, Farsi, etc.
192 // Used in the template.html
193 $short_lang_code = CRM_Core_I18n_PseudoConstant
::shortForLong($tsLocale);
194 $text_direction = (CRM_Core_I18n
::isLanguageRTL($tsLocale) ?
'rtl' : 'ltr');
197 if ($installType == 'drupal') {
198 //CRM-6840 -don't force to install in sites/all/modules/
199 $object = new CRM_Utils_System_Drupal();
200 $cmsPath = $object->cmsRootPath();
202 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
203 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
204 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
205 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
206 'civicrm.settings.php'
209 elseif ($installType == 'wordpress') {
210 $cmsPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm';
211 $upload_dir = wp_upload_dir();
212 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
213 $wp_civi_settings = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm.settings.php';
214 $wp_civi_settings_deprectated = CIVICRM_PLUGIN_DIR
. 'civicrm.settings.php';
215 if (file_exists($wp_civi_settings_deprectated)) {
216 $alreadyInstalled = $wp_civi_settings_deprectated;
218 elseif (file_exists($wp_civi_settings)) {
219 $alreadyInstalled = $wp_civi_settings;
223 if ($installType == 'drupal') {
224 // Lets check only /modules/.
225 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR
. 'modules', CIVICRM_DIRECTORY_SEPARATOR
) . '/';
227 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
228 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array('sites', 'all', 'modules'));
229 $errorTitle = ts("Oops! Please correct your install location");
230 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
231 errorDisplayPage($errorTitle, $errorMsg);
235 // Exit with error if CiviCRM has already been installed.
236 if ($alreadyInstalled) {
237 $errorTitle = ts("Oops! CiviCRM is already installed");
238 $settings_directory = $cmsPath;
240 if ($installType == 'drupal') {
241 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array(
242 ts('[your Drupal root directory]'),
248 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
249 $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));
250 errorDisplayPage($errorTitle, $errorMsg, FALSE);
253 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'civicrm-version.php';
254 if (file_exists($versionFile)) {
255 require_once $versionFile;
256 $civicrm_version = civicrmVersion();
259 $civicrm_version = 'unknown';
262 if ($installType == 'drupal') {
263 // Ensure that they have downloaded the correct version of CiviCRM
264 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
265 $errorTitle = ts("Oops! Incorrect CiviCRM version");
266 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
267 errorDisplayPage($errorTitle, $errorMsg);
270 define('DRUPAL_ROOT', $cmsPath);
271 $drupalVersionFiles = array(
273 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'modules', 'system', 'system.module')),
275 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'includes', 'bootstrap.inc')),
277 foreach ($drupalVersionFiles as $drupalVersionFile) {
278 if (file_exists($drupalVersionFile)) {
279 require_once $drupalVersionFile;
283 if (!defined('VERSION') or version_compare(VERSION
, '6.0') < 0) {
284 $errorTitle = ts("Oops! Incorrect Drupal version");
285 $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)));
286 errorDisplayPage($errorTitle, $errorMsg);
289 elseif ($installType == 'wordpress') {
291 $civicrm_version['cms'] = 'WordPress';
293 // Ensure that they have downloaded the correct version of CiviCRM
294 if ($civicrm_version['cms'] != 'WordPress') {
295 $errorTitle = ts("Oops! Incorrect CiviCRM version");
296 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
297 errorDisplayPage($errorTitle, $errorMsg);
301 // Check requirements
302 $req = new InstallRequirements();
305 if ($req->hasErrors()) {
306 $hasErrorOtherThanDatabase = TRUE;
309 if ($databaseConfig) {
310 $dbReq = new InstallRequirements();
311 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
312 if ($installType == 'drupal') {
313 $dbReq->checkdatabase($drupalConfig, 'Drupal');
318 if (isset($_POST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
319 // Confirm before reinstalling
320 if (!isset($_POST['force_reinstall']) && $alreadyInstalled) {
321 include $installDirPath . 'template.html';
324 $inst = new Installer();
325 $inst->install($_POST);
328 // Show the config form
331 include $installDirPath . 'template.html';
335 * This class checks requirements
336 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
338 * $description[0] - The test category
339 * $description[1] - The test title
340 * $description[2] - The test error to show, if it goes wrong
342 class InstallRequirements
{
343 var $errors, $warnings, $tests;
345 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
346 const MINIMUM_THREAD_STACK
= 192;
349 * Just check that the database configuration is okay.
350 * @param $databaseConfig
353 public function checkdatabase($databaseConfig, $dbName) {
354 if ($this->requireFunction('mysql_connect',
356 ts("PHP Configuration"),
358 ts("MySQL support not included in PHP."),
362 $this->requireMySQLServer($databaseConfig['server'],
364 ts("MySQL %1 Configuration", array(1 => $dbName)),
365 ts("Does the server exist?"),
366 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
367 $databaseConfig['server'],
370 if ($this->requireMysqlConnection($databaseConfig['server'],
371 $databaseConfig['username'],
372 $databaseConfig['password'],
374 ts("MySQL %1 Configuration", array(1 => $dbName)),
375 ts("Are the access credentials correct?"),
376 ts("That username/password doesn't work"),
380 @$this->requireMySQLVersion("5.1",
382 ts("MySQL %1 Configuration", array(1 => $dbName)),
383 ts("MySQL version at least %1", array(1 => '5.1')),
384 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
385 ts("MySQL %1", array(1 => mysql_get_server_info())),
388 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
389 $databaseConfig['username'],
390 $databaseConfig['password'],
392 ts("MySQL %1 Configuration", array(1 => $dbName)),
393 ts("Is auto_increment_increment set to 1"),
394 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
397 $this->requireMySQLThreadStack($databaseConfig['server'],
398 $databaseConfig['username'],
399 $databaseConfig['password'],
400 $databaseConfig['database'],
401 self
::MINIMUM_THREAD_STACK
,
403 ts("MySQL %1 Configuration", array(1 => $dbName)),
404 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self
::MINIMUM_THREAD_STACK
)),
406 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
410 $onlyRequire = ($dbName == 'Drupal') ?
TRUE : FALSE;
411 $this->requireDatabaseOrCreatePermissions(
412 $databaseConfig['server'],
413 $databaseConfig['username'],
414 $databaseConfig['password'],
415 $databaseConfig['database'],
417 ts("MySQL %1 Configuration", array(1 => $dbName)),
418 ts("Can I access/create the database?"),
419 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
423 if ($dbName != 'Drupal') {
424 $this->requireMySQLInnoDB($databaseConfig['server'],
425 $databaseConfig['username'],
426 $databaseConfig['password'],
427 $databaseConfig['database'],
429 ts("MySQL %1 Configuration", array(1 => $dbName)),
430 ts("Can I access/create InnoDB tables in the database?"),
431 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."),
434 $this->requireMySQLTempTables($databaseConfig['server'],
435 $databaseConfig['username'],
436 $databaseConfig['password'],
437 $databaseConfig['database'],
439 ts("MySQL %1 Configuration", array(1 => $dbName)),
440 ts('Can I create temporary tables in the database?'),
441 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
444 $this->requireMySQLLockTables($databaseConfig['server'],
445 $databaseConfig['username'],
446 $databaseConfig['password'],
447 $databaseConfig['database'],
449 ts("MySQL %1 Configuration", array(1 => $dbName)),
450 ts('Can I create lock tables in the database?'),
451 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
454 $this->requireMySQLTrigger($databaseConfig['server'],
455 $databaseConfig['username'],
456 $databaseConfig['password'],
457 $databaseConfig['database'],
459 ts("MySQL %1 Configuration", array(1 => $dbName)),
460 ts('Can I create triggers in the database?'),
461 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
469 * Check everything except the database.
471 public function check() {
472 global $crmPath, $installType;
474 $this->errors
= NULL;
476 $this->requirePHPVersion('5.3.4', array(
477 ts("PHP Configuration"),
478 ts("PHP5 installed"),
480 ts("PHP version %1", array(1 => phpversion())),
483 // Check that we can identify the root folder successfully
484 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'README.txt',
486 ts("File permissions"),
487 ts("Does the webserver know where files are stored?"),
488 ts("The webserver isn't letting me identify where files are stored."),
494 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
495 $this->requireNoPathSeparator(
497 ts("File permissions"),
498 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
499 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR
)),
504 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
505 foreach ($requiredDirectories as $dir) {
506 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. $dir,
508 ts("File permissions"),
509 ts("Folder '%1' exists?", array(1 => $dir)),
510 ts("There is no '%1' folder.", array(1 => $dir)),
515 $configIDSiniDir = NULL;
517 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
518 if ($installType == 'drupal') {
520 // make sure that we can write to sites/default and files/
521 $writableDirectories = array(
522 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
523 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
524 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
526 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
527 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
531 elseif ($installType == 'wordpress') {
532 // make sure that we can write to uploads/civicrm/
533 $upload_dir = wp_upload_dir();
534 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
535 if (!file_exists($files_dirname)) {
536 wp_mkdir_p($files_dirname);
538 $writableDirectories = array($files_dirname);
541 foreach ($writableDirectories as $dir) {
542 $dirName = CIVICRM_WINDOWS ?
$dir : CIVICRM_DIRECTORY_SEPARATOR
. $dir;
543 $testDetails = array(
544 ts("File permissions"),
545 ts("Is the %1 folder writeable?", array(1 => $dir)),
548 $this->requireWriteable($dirName, $testDetails, TRUE);
551 //check for Config.IDS.ini, file may exist in re-install
552 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
554 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
555 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR
, $configIDSiniDir);
556 if (file_exists($configIDSiniFile)) {
557 unlink($configIDSiniFile);
561 // Check for rewriting
562 if (isset($_SERVER['SERVER_SOFTWARE'])) {
563 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
565 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
566 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
569 if ($webserver == '') {
570 $webserver = ts("I can't tell what webserver you are running");
573 // Check for $_SERVER configuration
574 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
575 ts("Webserver config"),
576 ts("Recognised webserver"),
577 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
580 // Check for MySQL support
581 $this->requireFunction('mysql_connect', array(
582 ts("PHP Configuration"),
584 ts("MySQL support not included in PHP."),
587 // Check for JSON support
588 $this->requireFunction('json_encode', array(
589 ts("PHP Configuration"),
591 ts("JSON support not included in PHP."),
594 // Check for xcache_isset and emit warning if exists
595 $this->checkXCache(array(
596 ts("PHP Configuration"),
597 ts("XCache compatibility"),
598 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."),
601 // Check memory allocation
602 $this->requireMemory(32 * 1024 * 1024,
605 ts("PHP Configuration"),
606 ts("Memory allocated (PHP config option 'memory_limit')"),
607 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
608 ini_get("memory_limit"),
612 return $this->errors
;
617 * @param $recommended
618 * @param $testDetails
620 public function requireMemory($min, $recommended, $testDetails) {
621 $this->testing($testDetails);
622 $mem = $this->getPHPMemory();
624 if ($mem < $min && $mem > 0) {
625 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
626 $this->error($testDetails);
628 elseif ($mem < $recommended && $mem > 0) {
629 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
630 $this->warning($testDetails);
633 $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));
634 $this->warning($testDetails);
641 public function getPHPMemory() {
642 $memString = ini_get("memory_limit");
644 switch (strtolower(substr($memString, -1))) {
646 return round(substr($memString, 0, -1) * 1024);
649 return round(substr($memString, 0, -1) * 1024 * 1024);
652 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
655 return round($memString);
659 public function listErrors() {
661 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
662 foreach ($this->errors
as $error) {
663 echo "<li>" . htmlentities($error) . "</li>";
669 * @param null $section
671 public function showTable($section = NULL) {
673 $tests = $this->tests
[$section];
674 echo "<table class=\"testResults\" width=\"100%\">";
675 foreach ($tests as $test => $result) {
676 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
681 foreach ($this->tests
as $section => $tests) {
682 echo "<h3>$section</h3>";
683 echo "<table class=\"testResults\" width=\"100%\">";
685 foreach ($tests as $test => $result) {
686 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
694 * @param string $funcName
695 * @param $testDetails
699 public function requireFunction($funcName, $testDetails) {
700 $this->testing($testDetails);
702 if (!function_exists($funcName)) {
703 $this->error($testDetails);
712 * @param $testDetails
714 public function checkXCache($testDetails) {
715 if (function_exists('xcache_isset') &&
716 ini_get('xcache.size') > 0
718 $this->testing($testDetails);
719 $this->warning($testDetails);
725 * @param $testDetails
726 * @param null $maxVersion
728 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
730 $this->testing($testDetails);
732 $phpVersion = phpversion();
733 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
734 $belowMaxVersion = $maxVersion ?
version_compare($phpVersion, $maxVersion) < 0 : TRUE;
736 if ($aboveMinVersion && $belowMaxVersion) {
737 if (version_compare(phpversion(), CRM_Upgrade_Incremental_General
::MIN_RECOMMENDED_PHP_VER
) < 0) {
738 $testDetails[2] = ts('This webserver is running an outdated version of PHP (%1). It is strongly recommended to upgrade to PHP %2 or later, as older versions can present a security risk.', array(
740 2 => CRM_Upgrade_Incremental_General
::MIN_RECOMMENDED_PHP_VER
,
742 $this->warning($testDetails);
747 if (!$testDetails[2]) {
748 if (!$aboveMinVersion) {
749 $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));
752 $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));
756 $this->error($testDetails);
760 * @param string $filename
761 * @param $testDetails
762 * @param bool $absolute
764 public function requireFile($filename, $testDetails, $absolute = FALSE) {
765 $this->testing($testDetails);
767 $filename = $this->getBaseDir() . $filename;
769 if (!file_exists($filename)) {
770 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
771 $this->error($testDetails);
776 * @param $testDetails
778 public function requireNoPathSeparator($testDetails) {
779 $this->testing($testDetails);
780 if (substr_count($this->getBaseDir(), PATH_SEPARATOR
)) {
781 $this->error($testDetails);
786 * @param string $filename
787 * @param $testDetails
789 public function requireNoFile($filename, $testDetails) {
790 $this->testing($testDetails);
791 $filename = $this->getBaseDir() . $filename;
792 if (file_exists($filename)) {
793 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
794 $this->error($testDetails);
799 * @param string $filename
800 * @param $testDetails
802 public function moveFileOutOfTheWay($filename, $testDetails) {
803 $this->testing($testDetails);
804 $filename = $this->getBaseDir() . $filename;
805 if (file_exists($filename)) {
806 if (file_exists("$filename.bak")) {
809 rename($filename, "$filename.bak");
814 * @param string $filename
815 * @param $testDetails
816 * @param bool $absolute
818 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
819 $this->testing($testDetails);
821 $filename = $this->getBaseDir() . $filename;
824 if (!is_writable($filename)) {
826 if (function_exists('posix_getpwuid')) {
827 $user = posix_getpwuid(posix_geteuid());
828 $name = '- ' . $user['name'] . ' -';
831 if (!isset($testDetails[2])) {
832 $testDetails[2] = NULL;
834 $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";
835 $this->error($testDetails);
840 * @param string $moduleName
841 * @param $testDetails
843 public function requireApacheModule($moduleName, $testDetails) {
844 $this->testing($testDetails);
845 if (!in_array($moduleName, apache_get_modules())) {
846 $this->error($testDetails);
852 * @param string $username
854 * @param $testDetails
856 public function requireMysqlConnection($server, $username, $password, $testDetails) {
857 $this->testing($testDetails);
858 $conn = @mysql_connect
($server, $username, $password);
864 $testDetails[2] .= ": " . mysql_error();
865 $this->error($testDetails);
871 * @param $testDetails
873 public function requireMySQLServer($server, $testDetails) {
874 $this->testing($testDetails);
875 $conn = @mysql_connect
($server, NULL, NULL);
877 if ($conn ||
mysql_errno() < 2000) {
881 $testDetails[2] .= ": " . mysql_error();
882 $this->error($testDetails);
888 * @param $testDetails
890 public function requireMySQLVersion($version, $testDetails) {
891 $this->testing($testDetails);
893 if (!mysql_get_server_info()) {
894 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
895 $this->warning($testDetails);
898 list($majorRequested, $minorRequested) = explode('.', $version);
899 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
901 if (($majorHas > $majorRequested) ||
($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
905 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
906 $this->error($testDetails);
913 * @param string $username
916 * @param $testDetails
918 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
919 $this->testing($testDetails);
920 $conn = @mysql_connect
($server, $username, $password);
922 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
923 $this->error($testDetails);
927 $innodb_support = FALSE;
928 $result = mysql_query("SHOW ENGINES", $conn);
929 while ($values = mysql_fetch_array($result)) {
930 if ($values['Engine'] == 'InnoDB') {
931 if (strtolower($values['Support']) == 'yes' ||
932 strtolower($values['Support']) == 'default'
934 $innodb_support = TRUE;
938 if ($innodb_support) {
939 $testDetails[3] = ts('MySQL server does have InnoDB support');
942 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
948 * @param string $username
951 * @param $testDetails
953 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
954 $this->testing($testDetails);
955 $conn = @mysql_connect
($server, $username, $password);
957 $testDetails[2] = ts('Could not login to the database.');
958 $this->error($testDetails);
962 if (!@mysql_select_db
($database, $conn)) {
963 $testDetails[2] = ts('Could not select the database.');
964 $this->error($testDetails);
968 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
970 $testDetails[2] = ts('Could not create a temp table.');
971 $this->error($testDetails);
973 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
978 * @param string $username
981 * @param $testDetails
983 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
984 $this->testing($testDetails);
985 $conn = @mysql_connect
($server, $username, $password);
987 $testDetails[2] = ts('Could not login to the database.');
988 $this->error($testDetails);
992 if (!@mysql_select_db
($database, $conn)) {
993 $testDetails[2] = ts('Could not select the database.');
994 $this->error($testDetails);
998 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
1000 $testDetails[2] = ts('Could not create a table in the database.');
1001 $this->error($testDetails);
1004 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
1006 mysql_query('DROP TABLE civicrm_install_temp_table_test');
1007 $testDetails[2] = ts('Could not create a database trigger.');
1008 $this->error($testDetails);
1011 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
1012 mysql_query('DROP TABLE civicrm_install_temp_table_test');
1018 * @param string $username
1021 * @param $testDetails
1023 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
1024 $this->testing($testDetails);
1025 $conn = @mysql_connect
($server, $username, $password);
1027 $testDetails[2] = ts('Could not connect to the database server.');
1028 $this->error($testDetails);
1032 if (!@mysql_select_db
($database, $conn)) {
1033 $testDetails[2] = ts('Could not select the database.');
1034 $this->error($testDetails);
1038 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1040 $testDetails[2] = ts('Could not create a table in the database.');
1041 $this->error($testDetails);
1045 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1047 $testDetails[2] = ts('Could not obtain a write lock for the database table.');
1048 $this->error($testDetails);
1049 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1053 $result = mysql_query('UNLOCK TABLES', $conn);
1055 $testDetails[2] = ts('Could not release the lock for the database table.');
1056 $this->error($testDetails);
1057 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1061 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1066 * @param string $username
1068 * @param $testDetails
1070 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
1071 $this->testing($testDetails);
1072 $conn = @mysql_connect
($server, $username, $password);
1074 $testDetails[2] = ts('Could not connect to the database server.');
1075 $this->error($testDetails);
1079 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1081 $testDetails[2] = ts('Could not query database server variables.');
1082 $this->error($testDetails);
1086 $values = mysql_fetch_row($result);
1087 if ($values[1] == 1) {
1088 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
1091 $this->error($testDetails);
1098 * @param string $username
1101 * @param $minValueKB
1102 * @param $testDetails
1104 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1105 $this->testing($testDetails);
1106 $conn = @mysql_connect
($server, $username, $password);
1108 $testDetails[2] = ts('Could not connect to the database server.');
1109 $this->error($testDetails);
1113 if (!@mysql_select_db
($database, $conn)) {
1114 $testDetails[2] = ts('Could not select the database.');
1115 $this->error($testDetails);
1119 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1121 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
1122 $this->error($testDetails);
1125 $values = mysql_fetch_row($result);
1126 if ($values[1] < (1024 * $minValueKB)) {
1127 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
1128 $this->error($testDetails);
1135 * @param string $username
1138 * @param $testDetails
1139 * @param bool $onlyRequire
1141 public function requireDatabaseOrCreatePermissions(
1147 $onlyRequire = FALSE
1149 $this->testing($testDetails);
1150 $conn = @mysql_connect
($server, $username, $password);
1153 if (@mysql_select_db
($database)) {
1154 $okay = "Database '$database' exists";
1156 elseif ($onlyRequire) {
1157 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
1158 $this->error($testDetails);
1162 if (@mysql_query
("CREATE DATABASE $database")) {
1163 $okay = ts("Able to create a new database.");
1166 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
1167 $this->error($testDetails);
1173 $testDetails[3] = $okay;
1174 $this->testing($testDetails);
1180 * @param $errorMessage
1182 public function requireServerVariables($varNames, $errorMessage) {
1183 //$this->testing($testDetails);
1184 foreach ($varNames as $varName) {
1185 if (!$_SERVER[$varName]) {
1186 $missing[] = '$_SERVER[' . $varName . ']';
1189 if (!isset($missing)) {
1193 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
1194 $this->error($testDetails);
1199 * @param $testDetails
1203 public function isRunningApache($testDetails) {
1204 $this->testing($testDetails);
1205 if (function_exists('apache_get_modules') ||
stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1209 $this->warning($testDetails);
1216 public function getBaseDir() {
1217 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR
;
1221 * @param $testDetails
1223 public function testing($testDetails) {
1224 if (!$testDetails) {
1228 $section = $testDetails[0];
1229 $test = $testDetails[1];
1231 $message = ts("OK");
1232 if (isset($testDetails[3])) {
1233 $message .= " ($testDetails[3])";
1236 $this->tests
[$section][$test] = array("good", $message);
1240 * @param $testDetails
1242 public function error($testDetails) {
1243 $section = $testDetails[0];
1244 $test = $testDetails[1];
1246 $this->tests
[$section][$test] = array("error", $testDetails[2]);
1247 $this->errors
[] = $testDetails;
1251 * @param $testDetails
1253 public function warning($testDetails) {
1254 $section = $testDetails[0];
1255 $test = $testDetails[1];
1257 $this->tests
[$section][$test] = array("warning", $testDetails[2]);
1258 $this->warnings
[] = $testDetails;
1264 public function hasErrors() {
1265 return count($this->errors
);
1271 public function hasWarnings() {
1272 return count($this->warnings
);
1280 class Installer
extends InstallRequirements
{
1287 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1288 $conn = @mysql_connect
($server, $username, $password);
1290 if (@mysql_select_db
($database)) {
1291 // skip if database already present
1295 if (@mysql_query
("CREATE DATABASE $database")) {
1298 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1299 $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.");
1300 errorDisplayPage($errorTitle, $errorMsg);
1309 public function install($config) {
1310 global $installDirPath;
1312 // create database if does not exists
1313 $this->createDatabaseIfNotExists($config['mysql']['server'],
1314 $config['mysql']['username'],
1315 $config['mysql']['password'],
1316 $config['mysql']['database']
1319 global $installDirPath;
1322 require_once $installDirPath . 'civicrm.php';
1323 civicrm_main($config);
1325 if (!$this->errors
) {
1326 global $installType, $installURLPath;
1328 $registerSiteURL = "https://civicrm.org/register-site";
1329 $commonOutputMessage
1330 = "<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>"
1331 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
1336 $installType == 'drupal' &&
1337 version_compare(VERSION
, '7.0-rc1') >= 0
1343 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1344 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1345 $output .= '<head>';
1346 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1347 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1348 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1349 $output .= '</head>';
1350 $output .= '<body>';
1351 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1354 $drupalURL = civicrm_cms_base();
1355 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1356 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1358 $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>";
1359 $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>";
1360 $output .= $commonOutputMessage;
1362 // automatically enable CiviCRM module once it is installed successfully.
1363 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1364 global $cmsPath, $crmPath;
1366 // relative / abosolute paths are not working for drupal, hence using chdir()
1369 // Force the re-initialisation of the config singleton on the next call
1370 // since so far, we had used the Config object without loading the DB.
1371 $c = CRM_Core_Config
::singleton(FALSE);
1374 include_once "./includes/bootstrap.inc";
1375 include_once "./includes/unicode.inc";
1377 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1379 // prevent session information from being saved.
1380 drupal_save_session(FALSE);
1382 // Force the current user to anonymous.
1383 $original_user = $GLOBALS['user'];
1384 $GLOBALS['user'] = drupal_anonymous_user();
1386 // explicitly setting error reporting, since we cannot handle drupal related notices
1389 // rebuild modules, so that civicrm is added
1390 system_rebuild_module_data();
1392 // now enable civicrm module.
1393 module_enable(array('civicrm', 'civicrmtheme'));
1395 // clear block, page, theme, and hook caches
1396 drupal_flush_all_caches();
1398 //add basic drupal permissions
1399 civicrm_install_set_drupal_perms();
1401 // restore the user.
1402 $GLOBALS['user'] = $original_user;
1403 drupal_save_session(TRUE);
1405 //change the default language to one chosen
1406 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1407 civicrm_api3('Setting', 'create', array(
1408 'domain_id' => 'current_domain',
1409 'lcMessages' => $config['seedLanguage'],
1415 $output .= '</div>';
1416 $output .= '</body>';
1417 $output .= '</html>';
1420 elseif ($installType == 'drupal' && version_compare(VERSION
, '6.0') >= 0) {
1424 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1425 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1426 $output .= '<head>';
1427 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1428 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1429 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1430 $output .= '</head>';
1431 $output .= '<body>';
1432 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
1435 $drupalURL = civicrm_cms_base();
1436 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1437 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1439 $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>";
1440 $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>";
1441 $output .= $commonOutputMessage;
1443 // explicitly setting error reporting, since we cannot handle drupal related notices
1446 // automatically enable CiviCRM module once it is installed successfully.
1447 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1448 global $cmsPath, $crmPath;
1450 // relative / abosolute paths are not working for drupal, hence using chdir()
1453 // Force the re-initialisation of the config singleton on the next call
1454 // since so far, we had used the Config object without loading the DB.
1455 $c = CRM_Core_Config
::singleton(FALSE);
1458 include_once "./includes/bootstrap.inc";
1459 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1461 // rebuild modules, so that civicrm is added
1462 module_rebuild_cache();
1464 // now enable civicrm module.
1465 module_enable(array('civicrm'));
1467 // clear block, page, theme, and hook caches
1468 drupal_flush_all_caches();
1470 //add basic drupal permissions
1471 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)');
1475 elseif ($installType == 'wordpress') {
1476 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
1477 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
1480 $cmsURL = civicrm_cms_base();
1481 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1482 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1484 $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>";
1485 $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>";
1486 $output .= $commonOutputMessage;
1491 $c = CRM_Core_Config
::singleton(FALSE);
1493 $wpInstallRedirect = admin_url("?page=CiviCRM&q=civicrm&reset=1");
1495 window.location = '$wpInstallRedirect';
1500 return $this->errors
;
1505 function civicrm_install_set_drupal_perms() {
1506 if (!function_exists('db_select')) {
1507 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)');
1511 'access all custom data',
1512 'access uploaded files',
1513 'make online contributions',
1517 'register for events',
1519 'view event participants',
1520 'access CiviMail subscribe/unsubscribe pages',
1523 // Adding a permission that has not yet been assigned to a module by
1524 // a hook_permission implementation results in a database error.
1526 $allPerms = array_keys(module_invoke_all('permission'));
1527 foreach (array_diff($perms, $allPerms) as $perm) {
1529 'Cannot grant the %perm permission because it does not yet exist.',
1530 array('%perm' => $perm),
1534 $perms = array_intersect($perms, $allPerms);
1535 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID
, $perms);
1536 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID
, $perms);
1546 function getSiteDir($cmsPath, $str) {
1547 static $siteDir = '';
1553 $sites = CIVICRM_DIRECTORY_SEPARATOR
. 'sites' . CIVICRM_DIRECTORY_SEPARATOR
;
1554 $modules = CIVICRM_DIRECTORY_SEPARATOR
. 'modules' . CIVICRM_DIRECTORY_SEPARATOR
;
1555 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR
) .
1556 "([\-a-zA-Z0-9_.]+)" .
1557 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR
) . "/",
1558 $_SERVER['SCRIPT_FILENAME'], $matches
1560 $siteDir = isset($matches[1]) ?
$matches[1] : 'default';
1562 if (strtolower($siteDir) == 'all') {
1563 // For this case - use drupal's way of finding out multi-site directory
1564 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR
, $_SERVER['SCRIPT_FILENAME']);
1565 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1566 for ($i = count($uri) - 1; $i > 0; $i--) {
1567 for ($j = count($server); $j > 0; $j--) {
1568 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1569 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
1570 'sites' . CIVICRM_DIRECTORY_SEPARATOR
. $dir
1577 $siteDir = 'default';
1584 * @param $errorTitle
1588 function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1590 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1592 if (function_exists('ts')) {
1593 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1596 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1600 include 'error.html';