Merge remote-tracking branch 'origin/4.5' into 4.5-master-2015-02-24-17-24-05
[civicrm-core.git] / install / index.php
1 <?php
2
3 /**
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/. Please check
7 * http://www.silverstripe.com/licensing for licensing details.
8 *
9 * Copyright (c) 2006-7, SilverStripe Limited - www.silverstripe.com
10 * All rights reserved.
11 *
12 * Changes and modifications (c) 2007-8 by CiviCRM LLC
13 *
14 */
15
16 /**
17 * CiviCRM Installer
18 */
19
20 ini_set('max_execution_time', 3000);
21
22 if (stristr(PHP_OS, 'WIN')) {
23 define('CIVICRM_DIRECTORY_SEPARATOR', '/');
24 define('CIVICRM_WINDOWS', 1);
25 }
26 else {
27 define('CIVICRM_DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR);
28 define('CIVICRM_WINDOWS', 0);
29 }
30
31 // set installation type - drupal
32 if (!session_id()) {
33 session_start();
34 }
35
36 // unset civicrm session if any
37 if (array_key_exists('CiviCRM', $_SESSION)) {
38 unset($_SESSION['CiviCRM']);
39 }
40
41 if (isset($_GET['civicrm_install_type'])) {
42 $_SESSION['civicrm_install_type'] = $_GET['civicrm_install_type'];
43 }
44 else {
45 if (!isset($_SESSION['civicrm_install_type'])) {
46 $_SESSION['civicrm_install_type'] = "drupal";
47 }
48 }
49
50 global $installType;
51 $installType = strtolower($_SESSION['civicrm_install_type']);
52
53 if (!in_array($installType, array('drupal', 'wordpress'))) {
54 $errorTitle = "Oops! Unsupported installation mode";
55 $errorMsg = "";
56 errorDisplayPage($errorTitle, $errorMsg);
57 }
58
59 global $crmPath;
60 global $installDirPath;
61 global $installURLPath;
62 if ($installType == 'drupal') {
63 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
64 $installDirPath = $installURLPath = '';
65 }
66 elseif ($installType == 'wordpress') {
67 $crmPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR;
68 $installDirPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
69
70 $installURLPath = WP_PLUGIN_URL . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
71 }
72
73 set_include_path(get_include_path() . PATH_SEPARATOR . $crmPath);
74
75 require_once $crmPath . '/CRM/Core/ClassLoader.php';
76 CRM_Core_ClassLoader::singleton()->register();
77
78 $docLink = CRM_Utils_System::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
79
80 if ($installType == 'drupal') {
81 //lets check only /modules/.
82 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR . 'modules', CIVICRM_DIRECTORY_SEPARATOR) . '/';
83
84 if (!preg_match($pattern,
85 str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME'])
86 )
87 ) {
88 $errorTitle = "Oops! Please Correct Your Install Location";
89 $errorMsg = "Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>" . implode(CIVICRM_DIRECTORY_SEPARATOR, array(
90 'sites',
91 'all',
92 'modules',
93 )) . "</strong> directory below your Drupal root directory. Refer to the online " . $docLink . " for more information.";
94 errorDisplayPage($errorTitle, $errorMsg);
95 }
96 }
97
98 // Load civicrm database config
99 if (isset($_REQUEST['mysql'])) {
100 $databaseConfig = $_REQUEST['mysql'];
101 }
102 else {
103 $databaseConfig = array(
104 "server" => "localhost",
105 "username" => "civicrm",
106 "password" => "",
107 "database" => "civicrm",
108 );
109 }
110
111 if ($installType == 'drupal') {
112 // Load drupal database config
113 if (isset($_REQUEST['drupal'])) {
114 $drupalConfig = $_REQUEST['drupal'];
115 }
116 else {
117 $drupalConfig = array(
118 "server" => "localhost",
119 "username" => "drupal",
120 "password" => "",
121 "database" => "drupal",
122 );
123 }
124 }
125
126 $loadGenerated = 0;
127 if (isset($_REQUEST['loadGenerated'])) {
128 $loadGenerated = 1;
129 }
130
131 require_once dirname(__FILE__) . CIVICRM_DIRECTORY_SEPARATOR . 'langs.php';
132 foreach ($langs as $locale => $_) {
133 if ($locale == 'en_US') {
134 continue;
135 }
136 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
137 unset($langs[$locale]);
138 }
139 }
140
141 $seedLanguage = 'en_US';
142 if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
143 $seedLanguage = $_REQUEST['seedLanguage'];
144 }
145
146 global $cmsPath;
147 if ($installType == 'drupal') {
148 //CRM-6840 -don't force to install in sites/all/modules/
149 $object = new CRM_Utils_System_Drupal();
150 $cmsPath = $object->cmsRootPath();
151
152 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
153 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
154 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
155 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
156 'civicrm.settings.php'
157 );
158 }
159 elseif ($installType == 'wordpress') {
160 $cmsPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm';
161 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
162 'civicrm.settings.php'
163 );
164 }
165
166 // Exit with error if CiviCRM has already been installed.
167 if ($alreadyInstalled) {
168 $errorTitle = "Oops! CiviCRM is Already Installed";
169 if ($installType == 'drupal') {
170
171 $errorMsg = "CiviCRM has already been installed in this Drupal site. <ul><li>To <strong>start over</strong>, you must delete or rename the existing CiviCRM settings file - <strong>civicrm.settings.php</strong> - from <strong>" . implode(CIVICRM_DIRECTORY_SEPARATOR, array(
172 '[your Drupal root directory]',
173 'sites',
174 $siteDir,
175 )) . "</strong>.</li><li>To <strong>upgrade an existing installation</strong>, refer to the online " . $docLink . ".</li></ul>";
176 }
177 elseif ($installType == 'wordpress') {
178 $errorMsg = "CiviCRM has already been installed in this WordPress site. <ul><li>To <strong>start over</strong>, you must delete or rename the existing CiviCRM settings file - <strong>civicrm.settings.php</strong> - from <strong>" . $cmsPath . "</strong>.</li><li>To <strong>upgrade an existing installation</strong>, refer to the online " . $docLink . ".</li></ul>";
179 }
180 errorDisplayPage($errorTitle, $errorMsg);
181 }
182
183 $versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'civicrm-version.php';
184 if (file_exists($versionFile)) {
185 require_once $versionFile;
186 $civicrm_version = civicrmVersion();
187 }
188 else {
189 $civicrm_version = 'unknown';
190 }
191
192 if ($installType == 'drupal') {
193 // Ensure that they have downloaded the correct version of CiviCRM
194 if ($civicrm_version['cms'] != 'Drupal' &&
195 $civicrm_version['cms'] != 'Drupal6'
196 ) {
197 $errorTitle = "Oops! Incorrect CiviCRM Version";
198 $errorMsg = "This installer can only be used for the Drupal version of CiviCRM. Refer to the online " . $docLink . " for information about installing CiviCRM on PHP4 servers OR installing CiviCRM for Joomla!";
199 errorDisplayPage($errorTitle, $errorMsg);
200 }
201
202 define('DRUPAL_ROOT', $cmsPath);
203 $drupalVersionFiles = array(
204 // D6
205 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'modules', 'system', 'system.module')),
206 // D7
207 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'includes', 'bootstrap.inc')),
208 );
209 foreach ($drupalVersionFiles as $drupalVersionFile) {
210 if (file_exists($drupalVersionFile)) {
211 require_once $drupalVersionFile;
212 }
213 }
214
215 if (!defined('VERSION') or version_compare(VERSION, '6.0') < 0) {
216 $errorTitle = "Oops! Incorrect Drupal Version";
217 $errorMsg = "This version of CiviCRM can only be used with Drupal 6.x or 7.x. Please ensure that '" . implode("' or '", $drupalVersionFiles) . "' exists if you are running Drupal 7.0 and over. Refer to the online " . $docLink . " for information about installing CiviCRM.";
218 errorDisplayPage($errorTitle, $errorMsg);
219 }
220 }
221 elseif ($installType == 'wordpress') {
222 //HACK for now
223 $civicrm_version['cms'] = 'WordPress';
224
225 // Ensure that they have downloaded the correct version of CiviCRM
226 if ($civicrm_version['cms'] != 'WordPress') {
227 $errorTitle = "Oops! Incorrect CiviCRM Version";
228 $errorMsg = "This installer can only be used for the WordPress version of CiviCRM. Refer to the online " . $docLink . " for information about installing CiviCRM for Drupal or Joomla!";
229 errorDisplayPage($errorTitle, $errorMsg);
230 }
231 }
232
233 // Check requirements
234 $req = new InstallRequirements();
235 $req->check();
236
237 if ($req->hasErrors()) {
238 $hasErrorOtherThanDatabase = TRUE;
239 }
240
241 if ($databaseConfig) {
242 $dbReq = new InstallRequirements();
243 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
244 if ($installType == 'drupal') {
245 $dbReq->checkdatabase($drupalConfig, 'Drupal');
246 }
247 }
248
249 // Actual processor
250 if (isset($_REQUEST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
251 // Confirm before reinstalling
252 if (!isset($_REQUEST['force_reinstall']) && $alreadyInstalled) {
253 include $installDirPath . 'template.html';
254 }
255 else {
256 $inst = new Installer();
257 $inst->install($_REQUEST);
258 }
259
260 // Show the config form
261 }
262 else {
263 include $installDirPath . 'template.html';
264 }
265
266 /**
267 * This class checks requirements
268 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
269 * of 3 parts:
270 * $description[0] - The test catetgory
271 * $description[1] - The test title
272 * $description[2] - The test error to show, if it goes wrong
273 */
274 class InstallRequirements {
275 var $errors, $warnings, $tests;
276
277 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
278 const MINIMUM_THREAD_STACK = 192;
279
280 /**
281 * Just check that the database configuration is okay.
282 * @param $databaseConfig
283 * @param $dbName
284 */
285 public function checkdatabase($databaseConfig, $dbName) {
286 if ($this->requireFunction('mysql_connect',
287 array(
288 "PHP Configuration",
289 "MySQL support",
290 "MySQL support not included in PHP.",
291 )
292 )
293 ) {
294 $this->requireMySQLServer($databaseConfig['server'],
295 array(
296 "MySQL $dbName Configuration",
297 "Does the server exist",
298 "Can't find the a MySQL server on '$databaseConfig[server]'",
299 $databaseConfig['server'],
300 )
301 );
302 if ($this->requireMysqlConnection($databaseConfig['server'],
303 $databaseConfig['username'],
304 $databaseConfig['password'],
305 array(
306 "MySQL $dbName Configuration",
307 "Are the access credentials correct",
308 "That username/password doesn't work",
309 )
310 )
311 ) {
312 @$this->requireMySQLVersion("5.1",
313 array(
314 "MySQL $dbName Configuration",
315 "MySQL version at least 5.1",
316 "MySQL version 5.1 or higher is required, you only have ",
317 "MySQL " . mysql_get_server_info(),
318 )
319 );
320 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
321 $databaseConfig['username'],
322 $databaseConfig['password'],
323 array(
324 "MySQL $dbName Configuration",
325 "Is auto_increment_increment set to 1",
326 "An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround.",
327 )
328 );
329 $this->requireMySQLThreadStack($databaseConfig['server'],
330 $databaseConfig['username'],
331 $databaseConfig['password'],
332 $databaseConfig['database'],
333 self::MINIMUM_THREAD_STACK,
334 array(
335 "MySQL $dbName Configuration",
336 "Does MySQL thread_stack meet minimum (" . self::MINIMUM_THREAD_STACK . "k)",
337 "",
338 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
339 )
340 );
341 }
342 $onlyRequire = ($dbName == 'Drupal') ? TRUE : FALSE;
343 $this->requireDatabaseOrCreatePermissions(
344 $databaseConfig['server'],
345 $databaseConfig['username'],
346 $databaseConfig['password'],
347 $databaseConfig['database'],
348 array(
349 "MySQL $dbName Configuration",
350 "Can I access/create the database",
351 "I can't create new databases and the database '$databaseConfig[database]' doesn't exist",
352 ),
353 $onlyRequire
354 );
355 if ($dbName != 'Drupal') {
356 $this->requireMySQLInnoDB($databaseConfig['server'],
357 $databaseConfig['username'],
358 $databaseConfig['password'],
359 $databaseConfig['database'],
360 array(
361 "MySQL $dbName Configuration",
362 "Can I access/create InnoDB tables in the database",
363 "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.",
364 )
365 );
366 $this->requireMySQLTempTables($databaseConfig['server'],
367 $databaseConfig['username'],
368 $databaseConfig['password'],
369 $databaseConfig['database'],
370 array(
371 "MySQL $dbName Configuration",
372 'Can I create temporary tables in the database',
373 'Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.',
374 )
375 );
376 $this->requireMySQLLockTables($databaseConfig['server'],
377 $databaseConfig['username'],
378 $databaseConfig['password'],
379 $databaseConfig['database'],
380 array(
381 "MySQL $dbName Configuration",
382 'Can I create lock tables in the database',
383 'Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.',
384 )
385 );
386 $this->requireMySQLTrigger($databaseConfig['server'],
387 $databaseConfig['username'],
388 $databaseConfig['password'],
389 $databaseConfig['database'],
390 array(
391 "MySQL $dbName Configuration",
392 'Can I create triggers in the database',
393 'Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.',
394 )
395 );
396 }
397 }
398 }
399
400 /**
401 * Check everything except the database.
402 */
403 public function check() {
404 global $crmPath, $installType;
405
406 $this->errors = NULL;
407
408 $this->requirePHPVersion('5.3.3', array(
409 "PHP Configuration",
410 "PHP5 installed",
411 NULL,
412 "PHP version " . phpversion(),
413 ));
414
415 // Check that we can identify the root folder successfully
416 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'README.txt',
417 array(
418 "File permissions",
419 "Does the webserver know where files are stored?",
420 "The webserver isn't letting me identify where files are stored.",
421 $this->getBaseDir(),
422 ),
423 TRUE
424 );
425
426 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
427 $this->requireNoPathSeparator(
428 array(
429 'File permissions',
430 'does the CiviCRM path contain PATH_SEPARATOR?',
431 'the ' . $this->getBaseDir() . ' path contains PATH_SEPARATOR (the ' . PATH_SEPARATOR . ' character)',
432 $this->getBaseDir(),
433 )
434 );
435
436 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
437 foreach ($requiredDirectories as $dir) {
438 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . $dir,
439 array(
440 "File permissions",
441 "$dir folder exists",
442 "There is no $dir folder",
443 ), TRUE
444 );
445 }
446
447 $configIDSiniDir = NULL;
448 global $cmsPath;
449 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
450 if ($installType == 'drupal') {
451
452 // make sure that we can write to sites/default and files/
453 $writableDirectories = array(
454 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
455 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
456 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
457 'files',
458 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
459 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
460 $siteDir,
461 );
462 }
463 elseif ($installType == 'wordpress') {
464 // make sure that we can write to plugins/civicrm and plugins/files/
465 $writableDirectories = array(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'files', $cmsPath);
466 }
467
468 foreach ($writableDirectories as $dir) {
469 $dirName = CIVICRM_WINDOWS ? $dir : CIVICRM_DIRECTORY_SEPARATOR . $dir;
470 $this->requireWriteable($dirName,
471 array("File permissions", "Is the $dir folder writeable?", NULL),
472 TRUE
473 );
474 }
475
476 //check for Config.IDS.ini, file may exist in re-install
477 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
478
479 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
480 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR, $configIDSiniDir);
481 if (file_exists($configIDSiniFile)) {
482 unlink($configIDSiniFile);
483 }
484 }
485
486 // Check for rewriting
487 if (isset($_SERVER['SERVER_SOFTWARE'])) {
488 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
489 }
490 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
491 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
492 }
493
494 if ($webserver == '') {
495 $webserver = "I can't tell what webserver you are running";
496 }
497
498 // Check for $_SERVER configuration
499 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
500 "Webserver config",
501 "Recognised webserver",
502 "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set.",
503 ));
504
505 // Check for MySQL support
506 $this->requireFunction('mysql_connect',
507 array("PHP Configuration", "MySQL support", "MySQL support not included in PHP.")
508 );
509
510 // Check for JSON support
511 $this->requireFunction('json_encode',
512 array("PHP Configuration", "JSON support", "JSON support not included in PHP.")
513 );
514
515 // Check for xcache_isset and emit warning if exists
516 $this->checkXCache(array(
517 "PHP Configuration",
518 "XCache compatibility",
519 "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.",
520 ));
521
522 // Check memory allocation
523 $this->requireMemory(32 * 1024 * 1024,
524 64 * 1024 * 1024,
525 array(
526 "PHP Configuration",
527 "Memory allocated (PHP config option 'memory_limit')",
528 "CiviCRM needs a minimum of 32M allocated to PHP, but recommends 64M.",
529 ini_get("memory_limit"),
530 )
531 );
532
533 return $this->errors;
534 }
535
536 /**
537 * @param $min
538 * @param $recommended
539 * @param $testDetails
540 */
541 public function requireMemory($min, $recommended, $testDetails) {
542 $this->testing($testDetails);
543 $mem = $this->getPHPMemory();
544
545 if ($mem < $min && $mem > 0) {
546 $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
547 $this->error($testDetails);
548 }
549 elseif ($mem < $recommended && $mem > 0) {
550 $testDetails[2] .= " You only have " . ini_get("memory_limit") . " allocated";
551 $this->warning($testDetails);
552 }
553 elseif ($mem == 0) {
554 $testDetails[2] .= " We can't determine how much memory you have allocated. Install only if you're sure you've allocated at least 20 MB.";
555 $this->warning($testDetails);
556 }
557 }
558
559 /**
560 * @return float
561 */
562 public function getPHPMemory() {
563 $memString = ini_get("memory_limit");
564
565 switch (strtolower(substr($memString, -1))) {
566 case "k":
567 return round(substr($memString, 0, -1) * 1024);
568
569 case "m":
570 return round(substr($memString, 0, -1) * 1024 * 1024);
571
572 case "g":
573 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
574
575 default:
576 return round($memString);
577 }
578 }
579
580 public function listErrors() {
581 if ($this->errors) {
582 echo "<p>The following problems are preventing me from installing CiviCRM:</p>";
583 foreach ($this->errors as $error) {
584 echo "<li>" . htmlentities($error) . "</li>";
585 }
586 }
587 }
588
589 /**
590 * @param null $section
591 */
592 public function showTable($section = NULL) {
593 if ($section) {
594 $tests = $this->tests[$section];
595 echo "<table class=\"testResults\" width=\"100%\">";
596 foreach ($tests as $test => $result) {
597 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
598 }
599 echo "</table>";
600 }
601 else {
602 foreach ($this->tests as $section => $tests) {
603 echo "<h3>$section</h3>";
604 echo "<table class=\"testResults\" width=\"100%\">";
605
606 foreach ($tests as $test => $result) {
607 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
608 }
609 echo "</table>";
610 }
611 }
612 }
613
614 /**
615 * @param string $funcName
616 * @param $testDetails
617 *
618 * @return bool
619 */
620 public function requireFunction($funcName, $testDetails) {
621 $this->testing($testDetails);
622
623 if (!function_exists($funcName)) {
624 $this->error($testDetails);
625 return FALSE;
626 }
627 else {
628 return TRUE;
629 }
630 }
631
632 /**
633 * @param $testDetails
634 */
635 public function checkXCache($testDetails) {
636 if (function_exists('xcache_isset') &&
637 ini_get('xcache.size') > 0
638 ) {
639 $this->testing($testDetails);
640 $this->warning($testDetails);
641 }
642 }
643
644 /**
645 * @param $minVersion
646 * @param $testDetails
647 * @param null $maxVersion
648 */
649 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
650
651 $this->testing($testDetails);
652
653 $phpVersion = phpversion();
654 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
655 $belowMaxVersion = $maxVersion ? version_compare($phpVersion, $maxVersion) < 0 : TRUE;
656
657 if ($maxVersion && $aboveMinVersion && $belowMaxVersion) {
658 return TRUE;
659 }
660 elseif (!$maxVersion && $aboveMinVersion) {
661 return TRUE;
662 }
663
664 if (!$testDetails[2]) {
665 if (!$aboveMinVersion) {
666 $testDetails[2] = "You need PHP version $minVersion or later, only {$phpVersion} is installed. Please upgrade your server, or ask your web-host to do so.";
667 }
668 else {
669 $testDetails[2] = "PHP version {$phpVersion} is not supported. PHP version earlier than $maxVersion is required. You might want to downgrade your server, or ask your web-host to do so.";
670 }
671 }
672
673 $this->error($testDetails);
674 }
675
676 /**
677 * @param string $filename
678 * @param $testDetails
679 * @param bool $absolute
680 */
681 public function requireFile($filename, $testDetails, $absolute = FALSE) {
682 $this->testing($testDetails);
683 if (!$absolute) {
684 $filename = $this->getBaseDir() . $filename;
685 }
686 if (!file_exists($filename)) {
687 $testDetails[2] .= " (file '$filename' not found)";
688 $this->error($testDetails);
689 }
690 }
691
692 /**
693 * @param $testDetails
694 */
695 public function requireNoPathSeparator($testDetails) {
696 $this->testing($testDetails);
697 if (substr_count($this->getBaseDir(), PATH_SEPARATOR)) {
698 $this->error($testDetails);
699 }
700 }
701
702 /**
703 * @param string $filename
704 * @param $testDetails
705 */
706 public function requireNoFile($filename, $testDetails) {
707 $this->testing($testDetails);
708 $filename = $this->getBaseDir() . $filename;
709 if (file_exists($filename)) {
710 $testDetails[2] .= " (file '$filename' found)";
711 $this->error($testDetails);
712 }
713 }
714
715 /**
716 * @param string $filename
717 * @param $testDetails
718 */
719 public function moveFileOutOfTheWay($filename, $testDetails) {
720 $this->testing($testDetails);
721 $filename = $this->getBaseDir() . $filename;
722 if (file_exists($filename)) {
723 if (file_exists("$filename.bak")) {
724 rm("$filename.bak");
725 }
726 rename($filename, "$filename.bak");
727 }
728 }
729
730 /**
731 * @param string $filename
732 * @param $testDetails
733 * @param bool $absolute
734 */
735 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
736 $this->testing($testDetails);
737 if (!$absolute) {
738 $filename = $this->getBaseDir() . $filename;
739 }
740
741 if (!is_writable($filename)) {
742 $name = NULL;
743 if (function_exists('posix_getpwuid')) {
744 $user = posix_getpwuid(posix_geteuid());
745 $name = '- ' . $user['name'] . ' -';
746 }
747
748 if (!isset($testDetails[2])) {
749 $testDetails[2] = NULL;
750 }
751 $testDetails[2] .= "The user account used by your web-server $name needs to be granted write access to the following directory in order to configure the CiviCRM settings file:\n$filename";
752 $this->error($testDetails);
753 }
754 }
755
756 /**
757 * @param string $moduleName
758 * @param $testDetails
759 */
760 public function requireApacheModule($moduleName, $testDetails) {
761 $this->testing($testDetails);
762 if (!in_array($moduleName, apache_get_modules())) {
763 $this->error($testDetails);
764 }
765 }
766
767 /**
768 * @param $server
769 * @param string $username
770 * @param $password
771 * @param $testDetails
772 */
773 public function requireMysqlConnection($server, $username, $password, $testDetails) {
774 $this->testing($testDetails);
775 $conn = @mysql_connect($server, $username, $password);
776
777 if ($conn) {
778 return TRUE;
779 }
780 else {
781 $testDetails[2] .= ": " . mysql_error();
782 $this->error($testDetails);
783 }
784 }
785
786 /**
787 * @param $server
788 * @param $testDetails
789 */
790 public function requireMySQLServer($server, $testDetails) {
791 $this->testing($testDetails);
792 $conn = @mysql_connect($server, NULL, NULL);
793
794 if ($conn || mysql_errno() < 2000) {
795 return TRUE;
796 }
797 else {
798 $testDetails[2] .= ": " . mysql_error();
799 $this->error($testDetails);
800 }
801 }
802
803 /**
804 * @param $version
805 * @param $testDetails
806 */
807 public function requireMySQLVersion($version, $testDetails) {
808 $this->testing($testDetails);
809
810 if (!mysql_get_server_info()) {
811 $testDetails[2] = 'Cannot determine the version of MySQL installed. Please ensure at least version 4.1 is installed.';
812 $this->warning($testDetails);
813 }
814 else {
815 list($majorRequested, $minorRequested) = explode('.', $version);
816 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
817
818 if (($majorHas > $majorRequested) || ($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
819 return TRUE;
820 }
821 else {
822 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
823 $this->error($testDetails);
824 }
825 }
826 }
827
828 /**
829 * @param $server
830 * @param string $username
831 * @param $password
832 * @param $database
833 * @param $testDetails
834 */
835 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
836 $this->testing($testDetails);
837 $conn = @mysql_connect($server, $username, $password);
838 if (!$conn) {
839 $testDetails[2] .= ' Could not determine if mysql has innodb support. Assuming no';
840 $this->error($testDetails);
841 return;
842 }
843
844 $innodb_support = FALSE;
845 $result = mysql_query("SHOW ENGINES", $conn);
846 while ($values = mysql_fetch_array($result)) {
847 if ($values['Engine'] == 'InnoDB') {
848 if (strtolower($values['Support']) == 'yes' ||
849 strtolower($values['Support']) == 'default'
850 ) {
851 $innodb_support = TRUE;
852 }
853 }
854 }
855 if ($innodb_support) {
856 $testDetails[3] = 'MySQL server does have innodb support';
857 }
858 else {
859 $testDetails[2] .= ' Could not determine if mysql has innodb support. Assuming no';
860 }
861 }
862
863 /**
864 * @param $server
865 * @param string $username
866 * @param $password
867 * @param $database
868 * @param $testDetails
869 */
870 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
871 $this->testing($testDetails);
872 $conn = @mysql_connect($server, $username, $password);
873 if (!$conn) {
874 $testDetails[2] = 'Could not login to the database.';
875 $this->error($testDetails);
876 return;
877 }
878
879 if (!@mysql_select_db($database, $conn)) {
880 $testDetails[2] = 'Could not select the database.';
881 $this->error($testDetails);
882 return;
883 }
884
885 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
886 if (!$result) {
887 $testDetails[2] = 'Could not create a temp table.';
888 $this->error($testDetails);
889 }
890 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
891 }
892
893 /**
894 * @param $server
895 * @param string $username
896 * @param $password
897 * @param $database
898 * @param $testDetails
899 */
900 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
901 $this->testing($testDetails);
902 $conn = @mysql_connect($server, $username, $password);
903 if (!$conn) {
904 $testDetails[2] = 'Could not login to the database.';
905 $this->error($testDetails);
906 return;
907 }
908
909 if (!@mysql_select_db($database, $conn)) {
910 $testDetails[2] = 'Could not select the database.';
911 $this->error($testDetails);
912 return;
913 }
914
915 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
916 if (!$result) {
917 $testDetails[2] = 'Could not create a table.';
918 $this->error($testDetails);
919 }
920
921 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
922 if (!$result) {
923 mysql_query('DROP TABLE civicrm_install_temp_table_test');
924 $testDetails[2] = 'Could not create a trigger.';
925 $this->error($testDetails);
926 }
927
928 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
929 mysql_query('DROP TABLE civicrm_install_temp_table_test');
930 }
931
932
933 /**
934 * @param $server
935 * @param string $username
936 * @param $password
937 * @param $database
938 * @param $testDetails
939 */
940 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
941 $this->testing($testDetails);
942 $conn = @mysql_connect($server, $username, $password);
943 if (!$conn) {
944 $testDetails[2] = 'Could not login to the database.';
945 $this->error($testDetails);
946 return;
947 }
948
949 if (!@mysql_select_db($database, $conn)) {
950 $testDetails[2] = 'Could not select the database.';
951 $this->error($testDetails);
952 return;
953 }
954
955 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
956 if (!$result) {
957 $testDetails[2] = 'Could not create a table.';
958 $this->error($testDetails);
959 return;
960 }
961
962 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
963 if (!$result) {
964 $testDetails[2] = 'Could not obtain a write lock for the table.';
965 $this->error($testDetails);
966 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
967 return;
968 }
969
970 $result = mysql_query('UNLOCK TABLES', $conn);
971 if (!$result) {
972 $testDetails[2] = 'Could not release the lock for the table.';
973 $this->error($testDetails);
974 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
975 return;
976 }
977
978 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
979 }
980
981 /**
982 * @param $server
983 * @param string $username
984 * @param $password
985 * @param $testDetails
986 */
987 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
988 $this->testing($testDetails);
989 $conn = @mysql_connect($server, $username, $password);
990 if (!$conn) {
991 $testDetails[2] = 'Could not connect to the database server.';
992 $this->error($testDetails);
993 return;
994 }
995
996 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
997 if (!$result) {
998 $testDetails[2] = 'Could not query database server variables.';
999 $this->error($testDetails);
1000 return;
1001 }
1002 else {
1003 $values = mysql_fetch_row($result);
1004 if ($values[1] == 1) {
1005 $testDetails[3] = 'MySQL server auto_increment_increment is 1';
1006 }
1007 else {
1008 $this->error($testDetails);
1009 }
1010 }
1011 }
1012
1013 /**
1014 * @param $server
1015 * @param string $username
1016 * @param $password
1017 * @param $database
1018 * @param $minValueKB
1019 * @param $testDetails
1020 */
1021 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1022 $this->testing($testDetails);
1023 $conn = @mysql_connect($server, $username, $password);
1024 if (!$conn) {
1025 $testDetails[2] = 'Could not login to the database.';
1026 $this->error($testDetails);
1027 return;
1028 }
1029
1030 if (!@mysql_select_db($database, $conn)) {
1031 $testDetails[2] = 'Could not select the database.';
1032 $this->error($testDetails);
1033 return;
1034 }
1035
1036 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
1037 if (!$result) {
1038 $testDetails[2] = 'Could not query thread_stack.';
1039 $this->error($testDetails);
1040 }
1041 else {
1042 $values = mysql_fetch_row($result);
1043 if ($values[1] < (1024 * $minValueKB)) {
1044 $testDetails[2] = 'MySQL "thread_stack" is ' . ($values[1] / 1024) . 'k';
1045 $this->error($testDetails);
1046 }
1047 }
1048 }
1049
1050 /**
1051 * @param $server
1052 * @param string $username
1053 * @param $password
1054 * @param $database
1055 * @param $testDetails
1056 * @param bool $onlyRequire
1057 */
1058 public function requireDatabaseOrCreatePermissions(
1059 $server,
1060 $username,
1061 $password,
1062 $database,
1063 $testDetails,
1064 $onlyRequire = FALSE
1065 ) {
1066 $this->testing($testDetails);
1067 $conn = @mysql_connect($server, $username, $password);
1068
1069 $okay = NULL;
1070 if (@mysql_select_db($database)) {
1071 $okay = "Database '$database' exists";
1072 }
1073 elseif ($onlyRequire) {
1074 $testDetails[2] = "The database: '$database' does not exist";
1075 $this->error($testDetails);
1076 return;
1077 }
1078 else {
1079 if (@mysql_query("CREATE DATABASE $database")) {
1080 $okay = "Able to create a new database";
1081 }
1082 else {
1083 $testDetails[2] .= " (user '$username' doesn't have CREATE DATABASE permissions.)";
1084 $this->error($testDetails);
1085 return;
1086 }
1087 }
1088
1089 if ($okay) {
1090 $testDetails[3] = $okay;
1091 $this->testing($testDetails);
1092 }
1093 }
1094
1095 /**
1096 * @param $varNames
1097 * @param $errorMessage
1098 */
1099 public function requireServerVariables($varNames, $errorMessage) {
1100 //$this->testing($testDetails);
1101 foreach ($varNames as $varName) {
1102 if (!$_SERVER[$varName]) {
1103 $missing[] = '$_SERVER[' . $varName . ']';
1104 }
1105 }
1106 if (!isset($missing)) {
1107 return TRUE;
1108 }
1109 else {
1110 $testDetails[2] = " (the following PHP variables are missing: " . implode(", ", $missing) . ")";
1111 $this->error($testDetails);
1112 }
1113 }
1114
1115 /**
1116 * @param $testDetails
1117 *
1118 * @return bool
1119 */
1120 public function isRunningApache($testDetails) {
1121 $this->testing($testDetails);
1122 if (function_exists('apache_get_modules') || stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1123 return TRUE;
1124 }
1125
1126 $this->warning($testDetails);
1127 return FALSE;
1128 }
1129
1130 /**
1131 * @return string
1132 */
1133 public function getBaseDir() {
1134 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR;
1135 }
1136
1137 /**
1138 * @param $testDetails
1139 */
1140 public function testing($testDetails) {
1141 if (!$testDetails) {
1142 return;
1143 }
1144
1145 $section = $testDetails[0];
1146 $test = $testDetails[1];
1147
1148 $message = "OK";
1149 if (isset($testDetails[3])) {
1150 $message .= " ($testDetails[3])";
1151 }
1152
1153 $this->tests[$section][$test] = array("good", $message);
1154 }
1155
1156 /**
1157 * @param $testDetails
1158 */
1159 public function error($testDetails) {
1160 $section = $testDetails[0];
1161 $test = $testDetails[1];
1162
1163 $this->tests[$section][$test] = array("error", $testDetails[2]);
1164 $this->errors[] = $testDetails;
1165 }
1166
1167 /**
1168 * @param $testDetails
1169 */
1170 public function warning($testDetails) {
1171 $section = $testDetails[0];
1172 $test = $testDetails[1];
1173
1174 $this->tests[$section][$test] = array("warning", $testDetails[2]);
1175 $this->warnings[] = $testDetails;
1176 }
1177
1178 /**
1179 * @return int
1180 */
1181 public function hasErrors() {
1182 return count($this->errors);
1183 }
1184
1185 /**
1186 * @return int
1187 */
1188 public function hasWarnings() {
1189 return count($this->warnings);
1190 }
1191
1192 }
1193
1194 /**
1195 * Class Installer
1196 */
1197 class Installer extends InstallRequirements {
1198 /**
1199 * @param $server
1200 * @param $username
1201 * @param $password
1202 * @param $database
1203 */
1204 public function createDatabaseIfNotExists($server, $username, $password, $database) {
1205 $conn = @mysql_connect($server, $username, $password);
1206
1207 if (@mysql_select_db($database)) {
1208 // skip if database already present
1209 return;
1210 }
1211
1212 if (@mysql_query("CREATE DATABASE $database")) {
1213 }
1214 else {
1215 $errorTitle = "Oops! Could not create Database $database";
1216 $errorMsg = "We encountered an error when attempting to create the database. Please check your mysql server permissions and the database name and try again.";
1217 errorDisplayPage($errorTitle, $errorMsg);
1218 }
1219 }
1220
1221 /**
1222 * @param $config
1223 *
1224 * @return mixed
1225 */
1226 public function install($config) {
1227 global $installDirPath;
1228
1229 // create database if does not exists
1230 $this->createDatabaseIfNotExists($config['mysql']['server'],
1231 $config['mysql']['username'],
1232 $config['mysql']['password'],
1233 $config['mysql']['database']
1234 );
1235
1236 global $installDirPath;
1237
1238 // Build database
1239 require_once $installDirPath . 'civicrm.php';
1240 civicrm_main($config);
1241
1242 if (!$this->errors) {
1243 global $installType, $installURLPath;
1244
1245 $registerSiteURL = "https://civicrm.org/register-site";
1246 $commonOutputMessage = "
1247 <li>Have you registered this site at CiviCRM.org? If not, please help strengthen the CiviCRM ecosystem by taking a few minutes to <a href='$registerSiteURL' target='_blank'>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).</li>
1248 <li>We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.</li>
1249 ";
1250
1251 $output = NULL;
1252 if (
1253 $installType == 'drupal' &&
1254 version_compare(VERSION, '7.0-rc1') >= 0
1255 ) {
1256
1257 // clean output
1258 @ob_clean();
1259
1260 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1261 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1262 $output .= '<head>';
1263 $output .= '<title>CiviCRM Installed</title>';
1264 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1265 $output .= '</head>';
1266 $output .= '<body>';
1267 $output .= '<div style="padding: 1em;"><p class="good">CiviCRM has been successfully installed</p>';
1268 $output .= '<ul>';
1269 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here', NULL, NULL, "wiki");
1270 if (!function_exists('ts')) {
1271 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1272 }
1273 $drupalURL = civicrm_cms_base();
1274 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1275 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1276
1277 $output .= "<li>Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a target='_blank' href={$drupalPermissionsURL}>review these permissions</a> to ensure that they are appropriate for your requirements (<a target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'>learn more...</a>)</li>
1278 <li>Use the <a target='_blank' href=\"$drupalURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
1279 {$commonOutputMessage}";
1280
1281 // automatically enable CiviCRM module once it is installed successfully.
1282 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1283 global $cmsPath, $crmPath;
1284
1285 // relative / abosolute paths are not working for drupal, hence using chdir()
1286 chdir($cmsPath);
1287
1288 include_once "./includes/bootstrap.inc";
1289 include_once "./includes/unicode.inc";
1290
1291 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1292
1293 // prevent session information from being saved.
1294 drupal_save_session(FALSE);
1295
1296 // Force the current user to anonymous.
1297 $original_user = $GLOBALS['user'];
1298 $GLOBALS['user'] = drupal_anonymous_user();
1299
1300 // explicitly setting error reporting, since we cannot handle drupal related notices
1301 error_reporting(1);
1302
1303 // rebuild modules, so that civicrm is added
1304 system_rebuild_module_data();
1305
1306 // now enable civicrm module.
1307 module_enable(array('civicrm', 'civicrmtheme'));
1308
1309 // clear block, page, theme, and hook caches
1310 drupal_flush_all_caches();
1311
1312 //add basic drupal permissions
1313 civicrm_install_set_drupal_perms();
1314
1315 // restore the user.
1316 $GLOBALS['user'] = $original_user;
1317 drupal_save_session(TRUE);
1318
1319 $output .= '</ul>';
1320 $output .= '</div>';
1321 $output .= '</body>';
1322 $output .= '</html>';
1323 echo $output;
1324 }
1325 elseif ($installType == 'drupal' && version_compare(VERSION, '6.0') >= 0) {
1326 // clean output
1327 @ob_clean();
1328
1329 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1330 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1331 $output .= '<head>';
1332 $output .= '<title>CiviCRM Installed</title>';
1333 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1334 $output .= '</head>';
1335 $output .= '<body>';
1336 $output .= '<div style="padding: 1em;"><p class="good">CiviCRM has been successfully installed</p>';
1337 $output .= '<ul>';
1338 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here', NULL, NULL, "wiki");
1339 if (!function_exists('ts')) {
1340 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1341 }
1342 $drupalURL = civicrm_cms_base();
1343 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1344 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1345
1346 $output .= "<li>Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a target='_blank' href={$drupalPermissionsURL}>review these permissions</a> to ensure that they are appropriate for your requirements (<a target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'>learn more...</a>)</li>
1347 <li>Use the <a target='_blank' href=\"$drupalURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
1348 {$commonOutputMessage}";
1349
1350 // explicitly setting error reporting, since we cannot handle drupal related notices
1351 error_reporting(1);
1352
1353 // automatically enable CiviCRM module once it is installed successfully.
1354 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1355 global $cmsPath, $crmPath;
1356
1357 // relative / abosolute paths are not working for drupal, hence using chdir()
1358 chdir($cmsPath);
1359
1360 include_once "./includes/bootstrap.inc";
1361 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1362
1363 // rebuild modules, so that civicrm is added
1364 module_rebuild_cache();
1365
1366 // now enable civicrm module.
1367 module_enable(array('civicrm'));
1368
1369 // clear block, page, theme, and hook caches
1370 drupal_flush_all_caches();
1371
1372 //add basic drupal permissions
1373 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)');
1374
1375 echo $output;
1376 }
1377 elseif ($installType == 'wordpress') {
1378 echo '<h1>CiviCRM Installed</h1>';
1379 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">CiviCRM has been successfully installed</p>';
1380 echo '<ul>';
1381 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here', NULL, NULL, "wiki");
1382 if (!function_exists('ts')) {
1383 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1384 }
1385
1386 $cmsURL = civicrm_cms_base();
1387 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
1388 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1389
1390 $output .= "
1391 <li>WordPress user permissions have been automatically set - giving Anonymous and Subscribers access to public CiviCRM forms and features. We recommend that you <a target='_blank' href={$wpPermissionsURL}>review these permissions</a> to ensure that they are appropriate for your requirements (<a target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'>learn more...</a>)</li>
1392 <li>Use the <a target='_blank' href=\"$cmsURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
1393 {$commonOutputMessage}
1394 ";
1395
1396 echo '</ul>';
1397 echo '</div>';
1398 }
1399 }
1400
1401 return $this->errors;
1402 }
1403
1404 }
1405
1406 function civicrm_install_set_drupal_perms() {
1407 if (!function_exists('db_select')) {
1408 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)');
1409 }
1410 else {
1411 $perms = array(
1412 'access all custom data',
1413 'access uploaded files',
1414 'make online contributions',
1415 'profile create',
1416 'profile edit',
1417 'profile view',
1418 'register for events',
1419 'view event info',
1420 'view event participants',
1421 'access CiviMail subscribe/unsubscribe pages',
1422 );
1423
1424 // Adding a permission that has not yet been assigned to a module by
1425 // a hook_permission implementation results in a database error.
1426 // CRM-9042
1427 $allPerms = array_keys(module_invoke_all('permission'));
1428 foreach (array_diff($perms, $allPerms) as $perm) {
1429 watchdog('civicrm',
1430 'Cannot grant the %perm permission because it does not yet exist.',
1431 array('%perm' => $perm),
1432 WATCHDOG_ERROR
1433 );
1434 }
1435 $perms = array_intersect($perms, $allPerms);
1436 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $perms);
1437 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, $perms);
1438 }
1439 }
1440
1441 /**
1442 * @param $cmsPath
1443 * @param $str
1444 *
1445 * @return string
1446 */
1447 function getSiteDir($cmsPath, $str) {
1448 static $siteDir = '';
1449
1450 if ($siteDir) {
1451 return $siteDir;
1452 }
1453
1454 $sites = CIVICRM_DIRECTORY_SEPARATOR . 'sites' . CIVICRM_DIRECTORY_SEPARATOR;
1455 $modules = CIVICRM_DIRECTORY_SEPARATOR . 'modules' . CIVICRM_DIRECTORY_SEPARATOR;
1456 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR) .
1457 "([\-a-zA-Z0-9_.]+)" .
1458 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR) . "/",
1459 $_SERVER['SCRIPT_FILENAME'], $matches
1460 );
1461 $siteDir = isset($matches[1]) ? $matches[1] : 'default';
1462
1463 if (strtolower($siteDir) == 'all') {
1464 // For this case - use drupal's way of finding out multi-site directory
1465 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR, $_SERVER['SCRIPT_FILENAME']);
1466 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1467 for ($i = count($uri) - 1; $i > 0; $i--) {
1468 for ($j = count($server); $j > 0; $j--) {
1469 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1470 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
1471 'sites' . CIVICRM_DIRECTORY_SEPARATOR . $dir
1472 )) {
1473 $siteDir = $dir;
1474 return $siteDir;
1475 }
1476 }
1477 }
1478 $siteDir = 'default';
1479 }
1480
1481 return $siteDir;
1482 }
1483
1484 /**
1485 * @param $errorTitle
1486 * @param $errorMsg
1487 */
1488 function errorDisplayPage($errorTitle, $errorMsg) {
1489 include 'error.html';
1490 exit();
1491 }