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 if ($installType == 'wordpress') {
115 $databaseConfig = array(
117 "username" => DB_USER
,
118 "password" => DB_PASSWORD
,
119 "database" => DB_NAME
,
124 if ($installType == 'drupal') {
125 // Load drupal database config
126 if (isset($_POST['drupal'])) {
127 $drupalConfig = $_POST['drupal'];
130 $drupalConfig = array(
131 "server" => "localhost",
132 "username" => "drupal",
134 "database" => "drupal",
140 if (isset($_POST['loadGenerated'])) {
144 require_once dirname(__FILE__
) . CIVICRM_DIRECTORY_SEPARATOR
. 'langs.php';
145 foreach ($langs as $locale => $_) {
146 if ($locale == 'en_US') {
149 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR
, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
150 unset($langs[$locale]);
154 // Set the locale (required by CRM_Core_Config)
155 // This is mostly sympbolic, since nothing we do during the install
156 // really requires CIVICRM_UF to be defined.
157 $installTypeToUF = array(
158 'wordpress' => 'WordPress',
159 'drupal' => 'Drupal',
162 $uf = (isset($installTypeToUF[$installType]) ?
$installTypeToUF[$installType] : 'Drupal');
163 define('CIVICRM_UF', $uf);
168 $seedLanguage = 'en_US';
170 if (isset($_POST['seedLanguage']) and isset($langs[$_POST['seedLanguage']])) {
171 $seedLanguage = $_POST['seedLanguage'];
172 $tsLocale = $_POST['seedLanguage'];
175 $config = CRM_Core_Config
::singleton(FALSE);
176 $GLOBALS['civicrm_default_error_scope'] = NULL;
178 // The translation files are in the parent directory (l10n)
179 $i18n = CRM_Core_I18n
::singleton();
182 if ($installType == 'drupal') {
183 //CRM-6840 -don't force to install in sites/all/modules/
184 $object = new CRM_Utils_System_Drupal();
185 $cmsPath = $object->cmsRootPath();
187 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
188 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
189 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
190 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
191 'civicrm.settings.php'
194 elseif ($installType == 'wordpress') {
195 $cmsPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm';
196 $upload_dir = wp_upload_dir();
197 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
198 $wp_civi_settings = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm.settingsphp';
199 $wp_civi_settings_deprectated = CIVICRM_PLUGIN_DIR
. 'civicrm.settings.php';
200 if (file_exists($wp_civi_settings_deprectated)) {
201 $alreadyInstalled = $wp_civi_settings_deprectated;
203 elseif (file_exists($wp_civi_settings)) {
204 $alreadyInstalled = $wp_civi_settings;
208 if ($installType == 'drupal') {
209 // Lets check only /modules/.
210 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR
. 'modules', CIVICRM_DIRECTORY_SEPARATOR
) . '/';
212 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
213 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array('sites', 'all', 'modules'));
214 $errorTitle = ts("Oops! Please correct your install location");
215 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
216 errorDisplayPage($errorTitle, $errorMsg);
220 // Exit with error if CiviCRM has already been installed.
221 if ($alreadyInstalled) {
222 $errorTitle = ts("Oops! CiviCRM is already installed");
223 $settings_directory = $cmsPath;
225 if ($installType == 'drupal') {
226 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array(
227 ts('[your Drupal root directory]'),
233 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
234 $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));
235 errorDisplayPage($errorTitle, $errorMsg, FALSE);
238 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'civicrm-version.php';
239 if (file_exists($versionFile)) {
240 require_once $versionFile;
241 $civicrm_version = civicrmVersion();
244 $civicrm_version = 'unknown';
247 if ($installType == 'drupal') {
248 // Ensure that they have downloaded the correct version of CiviCRM
249 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
250 $errorTitle = ts("Oops! Incorrect CiviCRM version");
251 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
252 errorDisplayPage($errorTitle, $errorMsg);
255 define('DRUPAL_ROOT', $cmsPath);
256 $drupalVersionFiles = array(
258 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'modules', 'system', 'system.module')),
260 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'includes', 'bootstrap.inc')),
262 foreach ($drupalVersionFiles as $drupalVersionFile) {
263 if (file_exists($drupalVersionFile)) {
264 require_once $drupalVersionFile;
268 if (!defined('VERSION') or version_compare(VERSION
, '6.0') < 0) {
269 $errorTitle = ts("Oops! Incorrect Drupal version");
270 $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)));
271 errorDisplayPage($errorTitle, $errorMsg);
274 elseif ($installType == 'wordpress') {
276 $civicrm_version['cms'] = 'WordPress';
278 // Ensure that they have downloaded the correct version of CiviCRM
279 if ($civicrm_version['cms'] != 'WordPress') {
280 $errorTitle = ts("Oops! Incorrect CiviCRM version");
281 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
282 errorDisplayPage($errorTitle, $errorMsg);
286 // Check requirements
287 $req = new InstallRequirements();
290 if ($req->hasErrors()) {
291 $hasErrorOtherThanDatabase = TRUE;
294 if ($databaseConfig) {
295 $dbReq = new InstallRequirements();
296 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
297 if ($installType == 'drupal') {
298 $dbReq->checkdatabase($drupalConfig, 'Drupal');
303 if (isset($_POST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
304 // Confirm before reinstalling
305 if (!isset($_POST['force_reinstall']) && $alreadyInstalled) {
306 include $installDirPath . 'template.html';
309 $inst = new Installer();
310 $inst->install($_POST);
313 // Show the config form
316 include $installDirPath . 'template.html';
320 * This class checks requirements
321 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
323 * $description[0] - The test category
324 * $description[1] - The test title
325 * $description[2] - The test error to show, if it goes wrong
327 class InstallRequirements
{
328 var $errors, $warnings, $tests;
330 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
331 const MINIMUM_THREAD_STACK
= 192;
334 * Just check that the database configuration is okay.
335 * @param $databaseConfig
338 public function checkdatabase($databaseConfig, $dbName) {
339 if ($this->requireFunction('mysql_connect',
341 ts("PHP Configuration"),
343 ts("MySQL support not included in PHP."),
347 $this->requireMySQLServer($databaseConfig['server'],
349 ts("MySQL %1 Configuration", array(1 => $dbName)),
350 ts("Does the server exist?"),
351 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
352 $databaseConfig['server'],
355 if ($this->requireMysqlConnection($databaseConfig['server'],
356 $databaseConfig['username'],
357 $databaseConfig['password'],
359 ts("MySQL %1 Configuration", array(1 => $dbName)),
360 ts("Are the access credentials correct?"),
361 ts("That username/password doesn't work"),
365 @$this->requireMySQLVersion("5.1",
367 ts("MySQL %1 Configuration", array(1 => $dbName)),
368 ts("MySQL version at least %1", array(1 => '5.1')),
369 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
370 ts("MySQL %1", array(1 => mysql_get_server_info())),
373 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
374 $databaseConfig['username'],
375 $databaseConfig['password'],
377 ts("MySQL %1 Configuration", array(1 => $dbName)),
378 ts("Is auto_increment_increment set to 1"),
379 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
382 $this->requireMySQLThreadStack($databaseConfig['server'],
383 $databaseConfig['username'],
384 $databaseConfig['password'],
385 $databaseConfig['database'],
386 self
::MINIMUM_THREAD_STACK
,
388 ts("MySQL %1 Configuration", array(1 => $dbName)),
389 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self
::MINIMUM_THREAD_STACK
)),
391 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
395 $onlyRequire = ($dbName == 'Drupal') ?
TRUE : FALSE;
396 $this->requireDatabaseOrCreatePermissions(
397 $databaseConfig['server'],
398 $databaseConfig['username'],
399 $databaseConfig['password'],
400 $databaseConfig['database'],
402 ts("MySQL %1 Configuration", array(1 => $dbName)),
403 ts("Can I access/create the database?"),
404 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
408 if ($dbName != 'Drupal') {
409 $this->requireMySQLInnoDB($databaseConfig['server'],
410 $databaseConfig['username'],
411 $databaseConfig['password'],
412 $databaseConfig['database'],
414 ts("MySQL %1 Configuration", array(1 => $dbName)),
415 ts("Can I access/create InnoDB tables in the database?"),
416 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."),
419 $this->requireMySQLTempTables($databaseConfig['server'],
420 $databaseConfig['username'],
421 $databaseConfig['password'],
422 $databaseConfig['database'],
424 ts("MySQL %1 Configuration", array(1 => $dbName)),
425 ts('Can I create temporary tables in the database?'),
426 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
429 $this->requireMySQLLockTables($databaseConfig['server'],
430 $databaseConfig['username'],
431 $databaseConfig['password'],
432 $databaseConfig['database'],
434 ts("MySQL %1 Configuration", array(1 => $dbName)),
435 ts('Can I create lock tables in the database?'),
436 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
439 $this->requireMySQLTrigger($databaseConfig['server'],
440 $databaseConfig['username'],
441 $databaseConfig['password'],
442 $databaseConfig['database'],
444 ts("MySQL %1 Configuration", array(1 => $dbName)),
445 ts('Can I create triggers in the database?'),
446 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
454 * Check everything except the database.
456 public function check() {
457 global $crmPath, $installType;
459 $this->errors
= NULL;
461 $this->requirePHPVersion('5.3.4', array(
462 ts("PHP Configuration"),
463 ts("PHP5 installed"),
465 ts("PHP version %1", array(1 => phpversion())),
468 // Check that we can identify the root folder successfully
469 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'README.txt',
471 ts("File permissions"),
472 ts("Does the webserver know where files are stored?"),
473 ts("The webserver isn't letting me identify where files are stored."),
479 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
480 $this->requireNoPathSeparator(
482 ts("File permissions"),
483 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
484 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR
)),
489 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
490 foreach ($requiredDirectories as $dir) {
491 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. $dir,
493 ts("File permissions"),
494 ts("Folder '%1' exists?", array(1 => $dir)),
495 ts("There is no '%1' folder.", array(1 => $dir)),
500 $configIDSiniDir = NULL;
502 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
503 if ($installType == 'drupal') {
505 // make sure that we can write to sites/default and files/
506 $writableDirectories = array(
507 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
508 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
509 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
511 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
512 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
516 elseif ($installType == 'wordpress') {
517 // make sure that we can write to uploads/civicrm/
518 $upload_dir = wp_upload_dir();
519 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
520 if (!file_exists($files_dirname)) {
521 wp_mkdir_p($files_dirname);
523 $writableDirectories = array($files_dirname);
526 foreach ($writableDirectories as $dir) {
527 $dirName = CIVICRM_WINDOWS ?
$dir : CIVICRM_DIRECTORY_SEPARATOR
. $dir;
528 $testDetails = array(
529 ts("File permissions"),
530 ts("Is the %1 folder writeable?", array(1 => $dir)),
533 $this->requireWriteable($dirName, $testDetails, TRUE);
536 //check for Config.IDS.ini, file may exist in re-install
537 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
539 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
540 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR
, $configIDSiniDir);
541 if (file_exists($configIDSiniFile)) {
542 unlink($configIDSiniFile);
546 // Check for rewriting
547 if (isset($_SERVER['SERVER_SOFTWARE'])) {
548 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
550 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
551 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
554 if ($webserver == '') {
555 $webserver = ts("I can't tell what webserver you are running");
558 // Check for $_SERVER configuration
559 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
560 ts("Webserver config"),
561 ts("Recognised webserver"),
562 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
565 // Check for MySQL support
566 $this->requireFunction('mysql_connect', array(
567 ts("PHP Configuration"),
569 ts("MySQL support not included in PHP."),
572 // Check for JSON support
573 $this->requireFunction('json_encode', array(
574 ts("PHP Configuration"),
576 ts("JSON support not included in PHP."),
579 // Check for xcache_isset and emit warning if exists
580 $this->checkXCache(array(
581 ts("PHP Configuration"),
582 ts("XCache compatibility"),
583 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."),
586 // Check memory allocation
587 $this->requireMemory(32 * 1024 * 1024,
590 ts("PHP Configuration"),
591 ts("Memory allocated (PHP config option 'memory_limit')"),
592 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
593 ini_get("memory_limit"),
597 return $this->errors
;
602 * @param $recommended
603 * @param $testDetails
605 public function requireMemory($min, $recommended, $testDetails) {
606 $this->testing($testDetails);
607 $mem = $this->getPHPMemory();
609 if ($mem < $min && $mem > 0) {
610 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
611 $this->error($testDetails);
613 elseif ($mem < $recommended && $mem > 0) {
614 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
615 $this->warning($testDetails);
618 $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));
619 $this->warning($testDetails);
626 public function getPHPMemory() {
627 $memString = ini_get("memory_limit");
629 switch (strtolower(substr($memString, -1))) {
631 return round(substr($memString, 0, -1) * 1024);
634 return round(substr($memString, 0, -1) * 1024 * 1024);
637 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
640 return round($memString);
644 public function listErrors() {
646 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
647 foreach ($this->errors
as $error) {
648 echo "<li>" . htmlentities($error) . "</li>";
654 * @param null $section
656 public function showTable($section = NULL) {
658 $tests = $this->tests
[$section];
659 echo "<table class=\"testResults\" width=\"100%\">";
660 foreach ($tests as $test => $result) {
661 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
666 foreach ($this->tests
as $section => $tests) {
667 echo "<h3>$section</h3>";
668 echo "<table class=\"testResults\" width=\"100%\">";
670 foreach ($tests as $test => $result) {
671 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
679 * @param string $funcName
680 * @param $testDetails
684 public function requireFunction($funcName, $testDetails) {
685 $this->testing($testDetails);
687 if (!function_exists($funcName)) {
688 $this->error($testDetails);
697 * @param $testDetails
699 public function checkXCache($testDetails) {
700 if (function_exists('xcache_isset') &&
701 ini_get('xcache.size') > 0
703 $this->testing($testDetails);
704 $this->warning($testDetails);
710 * @param $testDetails
711 * @param null $maxVersion
713 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
715 $this->testing($testDetails);
717 $phpVersion = phpversion();
718 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
719 $belowMaxVersion = $maxVersion ?
version_compare($phpVersion, $maxVersion) < 0 : TRUE;
721 if ($maxVersion && $aboveMinVersion && $belowMaxVersion) {
724 elseif (!$maxVersion && $aboveMinVersion) {
728 if (!$testDetails[2]) {
729 if (!$aboveMinVersion) {
730 $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));
733 $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));
737 $this->error($testDetails);
741 * @param string $filename
742 * @param $testDetails
743 * @param bool $absolute
745 public function requireFile($filename, $testDetails, $absolute = FALSE) {
746 $this->testing($testDetails);
748 $filename = $this->getBaseDir() . $filename;
750 if (!file_exists($filename)) {
751 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
752 $this->error($testDetails);
757 * @param $testDetails
759 public function requireNoPathSeparator($testDetails) {
760 $this->testing($testDetails);
761 if (substr_count($this->getBaseDir(), PATH_SEPARATOR
)) {
762 $this->error($testDetails);
767 * @param string $filename
768 * @param $testDetails
770 public function requireNoFile($filename, $testDetails) {
771 $this->testing($testDetails);
772 $filename = $this->getBaseDir() . $filename;
773 if (file_exists($filename)) {
774 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
775 $this->error($testDetails);
780 * @param string $filename
781 * @param $testDetails
783 public function moveFileOutOfTheWay($filename, $testDetails) {
784 $this->testing($testDetails);
785 $filename = $this->getBaseDir() . $filename;
786 if (file_exists($filename)) {
787 if (file_exists("$filename.bak")) {
790 rename($filename, "$filename.bak");
795 * @param string $filename
796 * @param $testDetails
797 * @param bool $absolute
799 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
800 $this->testing($testDetails);
802 $filename = $this->getBaseDir() . $filename;
805 if (!is_writable($filename)) {
807 if (function_exists('posix_getpwuid')) {
808 $user = posix_getpwuid(posix_geteuid());
809 $name = '- ' . $user['name'] . ' -';
812 if (!isset($testDetails[2])) {
813 $testDetails[2] = NULL;
815 $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";
816 $this->error($testDetails);
821 * @param string $moduleName
822 * @param $testDetails
824 public function requireApacheModule($moduleName, $testDetails) {
825 $this->testing($testDetails);
826 if (!in_array($moduleName, apache_get_modules())) {
827 $this->error($testDetails);
833 * @param string $username
835 * @param $testDetails
837 public function requireMysqlConnection($server, $username, $password, $testDetails) {
838 $this->testing($testDetails);
839 $conn = @mysql_connect
($server, $username, $password);
845 $testDetails[2] .= ": " . mysql_error();
846 $this->error($testDetails);
852 * @param $testDetails
854 public function requireMySQLServer($server, $testDetails) {
855 $this->testing($testDetails);
856 $conn = @mysql_connect
($server, NULL, NULL);
858 if ($conn ||
mysql_errno() < 2000) {
862 $testDetails[2] .= ": " . mysql_error();
863 $this->error($testDetails);
869 * @param $testDetails
871 public function requireMySQLVersion($version, $testDetails) {
872 $this->testing($testDetails);
874 if (!mysql_get_server_info()) {
875 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
876 $this->warning($testDetails);
879 list($majorRequested, $minorRequested) = explode('.', $version);
880 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
882 if (($majorHas > $majorRequested) ||
($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
886 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
887 $this->error($testDetails);
894 * @param string $username
897 * @param $testDetails
899 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
900 $this->testing($testDetails);
901 $conn = @mysql_connect
($server, $username, $password);
903 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
904 $this->error($testDetails);
908 $innodb_support = FALSE;
909 $result = mysql_query("SHOW ENGINES", $conn);
910 while ($values = mysql_fetch_array($result)) {
911 if ($values['Engine'] == 'InnoDB') {
912 if (strtolower($values['Support']) == 'yes' ||
913 strtolower($values['Support']) == 'default'
915 $innodb_support = TRUE;
919 if ($innodb_support) {
920 $testDetails[3] = ts('MySQL server does have InnoDB support');
923 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
929 * @param string $username
932 * @param $testDetails
934 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
935 $this->testing($testDetails);
936 $conn = @mysql_connect
($server, $username, $password);
938 $testDetails[2] = ts('Could not login to the database.');
939 $this->error($testDetails);
943 if (!@mysql_select_db
($database, $conn)) {
944 $testDetails[2] = ts('Could not select the database.');
945 $this->error($testDetails);
949 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
951 $testDetails[2] = ts('Could not create a temp table.');
952 $this->error($testDetails);
954 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
959 * @param string $username
962 * @param $testDetails
964 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
965 $this->testing($testDetails);
966 $conn = @mysql_connect
($server, $username, $password);
968 $testDetails[2] = ts('Could not login to the database.');
969 $this->error($testDetails);
973 if (!@mysql_select_db
($database, $conn)) {
974 $testDetails[2] = ts('Could not select the database.');
975 $this->error($testDetails);
979 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
981 $testDetails[2] = ts('Could not create a table in the database.');
982 $this->error($testDetails);
985 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
987 mysql_query('DROP TABLE civicrm_install_temp_table_test');
988 $testDetails[2] = ts('Could not create a database trigger.');
989 $this->error($testDetails);
992 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
993 mysql_query('DROP TABLE civicrm_install_temp_table_test');
999 * @param string $username
1002 * @param $testDetails
1004 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
1005 $this->testing($testDetails);
1006 $conn = @mysql_connect
($server, $username, $password);
1008 $testDetails[2] = ts('Could not connect to the database server.');
1009 $this->error($testDetails);
1013 if (!@mysql_select_db
($database, $conn)) {
1014 $testDetails[2] = ts('Could not select the database.');
1015 $this->error($testDetails);
1019 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1021 $testDetails[2] = ts('Could not create a table in the database.');
1022 $this->error($testDetails);
1026 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1028 $testDetails[2] = ts('Could not obtain a write 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('UNLOCK TABLES', $conn);
1036 $testDetails[2] = ts('Could not release the lock for the database table.');
1037 $this->error($testDetails);
1038 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1042 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1047 * @param string $username
1049 * @param $testDetails
1051 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
1052 $this->testing($testDetails);
1053 $conn = @mysql_connect
($server, $username, $password);
1055 $testDetails[2] = ts('Could not connect to the database server.');
1056 $this->error($testDetails);
1060 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1062 $testDetails[2] = ts('Could not query database server variables.');
1063 $this->error($testDetails);
1067 $values = mysql_fetch_row($result);
1068 if ($values[1] == 1) {
1069 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
1072 $this->error($testDetails);
1079 * @param string $username
1082 * @param $minValueKB
1083 * @param $testDetails
1085 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1086 $this->testing($testDetails);
1087 $conn = @mysql_connect
($server, $username, $password);
1089 $testDetails[2] = ts('Could not connect to the database server.');
1090 $this->error($testDetails);
1094 if (!@mysql_select_db
($database, $conn)) {
1095 $testDetails[2] = ts('Could not select the database.');
1096 $this->error($testDetails);
1100 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1102 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
1103 $this->error($testDetails);
1106 $values = mysql_fetch_row($result);
1107 if ($values[1] < (1024 * $minValueKB)) {
1108 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
1109 $this->error($testDetails);
1116 * @param string $username
1119 * @param $testDetails
1120 * @param bool $onlyRequire
1122 public function requireDatabaseOrCreatePermissions(
1128 $onlyRequire = FALSE
1130 $this->testing($testDetails);
1131 $conn = @mysql_connect
($server, $username, $password);
1134 if (@mysql_select_db
($database)) {
1135 $okay = "Database '$database' exists";
1137 elseif ($onlyRequire) {
1138 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
1139 $this->error($testDetails);
1143 if (@mysql_query
("CREATE DATABASE $database")) {
1144 $okay = ts("Able to create a new database.");
1147 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
1148 $this->error($testDetails);
1154 $testDetails[3] = $okay;
1155 $this->testing($testDetails);
1161 * @param $errorMessage
1163 public function requireServerVariables($varNames, $errorMessage) {
1164 //$this->testing($testDetails);
1165 foreach ($varNames as $varName) {
1166 if (!$_SERVER[$varName]) {
1167 $missing[] = '$_SERVER[' . $varName . ']';
1170 if (!isset($missing)) {
1174 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
1175 $this->error($testDetails);
1180 * @param $testDetails
1184 public function isRunningApache($testDetails) {
1185 $this->testing($testDetails);
1186 if (function_exists('apache_get_modules') ||
stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1190 $this->warning($testDetails);
1197 public function getBaseDir() {
1198 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR
;
1202 * @param $testDetails
1204 public function testing($testDetails) {
1205 if (!$testDetails) {
1209 $section = $testDetails[0];
1210 $test = $testDetails[1];
1212 $message = ts("OK");
1213 if (isset($testDetails[3])) {
1214 $message .= " ($testDetails[3])";
1217 $this->tests
[$section][$test] = array("good", $message);
1221 * @param $testDetails
1223 public function error($testDetails) {
1224 $section = $testDetails[0];
1225 $test = $testDetails[1];
1227 $this->tests
[$section][$test] = array("error", $testDetails[2]);
1228 $this->errors
[] = $testDetails;
1232 * @param $testDetails
1234 public function warning($testDetails) {
1235 $section = $testDetails[0];
1236 $test = $testDetails[1];
1238 $this->tests
[$section][$test] = array("warning", $testDetails[2]);
1239 $this->warnings
[] = $testDetails;
1245 public function hasErrors() {
1246 return count($this->errors
);
1252 public function hasWarnings() {
1253 return count($this->warnings
);
1261 class Installer
extends InstallRequirements
{
1268 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1269 $conn = @mysql_connect
($server, $username, $password);
1271 if (@mysql_select_db
($database)) {
1272 // skip if database already present
1276 if (@mysql_query
("CREATE DATABASE $database")) {
1279 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1280 $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.");
1281 errorDisplayPage($errorTitle, $errorMsg);
1290 public function install($config) {
1291 global $installDirPath;
1293 // create database if does not exists
1294 $this->createDatabaseIfNotExists($config['mysql']['server'],
1295 $config['mysql']['username'],
1296 $config['mysql']['password'],
1297 $config['mysql']['database']
1300 global $installDirPath;
1303 require_once $installDirPath . 'civicrm.php';
1304 civicrm_main($config);
1306 if (!$this->errors
) {
1307 global $installType, $installURLPath;
1309 $registerSiteURL = "https://civicrm.org/register-site";
1310 $commonOutputMessage
1311 = "<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>"
1312 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
1317 $installType == 'drupal' &&
1318 version_compare(VERSION
, '7.0-rc1') >= 0
1324 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1325 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1326 $output .= '<head>';
1327 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1328 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1329 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1330 $output .= '</head>';
1331 $output .= '<body>';
1332 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1335 $drupalURL = civicrm_cms_base();
1336 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1337 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1339 $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>";
1340 $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>";
1341 $output .= $commonOutputMessage;
1343 // automatically enable CiviCRM module once it is installed successfully.
1344 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1345 global $cmsPath, $crmPath;
1347 // relative / abosolute paths are not working for drupal, hence using chdir()
1350 // Force the re-initialisation of the config singleton on the next call
1351 // since so far, we had used the Config object without loading the DB.
1352 $c = CRM_Core_Config
::singleton(FALSE);
1355 include_once "./includes/bootstrap.inc";
1356 include_once "./includes/unicode.inc";
1358 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1360 // prevent session information from being saved.
1361 drupal_save_session(FALSE);
1363 // Force the current user to anonymous.
1364 $original_user = $GLOBALS['user'];
1365 $GLOBALS['user'] = drupal_anonymous_user();
1367 // explicitly setting error reporting, since we cannot handle drupal related notices
1370 // rebuild modules, so that civicrm is added
1371 system_rebuild_module_data();
1373 // now enable civicrm module.
1374 module_enable(array('civicrm', 'civicrmtheme'));
1376 // clear block, page, theme, and hook caches
1377 drupal_flush_all_caches();
1379 //add basic drupal permissions
1380 civicrm_install_set_drupal_perms();
1382 // restore the user.
1383 $GLOBALS['user'] = $original_user;
1384 drupal_save_session(TRUE);
1386 //change the default language to one chosen
1387 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1388 // This ensures that defaults get set, otherwise the user will login
1389 // and most configurations will be empty, not set to en_US defaults.
1390 civicrm_api3('Setting', 'revert');
1392 civicrm_api3('Setting', 'create', array(
1393 'domain_id' => 'current_domain',
1394 'lcMessages' => $config['seedLanguage'],
1400 $output .= '</div>';
1401 $output .= '</body>';
1402 $output .= '</html>';
1405 elseif ($installType == 'drupal' && version_compare(VERSION
, '6.0') >= 0) {
1409 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1410 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1411 $output .= '<head>';
1412 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1413 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1414 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1415 $output .= '</head>';
1416 $output .= '<body>';
1417 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
1420 $drupalURL = civicrm_cms_base();
1421 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1422 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1424 $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>";
1425 $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>";
1426 $output .= $commonOutputMessage;
1428 // explicitly setting error reporting, since we cannot handle drupal related notices
1431 // automatically enable CiviCRM module once it is installed successfully.
1432 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1433 global $cmsPath, $crmPath;
1435 // relative / abosolute paths are not working for drupal, hence using chdir()
1438 // Force the re-initialisation of the config singleton on the next call
1439 // since so far, we had used the Config object without loading the DB.
1440 $c = CRM_Core_Config
::singleton(FALSE);
1443 include_once "./includes/bootstrap.inc";
1444 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1446 // rebuild modules, so that civicrm is added
1447 module_rebuild_cache();
1449 // now enable civicrm module.
1450 module_enable(array('civicrm'));
1452 // clear block, page, theme, and hook caches
1453 drupal_flush_all_caches();
1455 //add basic drupal permissions
1456 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)');
1460 elseif ($installType == 'wordpress') {
1461 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
1462 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
1465 $cmsURL = civicrm_cms_base();
1466 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1467 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1469 $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>";
1470 $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>";
1471 $output .= $commonOutputMessage;
1476 $c = CRM_Core_Config
::singleton(FALSE);
1478 $wpInstallRedirect = admin_url("?page=CiviCRM&q=civicrm&reset=1");
1480 window.location = '$wpInstallRedirect';
1485 return $this->errors
;
1490 function civicrm_install_set_drupal_perms() {
1491 if (!function_exists('db_select')) {
1492 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)');
1496 'access all custom data',
1497 'access uploaded files',
1498 'make online contributions',
1502 'register for events',
1504 'view event participants',
1505 'access CiviMail subscribe/unsubscribe pages',
1508 // Adding a permission that has not yet been assigned to a module by
1509 // a hook_permission implementation results in a database error.
1511 $allPerms = array_keys(module_invoke_all('permission'));
1512 foreach (array_diff($perms, $allPerms) as $perm) {
1514 'Cannot grant the %perm permission because it does not yet exist.',
1515 array('%perm' => $perm),
1519 $perms = array_intersect($perms, $allPerms);
1520 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID
, $perms);
1521 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID
, $perms);
1531 function getSiteDir($cmsPath, $str) {
1532 static $siteDir = '';
1538 $sites = CIVICRM_DIRECTORY_SEPARATOR
. 'sites' . CIVICRM_DIRECTORY_SEPARATOR
;
1539 $modules = CIVICRM_DIRECTORY_SEPARATOR
. 'modules' . CIVICRM_DIRECTORY_SEPARATOR
;
1540 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR
) .
1541 "([\-a-zA-Z0-9_.]+)" .
1542 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR
) . "/",
1543 $_SERVER['SCRIPT_FILENAME'], $matches
1545 $siteDir = isset($matches[1]) ?
$matches[1] : 'default';
1547 if (strtolower($siteDir) == 'all') {
1548 // For this case - use drupal's way of finding out multi-site directory
1549 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR
, $_SERVER['SCRIPT_FILENAME']);
1550 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1551 for ($i = count($uri) - 1; $i > 0; $i--) {
1552 for ($j = count($server); $j > 0; $j--) {
1553 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1554 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
1555 'sites' . CIVICRM_DIRECTORY_SEPARATOR
. $dir
1562 $siteDir = 'default';
1569 * @param $errorTitle
1573 function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1575 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1577 if (function_exists('ts')) {
1578 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1581 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1585 include 'error.html';