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 if ($installType == 'wordpress') {
112 $databaseConfig = array(
114 "username" => DB_USER
,
115 "password" => DB_PASSWORD
,
116 "database" => DB_NAME
,
121 if ($installType == 'drupal') {
122 // Load drupal database config
123 if (isset($_REQUEST['drupal'])) {
124 $drupalConfig = $_REQUEST['drupal'];
127 $drupalConfig = array(
128 "server" => "localhost",
129 "username" => "drupal",
131 "database" => "drupal",
137 if (isset($_REQUEST['loadGenerated'])) {
141 require_once dirname(__FILE__
) . CIVICRM_DIRECTORY_SEPARATOR
. 'langs.php';
142 foreach ($langs as $locale => $_) {
143 if ($locale == 'en_US') {
146 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR
, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
147 unset($langs[$locale]);
151 // Set the locale (required by CRM_Core_Config)
152 // This is mostly sympbolic, since nothing we do during the install
153 // really requires CIVICRM_UF to be defined.
154 $installTypeToUF = array(
155 'wordpress' => 'WordPress',
156 'drupal' => 'Drupal',
159 $uf = (isset($installTypeToUF[$installType]) ?
$installTypeToUF[$installType] : 'Drupal');
160 define('CIVICRM_UF', $uf);
165 $seedLanguage = 'en_US';
167 if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
168 $seedLanguage = $_REQUEST['seedLanguage'];
169 $tsLocale = $_REQUEST['seedLanguage'];
172 $config = CRM_Core_Config
::singleton(FALSE);
173 $GLOBALS['civicrm_default_error_scope'] = NULL;
175 // The translation files are in the parent directory (l10n)
176 $i18n = CRM_Core_I18n
::singleton();
179 if ($installType == 'drupal') {
180 //CRM-6840 -don't force to install in sites/all/modules/
181 $object = new CRM_Utils_System_Drupal();
182 $cmsPath = $object->cmsRootPath();
184 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
185 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
186 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
187 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
188 'civicrm.settings.php'
191 elseif ($installType == 'wordpress') {
192 $cmsPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm';
193 $upload_dir = wp_upload_dir();
194 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
195 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
196 'civicrm.settings.php'
200 if ($installType == 'drupal') {
201 // Lets check only /modules/.
202 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR
. 'modules', CIVICRM_DIRECTORY_SEPARATOR
) . '/';
204 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
205 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array('sites', 'all', 'modules'));
206 $errorTitle = ts("Oops! Please correct your install location");
207 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
208 errorDisplayPage($errorTitle, $errorMsg);
212 // Exit with error if CiviCRM has already been installed.
213 if ($alreadyInstalled) {
214 $errorTitle = ts("Oops! CiviCRM is already installed");
215 $settings_directory = $cmsPath;
217 if ($installType == 'drupal') {
218 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array(
219 ts('[your Drupal root directory]'),
225 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
226 $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));
227 errorDisplayPage($errorTitle, $errorMsg, FALSE);
230 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'civicrm-version.php';
231 if (file_exists($versionFile)) {
232 require_once $versionFile;
233 $civicrm_version = civicrmVersion();
236 $civicrm_version = 'unknown';
239 if ($installType == 'drupal') {
240 // Ensure that they have downloaded the correct version of CiviCRM
241 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
242 $errorTitle = ts("Oops! Incorrect CiviCRM version");
243 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
244 errorDisplayPage($errorTitle, $errorMsg);
247 define('DRUPAL_ROOT', $cmsPath);
248 $drupalVersionFiles = array(
250 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'modules', 'system', 'system.module')),
252 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'includes', 'bootstrap.inc')),
254 foreach ($drupalVersionFiles as $drupalVersionFile) {
255 if (file_exists($drupalVersionFile)) {
256 require_once $drupalVersionFile;
260 if (!defined('VERSION') or version_compare(VERSION
, '6.0') < 0) {
261 $errorTitle = ts("Oops! Incorrect Drupal version");
262 $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)));
263 errorDisplayPage($errorTitle, $errorMsg);
266 elseif ($installType == 'wordpress') {
268 $civicrm_version['cms'] = 'WordPress';
270 // Ensure that they have downloaded the correct version of CiviCRM
271 if ($civicrm_version['cms'] != 'WordPress') {
272 $errorTitle = ts("Oops! Incorrect CiviCRM version");
273 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
274 errorDisplayPage($errorTitle, $errorMsg);
278 // Check requirements
279 $req = new InstallRequirements();
282 if ($req->hasErrors()) {
283 $hasErrorOtherThanDatabase = TRUE;
286 if ($databaseConfig) {
287 $dbReq = new InstallRequirements();
288 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
289 if ($installType == 'drupal') {
290 $dbReq->checkdatabase($drupalConfig, 'Drupal');
295 if (isset($_REQUEST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
296 // Confirm before reinstalling
297 if (!isset($_REQUEST['force_reinstall']) && $alreadyInstalled) {
298 include $installDirPath . 'template.html';
301 $inst = new Installer();
302 $inst->install($_REQUEST);
305 // Show the config form
308 include $installDirPath . 'template.html';
312 * This class checks requirements
313 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
315 * $description[0] - The test category
316 * $description[1] - The test title
317 * $description[2] - The test error to show, if it goes wrong
319 class InstallRequirements
{
320 var $errors, $warnings, $tests;
322 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
323 const MINIMUM_THREAD_STACK
= 192;
326 * Just check that the database configuration is okay.
327 * @param $databaseConfig
330 public function checkdatabase($databaseConfig, $dbName) {
331 if ($this->requireFunction('mysql_connect',
333 ts("PHP Configuration"),
335 ts("MySQL support not included in PHP."),
339 $this->requireMySQLServer($databaseConfig['server'],
341 ts("MySQL %1 Configuration", array(1 => $dbName)),
342 ts("Does the server exist?"),
343 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
344 $databaseConfig['server'],
347 if ($this->requireMysqlConnection($databaseConfig['server'],
348 $databaseConfig['username'],
349 $databaseConfig['password'],
351 ts("MySQL %1 Configuration", array(1 => $dbName)),
352 ts("Are the access credentials correct?"),
353 ts("That username/password doesn't work"),
357 @$this->requireMySQLVersion("5.1",
359 ts("MySQL %1 Configuration", array(1 => $dbName)),
360 ts("MySQL version at least %1", array(1 => '5.1')),
361 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
362 ts("MySQL %1", array(1 => mysql_get_server_info())),
365 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
366 $databaseConfig['username'],
367 $databaseConfig['password'],
369 ts("MySQL %1 Configuration", array(1 => $dbName)),
370 ts("Is auto_increment_increment set to 1"),
371 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
374 $this->requireMySQLThreadStack($databaseConfig['server'],
375 $databaseConfig['username'],
376 $databaseConfig['password'],
377 $databaseConfig['database'],
378 self
::MINIMUM_THREAD_STACK
,
380 ts("MySQL %1 Configuration", array(1 => $dbName)),
381 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self
::MINIMUM_THREAD_STACK
)),
383 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
387 $onlyRequire = ($dbName == 'Drupal') ?
TRUE : FALSE;
388 $this->requireDatabaseOrCreatePermissions(
389 $databaseConfig['server'],
390 $databaseConfig['username'],
391 $databaseConfig['password'],
392 $databaseConfig['database'],
394 ts("MySQL %1 Configuration", array(1 => $dbName)),
395 ts("Can I access/create the database?"),
396 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
400 if ($dbName != 'Drupal') {
401 $this->requireMySQLInnoDB($databaseConfig['server'],
402 $databaseConfig['username'],
403 $databaseConfig['password'],
404 $databaseConfig['database'],
406 ts("MySQL %1 Configuration", array(1 => $dbName)),
407 ts("Can I access/create InnoDB tables in the database?"),
408 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."),
411 $this->requireMySQLTempTables($databaseConfig['server'],
412 $databaseConfig['username'],
413 $databaseConfig['password'],
414 $databaseConfig['database'],
416 ts("MySQL %1 Configuration", array(1 => $dbName)),
417 ts('Can I create temporary tables in the database?'),
418 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
421 $this->requireMySQLLockTables($databaseConfig['server'],
422 $databaseConfig['username'],
423 $databaseConfig['password'],
424 $databaseConfig['database'],
426 ts("MySQL %1 Configuration", array(1 => $dbName)),
427 ts('Can I create lock tables in the database?'),
428 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
431 $this->requireMySQLTrigger($databaseConfig['server'],
432 $databaseConfig['username'],
433 $databaseConfig['password'],
434 $databaseConfig['database'],
436 ts("MySQL %1 Configuration", array(1 => $dbName)),
437 ts('Can I create triggers in the database?'),
438 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
446 * Check everything except the database.
448 public function check() {
449 global $crmPath, $installType;
451 $this->errors
= NULL;
453 $this->requirePHPVersion('5.3.4', array(
454 ts("PHP Configuration"),
455 ts("PHP5 installed"),
457 ts("PHP version %1", array(1 => phpversion())),
460 // Check that we can identify the root folder successfully
461 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'README.txt',
463 ts("File permissions"),
464 ts("Does the webserver know where files are stored?"),
465 ts("The webserver isn't letting me identify where files are stored."),
471 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
472 $this->requireNoPathSeparator(
474 ts("File permissions"),
475 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
476 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR
)),
481 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
482 foreach ($requiredDirectories as $dir) {
483 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. $dir,
485 ts("File permissions"),
486 ts("Folder '%1' exists?", array(1 => $dir)),
487 ts("There is no '%1' folder.", array(1 => $dir)),
492 $configIDSiniDir = NULL;
494 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
495 if ($installType == 'drupal') {
497 // make sure that we can write to sites/default and files/
498 $writableDirectories = array(
499 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
500 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
501 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
503 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
504 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
508 elseif ($installType == 'wordpress') {
509 // make sure that we can write to uploads/civicrm/
510 $upload_dir = wp_upload_dir();
511 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
512 if (!file_exists($files_dirname)) {
513 wp_mkdir_p($files_dirname);
515 $writableDirectories = array($files_dirname);
518 foreach ($writableDirectories as $dir) {
519 $dirName = CIVICRM_WINDOWS ?
$dir : CIVICRM_DIRECTORY_SEPARATOR
. $dir;
520 $testDetails = array(
521 ts("File permissions"),
522 ts("Is the %1 folder writeable?", array(1 => $dir)),
525 $this->requireWriteable($dirName, $testDetails, TRUE);
528 //check for Config.IDS.ini, file may exist in re-install
529 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
531 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
532 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR
, $configIDSiniDir);
533 if (file_exists($configIDSiniFile)) {
534 unlink($configIDSiniFile);
538 // Check for rewriting
539 if (isset($_SERVER['SERVER_SOFTWARE'])) {
540 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
542 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
543 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
546 if ($webserver == '') {
547 $webserver = ts("I can't tell what webserver you are running");
550 // Check for $_SERVER configuration
551 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
552 ts("Webserver config"),
553 ts("Recognised webserver"),
554 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
557 // Check for MySQL support
558 $this->requireFunction('mysql_connect', array(
559 ts("PHP Configuration"),
561 ts("MySQL support not included in PHP."),
564 // Check for JSON support
565 $this->requireFunction('json_encode', array(
566 ts("PHP Configuration"),
568 ts("JSON support not included in PHP."),
571 // Check for xcache_isset and emit warning if exists
572 $this->checkXCache(array(
573 ts("PHP Configuration"),
574 ts("XCache compatibility"),
575 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."),
578 // Check memory allocation
579 $this->requireMemory(32 * 1024 * 1024,
582 ts("PHP Configuration"),
583 ts("Memory allocated (PHP config option 'memory_limit')"),
584 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
585 ini_get("memory_limit"),
589 return $this->errors
;
594 * @param $recommended
595 * @param $testDetails
597 public function requireMemory($min, $recommended, $testDetails) {
598 $this->testing($testDetails);
599 $mem = $this->getPHPMemory();
601 if ($mem < $min && $mem > 0) {
602 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
603 $this->error($testDetails);
605 elseif ($mem < $recommended && $mem > 0) {
606 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
607 $this->warning($testDetails);
610 $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));
611 $this->warning($testDetails);
618 public function getPHPMemory() {
619 $memString = ini_get("memory_limit");
621 switch (strtolower(substr($memString, -1))) {
623 return round(substr($memString, 0, -1) * 1024);
626 return round(substr($memString, 0, -1) * 1024 * 1024);
629 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
632 return round($memString);
636 public function listErrors() {
638 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
639 foreach ($this->errors
as $error) {
640 echo "<li>" . htmlentities($error) . "</li>";
646 * @param null $section
648 public function showTable($section = NULL) {
650 $tests = $this->tests
[$section];
651 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>";
658 foreach ($this->tests
as $section => $tests) {
659 echo "<h3>$section</h3>";
660 echo "<table class=\"testResults\" width=\"100%\">";
662 foreach ($tests as $test => $result) {
663 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
671 * @param string $funcName
672 * @param $testDetails
676 public function requireFunction($funcName, $testDetails) {
677 $this->testing($testDetails);
679 if (!function_exists($funcName)) {
680 $this->error($testDetails);
689 * @param $testDetails
691 public function checkXCache($testDetails) {
692 if (function_exists('xcache_isset') &&
693 ini_get('xcache.size') > 0
695 $this->testing($testDetails);
696 $this->warning($testDetails);
702 * @param $testDetails
703 * @param null $maxVersion
705 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
707 $this->testing($testDetails);
709 $phpVersion = phpversion();
710 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
711 $belowMaxVersion = $maxVersion ?
version_compare($phpVersion, $maxVersion) < 0 : TRUE;
713 if ($maxVersion && $aboveMinVersion && $belowMaxVersion) {
716 elseif (!$maxVersion && $aboveMinVersion) {
720 if (!$testDetails[2]) {
721 if (!$aboveMinVersion) {
722 $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));
725 $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));
729 $this->error($testDetails);
733 * @param string $filename
734 * @param $testDetails
735 * @param bool $absolute
737 public function requireFile($filename, $testDetails, $absolute = FALSE) {
738 $this->testing($testDetails);
740 $filename = $this->getBaseDir() . $filename;
742 if (!file_exists($filename)) {
743 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
744 $this->error($testDetails);
749 * @param $testDetails
751 public function requireNoPathSeparator($testDetails) {
752 $this->testing($testDetails);
753 if (substr_count($this->getBaseDir(), PATH_SEPARATOR
)) {
754 $this->error($testDetails);
759 * @param string $filename
760 * @param $testDetails
762 public function requireNoFile($filename, $testDetails) {
763 $this->testing($testDetails);
764 $filename = $this->getBaseDir() . $filename;
765 if (file_exists($filename)) {
766 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
767 $this->error($testDetails);
772 * @param string $filename
773 * @param $testDetails
775 public function moveFileOutOfTheWay($filename, $testDetails) {
776 $this->testing($testDetails);
777 $filename = $this->getBaseDir() . $filename;
778 if (file_exists($filename)) {
779 if (file_exists("$filename.bak")) {
782 rename($filename, "$filename.bak");
787 * @param string $filename
788 * @param $testDetails
789 * @param bool $absolute
791 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
792 $this->testing($testDetails);
794 $filename = $this->getBaseDir() . $filename;
797 if (!is_writable($filename)) {
799 if (function_exists('posix_getpwuid')) {
800 $user = posix_getpwuid(posix_geteuid());
801 $name = '- ' . $user['name'] . ' -';
804 if (!isset($testDetails[2])) {
805 $testDetails[2] = NULL;
807 $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";
808 $this->error($testDetails);
813 * @param string $moduleName
814 * @param $testDetails
816 public function requireApacheModule($moduleName, $testDetails) {
817 $this->testing($testDetails);
818 if (!in_array($moduleName, apache_get_modules())) {
819 $this->error($testDetails);
825 * @param string $username
827 * @param $testDetails
829 public function requireMysqlConnection($server, $username, $password, $testDetails) {
830 $this->testing($testDetails);
831 $conn = @mysql_connect
($server, $username, $password);
837 $testDetails[2] .= ": " . mysql_error();
838 $this->error($testDetails);
844 * @param $testDetails
846 public function requireMySQLServer($server, $testDetails) {
847 $this->testing($testDetails);
848 $conn = @mysql_connect
($server, NULL, NULL);
850 if ($conn ||
mysql_errno() < 2000) {
854 $testDetails[2] .= ": " . mysql_error();
855 $this->error($testDetails);
861 * @param $testDetails
863 public function requireMySQLVersion($version, $testDetails) {
864 $this->testing($testDetails);
866 if (!mysql_get_server_info()) {
867 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
868 $this->warning($testDetails);
871 list($majorRequested, $minorRequested) = explode('.', $version);
872 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
874 if (($majorHas > $majorRequested) ||
($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
878 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
879 $this->error($testDetails);
886 * @param string $username
889 * @param $testDetails
891 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
892 $this->testing($testDetails);
893 $conn = @mysql_connect
($server, $username, $password);
895 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
896 $this->error($testDetails);
900 $innodb_support = FALSE;
901 $result = mysql_query("SHOW ENGINES", $conn);
902 while ($values = mysql_fetch_array($result)) {
903 if ($values['Engine'] == 'InnoDB') {
904 if (strtolower($values['Support']) == 'yes' ||
905 strtolower($values['Support']) == 'default'
907 $innodb_support = TRUE;
911 if ($innodb_support) {
912 $testDetails[3] = ts('MySQL server does have InnoDB support');
915 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
921 * @param string $username
924 * @param $testDetails
926 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
927 $this->testing($testDetails);
928 $conn = @mysql_connect
($server, $username, $password);
930 $testDetails[2] = ts('Could not login to the database.');
931 $this->error($testDetails);
935 if (!@mysql_select_db
($database, $conn)) {
936 $testDetails[2] = ts('Could not select the database.');
937 $this->error($testDetails);
941 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
943 $testDetails[2] = ts('Could not create a temp table.');
944 $this->error($testDetails);
946 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
951 * @param string $username
954 * @param $testDetails
956 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
957 $this->testing($testDetails);
958 $conn = @mysql_connect
($server, $username, $password);
960 $testDetails[2] = ts('Could not login to the database.');
961 $this->error($testDetails);
965 if (!@mysql_select_db
($database, $conn)) {
966 $testDetails[2] = ts('Could not select the database.');
967 $this->error($testDetails);
971 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
973 $testDetails[2] = ts('Could not create a table in the database.');
974 $this->error($testDetails);
977 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
979 mysql_query('DROP TABLE civicrm_install_temp_table_test');
980 $testDetails[2] = ts('Could not create a database trigger.');
981 $this->error($testDetails);
984 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
985 mysql_query('DROP TABLE civicrm_install_temp_table_test');
991 * @param string $username
994 * @param $testDetails
996 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
997 $this->testing($testDetails);
998 $conn = @mysql_connect
($server, $username, $password);
1000 $testDetails[2] = ts('Could not connect to the database server.');
1001 $this->error($testDetails);
1005 if (!@mysql_select_db
($database, $conn)) {
1006 $testDetails[2] = ts('Could not select the database.');
1007 $this->error($testDetails);
1011 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1013 $testDetails[2] = ts('Could not create a table in the database.');
1014 $this->error($testDetails);
1018 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1020 $testDetails[2] = ts('Could not obtain a write lock for the database table.');
1021 $this->error($testDetails);
1022 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1026 $result = mysql_query('UNLOCK TABLES', $conn);
1028 $testDetails[2] = ts('Could not release the lock for the database table.');
1029 $this->error($testDetails);
1030 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1034 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1039 * @param string $username
1041 * @param $testDetails
1043 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
1044 $this->testing($testDetails);
1045 $conn = @mysql_connect
($server, $username, $password);
1047 $testDetails[2] = ts('Could not connect to the database server.');
1048 $this->error($testDetails);
1052 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1054 $testDetails[2] = ts('Could not query database server variables.');
1055 $this->error($testDetails);
1059 $values = mysql_fetch_row($result);
1060 if ($values[1] == 1) {
1061 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
1064 $this->error($testDetails);
1071 * @param string $username
1074 * @param $minValueKB
1075 * @param $testDetails
1077 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1078 $this->testing($testDetails);
1079 $conn = @mysql_connect
($server, $username, $password);
1081 $testDetails[2] = ts('Could not connect to the database server.');
1082 $this->error($testDetails);
1086 if (!@mysql_select_db
($database, $conn)) {
1087 $testDetails[2] = ts('Could not select the database.');
1088 $this->error($testDetails);
1092 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1094 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
1095 $this->error($testDetails);
1098 $values = mysql_fetch_row($result);
1099 if ($values[1] < (1024 * $minValueKB)) {
1100 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
1101 $this->error($testDetails);
1108 * @param string $username
1111 * @param $testDetails
1112 * @param bool $onlyRequire
1114 public function requireDatabaseOrCreatePermissions(
1120 $onlyRequire = FALSE
1122 $this->testing($testDetails);
1123 $conn = @mysql_connect
($server, $username, $password);
1126 if (@mysql_select_db
($database)) {
1127 $okay = "Database '$database' exists";
1129 elseif ($onlyRequire) {
1130 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
1131 $this->error($testDetails);
1135 if (@mysql_query
("CREATE DATABASE $database")) {
1136 $okay = ts("Able to create a new database.");
1139 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
1140 $this->error($testDetails);
1146 $testDetails[3] = $okay;
1147 $this->testing($testDetails);
1153 * @param $errorMessage
1155 public function requireServerVariables($varNames, $errorMessage) {
1156 //$this->testing($testDetails);
1157 foreach ($varNames as $varName) {
1158 if (!$_SERVER[$varName]) {
1159 $missing[] = '$_SERVER[' . $varName . ']';
1162 if (!isset($missing)) {
1166 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
1167 $this->error($testDetails);
1172 * @param $testDetails
1176 public function isRunningApache($testDetails) {
1177 $this->testing($testDetails);
1178 if (function_exists('apache_get_modules') ||
stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1182 $this->warning($testDetails);
1189 public function getBaseDir() {
1190 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR
;
1194 * @param $testDetails
1196 public function testing($testDetails) {
1197 if (!$testDetails) {
1201 $section = $testDetails[0];
1202 $test = $testDetails[1];
1204 $message = ts("OK");
1205 if (isset($testDetails[3])) {
1206 $message .= " ($testDetails[3])";
1209 $this->tests
[$section][$test] = array("good", $message);
1213 * @param $testDetails
1215 public function error($testDetails) {
1216 $section = $testDetails[0];
1217 $test = $testDetails[1];
1219 $this->tests
[$section][$test] = array("error", $testDetails[2]);
1220 $this->errors
[] = $testDetails;
1224 * @param $testDetails
1226 public function warning($testDetails) {
1227 $section = $testDetails[0];
1228 $test = $testDetails[1];
1230 $this->tests
[$section][$test] = array("warning", $testDetails[2]);
1231 $this->warnings
[] = $testDetails;
1237 public function hasErrors() {
1238 return count($this->errors
);
1244 public function hasWarnings() {
1245 return count($this->warnings
);
1253 class Installer
extends InstallRequirements
{
1260 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1261 $conn = @mysql_connect
($server, $username, $password);
1263 if (@mysql_select_db
($database)) {
1264 // skip if database already present
1268 if (@mysql_query
("CREATE DATABASE $database")) {
1271 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1272 $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.");
1273 errorDisplayPage($errorTitle, $errorMsg);
1282 public function install($config) {
1283 global $installDirPath;
1285 // create database if does not exists
1286 $this->createDatabaseIfNotExists($config['mysql']['server'],
1287 $config['mysql']['username'],
1288 $config['mysql']['password'],
1289 $config['mysql']['database']
1292 global $installDirPath;
1295 require_once $installDirPath . 'civicrm.php';
1296 civicrm_main($config);
1298 if (!$this->errors
) {
1299 global $installType, $installURLPath;
1301 $registerSiteURL = "https://civicrm.org/register-site";
1302 $commonOutputMessage
1303 = "<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>"
1304 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
1309 $installType == 'drupal' &&
1310 version_compare(VERSION
, '7.0-rc1') >= 0
1316 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1317 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1318 $output .= '<head>';
1319 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1320 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1321 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1322 $output .= '</head>';
1323 $output .= '<body>';
1324 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1327 $drupalURL = civicrm_cms_base();
1328 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1329 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1331 $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>";
1332 $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>";
1333 $output .= $commonOutputMessage;
1335 // automatically enable CiviCRM module once it is installed successfully.
1336 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1337 global $cmsPath, $crmPath;
1339 // relative / abosolute paths are not working for drupal, hence using chdir()
1342 // Force the re-initialisation of the config singleton on the next call
1343 // since so far, we had used the Config object without loading the DB.
1344 $c = CRM_Core_Config
::singleton(FALSE);
1347 include_once "./includes/bootstrap.inc";
1348 include_once "./includes/unicode.inc";
1350 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1352 // prevent session information from being saved.
1353 drupal_save_session(FALSE);
1355 // Force the current user to anonymous.
1356 $original_user = $GLOBALS['user'];
1357 $GLOBALS['user'] = drupal_anonymous_user();
1359 // explicitly setting error reporting, since we cannot handle drupal related notices
1362 // rebuild modules, so that civicrm is added
1363 system_rebuild_module_data();
1365 // now enable civicrm module.
1366 module_enable(array('civicrm', 'civicrmtheme'));
1368 // clear block, page, theme, and hook caches
1369 drupal_flush_all_caches();
1371 //add basic drupal permissions
1372 civicrm_install_set_drupal_perms();
1374 // restore the user.
1375 $GLOBALS['user'] = $original_user;
1376 drupal_save_session(TRUE);
1378 //change the default language to one chosen
1379 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1380 // This ensures that defaults get set, otherwise the user will login
1381 // and most configurations will be empty, not set to en_US defaults.
1382 civicrm_api3('Setting', 'revert');
1384 civicrm_api3('Setting', 'create', array(
1385 'domain_id' => 'current_domain',
1386 'lcMessages' => $config['seedLanguage'],
1392 $output .= '</div>';
1393 $output .= '</body>';
1394 $output .= '</html>';
1397 elseif ($installType == 'drupal' && version_compare(VERSION
, '6.0') >= 0) {
1401 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1402 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1403 $output .= '<head>';
1404 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1405 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1406 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1407 $output .= '</head>';
1408 $output .= '<body>';
1409 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
1412 $drupalURL = civicrm_cms_base();
1413 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1414 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1416 $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>";
1417 $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>";
1418 $output .= $commonOutputMessage;
1420 // explicitly setting error reporting, since we cannot handle drupal related notices
1423 // automatically enable CiviCRM module once it is installed successfully.
1424 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1425 global $cmsPath, $crmPath;
1427 // relative / abosolute paths are not working for drupal, hence using chdir()
1430 // Force the re-initialisation of the config singleton on the next call
1431 // since so far, we had used the Config object without loading the DB.
1432 $c = CRM_Core_Config
::singleton(FALSE);
1435 include_once "./includes/bootstrap.inc";
1436 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1438 // rebuild modules, so that civicrm is added
1439 module_rebuild_cache();
1441 // now enable civicrm module.
1442 module_enable(array('civicrm'));
1444 // clear block, page, theme, and hook caches
1445 drupal_flush_all_caches();
1447 //add basic drupal permissions
1448 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)');
1452 elseif ($installType == 'wordpress') {
1453 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
1454 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
1457 $cmsURL = civicrm_cms_base();
1458 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1459 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1461 $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>";
1462 $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>";
1463 $output .= $commonOutputMessage;
1468 $c = CRM_Core_Config
::singleton(FALSE);
1470 $wpInstallRedirect = admin_url("?page=CiviCRM&q=civicrm&reset=1");
1472 window.location = '$wpInstallRedirect';
1477 return $this->errors
;
1482 function civicrm_install_set_drupal_perms() {
1483 if (!function_exists('db_select')) {
1484 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)');
1488 'access all custom data',
1489 'access uploaded files',
1490 'make online contributions',
1494 'register for events',
1496 'view event participants',
1497 'access CiviMail subscribe/unsubscribe pages',
1500 // Adding a permission that has not yet been assigned to a module by
1501 // a hook_permission implementation results in a database error.
1503 $allPerms = array_keys(module_invoke_all('permission'));
1504 foreach (array_diff($perms, $allPerms) as $perm) {
1506 'Cannot grant the %perm permission because it does not yet exist.',
1507 array('%perm' => $perm),
1511 $perms = array_intersect($perms, $allPerms);
1512 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID
, $perms);
1513 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID
, $perms);
1523 function getSiteDir($cmsPath, $str) {
1524 static $siteDir = '';
1530 $sites = CIVICRM_DIRECTORY_SEPARATOR
. 'sites' . CIVICRM_DIRECTORY_SEPARATOR
;
1531 $modules = CIVICRM_DIRECTORY_SEPARATOR
. 'modules' . CIVICRM_DIRECTORY_SEPARATOR
;
1532 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR
) .
1533 "([\-a-zA-Z0-9_.]+)" .
1534 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR
) . "/",
1535 $_SERVER['SCRIPT_FILENAME'], $matches
1537 $siteDir = isset($matches[1]) ?
$matches[1] : 'default';
1539 if (strtolower($siteDir) == 'all') {
1540 // For this case - use drupal's way of finding out multi-site directory
1541 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR
, $_SERVER['SCRIPT_FILENAME']);
1542 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1543 for ($i = count($uri) - 1; $i > 0; $i--) {
1544 for ($j = count($server); $j > 0; $j--) {
1545 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1546 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
1547 'sites' . CIVICRM_DIRECTORY_SEPARATOR
. $dir
1554 $siteDir = 'default';
1561 * @param $errorTitle
1565 function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1567 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1569 if (function_exists('ts')) {
1570 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1573 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1577 include 'error.html';