add a few remaining missing comment blocks (autogenerated)
[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', '/');
24 define('CIVICRM_WINDOWS', 1 );
25}
26else {
27 define('CIVICRM_DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR);
28 define('CIVICRM_WINDOWS', 0 );
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(
54 'drupal', 'wordpress'))) {
55 $errorTitle = "Oops! Unsupported installation mode";
56 $errorMsg = "";
57 errorDisplayPage($errorTitle, $errorMsg);
58}
59
60global $crmPath;
62fbebae 61global $pkgPath;
6a488035
TO
62global $installDirPath;
63global $installURLPath;
62fbebae 64
6a488035
TO
65if ($installType == 'drupal') {
66 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
67 $installDirPath = $installURLPath = '';
68}
69elseif ($installType == 'wordpress') {
70 $crmPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR;
71 $installDirPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
6a488035
TO
72 $installURLPath = WP_PLUGIN_URL . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
73}
74
62fbebae
ML
75$pkgPath = $crmPath . DIRECTORY_SEPARATOR . 'packages';
76
77set_include_path(
78 $crmPath . PATH_SEPARATOR .
79 $pkgPath . PATH_SEPARATOR .
80 get_include_path()
81);
6a488035
TO
82
83require_once $crmPath . '/CRM/Core/ClassLoader.php';
84CRM_Core_ClassLoader::singleton()->register();
85
86$docLink = CRM_Utils_System::docURL2('Installation and Upgrades', FALSE, 'Installation Guide',NULL,NULL,"wiki");
87
88if ($installType == 'drupal') {
62fbebae 89 // Lets check only /modules/.
6a488035
TO
90 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR . 'modules', CIVICRM_DIRECTORY_SEPARATOR) . '/';
91
62fbebae 92 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
6a488035
TO
93 $errorTitle = "Oops! Please Correct Your Install Location";
94 $errorMsg = "Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>" . implode(CIVICRM_DIRECTORY_SEPARATOR, array(
95 'sites', 'all', 'modules')) . "</strong> directory below your Drupal root directory. Refer to the online " . $docLink . " for more information.";
96 errorDisplayPage($errorTitle, $errorMsg);
97 }
98}
99
100// Load civicrm database config
101if (isset($_REQUEST['mysql'])) {
102 $databaseConfig = $_REQUEST['mysql'];
103}
104else {
105 $databaseConfig = array(
106 "server" => "localhost",
107 "username" => "civicrm",
108 "password" => "",
109 "database" => "civicrm",
110 );
111}
112
113if ($installType == 'drupal') {
114 // Load drupal database config
115 if (isset($_REQUEST['drupal'])) {
116 $drupalConfig = $_REQUEST['drupal'];
117 }
118 else {
119 $drupalConfig = array(
120 "server" => "localhost",
121 "username" => "drupal",
122 "password" => "",
123 "database" => "drupal",
124 );
125 }
126}
127
128$loadGenerated = 0;
129if (isset($_REQUEST['loadGenerated'])) {
130 $loadGenerated = 1;
131}
132
133require_once dirname(__FILE__) . CIVICRM_DIRECTORY_SEPARATOR . 'langs.php';
134foreach ($langs as $locale => $_) {
135 if ($locale == 'en_US') {
136 continue;
137 }
62fbebae
ML
138 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
139 unset($langs[$locale]);
140 }
6a488035
TO
141}
142
62fbebae
ML
143// Set the locale (works with both native gettext and phpgettext)
144define('CIVICRM_UF', 'Drupal');
145define('CIVICRM_GETTEXT_NATIVE', 1);
146global $tsLocale;
147
148$tsLocale = 'en_US';
6a488035 149$seedLanguage = 'en_US';
62fbebae 150
6a488035
TO
151if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
152 $seedLanguage = $_REQUEST['seedLanguage'];
62fbebae 153 $tsLocale = $_REQUEST['seedLanguage'];
6a488035
TO
154}
155
62fbebae
ML
156$config = CRM_Core_Config::singleton(FALSE);
157
158// The translation files are in the parent directory (l10n)
159$config->gettextResourceDir = '..' . DIRECTORY_SEPARATOR . $config->gettextResourceDir;
160$i18n = CRM_Core_I18n::singleton();
161
6a488035
TO
162global $cmsPath;
163if ($installType == 'drupal') {
164 //CRM-6840 -don't force to install in sites/all/modules/
165 $object = new CRM_Utils_System_Drupal();
166 $cmsPath = $object->cmsRootPath();
167
168 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
169 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
170 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
171 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
172 'civicrm.settings.php'
173 );
174}
175elseif ($installType == 'wordpress') {
176 $cmsPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm';
177 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
178 'civicrm.settings.php'
179 );
180}
181
182// Exit with error if CiviCRM has already been installed.
183if ($alreadyInstalled) {
184 $errorTitle = "Oops! CiviCRM is Already Installed";
185 if ($installType == 'drupal') {
186
187 $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(
188 '[your Drupal root directory]', 'sites', $siteDir)) . "</strong>.</li><li>To <strong>upgrade an existing installation</strong>, refer to the online " . $docLink . ".</li></ul>";
189 }
190 elseif ($installType == 'wordpress') {
191 $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>";
192 }
193 errorDisplayPage($errorTitle, $errorMsg);
194}
195
196$versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'civicrm-version.php';
197if (file_exists($versionFile)) {
198 require_once ($versionFile);
199 $civicrm_version = civicrmVersion();
200}
201else {
202 $civicrm_version = 'unknown';
203}
204
205if ($installType == 'drupal') {
206 // Ensure that they have downloaded the correct version of CiviCRM
207 if ($civicrm_version['cms'] != 'Drupal' &&
208 $civicrm_version['cms'] != 'Drupal6'
209 ) {
210 $errorTitle = "Oops! Incorrect CiviCRM Version";
211 $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!";
212 errorDisplayPage($errorTitle, $errorMsg);
213 }
214
215 define('DRUPAL_ROOT', $cmsPath);
216 $drupalVersionFiles = array(
217 // D6
218 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'modules', 'system', 'system.module')),
219 // D7
220 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'includes', 'bootstrap.inc')),
221 );
222 foreach ($drupalVersionFiles as $drupalVersionFile) {
223 if (file_exists($drupalVersionFile)) {
224 require_once $drupalVersionFile;
225 }
226 }
227
228 if (!defined('VERSION') or version_compare(VERSION, '6.0') < 0) {
229 $errorTitle = "Oops! Incorrect Drupal Version";
230 $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.";
231 errorDisplayPage($errorTitle, $errorMsg);
232 }
233}
234elseif ($installType == 'wordpress') {
235 //HACK for now
236 $civicrm_version['cms'] = 'WordPress';
237
238 // Ensure that they have downloaded the correct version of CiviCRM
239 if ($civicrm_version['cms'] != 'WordPress') {
240 $errorTitle = "Oops! Incorrect CiviCRM Version";
241 $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!";
242 errorDisplayPage($errorTitle, $errorMsg);
243 }
244}
245
246// Check requirements
247$req = new InstallRequirements();
248$req->check();
249
250if ($req->hasErrors()) {
251 $hasErrorOtherThanDatabase = TRUE;
252}
253
254if ($databaseConfig) {
255 $dbReq = new InstallRequirements();
256 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
257 if ($installType == 'drupal') {
258 $dbReq->checkdatabase($drupalConfig, 'Drupal');
259 }
260}
261
262// Actual processor
263if (isset($_REQUEST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
264 // Confirm before reinstalling
265 if (!isset($_REQUEST['force_reinstall']) && $alreadyInstalled) {
266 include ($installDirPath . 'template.html');
267 }
268 else {
269 $inst = new Installer();
270 $inst->install($_REQUEST);
271 }
272
273 // Show the config form
274}
275else {
276 include ($installDirPath . 'template.html');
277}
278
279/**
280 * This class checks requirements
281 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
282 * of 3 parts:
283 * $description[0] - The test catetgory
284 * $description[1] - The test title
285 * $description[2] - The test error to show, if it goes wrong
286 */
287class InstallRequirements {
288 var $errors, $warnings, $tests;
289
290 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
291 const MINIMUM_THREAD_STACK = 192;
292
293 /**
294 * Just check that the database configuration is okay
295 */
296 function checkdatabase($databaseConfig, $dbName) {
297 if ($this->requireFunction('mysql_connect',
298 array(
62fbebae
ML
299 ts("PHP Configuration"),
300 ts("MySQL support"),
301 ts("MySQL support not included in PHP."),
6a488035
TO
302 )
303 )) {
304 $this->requireMySQLServer($databaseConfig['server'],
305 array(
62fbebae
ML
306 ts("MySQL %1 Configuration", array(1 => $dbName)),
307 ts("Does the server exist?"),
308 ts("Can't find the a MySQL server on '%1'", array(1 => $databaseConfig['server'])),
6a488035
TO
309 $databaseConfig['server'],
310 )
311 );
312 if ($this->requireMysqlConnection($databaseConfig['server'],
313 $databaseConfig['username'],
314 $databaseConfig['password'],
315 array(
62fbebae
ML
316 ts("MySQL %1 Configuration", array(1 => $dbName)),
317 ts("Are the access credentials correct?"),
318 ts("That username/password doesn't work"),
6a488035
TO
319 )
320 )) {
321 @$this->requireMySQLVersion("5.1",
322 array(
62fbebae
ML
323 ts("MySQL %1 Configuration", array(1 => $dbName)),
324 ts("MySQL version at least %1", array(1 => '5.1')),
6a488035
TO
325 "MySQL version 5.1 or higher is required, you only have ",
326 "MySQL " . mysql_get_server_info(),
327 )
328 );
329 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
330 $databaseConfig['username'],
331 $databaseConfig['password'],
332 array(
333 "MySQL $dbName Configuration",
334 "Is auto_increment_increment set to 1",
335 "An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround.",
336 )
337 );
338 $this->requireMySQLThreadStack($databaseConfig['server'],
339 $databaseConfig['username'],
340 $databaseConfig['password'],
341 $databaseConfig['database'],
342 self::MINIMUM_THREAD_STACK,
343 array(
344 "MySQL $dbName Configuration",
345 "Does MySQL thread_stack meet minimum (" . self::MINIMUM_THREAD_STACK . "k)",
346 "", // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
347 )
348 );
349 }
350 $onlyRequire = ($dbName == 'Drupal') ? TRUE : FALSE;
351 $this->requireDatabaseOrCreatePermissions(
352 $databaseConfig['server'],
353 $databaseConfig['username'],
354 $databaseConfig['password'],
355 $databaseConfig['database'],
356 array(
357 "MySQL $dbName Configuration",
358 "Can I access/create the database",
359 "I can't create new databases and the database '$databaseConfig[database]' doesn't exist",
360 ),
361 $onlyRequire
362 );
363 if ($dbName != 'Drupal') {
364 $this->requireMySQLInnoDB($databaseConfig['server'],
365 $databaseConfig['username'],
366 $databaseConfig['password'],
367 $databaseConfig['database'],
368 array(
369 "MySQL $dbName Configuration",
370 "Can I access/create InnoDB tables in the database",
371 "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.",
372 )
373 );
374 $this->requireMySQLTempTables($databaseConfig['server'],
375 $databaseConfig['username'],
376 $databaseConfig['password'],
377 $databaseConfig['database'],
378 array(
379 "MySQL $dbName Configuration",
380 'Can I create temporary tables in the database',
381 'Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.',
382 )
383 );
384 $this->requireMySQLLockTables($databaseConfig['server'],
385 $databaseConfig['username'],
386 $databaseConfig['password'],
387 $databaseConfig['database'],
388 array(
389 "MySQL $dbName Configuration",
390 'Can I create lock tables in the database',
391 'Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.',
392 )
393 );
394 $this->requireMySQLTrigger($databaseConfig['server'],
395 $databaseConfig['username'],
396 $databaseConfig['password'],
397 $databaseConfig['database'],
398 array(
399 "MySQL $dbName Configuration",
400 'Can I create triggers in the database',
401 'Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.',
402 )
403 );
404 }
405 }
406 }
407
408 /**
409 * Check everything except the database
410 */
411 function check() {
412 global $crmPath, $installType;
413
414 $this->errors = NULL;
415
62fbebae 416 $this->requirePHPVersion('5.3.3', array(ts("PHP Configuration"), ts("PHP5 installed"), NULL, ts("PHP version %1", array(1 => phpversion()))));
6a488035
TO
417
418 // Check that we can identify the root folder successfully
419 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'README.txt',
420 array(
62fbebae
ML
421 ts("File permissions"),
422 ts("Does the webserver know where files are stored?"),
423 ts("The webserver isn't letting me identify where files are stored."),
6a488035
TO
424 $this->getBaseDir(),
425 ),
426 TRUE
427 );
428
429 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
430 $this->requireNoPathSeparator(
431 array(
62fbebae
ML
432 ts('File permissions'),
433 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
434 ts('The %1 path contains the PATH_SEPARATOR (the %2 character)', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR)),
6a488035
TO
435 $this->getBaseDir(),
436 )
437 );
438
439 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
440 foreach ($requiredDirectories as $dir) {
441 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . $dir,
442 array(
62fbebae
ML
443 ts("File permissions"),
444 ts("%1: folder exists", array(1 => $dir)),
445 ts("%1: folder is missing", array(1 => $dir)),
446 ),
447 TRUE
6a488035
TO
448 );
449 }
450
451 $configIDSiniDir = NULL;
452 global $cmsPath;
3fdcdfbb 453 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
6a488035 454 if ($installType == 'drupal') {
6a488035
TO
455
456 // make sure that we can write to sites/default and files/
457 $writableDirectories = array(
458 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
459 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
460 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
461 'files',
462 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
463 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
464 $siteDir,
465 );
466 }
467 elseif ($installType == 'wordpress') {
468 // make sure that we can write to plugins/civicrm and plugins/files/
469 $writableDirectories = array(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'files', $cmsPath);
470 }
471
472 foreach ($writableDirectories as $dir) {
473 $dirName = CIVICRM_WINDOWS ? $dir : CIVICRM_DIRECTORY_SEPARATOR . $dir;
474 $this->requireWriteable($dirName,
62fbebae 475 array(ts("File permissions"), ts("Is the %1 folder writeable?", array(1 => $dir)), NULL),
6a488035
TO
476 TRUE
477 );
478 }
479
480 //check for Config.IDS.ini, file may exist in re-install
481 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
482
483 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
484 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR, $configIDSiniDir);
485 if (file_exists($configIDSiniFile)) {
486 unlink($configIDSiniFile);
487 }
488 }
489
490 // Check for rewriting
491 if (isset($_SERVER['SERVER_SOFTWARE'])) {
492 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
493 }
494 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
495 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
496 }
497
498 if ($webserver == '') {
62fbebae 499 $webserver = ts("I can't tell what webserver you are running");
6a488035
TO
500 }
501
502 // Check for $_SERVER configuration
503 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array("Webserver config", "Recognised webserver", "You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."));
504
505 // Check for MySQL support
506 $this->requireFunction('mysql_connect',
62fbebae 507 array(ts("PHP Configuration"), ts("MySQL support"), ts("MySQL support not included in PHP."))
6a488035
TO
508 );
509
510 // Check for JSON support
511 $this->requireFunction('json_encode',
62fbebae 512 array(ts("PHP Configuration"), ts("JSON support"), ts("JSON support not included in PHP."))
6a488035
TO
513 );
514
515 // Check for xcache_isset and emit warning if exists
516 $this->checkXCache(array(
62fbebae 517 ts("PHP Configuration"),
6a488035
TO
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(
62fbebae
ML
526 ts("PHP Configuration"),
527 ts("Memory allocated (PHP config option 'memory_limit')"),
528 ts("CiviCRM needs a minimum of 32M allocated to PHP, but recommends 64M."),
6a488035
TO
529 ini_get("memory_limit"),
530 )
531 );
532
533 return $this->errors;
534 }
535
627456b5
EM
536 /**
537 * @param $min
538 * @param $recommended
539 * @param $testDetails
540 */
6a488035
TO
541 function requireMemory($min, $recommended, $testDetails) {
542 $this->testing($testDetails);
543 $mem = $this->getPHPMemory();
544
545 if ($mem < $min && $mem > 0) {
62fbebae 546 $testDetails[2] .= " " . ts("You only have %1 of memory allocated", array(1 => ini_get("memory_limit")));
6a488035
TO
547 $this->error($testDetails);
548 }
549 elseif ($mem < $recommended && $mem > 0) {
62fbebae 550 $testDetails[2] .= " " . ts("You only have %1 of memory allocated", array(1 => ini_get("memory_limit")));
6a488035
TO
551 $this->warning($testDetails);
552 }
553 elseif ($mem == 0) {
62fbebae 554 $testDetails[2] .= " " . ts("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
555 $this->warning($testDetails);
556 }
557 }
558
627456b5
EM
559 /**
560 * @return float
561 */
6a488035
TO
562 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 function listErrors() {
581 if ($this->errors) {
62fbebae 582 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
6a488035
TO
583 foreach ($this->errors as $error) {
584 echo "<li>" . htmlentities($error) . "</li>";
585 }
586 }
587 }
588
627456b5
EM
589 /**
590 * @param null $section
591 */
6a488035
TO
592 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
627456b5
EM
614 /**
615 * @param $funcName
616 * @param $testDetails
617 *
618 * @return bool
619 */
6a488035
TO
620 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
627456b5
EM
632 /**
633 * @param $testDetails
634 */
6a488035
TO
635 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
627456b5
EM
644 /**
645 * @param $minVersion
646 * @param $testDetails
647 * @param null $maxVersion
648 */
6a488035
TO
649 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
627456b5
EM
676 /**
677 * @param $filename
678 * @param $testDetails
679 * @param bool $absolute
680 */
6a488035
TO
681 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
627456b5
EM
692 /**
693 * @param $testDetails
694 */
6a488035
TO
695 function requireNoPathSeparator($testDetails) {
696 $this->testing($testDetails);
697 if (substr_count($this->getBaseDir(), PATH_SEPARATOR)) {
698 $this->error($testDetails);
699 }
700 }
701
627456b5
EM
702 /**
703 * @param $filename
704 * @param $testDetails
705 */
6a488035
TO
706 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
627456b5
EM
715 /**
716 * @param $filename
717 * @param $testDetails
718 */
6a488035
TO
719 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
627456b5
EM
730 /**
731 * @param $filename
732 * @param $testDetails
733 * @param bool $absolute
734 */
6a488035
TO
735 function requireWriteable($filename, $testDetails, $absolute = FALSE) {
736 $this->testing($testDetails);
737 if (!$absolute) {
738 $filename = $this->getBaseDir() . $filename;
739 }
740
741 if (!is_writeable($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
627456b5
EM
756 /**
757 * @param $moduleName
758 * @param $testDetails
759 */
6a488035
TO
760 function requireApacheModule($moduleName, $testDetails) {
761 $this->testing($testDetails);
762 if (!in_array($moduleName, apache_get_modules())) {
763 $this->error($testDetails);
764 }
765 }
766
627456b5
EM
767 /**
768 * @param $server
769 * @param $username
770 * @param $password
771 * @param $testDetails
772 */
6a488035
TO
773 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
627456b5
EM
786 /**
787 * @param $server
788 * @param $testDetails
789 */
6a488035
TO
790 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
627456b5
EM
803 /**
804 * @param $version
805 * @param $testDetails
806 */
6a488035
TO
807 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
627456b5
EM
828 /**
829 * @param $server
830 * @param $username
831 * @param $password
832 * @param $database
833 * @param $testDetails
834 */
6a488035
TO
835 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
627456b5
EM
863 /**
864 * @param $server
865 * @param $username
866 * @param $password
867 * @param $database
868 * @param $testDetails
869 */
6a488035
TO
870 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
627456b5
EM
893 /**
894 * @param $server
895 * @param $username
896 * @param $password
897 * @param $database
898 * @param $testDetails
899 */
6a488035
TO
900 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
929 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
930 mysql_query('DROP TABLE civicrm_install_temp_table_test');
931 }
932
933
627456b5
EM
934 /**
935 * @param $server
936 * @param $username
937 * @param $password
938 * @param $database
939 * @param $testDetails
940 */
6a488035
TO
941 function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
942 $this->testing($testDetails);
943 $conn = @mysql_connect($server, $username, $password);
944 if (!$conn) {
945 $testDetails[2] = 'Could not login to the database.';
946 $this->error($testDetails);
947 return;
948 }
949
950 if (!@mysql_select_db($database, $conn)) {
951 $testDetails[2] = 'Could not select the database.';
952 $this->error($testDetails);
953 return;
954 }
955
956 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
957 if (!$result) {
958 $testDetails[2] = 'Could not create a table.';
959 $this->error($testDetails);
960 return;
961 }
962
963 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
964 if (!$result) {
965 $testDetails[2] = 'Could not obtain a write lock for the table.';
966 $this->error($testDetails);
967 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
968 return;
969 }
970
971 $result = mysql_query('UNLOCK TABLES', $conn);
972 if (!$result) {
973 $testDetails[2] = 'Could not release the lock for the table.';
974 $this->error($testDetails);
975 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
976 return;
977 }
978
979 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
980 return;
981 }
982
627456b5
EM
983 /**
984 * @param $server
985 * @param $username
986 * @param $password
987 * @param $testDetails
988 */
6a488035
TO
989 function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
990 $this->testing($testDetails);
991 $conn = @mysql_connect($server, $username, $password);
992 if (!$conn) {
993 $testDetails[2] = 'Could not connect to the database server.';
994 $this->error($testDetails);
995 return;
996 }
997
998 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
999 if (!$result) {
1000 $testDetails[2] = 'Could not query database server variables.';
1001 $this->error($testDetails);
1002 return;
1003 }
1004 else {
1005 $values = mysql_fetch_row($result);
1006 if ($values[1] == 1) {
1007 $testDetails[3] = 'MySQL server auto_increment_increment is 1';
1008 }
1009 else {
1010 $this->error($testDetails);
1011 }
1012 }
1013 }
1014
627456b5
EM
1015 /**
1016 * @param $server
1017 * @param $username
1018 * @param $password
1019 * @param $database
1020 * @param $minValueKB
1021 * @param $testDetails
1022 */
6a488035
TO
1023 function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
1024 $this->testing($testDetails);
1025 $conn = @mysql_connect($server, $username, $password);
1026 if (!$conn) {
1027 $testDetails[2] = 'Could not login to the database.';
1028 $this->error($testDetails);
1029 return;
1030 }
1031
1032 if (!@mysql_select_db($database, $conn)) {
1033 $testDetails[2] = 'Could not select the database.';
1034 $this->error($testDetails);
1035 return;
1036 }
1037
032c9d10 1038 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
6a488035
TO
1039 if (!$result) {
1040 $testDetails[2] = 'Could not query thread_stack.';
1041 $this->error($testDetails);
1042 } else {
1043 $values = mysql_fetch_row($result);
032c9d10
TO
1044 if ($values[1] < (1024*$minValueKB)) {
1045 $testDetails[2] = 'MySQL "thread_stack" is ' . ($values[1]/1024) . 'k';
6a488035
TO
1046 $this->error($testDetails);
1047 }
1048 }
1049 }
1050
627456b5
EM
1051 /**
1052 * @param $server
1053 * @param $username
1054 * @param $password
1055 * @param $database
1056 * @param $testDetails
1057 * @param bool $onlyRequire
1058 */
6a488035
TO
1059 function requireDatabaseOrCreatePermissions($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
627456b5
EM
1095 /**
1096 * @param $varNames
1097 * @param $errorMessage
1098 */
6a488035
TO
1099 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 {
3fdcdfbb 1110 $testDetails[2] = " (the following PHP variables are missing: " . implode(", ", $missing) . ")";
6a488035
TO
1111 $this->error($testDetails);
1112 }
1113 }
1114
627456b5
EM
1115 /**
1116 * @param $testDetails
1117 *
1118 * @return bool
1119 */
6a488035
TO
1120 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
627456b5
EM
1130 /**
1131 * @return string
1132 */
6a488035
TO
1133 function getBaseDir() {
1134 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR;
1135 }
1136
627456b5
EM
1137 /**
1138 * @param $testDetails
1139 */
6a488035
TO
1140 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
627456b5
EM
1156 /**
1157 * @param $testDetails
1158 */
6a488035
TO
1159 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
627456b5
EM
1167 /**
1168 * @param $testDetails
1169 */
6a488035
TO
1170 function warning($testDetails) {
1171 $section = $testDetails[0];
1172 $test = $testDetails[1];
1173
1174
1175 $this->tests[$section][$test] = array("warning", $testDetails[2]);
1176 $this->warnings[] = $testDetails;
1177 }
1178
627456b5
EM
1179 /**
1180 * @return int
1181 */
6a488035
TO
1182 function hasErrors() {
1183 return sizeof($this->errors);
1184 }
1185
627456b5
EM
1186 /**
1187 * @return int
1188 */
6a488035
TO
1189 function hasWarnings() {
1190 return sizeof($this->warnings);
1191 }
1192}
1193
627456b5
EM
1194/**
1195 * Class Installer
1196 */
6a488035 1197class Installer extends InstallRequirements {
627456b5
EM
1198 /**
1199 * @param $server
1200 * @param $username
1201 * @param $password
1202 * @param $database
1203 */
6a488035
TO
1204 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 else {
1214 $errorTitle = "Oops! Could not create Database $database";
1215 $errorMsg = "We encountered an error when attempting to create the database. Please check your mysql server permissions and the database name and try again.";
1216 errorDisplayPage($errorTitle, $errorMsg);
1217 }
1218 }
1219
627456b5
EM
1220 /**
1221 * @param $config
1222 *
1223 * @return mixed
1224 */
6a488035
TO
1225 function install($config) {
1226 global $installDirPath;
1227
1228 // create database if does not exists
1229 $this->createDatabaseIfNotExists($config['mysql']['server'],
1230 $config['mysql']['username'],
1231 $config['mysql']['password'],
1232 $config['mysql']['database']
1233 );
1234
1235 global $installDirPath;
1236
1237 // Build database
1238 require_once $installDirPath . 'civicrm.php';
1239 civicrm_main($config);
1240
1241 if (!$this->errors) {
1242 global $installType, $installURLPath;
1243
41547a19
DL
1244 $registerSiteURL = "http://civicrm.org/civicrm/profile/create?reset=1&gid=15";
1245 $commonOutputMessage = "
1246 <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>
1247 <li>We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.</li>
1248";
1249
6a488035
TO
1250 $output = NULL;
1251 if (
1252 $installType == 'drupal' &&
1253 version_compare(VERSION, '7.0-rc1') >= 0
1254 ) {
1255
1256 // clean output
1257 @ob_clean();
1258
1259 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1260 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1261 $output .= '<head>';
1262 $output .= '<title>CiviCRM Installed</title>';
1263 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1264 $output .= '</head>';
1265 $output .= '<body>';
1266 $output .= '<div style="padding: 1em;"><p class="good">CiviCRM has been successfully installed</p>';
1267 $output .= '<ul>';
1268 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here',NULL,NULL,"wiki");
1269 if (!function_exists('ts')) {
1270 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1271 }
1272 $drupalURL = civicrm_cms_base();
1273 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1274 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
6a488035
TO
1275
1276 $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>
1277 <li>Use the <a target='_blank' href=\"$drupalURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
41547a19 1278 {$commonOutputMessage}";
6a488035
TO
1279
1280 // automatically enable CiviCRM module once it is installed successfully.
1281 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1282 global $cmsPath, $crmPath;
1283
1284 // relative / abosolute paths are not working for drupal, hence using chdir()
1285 chdir($cmsPath);
1286
1287 include_once "./includes/bootstrap.inc";
1288 include_once "./includes/unicode.inc";
1289
1290 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1291
1292 // prevent session information from being saved.
1293 drupal_save_session(FALSE);
1294
1295 // Force the current user to anonymous.
1296 $original_user = $GLOBALS['user'];
1297 $GLOBALS['user'] = drupal_anonymous_user();
1298
1299 // explicitly setting error reporting, since we cannot handle drupal related notices
1300 error_reporting(1);
1301
1302 // rebuild modules, so that civicrm is added
1303 system_rebuild_module_data();
1304
1305 // now enable civicrm module.
1306 module_enable(array('civicrm', 'civicrmtheme'));
1307
d8a4acc0
C
1308 // clear block, page, theme, and hook caches
1309 drupal_flush_all_caches();
6a488035
TO
1310
1311 //add basic drupal permissions
1312 civicrm_install_set_drupal_perms();
1313
1314 // restore the user.
1315 $GLOBALS['user'] = $original_user;
1316 drupal_save_session(TRUE);
1317
1318 $output .= '</ul>';
1319 $output .= '</div>';
1320 $output .= '</body>';
1321 $output .= '</html>';
1322 echo $output;
1323 }
1324 elseif ($installType == 'drupal' && version_compare(VERSION, '6.0') >= 0) {
1325 // clean output
1326 @ob_clean();
1327
1328 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1329 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1330 $output .= '<head>';
1331 $output .= '<title>CiviCRM Installed</title>';
1332 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1333 $output .= '</head>';
1334 $output .= '<body>';
1335 $output .= '<div style="padding: 1em;"><p class="good">CiviCRM has been successfully installed</p>';
1336 $output .= '<ul>';
1337 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here',NULL,NULL,"wiki");
1338 if (!function_exists('ts')) {
1339 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1340 }
1341 $drupalURL = civicrm_cms_base();
1342 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1343 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
6a488035
TO
1344
1345 $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>
1346 <li>Use the <a target='_blank' href=\"$drupalURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
41547a19 1347 {$commonOutputMessage}";
6a488035
TO
1348
1349 // explicitly setting error reporting, since we cannot handle drupal related notices
1350 error_reporting(1);
1351
1352 // automatically enable CiviCRM module once it is installed successfully.
1353 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1354 global $cmsPath, $crmPath;
1355
1356 // relative / abosolute paths are not working for drupal, hence using chdir()
1357 chdir($cmsPath);
1358
1359 include_once "./includes/bootstrap.inc";
1360 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1361
1362 // rebuild modules, so that civicrm is added
1363 module_rebuild_cache();
1364
1365 // now enable civicrm module.
1366 module_enable(array('civicrm'));
1367
d8a4acc0
C
1368 // clear block, page, theme, and hook caches
1369 drupal_flush_all_caches();
6a488035
TO
1370
1371 //add basic drupal permissions
1372 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)');
1373
1374 echo $output;
1375 }
1376 elseif ($installType == 'wordpress') {
1377 echo '<h1>CiviCRM Installed</h1>';
1378 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">CiviCRM has been successfully installed</p>';
1379 echo '<ul>';
1380 $docLinkConfig = CRM_Utils_System::docURL2('Configuring a New Site', FALSE, 'here',NULL,NULL,"wiki");
1381 if (!function_exists('ts')) {
1382 $docLinkConfig = "<a href=\"{$docLinkConfig}\">here</a>";
1383 }
1384
1385 $cmsURL = civicrm_cms_base();
1386 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
41547a19
DL
1387 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1388
1389 $output .= "
bc62fd4e 1390 <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
1391 <li>Use the <a target='_blank' href=\"$cmsURL\">Configuration Checklist</a> to review and configure settings for your new site</li>
1392 {$commonOutputMessage}
1393";
1394
1395 echo '</ul>';
1396 echo '</div>';
1397 }
1398 }
6a488035
TO
1399
1400 return $this->errors;
1401 }
1402}
1403
1404function civicrm_install_set_drupal_perms() {
1405 if (!function_exists('db_select')) {
1406 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)');
1407 }
1408 else {
1409 $perms = array(
1410 'access all custom data',
1411 'access uploaded files',
1412 'make online contributions',
1413 'profile create',
1414 'profile edit',
1415 'profile view',
1416 'register for events',
1417 'view event info',
1418 'view event participants',
1419 'access CiviMail subscribe/unsubscribe pages',
1420 );
1421
1422 // Adding a permission that has not yet been assigned to a module by
1423 // a hook_permission implementation results in a database error.
1424 // CRM-9042
1425 $allPerms = array_keys(module_invoke_all('permission'));
1426 foreach (array_diff($perms, $allPerms) as $perm) {
1427 watchdog('civicrm',
1428 'Cannot grant the %perm permission because it does not yet exist.',
1429 array(
1430 '%perm' => $perm), WATCHDOG_ERROR
1431 );
1432 }
1433 $perms = array_intersect($perms, $allPerms);
1434 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $perms);
1435 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, $perms);
1436 }
1437}
1438
627456b5
EM
1439/**
1440 * @param $cmsPath
1441 * @param $str
1442 *
1443 * @return string
1444 */
6a488035
TO
1445function getSiteDir($cmsPath, $str) {
1446 static $siteDir = '';
1447
1448 if ($siteDir) {
1449 return $siteDir;
1450 }
1451
1452 $sites = CIVICRM_DIRECTORY_SEPARATOR . 'sites' . CIVICRM_DIRECTORY_SEPARATOR;
1453 $modules = CIVICRM_DIRECTORY_SEPARATOR . 'modules' . CIVICRM_DIRECTORY_SEPARATOR;
1454 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR) .
1455 "([\-a-zA-Z0-9_.]+)" .
1456 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR) . "/",
1457 $_SERVER['SCRIPT_FILENAME'], $matches
1458 );
1459 $siteDir = isset($matches[1]) ? $matches[1] : 'default';
1460
1461 if (strtolower($siteDir) == 'all') {
1462 // For this case - use drupal's way of finding out multi-site directory
1463 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR, $_SERVER['SCRIPT_FILENAME']);
1464 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1465 for ($i = count($uri) - 1; $i > 0; $i--) {
1466 for ($j = count($server); $j > 0; $j--) {
1467 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1468 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
1469 'sites' . CIVICRM_DIRECTORY_SEPARATOR . $dir
1470 )) {
1471 $siteDir = $dir;
1472 return $siteDir;
1473 }
1474 }
1475 }
1476 $siteDir = 'default';
1477 }
1478
1479 return $siteDir;
1480}
1481
627456b5
EM
1482/**
1483 * @param $errorTitle
1484 * @param $errorMsg
1485 */
6a488035
TO
1486function errorDisplayPage($errorTitle, $errorMsg) {
1487 include ('error.html');
1488 exit();
1489}
1490