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