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