4 * Note that this installer has been based of the SilverStripe installer.
5 * You can get more information from the SilverStripe Website at
6 * http://www.silverstripe.com/.
8 * Copyright (c) 2006-7, SilverStripe Limited - www.silverstripe.com
11 * License: BSD-3-clause
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are
16 * Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
23 * Neither the name of SilverStripe nor the names of its contributors may
24 * be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
31 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * Changes and modifications (c) 2007-2015 by CiviCRM LLC
47 ini_set('max_execution_time', 3000);
49 if (stristr(PHP_OS
, 'WIN')) {
50 define('CIVICRM_DIRECTORY_SEPARATOR', '/');
51 define('CIVICRM_WINDOWS', 1);
54 define('CIVICRM_DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR
);
55 define('CIVICRM_WINDOWS', 0);
58 // set installation type - drupal
60 if (defined('PANTHEON_ENVIRONMENT')) {
61 ini_set('session.save_handler', 'files');
66 // unset civicrm session if any
67 if (array_key_exists('CiviCRM', $_SESSION)) {
68 unset($_SESSION['CiviCRM']);
71 if (isset($_GET['civicrm_install_type'])) {
72 $_SESSION['civicrm_install_type'] = $_GET['civicrm_install_type'];
75 if (!isset($_SESSION['civicrm_install_type'])) {
76 $_SESSION['civicrm_install_type'] = "drupal";
83 global $installDirPath;
84 global $installURLPath;
86 $installType = strtolower($_SESSION['civicrm_install_type']);
88 if ($installType == 'drupal') {
89 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
90 $installDirPath = $installURLPath = '';
92 elseif ($installType == 'wordpress') {
93 $crmPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
;
94 $installDirPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
95 $installURLPath = WP_PLUGIN_URL
. DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'install' . DIRECTORY_SEPARATOR
;
98 $errorTitle = "Oops! Unsupported installation mode";
99 $errorMsg = sprintf('%s: unknown installation mode. Please refer to the online documentation for more information.', $installType);
100 errorDisplayPage($errorTitle, $errorMsg, FALSE);
103 $pkgPath = $crmPath . DIRECTORY_SEPARATOR
. 'packages';
105 require_once $crmPath . '/CRM/Core/ClassLoader.php';
106 CRM_Core_ClassLoader
::singleton()->register();
108 // Load civicrm database config
109 if (isset($_POST['mysql'])) {
110 $databaseConfig = $_POST['mysql'];
113 $databaseConfig = array(
114 "server" => "localhost",
115 "username" => "civicrm",
117 "database" => "civicrm",
121 if ($installType == 'wordpress') {
123 $databaseConfig = array(
125 "username" => DB_USER
,
126 "password" => DB_PASSWORD
,
127 "database" => DB_NAME
,
131 if ($installType == 'drupal') {
132 // Load drupal database config
133 if (isset($_POST['drupal'])) {
134 $drupalConfig = $_POST['drupal'];
137 $drupalConfig = array(
138 "server" => "localhost",
139 "username" => "drupal",
141 "database" => "drupal",
147 if (isset($_POST['loadGenerated'])) {
151 require_once dirname(__FILE__
) . CIVICRM_DIRECTORY_SEPARATOR
. 'langs.php';
152 foreach ($langs as $locale => $_) {
153 if ($locale == 'en_US') {
156 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR
, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
157 unset($langs[$locale]);
161 // Set the locale (required by CRM_Core_Config)
162 // This is mostly sympbolic, since nothing we do during the install
163 // really requires CIVICRM_UF to be defined.
164 $installTypeToUF = array(
165 'wordpress' => 'WordPress',
166 'drupal' => 'Drupal',
169 $uf = (isset($installTypeToUF[$installType]) ?
$installTypeToUF[$installType] : 'Drupal');
170 define('CIVICRM_UF', $uf);
175 $seedLanguage = 'en_US';
177 if (isset($_POST['seedLanguage']) and isset($langs[$_POST['seedLanguage']])) {
178 $seedLanguage = $_POST['seedLanguage'];
179 $tsLocale = $_POST['seedLanguage'];
182 $config = CRM_Core_Config
::singleton(FALSE);
183 $GLOBALS['civicrm_default_error_scope'] = NULL;
185 // The translation files are in the parent directory (l10n)
186 $i18n = CRM_Core_I18n
::singleton();
189 if ($installType == 'drupal') {
190 //CRM-6840 -don't force to install in sites/all/modules/
191 $object = new CRM_Utils_System_Drupal();
192 $cmsPath = $object->cmsRootPath();
194 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
195 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
196 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
197 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
198 'civicrm.settings.php'
201 elseif ($installType == 'wordpress') {
202 $cmsPath = WP_PLUGIN_DIR
. DIRECTORY_SEPARATOR
. 'civicrm';
203 $upload_dir = wp_upload_dir();
204 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
205 $wp_civi_settings = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm' . DIRECTORY_SEPARATOR
. 'civicrm.settingsphp';
206 $wp_civi_settings_deprectated = CIVICRM_PLUGIN_DIR
. 'civicrm.settings.php';
207 if (file_exists($wp_civi_settings_deprectated)) {
208 $alreadyInstalled = $wp_civi_settings_deprectated;
210 elseif (file_exists($wp_civi_settings)) {
211 $alreadyInstalled = $wp_civi_settings;
215 if ($installType == 'drupal') {
216 // Lets check only /modules/.
217 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR
. 'modules', CIVICRM_DIRECTORY_SEPARATOR
) . '/';
219 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
220 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array('sites', 'all', 'modules'));
221 $errorTitle = ts("Oops! Please correct your install location");
222 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
223 errorDisplayPage($errorTitle, $errorMsg);
227 // Exit with error if CiviCRM has already been installed.
228 if ($alreadyInstalled) {
229 $errorTitle = ts("Oops! CiviCRM is already installed");
230 $settings_directory = $cmsPath;
232 if ($installType == 'drupal') {
233 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR
, array(
234 ts('[your Drupal root directory]'),
240 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
241 $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));
242 errorDisplayPage($errorTitle, $errorMsg, FALSE);
245 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'civicrm-version.php';
246 if (file_exists($versionFile)) {
247 require_once $versionFile;
248 $civicrm_version = civicrmVersion();
251 $civicrm_version = 'unknown';
254 if ($installType == 'drupal') {
255 // Ensure that they have downloaded the correct version of CiviCRM
256 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
257 $errorTitle = ts("Oops! Incorrect CiviCRM version");
258 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
259 errorDisplayPage($errorTitle, $errorMsg);
262 define('DRUPAL_ROOT', $cmsPath);
263 $drupalVersionFiles = array(
265 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'modules', 'system', 'system.module')),
267 implode(CIVICRM_DIRECTORY_SEPARATOR
, array($cmsPath, 'includes', 'bootstrap.inc')),
269 foreach ($drupalVersionFiles as $drupalVersionFile) {
270 if (file_exists($drupalVersionFile)) {
271 require_once $drupalVersionFile;
275 if (!defined('VERSION') or version_compare(VERSION
, '6.0') < 0) {
276 $errorTitle = ts("Oops! Incorrect Drupal version");
277 $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)));
278 errorDisplayPage($errorTitle, $errorMsg);
281 elseif ($installType == 'wordpress') {
283 $civicrm_version['cms'] = 'WordPress';
285 // Ensure that they have downloaded the correct version of CiviCRM
286 if ($civicrm_version['cms'] != 'WordPress') {
287 $errorTitle = ts("Oops! Incorrect CiviCRM version");
288 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
289 errorDisplayPage($errorTitle, $errorMsg);
293 // Check requirements
294 $req = new InstallRequirements();
297 if ($req->hasErrors()) {
298 $hasErrorOtherThanDatabase = TRUE;
301 if ($databaseConfig) {
302 $dbReq = new InstallRequirements();
303 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
304 if ($installType == 'drupal') {
305 $dbReq->checkdatabase($drupalConfig, 'Drupal');
310 if (isset($_POST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
311 // Confirm before reinstalling
312 if (!isset($_POST['force_reinstall']) && $alreadyInstalled) {
313 include $installDirPath . 'template.html';
316 $inst = new Installer();
317 $inst->install($_POST);
320 // Show the config form
323 include $installDirPath . 'template.html';
327 * This class checks requirements
328 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
330 * $description[0] - The test category
331 * $description[1] - The test title
332 * $description[2] - The test error to show, if it goes wrong
334 class InstallRequirements
{
335 var $errors, $warnings, $tests;
337 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
338 const MINIMUM_THREAD_STACK
= 192;
341 * Just check that the database configuration is okay.
342 * @param $databaseConfig
345 public function checkdatabase($databaseConfig, $dbName) {
346 if ($this->requireFunction('mysql_connect',
348 ts("PHP Configuration"),
350 ts("MySQL support not included in PHP."),
354 $this->requireMySQLServer($databaseConfig['server'],
356 ts("MySQL %1 Configuration", array(1 => $dbName)),
357 ts("Does the server exist?"),
358 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
359 $databaseConfig['server'],
362 if ($this->requireMysqlConnection($databaseConfig['server'],
363 $databaseConfig['username'],
364 $databaseConfig['password'],
366 ts("MySQL %1 Configuration", array(1 => $dbName)),
367 ts("Are the access credentials correct?"),
368 ts("That username/password doesn't work"),
372 @$this->requireMySQLVersion("5.1",
374 ts("MySQL %1 Configuration", array(1 => $dbName)),
375 ts("MySQL version at least %1", array(1 => '5.1')),
376 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
377 ts("MySQL %1", array(1 => mysql_get_server_info())),
380 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
381 $databaseConfig['username'],
382 $databaseConfig['password'],
384 ts("MySQL %1 Configuration", array(1 => $dbName)),
385 ts("Is auto_increment_increment set to 1"),
386 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
389 $this->requireMySQLThreadStack($databaseConfig['server'],
390 $databaseConfig['username'],
391 $databaseConfig['password'],
392 $databaseConfig['database'],
393 self
::MINIMUM_THREAD_STACK
,
395 ts("MySQL %1 Configuration", array(1 => $dbName)),
396 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self
::MINIMUM_THREAD_STACK
)),
398 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
402 $onlyRequire = ($dbName == 'Drupal') ?
TRUE : FALSE;
403 $this->requireDatabaseOrCreatePermissions(
404 $databaseConfig['server'],
405 $databaseConfig['username'],
406 $databaseConfig['password'],
407 $databaseConfig['database'],
409 ts("MySQL %1 Configuration", array(1 => $dbName)),
410 ts("Can I access/create the database?"),
411 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
415 if ($dbName != 'Drupal') {
416 $this->requireMySQLInnoDB($databaseConfig['server'],
417 $databaseConfig['username'],
418 $databaseConfig['password'],
419 $databaseConfig['database'],
421 ts("MySQL %1 Configuration", array(1 => $dbName)),
422 ts("Can I access/create InnoDB tables in the database?"),
423 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."),
426 $this->requireMySQLTempTables($databaseConfig['server'],
427 $databaseConfig['username'],
428 $databaseConfig['password'],
429 $databaseConfig['database'],
431 ts("MySQL %1 Configuration", array(1 => $dbName)),
432 ts('Can I create temporary tables in the database?'),
433 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
436 $this->requireMySQLLockTables($databaseConfig['server'],
437 $databaseConfig['username'],
438 $databaseConfig['password'],
439 $databaseConfig['database'],
441 ts("MySQL %1 Configuration", array(1 => $dbName)),
442 ts('Can I create lock tables in the database?'),
443 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
446 $this->requireMySQLTrigger($databaseConfig['server'],
447 $databaseConfig['username'],
448 $databaseConfig['password'],
449 $databaseConfig['database'],
451 ts("MySQL %1 Configuration", array(1 => $dbName)),
452 ts('Can I create triggers in the database?'),
453 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
461 * Check everything except the database.
463 public function check() {
464 global $crmPath, $installType;
466 $this->errors
= NULL;
468 $this->requirePHPVersion('5.3.4', array(
469 ts("PHP Configuration"),
470 ts("PHP5 installed"),
472 ts("PHP version %1", array(1 => phpversion())),
475 // Check that we can identify the root folder successfully
476 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. 'README.txt',
478 ts("File permissions"),
479 ts("Does the webserver know where files are stored?"),
480 ts("The webserver isn't letting me identify where files are stored."),
486 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
487 $this->requireNoPathSeparator(
489 ts("File permissions"),
490 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
491 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR
)),
496 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
497 foreach ($requiredDirectories as $dir) {
498 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR
. $dir,
500 ts("File permissions"),
501 ts("Folder '%1' exists?", array(1 => $dir)),
502 ts("There is no '%1' folder.", array(1 => $dir)),
507 $configIDSiniDir = NULL;
509 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
510 if ($installType == 'drupal') {
512 // make sure that we can write to sites/default and files/
513 $writableDirectories = array(
514 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
515 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
516 $siteDir . CIVICRM_DIRECTORY_SEPARATOR
.
518 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
519 'sites' . CIVICRM_DIRECTORY_SEPARATOR
.
523 elseif ($installType == 'wordpress') {
524 // make sure that we can write to uploads/civicrm/
525 $upload_dir = wp_upload_dir();
526 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR
. 'civicrm';
527 if (!file_exists($files_dirname)) {
528 wp_mkdir_p($files_dirname);
530 $writableDirectories = array($files_dirname);
533 foreach ($writableDirectories as $dir) {
534 $dirName = CIVICRM_WINDOWS ?
$dir : CIVICRM_DIRECTORY_SEPARATOR
. $dir;
535 $testDetails = array(
536 ts("File permissions"),
537 ts("Is the %1 folder writeable?", array(1 => $dir)),
540 $this->requireWriteable($dirName, $testDetails, TRUE);
543 //check for Config.IDS.ini, file may exist in re-install
544 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
546 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
547 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR
, $configIDSiniDir);
548 if (file_exists($configIDSiniFile)) {
549 unlink($configIDSiniFile);
553 // Check for rewriting
554 if (isset($_SERVER['SERVER_SOFTWARE'])) {
555 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
557 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
558 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
561 if ($webserver == '') {
562 $webserver = ts("I can't tell what webserver you are running");
565 // Check for $_SERVER configuration
566 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
567 ts("Webserver config"),
568 ts("Recognised webserver"),
569 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
572 // Check for MySQL support
573 $this->requireFunction('mysql_connect', array(
574 ts("PHP Configuration"),
576 ts("MySQL support not included in PHP."),
579 // Check for JSON support
580 $this->requireFunction('json_encode', array(
581 ts("PHP Configuration"),
583 ts("JSON support not included in PHP."),
586 // Check for xcache_isset and emit warning if exists
587 $this->checkXCache(array(
588 ts("PHP Configuration"),
589 ts("XCache compatibility"),
590 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."),
593 // Check memory allocation
594 $this->requireMemory(32 * 1024 * 1024,
597 ts("PHP Configuration"),
598 ts("Memory allocated (PHP config option 'memory_limit')"),
599 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
600 ini_get("memory_limit"),
604 return $this->errors
;
609 * @param $recommended
610 * @param $testDetails
612 public function requireMemory($min, $recommended, $testDetails) {
613 $this->testing($testDetails);
614 $mem = $this->getPHPMemory();
616 if ($mem < $min && $mem > 0) {
617 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
618 $this->error($testDetails);
620 elseif ($mem < $recommended && $mem > 0) {
621 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
622 $this->warning($testDetails);
625 $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));
626 $this->warning($testDetails);
633 public function getPHPMemory() {
634 $memString = ini_get("memory_limit");
636 switch (strtolower(substr($memString, -1))) {
638 return round(substr($memString, 0, -1) * 1024);
641 return round(substr($memString, 0, -1) * 1024 * 1024);
644 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
647 return round($memString);
651 public function listErrors() {
653 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
654 foreach ($this->errors
as $error) {
655 echo "<li>" . htmlentities($error) . "</li>";
661 * @param null $section
663 public function showTable($section = NULL) {
665 $tests = $this->tests
[$section];
666 echo "<table class=\"testResults\" width=\"100%\">";
667 foreach ($tests as $test => $result) {
668 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
673 foreach ($this->tests
as $section => $tests) {
674 echo "<h3>$section</h3>";
675 echo "<table class=\"testResults\" width=\"100%\">";
677 foreach ($tests as $test => $result) {
678 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
686 * @param string $funcName
687 * @param $testDetails
691 public function requireFunction($funcName, $testDetails) {
692 $this->testing($testDetails);
694 if (!function_exists($funcName)) {
695 $this->error($testDetails);
704 * @param $testDetails
706 public function checkXCache($testDetails) {
707 if (function_exists('xcache_isset') &&
708 ini_get('xcache.size') > 0
710 $this->testing($testDetails);
711 $this->warning($testDetails);
717 * @param $testDetails
718 * @param null $maxVersion
720 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
722 $this->testing($testDetails);
724 $phpVersion = phpversion();
725 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
726 $belowMaxVersion = $maxVersion ?
version_compare($phpVersion, $maxVersion) < 0 : TRUE;
728 if ($maxVersion && $aboveMinVersion && $belowMaxVersion) {
731 elseif (!$maxVersion && $aboveMinVersion) {
735 if (!$testDetails[2]) {
736 if (!$aboveMinVersion) {
737 $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));
740 $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));
744 $this->error($testDetails);
748 * @param string $filename
749 * @param $testDetails
750 * @param bool $absolute
752 public function requireFile($filename, $testDetails, $absolute = FALSE) {
753 $this->testing($testDetails);
755 $filename = $this->getBaseDir() . $filename;
757 if (!file_exists($filename)) {
758 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
759 $this->error($testDetails);
764 * @param $testDetails
766 public function requireNoPathSeparator($testDetails) {
767 $this->testing($testDetails);
768 if (substr_count($this->getBaseDir(), PATH_SEPARATOR
)) {
769 $this->error($testDetails);
774 * @param string $filename
775 * @param $testDetails
777 public function requireNoFile($filename, $testDetails) {
778 $this->testing($testDetails);
779 $filename = $this->getBaseDir() . $filename;
780 if (file_exists($filename)) {
781 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
782 $this->error($testDetails);
787 * @param string $filename
788 * @param $testDetails
790 public function moveFileOutOfTheWay($filename, $testDetails) {
791 $this->testing($testDetails);
792 $filename = $this->getBaseDir() . $filename;
793 if (file_exists($filename)) {
794 if (file_exists("$filename.bak")) {
797 rename($filename, "$filename.bak");
802 * @param string $filename
803 * @param $testDetails
804 * @param bool $absolute
806 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
807 $this->testing($testDetails);
809 $filename = $this->getBaseDir() . $filename;
812 if (!is_writable($filename)) {
814 if (function_exists('posix_getpwuid')) {
815 $user = posix_getpwuid(posix_geteuid());
816 $name = '- ' . $user['name'] . ' -';
819 if (!isset($testDetails[2])) {
820 $testDetails[2] = NULL;
822 $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";
823 $this->error($testDetails);
828 * @param string $moduleName
829 * @param $testDetails
831 public function requireApacheModule($moduleName, $testDetails) {
832 $this->testing($testDetails);
833 if (!in_array($moduleName, apache_get_modules())) {
834 $this->error($testDetails);
840 * @param string $username
842 * @param $testDetails
844 public function requireMysqlConnection($server, $username, $password, $testDetails) {
845 $this->testing($testDetails);
846 $conn = @mysql_connect
($server, $username, $password);
852 $testDetails[2] .= ": " . mysql_error();
853 $this->error($testDetails);
859 * @param $testDetails
861 public function requireMySQLServer($server, $testDetails) {
862 $this->testing($testDetails);
863 $conn = @mysql_connect
($server, NULL, NULL);
865 if ($conn ||
mysql_errno() < 2000) {
869 $testDetails[2] .= ": " . mysql_error();
870 $this->error($testDetails);
876 * @param $testDetails
878 public function requireMySQLVersion($version, $testDetails) {
879 $this->testing($testDetails);
881 if (!mysql_get_server_info()) {
882 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
883 $this->warning($testDetails);
886 list($majorRequested, $minorRequested) = explode('.', $version);
887 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
889 if (($majorHas > $majorRequested) ||
($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
893 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
894 $this->error($testDetails);
901 * @param string $username
904 * @param $testDetails
906 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
907 $this->testing($testDetails);
908 $conn = @mysql_connect
($server, $username, $password);
910 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
911 $this->error($testDetails);
915 $innodb_support = FALSE;
916 $result = mysql_query("SHOW ENGINES", $conn);
917 while ($values = mysql_fetch_array($result)) {
918 if ($values['Engine'] == 'InnoDB') {
919 if (strtolower($values['Support']) == 'yes' ||
920 strtolower($values['Support']) == 'default'
922 $innodb_support = TRUE;
926 if ($innodb_support) {
927 $testDetails[3] = ts('MySQL server does have InnoDB support');
930 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
936 * @param string $username
939 * @param $testDetails
941 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
942 $this->testing($testDetails);
943 $conn = @mysql_connect
($server, $username, $password);
945 $testDetails[2] = ts('Could not login to the database.');
946 $this->error($testDetails);
950 if (!@mysql_select_db
($database, $conn)) {
951 $testDetails[2] = ts('Could not select the database.');
952 $this->error($testDetails);
956 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
958 $testDetails[2] = ts('Could not create a temp table.');
959 $this->error($testDetails);
961 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
966 * @param string $username
969 * @param $testDetails
971 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
972 $this->testing($testDetails);
973 $conn = @mysql_connect
($server, $username, $password);
975 $testDetails[2] = ts('Could not login to the database.');
976 $this->error($testDetails);
980 if (!@mysql_select_db
($database, $conn)) {
981 $testDetails[2] = ts('Could not select the database.');
982 $this->error($testDetails);
986 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
988 $testDetails[2] = ts('Could not create a table in the database.');
989 $this->error($testDetails);
992 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
994 mysql_query('DROP TABLE civicrm_install_temp_table_test');
995 $testDetails[2] = ts('Could not create a database trigger.');
996 $this->error($testDetails);
999 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
1000 mysql_query('DROP TABLE civicrm_install_temp_table_test');
1006 * @param string $username
1009 * @param $testDetails
1011 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
1012 $this->testing($testDetails);
1013 $conn = @mysql_connect
($server, $username, $password);
1015 $testDetails[2] = ts('Could not connect to the database server.');
1016 $this->error($testDetails);
1020 if (!@mysql_select_db
($database, $conn)) {
1021 $testDetails[2] = ts('Could not select the database.');
1022 $this->error($testDetails);
1026 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1028 $testDetails[2] = ts('Could not create a table in the database.');
1029 $this->error($testDetails);
1033 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1035 $testDetails[2] = ts('Could not obtain a write lock for the database table.');
1036 $this->error($testDetails);
1037 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1041 $result = mysql_query('UNLOCK TABLES', $conn);
1043 $testDetails[2] = ts('Could not release the lock for the database table.');
1044 $this->error($testDetails);
1045 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1049 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1054 * @param string $username
1056 * @param $testDetails
1058 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
1059 $this->testing($testDetails);
1060 $conn = @mysql_connect
($server, $username, $password);
1062 $testDetails[2] = ts('Could not connect to the database server.');
1063 $this->error($testDetails);
1067 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1069 $testDetails[2] = ts('Could not query database server variables.');
1070 $this->error($testDetails);
1074 $values = mysql_fetch_row($result);
1075 if ($values[1] == 1) {
1076 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
1079 $this->error($testDetails);
1086 * @param string $username
1089 * @param $minValueKB
1090 * @param $testDetails
1092 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1093 $this->testing($testDetails);
1094 $conn = @mysql_connect
($server, $username, $password);
1096 $testDetails[2] = ts('Could not connect to the database server.');
1097 $this->error($testDetails);
1101 if (!@mysql_select_db
($database, $conn)) {
1102 $testDetails[2] = ts('Could not select the database.');
1103 $this->error($testDetails);
1107 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1109 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
1110 $this->error($testDetails);
1113 $values = mysql_fetch_row($result);
1114 if ($values[1] < (1024 * $minValueKB)) {
1115 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
1116 $this->error($testDetails);
1123 * @param string $username
1126 * @param $testDetails
1127 * @param bool $onlyRequire
1129 public function requireDatabaseOrCreatePermissions(
1135 $onlyRequire = FALSE
1137 $this->testing($testDetails);
1138 $conn = @mysql_connect
($server, $username, $password);
1141 if (@mysql_select_db
($database)) {
1142 $okay = "Database '$database' exists";
1144 elseif ($onlyRequire) {
1145 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
1146 $this->error($testDetails);
1150 if (@mysql_query
("CREATE DATABASE $database")) {
1151 $okay = ts("Able to create a new database.");
1154 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
1155 $this->error($testDetails);
1161 $testDetails[3] = $okay;
1162 $this->testing($testDetails);
1168 * @param $errorMessage
1170 public function requireServerVariables($varNames, $errorMessage) {
1171 //$this->testing($testDetails);
1172 foreach ($varNames as $varName) {
1173 if (!$_SERVER[$varName]) {
1174 $missing[] = '$_SERVER[' . $varName . ']';
1177 if (!isset($missing)) {
1181 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
1182 $this->error($testDetails);
1187 * @param $testDetails
1191 public function isRunningApache($testDetails) {
1192 $this->testing($testDetails);
1193 if (function_exists('apache_get_modules') ||
stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1197 $this->warning($testDetails);
1204 public function getBaseDir() {
1205 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR
;
1209 * @param $testDetails
1211 public function testing($testDetails) {
1212 if (!$testDetails) {
1216 $section = $testDetails[0];
1217 $test = $testDetails[1];
1219 $message = ts("OK");
1220 if (isset($testDetails[3])) {
1221 $message .= " ($testDetails[3])";
1224 $this->tests
[$section][$test] = array("good", $message);
1228 * @param $testDetails
1230 public function error($testDetails) {
1231 $section = $testDetails[0];
1232 $test = $testDetails[1];
1234 $this->tests
[$section][$test] = array("error", $testDetails[2]);
1235 $this->errors
[] = $testDetails;
1239 * @param $testDetails
1241 public function warning($testDetails) {
1242 $section = $testDetails[0];
1243 $test = $testDetails[1];
1245 $this->tests
[$section][$test] = array("warning", $testDetails[2]);
1246 $this->warnings
[] = $testDetails;
1252 public function hasErrors() {
1253 return count($this->errors
);
1259 public function hasWarnings() {
1260 return count($this->warnings
);
1268 class Installer
extends InstallRequirements
{
1275 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1276 $conn = @mysql_connect
($server, $username, $password);
1278 if (@mysql_select_db
($database)) {
1279 // skip if database already present
1283 if (@mysql_query
("CREATE DATABASE $database")) {
1286 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1287 $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.");
1288 errorDisplayPage($errorTitle, $errorMsg);
1297 public function install($config) {
1298 global $installDirPath;
1300 // create database if does not exists
1301 $this->createDatabaseIfNotExists($config['mysql']['server'],
1302 $config['mysql']['username'],
1303 $config['mysql']['password'],
1304 $config['mysql']['database']
1307 global $installDirPath;
1310 require_once $installDirPath . 'civicrm.php';
1311 civicrm_main($config);
1313 if (!$this->errors
) {
1314 global $installType, $installURLPath;
1316 $registerSiteURL = "https://civicrm.org/register-site";
1317 $commonOutputMessage
1318 = "<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>"
1319 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
1324 $installType == 'drupal' &&
1325 version_compare(VERSION
, '7.0-rc1') >= 0
1331 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1332 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1333 $output .= '<head>';
1334 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1335 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1336 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1337 $output .= '</head>';
1338 $output .= '<body>';
1339 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1342 $drupalURL = civicrm_cms_base();
1343 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1344 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1346 $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>";
1347 $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>";
1348 $output .= $commonOutputMessage;
1350 // automatically enable CiviCRM module once it is installed successfully.
1351 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1352 global $cmsPath, $crmPath;
1354 // relative / abosolute paths are not working for drupal, hence using chdir()
1357 // Force the re-initialisation of the config singleton on the next call
1358 // since so far, we had used the Config object without loading the DB.
1359 $c = CRM_Core_Config
::singleton(FALSE);
1362 include_once "./includes/bootstrap.inc";
1363 include_once "./includes/unicode.inc";
1365 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1367 // prevent session information from being saved.
1368 drupal_save_session(FALSE);
1370 // Force the current user to anonymous.
1371 $original_user = $GLOBALS['user'];
1372 $GLOBALS['user'] = drupal_anonymous_user();
1374 // explicitly setting error reporting, since we cannot handle drupal related notices
1377 // rebuild modules, so that civicrm is added
1378 system_rebuild_module_data();
1380 // now enable civicrm module.
1381 module_enable(array('civicrm', 'civicrmtheme'));
1383 // clear block, page, theme, and hook caches
1384 drupal_flush_all_caches();
1386 //add basic drupal permissions
1387 civicrm_install_set_drupal_perms();
1389 // restore the user.
1390 $GLOBALS['user'] = $original_user;
1391 drupal_save_session(TRUE);
1393 //change the default language to one chosen
1394 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1395 // This ensures that defaults get set, otherwise the user will login
1396 // and most configurations will be empty, not set to en_US defaults.
1397 civicrm_api3('Setting', 'revert');
1399 civicrm_api3('Setting', 'create', array(
1400 'domain_id' => 'current_domain',
1401 'lcMessages' => $config['seedLanguage'],
1407 $output .= '</div>';
1408 $output .= '</body>';
1409 $output .= '</html>';
1412 elseif ($installType == 'drupal' && version_compare(VERSION
, '6.0') >= 0) {
1416 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1417 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1418 $output .= '<head>';
1419 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1420 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1421 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1422 $output .= '</head>';
1423 $output .= '<body>';
1424 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
1427 $drupalURL = civicrm_cms_base();
1428 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1429 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1431 $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>";
1432 $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>";
1433 $output .= $commonOutputMessage;
1435 // explicitly setting error reporting, since we cannot handle drupal related notices
1438 // automatically enable CiviCRM module once it is installed successfully.
1439 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1440 global $cmsPath, $crmPath;
1442 // relative / abosolute paths are not working for drupal, hence using chdir()
1445 // Force the re-initialisation of the config singleton on the next call
1446 // since so far, we had used the Config object without loading the DB.
1447 $c = CRM_Core_Config
::singleton(FALSE);
1450 include_once "./includes/bootstrap.inc";
1451 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL
);
1453 // rebuild modules, so that civicrm is added
1454 module_rebuild_cache();
1456 // now enable civicrm module.
1457 module_enable(array('civicrm'));
1459 // clear block, page, theme, and hook caches
1460 drupal_flush_all_caches();
1462 //add basic drupal permissions
1463 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)');
1467 elseif ($installType == 'wordpress') {
1468 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
1469 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
1472 $cmsURL = civicrm_cms_base();
1473 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1474 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1476 $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>";
1477 $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>";
1478 $output .= $commonOutputMessage;
1483 $c = CRM_Core_Config
::singleton(FALSE);
1485 $wpInstallRedirect = admin_url("?page=CiviCRM&q=civicrm&reset=1");
1487 window.location = '$wpInstallRedirect';
1492 return $this->errors
;
1497 function civicrm_install_set_drupal_perms() {
1498 if (!function_exists('db_select')) {
1499 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)');
1503 'access all custom data',
1504 'access uploaded files',
1505 'make online contributions',
1509 'register for events',
1511 'view event participants',
1512 'access CiviMail subscribe/unsubscribe pages',
1515 // Adding a permission that has not yet been assigned to a module by
1516 // a hook_permission implementation results in a database error.
1518 $allPerms = array_keys(module_invoke_all('permission'));
1519 foreach (array_diff($perms, $allPerms) as $perm) {
1521 'Cannot grant the %perm permission because it does not yet exist.',
1522 array('%perm' => $perm),
1526 $perms = array_intersect($perms, $allPerms);
1527 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID
, $perms);
1528 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID
, $perms);
1538 function getSiteDir($cmsPath, $str) {
1539 static $siteDir = '';
1545 $sites = CIVICRM_DIRECTORY_SEPARATOR
. 'sites' . CIVICRM_DIRECTORY_SEPARATOR
;
1546 $modules = CIVICRM_DIRECTORY_SEPARATOR
. 'modules' . CIVICRM_DIRECTORY_SEPARATOR
;
1547 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR
) .
1548 "([\-a-zA-Z0-9_.]+)" .
1549 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR
) . "/",
1550 $_SERVER['SCRIPT_FILENAME'], $matches
1552 $siteDir = isset($matches[1]) ?
$matches[1] : 'default';
1554 if (strtolower($siteDir) == 'all') {
1555 // For this case - use drupal's way of finding out multi-site directory
1556 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR
, $_SERVER['SCRIPT_FILENAME']);
1557 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1558 for ($i = count($uri) - 1; $i > 0; $i--) {
1559 for ($j = count($server); $j > 0; $j--) {
1560 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1561 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR
.
1562 'sites' . CIVICRM_DIRECTORY_SEPARATOR
. $dir
1569 $siteDir = 'default';
1576 * @param $errorTitle
1580 function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1582 $docLink = CRM_Utils_System
::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1584 if (function_exists('ts')) {
1585 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1588 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1592 include 'error.html';