CRM-19126 further fix - less aggressive return
[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
47465875 6 * http://www.silverstripe.com/.
6a488035
TO
7 *
8 * Copyright (c) 2006-7, SilverStripe Limited - www.silverstripe.com
9 * All rights reserved.
10 *
47465875
DS
11 * License: BSD-3-clause
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are
14 * met:
15 *
16 * Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * Neither the name of SilverStripe nor the names of its contributors may
24 * be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
31 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
6a9514e1 39 * Changes and modifications (c) 2007-2015 by CiviCRM LLC
6a488035
TO
40 *
41 */
42
43/**
44 * CiviCRM Installer
45 */
6a488035
TO
46ini_set('max_execution_time', 3000);
47
48if (stristr(PHP_OS, 'WIN')) {
49 define('CIVICRM_DIRECTORY_SEPARATOR', '/');
481a74f4 50 define('CIVICRM_WINDOWS', 1);
6a488035
TO
51}
52else {
53 define('CIVICRM_DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR);
481a74f4 54 define('CIVICRM_WINDOWS', 0);
6a488035
TO
55}
56
57// set installation type - drupal
58if (!session_id()) {
064bf239
CB
59 if (defined('PANTHEON_ENVIRONMENT')) {
60 ini_set('session.save_handler', 'files');
61 }
6a488035
TO
62 session_start();
63}
64
65// unset civicrm session if any
66if (array_key_exists('CiviCRM', $_SESSION)) {
67 unset($_SESSION['CiviCRM']);
68}
69
70if (isset($_GET['civicrm_install_type'])) {
71 $_SESSION['civicrm_install_type'] = $_GET['civicrm_install_type'];
72}
73else {
74 if (!isset($_SESSION['civicrm_install_type'])) {
75 $_SESSION['civicrm_install_type'] = "drupal";
76 }
77}
78
79global $installType;
6a488035 80global $crmPath;
97b8e6b2 81global $pkgPath;
6a488035
TO
82global $installDirPath;
83global $installURLPath;
97b8e6b2 84
6a9514e1
ML
85$installType = strtolower($_SESSION['civicrm_install_type']);
86
5757adf3 87if ($installType == 'drupal' || $installType == 'backdrop') {
6a488035
TO
88 $crmPath = dirname(dirname($_SERVER['SCRIPT_FILENAME']));
89 $installDirPath = $installURLPath = '';
90}
91elseif ($installType == 'wordpress') {
92 $crmPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR;
93 $installDirPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
6a488035
TO
94 $installURLPath = WP_PLUGIN_URL . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR;
95}
6a9514e1
ML
96else {
97 $errorTitle = "Oops! Unsupported installation mode";
98 $errorMsg = sprintf('%s: unknown installation mode. Please refer to the online documentation for more information.', $installType);
99 errorDisplayPage($errorTitle, $errorMsg, FALSE);
100}
6a488035 101
97b8e6b2 102$pkgPath = $crmPath . DIRECTORY_SEPARATOR . 'packages';
103
6a488035
TO
104require_once $crmPath . '/CRM/Core/ClassLoader.php';
105CRM_Core_ClassLoader::singleton()->register();
106
6a488035 107// Load civicrm database config
aca6ce6e
PN
108if (isset($_POST['mysql'])) {
109 $databaseConfig = $_POST['mysql'];
6a488035
TO
110}
111else {
7267b6be
KC
112 $databaseConfig = array(
113 "server" => "localhost",
114 "username" => "civicrm",
115 "password" => "",
116 "database" => "civicrm",
117 );
118}
119
120if ($installType == 'wordpress') {
121 //WP Database Data
122 $databaseConfig = array(
123 "server" => DB_HOST,
124 "username" => DB_USER,
125 "password" => DB_PASSWORD,
126 "database" => DB_NAME,
127 );
6a488035
TO
128}
129
130if ($installType == 'drupal') {
131 // Load drupal database config
aca6ce6e
PN
132 if (isset($_POST['drupal'])) {
133 $drupalConfig = $_POST['drupal'];
6a488035
TO
134 }
135 else {
136 $drupalConfig = array(
137 "server" => "localhost",
138 "username" => "drupal",
139 "password" => "",
140 "database" => "drupal",
141 );
142 }
143}
144
5757adf3
HD
145if ($installType == 'backdrop') {
146 // Load backdrop database config
147 if (isset($_POST['backdrop'])) {
148 $backdropConfig = $_POST['backdrop'];
149 }
150 else {
151 $backdropConfig = array(
152 "server" => "localhost",
153 "username" => "backdrop",
154 "password" => "",
155 "database" => "backdrop",
156 );
157 }
158}
159
6a488035 160$loadGenerated = 0;
aca6ce6e 161if (isset($_POST['loadGenerated'])) {
6a488035
TO
162 $loadGenerated = 1;
163}
164
165require_once dirname(__FILE__) . CIVICRM_DIRECTORY_SEPARATOR . 'langs.php';
166foreach ($langs as $locale => $_) {
167 if ($locale == 'en_US') {
168 continue;
169 }
4f99ca55
TO
170 if (!file_exists(implode(CIVICRM_DIRECTORY_SEPARATOR, array($crmPath, 'sql', "civicrm_data.$locale.mysql")))) {
171 unset($langs[$locale]);
1f5f3294 172 }
6a488035
TO
173}
174
97b8e6b2 175// Set the locale (required by CRM_Core_Config)
176// This is mostly sympbolic, since nothing we do during the install
177// really requires CIVICRM_UF to be defined.
178$installTypeToUF = array(
179 'wordpress' => 'WordPress',
180 'drupal' => 'Drupal',
5757adf3 181 'backdrop' => 'Backdrop',
97b8e6b2 182);
183
c8ab0a65 184$uf = (isset($installTypeToUF[$installType]) ? $installTypeToUF[$installType] : 'Drupal');
97b8e6b2 185define('CIVICRM_UF', $uf);
186
187global $tsLocale;
188
189$tsLocale = 'en_US';
6a488035 190$seedLanguage = 'en_US';
97b8e6b2 191
5f6b3b5d
ML
192// CRM-16801 This validates that seedLanguage is valid by looking in $langs.
193// NB: the variable is initial a $_REQUEST for the initial page reload,
194// then becomes a $_POST when the installation form is submitted.
195if (isset($_REQUEST['seedLanguage']) and isset($langs[$_REQUEST['seedLanguage']])) {
196 $seedLanguage = $_REQUEST['seedLanguage'];
197 $tsLocale = $_REQUEST['seedLanguage'];
6a488035
TO
198}
199
97b8e6b2 200$config = CRM_Core_Config::singleton(FALSE);
0ad1e2de
ML
201$GLOBALS['civicrm_default_error_scope'] = NULL;
202
97b8e6b2 203// The translation files are in the parent directory (l10n)
97b8e6b2 204$i18n = CRM_Core_I18n::singleton();
205
3a55aa6b
ML
206// Support for Arabic, Hebrew, Farsi, etc.
207// Used in the template.html
208$short_lang_code = CRM_Core_I18n_PseudoConstant::shortForLong($tsLocale);
209$text_direction = (CRM_Core_I18n::isLanguageRTL($tsLocale) ? 'rtl' : 'ltr');
210
6a488035
TO
211global $cmsPath;
212if ($installType == 'drupal') {
213 //CRM-6840 -don't force to install in sites/all/modules/
214 $object = new CRM_Utils_System_Drupal();
215 $cmsPath = $object->cmsRootPath();
216
217 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
218 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
219 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
220 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
221 'civicrm.settings.php'
222 );
223}
5757adf3
HD
224elseif ($installType == 'backdrop') {
225 $object = new CRM_Utils_System_Backdrop();
226 $cmsPath = $object->cmsRootPath();
227 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
228 $alreadyInstalled = file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR . 'civicrm.settings.php');
229}
6a488035
TO
230elseif ($installType == 'wordpress') {
231 $cmsPath = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'civicrm';
7ba2c8ad
KC
232 $upload_dir = wp_upload_dir();
233 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm';
895a7985 234 $wp_civi_settings = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm' . DIRECTORY_SEPARATOR . 'civicrm.settings.php';
e7bf24e8
KC
235 $wp_civi_settings_deprectated = CIVICRM_PLUGIN_DIR . 'civicrm.settings.php';
236 if (file_exists($wp_civi_settings_deprectated)) {
237 $alreadyInstalled = $wp_civi_settings_deprectated;
238 }
239 elseif (file_exists($wp_civi_settings)) {
240 $alreadyInstalled = $wp_civi_settings;
241 }
6a488035
TO
242}
243
6a9514e1
ML
244if ($installType == 'drupal') {
245 // Lets check only /modules/.
246 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR . 'modules', CIVICRM_DIRECTORY_SEPARATOR) . '/';
247
248 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
249 $directory = implode(CIVICRM_DIRECTORY_SEPARATOR, array('sites', 'all', 'modules'));
250 $errorTitle = ts("Oops! Please correct your install location");
251 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
252 errorDisplayPage($errorTitle, $errorMsg);
253 }
254}
255
5757adf3
HD
256if ($installType == 'backdrop') {
257 // Lets check only /modules/.
258 $pattern = '/' . preg_quote(CIVICRM_DIRECTORY_SEPARATOR . 'modules', CIVICRM_DIRECTORY_SEPARATOR) . '/';
259
260 if (!preg_match($pattern, str_replace("\\", "/", $_SERVER['SCRIPT_FILENAME']))) {
261 $directory = 'modules';
262 $errorTitle = ts("Oops! Please correct your install location");
263 $errorMsg = ts("Please untar (uncompress) your downloaded copy of CiviCRM in the <strong>%1</strong> directory below your Drupal root directory.", array(1 => $directory));
264 errorDisplayPage($errorTitle, $errorMsg);
265 }
266}
267
6a488035
TO
268// Exit with error if CiviCRM has already been installed.
269if ($alreadyInstalled) {
6a9514e1
ML
270 $errorTitle = ts("Oops! CiviCRM is already installed");
271 $settings_directory = $cmsPath;
6a488035 272
6a9514e1
ML
273 if ($installType == 'drupal') {
274 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR, array(
275 ts('[your Drupal root directory]'),
276 'sites',
277 $siteDir,
278 ));
6a488035 279 }
5757adf3
HD
280 if ($installType == 'backdrop') {
281 $settings_directory = implode(CIVICRM_DIRECTORY_SEPARATOR, array(
282 ts('[your Backdrop root directory]'),
283 $siteDir,
284 ));
285 }
6a9514e1
ML
286
287 $docLink = CRM_Utils_System::docURL2('Installation and Upgrades', FALSE, ts('Installation Guide'), NULL, NULL, "wiki");
288 $errorMsg = ts("CiviCRM has already been installed. <ul><li>To <strong>start over</strong>, you must delete or rename the existing CiviCRM settings file - <strong>civicrm.settings.php</strong> - from <strong>%1</strong>.</li><li>To <strong>upgrade an existing installation</strong>, <a href='%2'>refer to the online documentation</a>.</li></ul>", array(1 => $settings_directory, 2 => $docLink));
289 errorDisplayPage($errorTitle, $errorMsg, FALSE);
6a488035
TO
290}
291
292$versionFile = $crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'civicrm-version.php';
293if (file_exists($versionFile)) {
1f5f3294 294 require_once $versionFile;
6a488035
TO
295 $civicrm_version = civicrmVersion();
296}
297else {
298 $civicrm_version = 'unknown';
299}
300
301if ($installType == 'drupal') {
302 // Ensure that they have downloaded the correct version of CiviCRM
6a9514e1
ML
303 if ($civicrm_version['cms'] != 'Drupal' && $civicrm_version['cms'] != 'Drupal6') {
304 $errorTitle = ts("Oops! Incorrect CiviCRM version");
305 $errorMsg = ts("This installer can only be used for the Drupal version of CiviCRM.");
6a488035
TO
306 errorDisplayPage($errorTitle, $errorMsg);
307 }
308
309 define('DRUPAL_ROOT', $cmsPath);
310 $drupalVersionFiles = array(
311 // D6
312 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'modules', 'system', 'system.module')),
313 // D7
314 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'includes', 'bootstrap.inc')),
315 );
316 foreach ($drupalVersionFiles as $drupalVersionFile) {
317 if (file_exists($drupalVersionFile)) {
318 require_once $drupalVersionFile;
319 }
320 }
321
322 if (!defined('VERSION') or version_compare(VERSION, '6.0') < 0) {
6a9514e1
ML
323 $errorTitle = ts("Oops! Incorrect Drupal version");
324 $errorMsg = ts("This version of CiviCRM can only be used with Drupal 6.x or 7.x. Please ensure that '%1' exists if you are running Drupal 7.0 and over.", array(1 => implode("' or '", $drupalVersionFiles)));
6a488035
TO
325 errorDisplayPage($errorTitle, $errorMsg);
326 }
327}
5757adf3
HD
328elseif ($installType == 'backdrop') {
329 // Ensure that they have downloaded the correct version of CiviCRM
330 if ($civicrm_version['cms'] != 'Backdrop') {
331 $errorTitle = ts("Oops! Incorrect CiviCRM version");
332 $errorMsg = ts("This installer can only be used for the Backdrop version of CiviCRM.");
333 errorDisplayPage($errorTitle, $errorMsg);
334 }
335
336 define('BACKDROP_ROOT', $cmsPath);
337
338 $backdropVersionFiles = array(
339 // Backdrop
340 implode(CIVICRM_DIRECTORY_SEPARATOR, array($cmsPath, 'core', 'includes', 'bootstrap.inc')),
341 );
342 foreach ($backdropVersionFiles as $backdropVersionFile) {
343 if (file_exists($backdropVersionFile)) {
344 require_once $backdropVersionFile;
345 }
346 }
347 if (!defined('BACKDROP_VERSION') or version_compare(BACKDROP_VERSION, '1.0') < 0) {
348 $errorTitle = ts("Oops! Incorrect Backdrop version");
349 $errorMsg = ts("This version of CiviCRM can only be used with Backdrop 1.x. Please ensure that '%1' exists if you are running Backdrop 1.0 and over.", array(1 => implode("' or '", $backdropVersionFiles)));
350 errorDisplayPage($errorTitle, $errorMsg);
351 }
352}
6a488035
TO
353elseif ($installType == 'wordpress') {
354 //HACK for now
355 $civicrm_version['cms'] = 'WordPress';
356
357 // Ensure that they have downloaded the correct version of CiviCRM
358 if ($civicrm_version['cms'] != 'WordPress') {
6a9514e1
ML
359 $errorTitle = ts("Oops! Incorrect CiviCRM version");
360 $errorMsg = ts("This installer can only be used for the WordPress version of CiviCRM.");
6a488035
TO
361 errorDisplayPage($errorTitle, $errorMsg);
362 }
363}
364
365// Check requirements
366$req = new InstallRequirements();
367$req->check();
368
369if ($req->hasErrors()) {
370 $hasErrorOtherThanDatabase = TRUE;
371}
372
373if ($databaseConfig) {
374 $dbReq = new InstallRequirements();
375 $dbReq->checkdatabase($databaseConfig, 'CiviCRM');
376 if ($installType == 'drupal') {
377 $dbReq->checkdatabase($drupalConfig, 'Drupal');
378 }
5757adf3
HD
379 if ($installType == 'backdrop') {
380 $dbReq->checkdatabase($backdropConfig, 'Backdrop');
381 }
6a488035
TO
382}
383
384// Actual processor
aca6ce6e 385if (isset($_POST['go']) && !$req->hasErrors() && !$dbReq->hasErrors()) {
6a488035 386 // Confirm before reinstalling
aca6ce6e 387 if (!isset($_POST['force_reinstall']) && $alreadyInstalled) {
1f5f3294 388 include $installDirPath . 'template.html';
6a488035
TO
389 }
390 else {
391 $inst = new Installer();
aca6ce6e 392 $inst->install($_POST);
6a488035
TO
393 }
394
395 // Show the config form
396}
397else {
1f5f3294 398 include $installDirPath . 'template.html';
6a488035
TO
399}
400
401/**
402 * This class checks requirements
403 * Each of the requireXXX functions takes an argument which gives a user description of the test. It's an array
404 * of 3 parts:
6a9514e1 405 * $description[0] - The test category
6a488035
TO
406 * $description[1] - The test title
407 * $description[2] - The test error to show, if it goes wrong
408 */
409class InstallRequirements {
410 var $errors, $warnings, $tests;
411
412 // @see CRM_Upgrade_Form::MINIMUM_THREAD_STACK
413 const MINIMUM_THREAD_STACK = 192;
414
415 /**
fe482240 416 * Just check that the database configuration is okay.
d7c8cf03
EM
417 * @param $databaseConfig
418 * @param $dbName
6a488035 419 */
971d41b1 420 public function checkdatabase($databaseConfig, $dbName) {
6a488035 421 if ($this->requireFunction('mysql_connect',
56fdfc52 422 array(
97b8e6b2 423 ts("PHP Configuration"),
424 ts("MySQL support"),
425 ts("MySQL support not included in PHP."),
56fdfc52
TO
426 )
427 )
428 ) {
6a488035
TO
429 $this->requireMySQLServer($databaseConfig['server'],
430 array(
2f8082cd
ML
431 ts("MySQL %1 Configuration", array(1 => $dbName)),
432 ts("Does the server exist?"),
433 ts("Can't find the a MySQL server on '%1'.", array(1 => $databaseConfig['server'])),
6a488035
TO
434 $databaseConfig['server'],
435 )
436 );
437 if ($this->requireMysqlConnection($databaseConfig['server'],
56fdfc52
TO
438 $databaseConfig['username'],
439 $databaseConfig['password'],
440 array(
2f8082cd
ML
441 ts("MySQL %1 Configuration", array(1 => $dbName)),
442 ts("Are the access credentials correct?"),
443 ts("That username/password doesn't work"),
56fdfc52
TO
444 )
445 )
446 ) {
6a488035
TO
447 @$this->requireMySQLVersion("5.1",
448 array(
2f8082cd
ML
449 ts("MySQL %1 Configuration", array(1 => $dbName)),
450 ts("MySQL version at least %1", array(1 => '5.1')),
451 ts("MySQL version %1 or higher is required, you are running MySQL %2.", array(1 => '5.1', 2 => mysql_get_server_info())),
452 ts("MySQL %1", array(1 => mysql_get_server_info())),
6a488035
TO
453 )
454 );
455 $this->requireMySQLAutoIncrementIncrementOne($databaseConfig['server'],
456 $databaseConfig['username'],
457 $databaseConfig['password'],
458 array(
2f8082cd
ML
459 ts("MySQL %1 Configuration", array(1 => $dbName)),
460 ts("Is auto_increment_increment set to 1"),
461 ts("An auto_increment_increment value greater than 1 is not currently supported. Please see issue CRM-7923 for further details and potential workaround."),
6a488035
TO
462 )
463 );
e5d3a11d
PN
464 $testDetails = array(
465 ts("MySQL %1 Configuration", array(1 => $dbName)),
466 ts("Is the provided database name valid?"),
467 ts("The database name provided is not valid. Please use only 0-9, a-z, A-Z and _ as characters in the name."),
468 );
469 if (!CRM_Core_DAO::requireValidDBName($databaseConfig['database'])) {
470 $this->error($testDetails);
ff3f52f7
PN
471 return FALSE;
472 }
e5d3a11d
PN
473 else {
474 $this->testing($testDetails);
475 }
6a488035
TO
476 $this->requireMySQLThreadStack($databaseConfig['server'],
477 $databaseConfig['username'],
478 $databaseConfig['password'],
479 $databaseConfig['database'],
480 self::MINIMUM_THREAD_STACK,
481 array(
2f8082cd
ML
482 ts("MySQL %1 Configuration", array(1 => $dbName)),
483 ts("Does MySQL thread_stack meet minimum (%1k)", array(1 => self::MINIMUM_THREAD_STACK)),
56fdfc52
TO
484 "",
485 // "The MySQL thread_stack does not meet minimum " . CRM_Upgrade_Form::MINIMUM_THREAD_STACK . "k. Please update thread_stack in my.cnf.",
6a488035
TO
486 )
487 );
488 }
5757adf3 489 $onlyRequire = ($dbName == 'Drupal' || $dbName == 'Backdrop') ? TRUE : FALSE;
6a488035
TO
490 $this->requireDatabaseOrCreatePermissions(
491 $databaseConfig['server'],
492 $databaseConfig['username'],
493 $databaseConfig['password'],
494 $databaseConfig['database'],
495 array(
2f8082cd
ML
496 ts("MySQL %1 Configuration", array(1 => $dbName)),
497 ts("Can I access/create the database?"),
5f40a878 498 ts("I can't create new databases and the database '%1' doesn't exist.", array(1 => $databaseConfig['database'])),
6a488035
TO
499 ),
500 $onlyRequire
501 );
5757adf3 502 if ($dbName != 'Drupal' && $dbName != 'Backdrop') {
6a488035
TO
503 $this->requireMySQLInnoDB($databaseConfig['server'],
504 $databaseConfig['username'],
505 $databaseConfig['password'],
506 $databaseConfig['database'],
507 array(
2f8082cd
ML
508 ts("MySQL %1 Configuration", array(1 => $dbName)),
509 ts("Can I access/create InnoDB tables in the database?"),
510 ts("Unable to create InnoDB tables. MySQL InnoDB support is required for CiviCRM but is either not available or not enabled in this MySQL database server."),
6a488035
TO
511 )
512 );
513 $this->requireMySQLTempTables($databaseConfig['server'],
514 $databaseConfig['username'],
515 $databaseConfig['password'],
516 $databaseConfig['database'],
517 array(
2f8082cd
ML
518 ts("MySQL %1 Configuration", array(1 => $dbName)),
519 ts('Can I create temporary tables in the database?'),
520 ts('Unable to create temporary tables. This MySQL user is missing the CREATE TEMPORARY TABLES privilege.'),
6a488035
TO
521 )
522 );
523 $this->requireMySQLLockTables($databaseConfig['server'],
524 $databaseConfig['username'],
525 $databaseConfig['password'],
526 $databaseConfig['database'],
527 array(
2f8082cd
ML
528 ts("MySQL %1 Configuration", array(1 => $dbName)),
529 ts('Can I create lock tables in the database?'),
530 ts('Unable to lock tables. This MySQL user is missing the LOCK TABLES privilege.'),
6a488035
TO
531 )
532 );
533 $this->requireMySQLTrigger($databaseConfig['server'],
534 $databaseConfig['username'],
535 $databaseConfig['password'],
536 $databaseConfig['database'],
537 array(
2f8082cd
ML
538 ts("MySQL %1 Configuration", array(1 => $dbName)),
539 ts('Can I create triggers in the database?'),
540 ts('Unable to create triggers. This MySQL user is missing the CREATE TRIGGERS privilege.'),
6a488035
TO
541 )
542 );
543 }
544 }
545 }
546
547 /**
fe482240 548 * Check everything except the database.
6a488035 549 */
971d41b1 550 public function check() {
6a488035
TO
551 global $crmPath, $installType;
552
553 $this->errors = NULL;
554
678d6d82 555 $this->requirePHPVersion('5.3.4', array(
2f8082cd
ML
556 ts("PHP Configuration"),
557 ts("PHP5 installed"),
56fdfc52 558 NULL,
2f8082cd 559 ts("PHP version %1", array(1 => phpversion())),
56fdfc52 560 ));
6a488035
TO
561
562 // Check that we can identify the root folder successfully
563 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . 'README.txt',
564 array(
2f8082cd
ML
565 ts("File permissions"),
566 ts("Does the webserver know where files are stored?"),
567 ts("The webserver isn't letting me identify where files are stored."),
6a488035
TO
568 $this->getBaseDir(),
569 ),
570 TRUE
571 );
572
573 // CRM-6485: make sure the path does not contain PATH_SEPARATOR, as we don’t know how to escape it
574 $this->requireNoPathSeparator(
575 array(
2f8082cd
ML
576 ts("File permissions"),
577 ts('Does the CiviCRM path contain PATH_SEPARATOR?'),
578 ts('The path %1 contains PATH_SEPARATOR (the %2 character).', array(1 => $this->getBaseDir(), 2 => PATH_SEPARATOR)),
6a488035
TO
579 $this->getBaseDir(),
580 )
581 );
582
583 $requiredDirectories = array('CRM', 'packages', 'templates', 'js', 'api', 'i', 'sql');
584 foreach ($requiredDirectories as $dir) {
585 $this->requireFile($crmPath . CIVICRM_DIRECTORY_SEPARATOR . $dir,
586 array(
2f8082cd
ML
587 ts("File permissions"),
588 ts("Folder '%1' exists?", array(1 => $dir)),
589 ts("There is no '%1' folder.", array(1 => $dir)),
56fdfc52 590 ), TRUE
6a488035
TO
591 );
592 }
593
594 $configIDSiniDir = NULL;
595 global $cmsPath;
3fdcdfbb 596 $siteDir = getSiteDir($cmsPath, $_SERVER['SCRIPT_FILENAME']);
6a488035 597 if ($installType == 'drupal') {
6a488035
TO
598
599 // make sure that we can write to sites/default and files/
600 $writableDirectories = array(
601 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
602 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
603 $siteDir . CIVICRM_DIRECTORY_SEPARATOR .
604 'files',
605 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
606 'sites' . CIVICRM_DIRECTORY_SEPARATOR .
607 $siteDir,
608 );
609 }
5757adf3
HD
610 elseif ($installType == 'backdrop') {
611
612 // make sure that we can write to sites/default and files/
613 $writableDirectories = array(
614 $cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
615 'files',
616 $cmsPath,
617 );
618 }
6a488035 619 elseif ($installType == 'wordpress') {
7ba2c8ad
KC
620 // make sure that we can write to uploads/civicrm/
621 $upload_dir = wp_upload_dir();
622 $files_dirname = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'civicrm';
623 if (!file_exists($files_dirname)) {
624 wp_mkdir_p($files_dirname);
625 }
626 $writableDirectories = array($files_dirname);
6a488035
TO
627 }
628
629 foreach ($writableDirectories as $dir) {
630 $dirName = CIVICRM_WINDOWS ? $dir : CIVICRM_DIRECTORY_SEPARATOR . $dir;
2f8082cd
ML
631 $testDetails = array(
632 ts("File permissions"),
633 ts("Is the %1 folder writeable?", array(1 => $dir)),
634 NULL,
6a488035 635 );
2f8082cd 636 $this->requireWriteable($dirName, $testDetails, TRUE);
6a488035
TO
637 }
638
639 //check for Config.IDS.ini, file may exist in re-install
640 $configIDSiniDir = array($cmsPath, 'sites', $siteDir, 'files', 'civicrm', 'upload', 'Config.IDS.ini');
641
642 if (is_array($configIDSiniDir) && !empty($configIDSiniDir)) {
643 $configIDSiniFile = implode(CIVICRM_DIRECTORY_SEPARATOR, $configIDSiniDir);
644 if (file_exists($configIDSiniFile)) {
645 unlink($configIDSiniFile);
646 }
647 }
648
649 // Check for rewriting
650 if (isset($_SERVER['SERVER_SOFTWARE'])) {
651 $webserver = strip_tags(trim($_SERVER['SERVER_SOFTWARE']));
652 }
653 elseif (isset($_SERVER['SERVER_SIGNATURE'])) {
654 $webserver = strip_tags(trim($_SERVER['SERVER_SIGNATURE']));
655 }
656
657 if ($webserver == '') {
2f8082cd 658 $webserver = ts("I can't tell what webserver you are running");
6a488035
TO
659 }
660
661 // Check for $_SERVER configuration
56fdfc52 662 $this->requireServerVariables(array('SCRIPT_NAME', 'HTTP_HOST', 'SCRIPT_FILENAME'), array(
2f8082cd
ML
663 ts("Webserver config"),
664 ts("Recognised webserver"),
665 ts("You seem to be using an unsupported webserver. The server variables SCRIPT_NAME, HTTP_HOST, SCRIPT_FILENAME need to be set."),
56fdfc52 666 ));
6a488035
TO
667
668 // Check for MySQL support
2f8082cd
ML
669 $this->requireFunction('mysql_connect', array(
670 ts("PHP Configuration"),
671 ts("MySQL support"),
672 ts("MySQL support not included in PHP."),
673 ));
6a488035
TO
674
675 // Check for JSON support
2f8082cd
ML
676 $this->requireFunction('json_encode', array(
677 ts("PHP Configuration"),
678 ts("JSON support"),
679 ts("JSON support not included in PHP."),
680 ));
6a488035
TO
681
682 // Check for xcache_isset and emit warning if exists
683 $this->checkXCache(array(
2f8082cd
ML
684 ts("PHP Configuration"),
685 ts("XCache compatibility"),
686 ts("XCache is installed and there are known compatibility issues between XCache and CiviCRM. Consider using an alternative PHP caching mechanism or disable PHP caching altogether."),
56fdfc52 687 ));
6a488035
TO
688
689 // Check memory allocation
690 $this->requireMemory(32 * 1024 * 1024,
691 64 * 1024 * 1024,
692 array(
2f8082cd
ML
693 ts("PHP Configuration"),
694 ts("Memory allocated (PHP config option 'memory_limit')"),
695 ts("CiviCRM needs a minimum of %1 MB allocated to PHP, but recommends %2 MB.", array(1 => 32, 2 => 64)),
6a488035
TO
696 ini_get("memory_limit"),
697 )
698 );
699
700 return $this->errors;
701 }
702
627456b5
EM
703 /**
704 * @param $min
705 * @param $recommended
706 * @param $testDetails
707 */
971d41b1 708 public function requireMemory($min, $recommended, $testDetails) {
6a488035
TO
709 $this->testing($testDetails);
710 $mem = $this->getPHPMemory();
711
712 if ($mem < $min && $mem > 0) {
2f8082cd 713 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
6a488035
TO
714 $this->error($testDetails);
715 }
716 elseif ($mem < $recommended && $mem > 0) {
2f8082cd 717 $testDetails[2] .= " " . ts("You only have %1 allocated", array(1 => ini_get("memory_limit")));
6a488035
TO
718 $this->warning($testDetails);
719 }
720 elseif ($mem == 0) {
2f8082cd 721 $testDetails[2] .= " " . ts("We can't determine how much memory you have allocated. Install only if you're sure you've allocated at least %1 MB.", array(1 => 32));
6a488035
TO
722 $this->warning($testDetails);
723 }
724 }
725
627456b5
EM
726 /**
727 * @return float
728 */
971d41b1 729 public function getPHPMemory() {
6a488035
TO
730 $memString = ini_get("memory_limit");
731
732 switch (strtolower(substr($memString, -1))) {
733 case "k":
734 return round(substr($memString, 0, -1) * 1024);
735
736 case "m":
737 return round(substr($memString, 0, -1) * 1024 * 1024);
738
739 case "g":
740 return round(substr($memString, 0, -1) * 1024 * 1024 * 1024);
741
742 default:
743 return round($memString);
744 }
745 }
746
971d41b1 747 public function listErrors() {
6a488035 748 if ($this->errors) {
2f8082cd 749 echo "<p>" . ts("The following problems are preventing me from installing CiviCRM:") . "</p>";
6a488035
TO
750 foreach ($this->errors as $error) {
751 echo "<li>" . htmlentities($error) . "</li>";
752 }
753 }
754 }
755
627456b5
EM
756 /**
757 * @param null $section
758 */
971d41b1 759 public function showTable($section = NULL) {
6a488035
TO
760 if ($section) {
761 $tests = $this->tests[$section];
762 echo "<table class=\"testResults\" width=\"100%\">";
763 foreach ($tests as $test => $result) {
764 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
765 }
766 echo "</table>";
767 }
768 else {
769 foreach ($this->tests as $section => $tests) {
770 echo "<h3>$section</h3>";
771 echo "<table class=\"testResults\" width=\"100%\">";
772
773 foreach ($tests as $test => $result) {
774 echo "<tr class=\"$result[0]\"><td>$test</td><td>" . nl2br(htmlentities($result[1])) . "</td></tr>";
775 }
776 echo "</table>";
777 }
778 }
779 }
780
627456b5 781 /**
100fef9d 782 * @param string $funcName
627456b5
EM
783 * @param $testDetails
784 *
785 * @return bool
786 */
971d41b1 787 public function requireFunction($funcName, $testDetails) {
6a488035
TO
788 $this->testing($testDetails);
789
790 if (!function_exists($funcName)) {
791 $this->error($testDetails);
792 return FALSE;
793 }
794 else {
795 return TRUE;
796 }
797 }
798
627456b5
EM
799 /**
800 * @param $testDetails
801 */
971d41b1 802 public function checkXCache($testDetails) {
6a488035
TO
803 if (function_exists('xcache_isset') &&
804 ini_get('xcache.size') > 0
805 ) {
806 $this->testing($testDetails);
807 $this->warning($testDetails);
808 }
809 }
810
627456b5
EM
811 /**
812 * @param $minVersion
813 * @param $testDetails
814 * @param null $maxVersion
815 */
971d41b1 816 public function requirePHPVersion($minVersion, $testDetails, $maxVersion = NULL) {
6a488035
TO
817
818 $this->testing($testDetails);
819
56fdfc52 820 $phpVersion = phpversion();
6a488035
TO
821 $aboveMinVersion = version_compare($phpVersion, $minVersion) >= 0;
822 $belowMaxVersion = $maxVersion ? version_compare($phpVersion, $maxVersion) < 0 : TRUE;
823
ef064e55
CW
824 if ($aboveMinVersion && $belowMaxVersion) {
825 if (version_compare(phpversion(), CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER) < 0) {
826 $testDetails[2] = ts('This webserver is running an outdated version of PHP (%1). It is strongly recommended to upgrade to PHP %2 or later, as older versions can present a security risk.', array(
827 1 => phpversion(),
828 2 => CRM_Upgrade_Incremental_General::MIN_RECOMMENDED_PHP_VER,
829 ));
830 $this->warning($testDetails);
831 }
6a488035
TO
832 return TRUE;
833 }
834
835 if (!$testDetails[2]) {
836 if (!$aboveMinVersion) {
2f8082cd 837 $testDetails[2] = ts("You need PHP version %1 or later, only %2 is installed. Please upgrade your server, or ask your web-host to do so.", array(1 => $minVersion, 2 => $phpVersion));
6a488035
TO
838 }
839 else {
2f8082cd 840 $testDetails[2] = ts("PHP version %1 is not supported. PHP version earlier than %2 is required. You might want to downgrade your server, or ask your web-host to do so.", array(1 => $maxVersion, 2 => $phpVersion));
6a488035
TO
841 }
842 }
843
844 $this->error($testDetails);
845 }
846
627456b5 847 /**
100fef9d 848 * @param string $filename
627456b5
EM
849 * @param $testDetails
850 * @param bool $absolute
851 */
971d41b1 852 public function requireFile($filename, $testDetails, $absolute = FALSE) {
6a488035
TO
853 $this->testing($testDetails);
854 if (!$absolute) {
855 $filename = $this->getBaseDir() . $filename;
856 }
857 if (!file_exists($filename)) {
2f8082cd 858 $testDetails[2] .= " (" . ts("file '%1' not found", array(1 => $filename)) . ')';
6a488035
TO
859 $this->error($testDetails);
860 }
861 }
862
627456b5
EM
863 /**
864 * @param $testDetails
865 */
971d41b1 866 public function requireNoPathSeparator($testDetails) {
6a488035
TO
867 $this->testing($testDetails);
868 if (substr_count($this->getBaseDir(), PATH_SEPARATOR)) {
869 $this->error($testDetails);
870 }
871 }
872
627456b5 873 /**
100fef9d 874 * @param string $filename
627456b5
EM
875 * @param $testDetails
876 */
971d41b1 877 public function requireNoFile($filename, $testDetails) {
6a488035
TO
878 $this->testing($testDetails);
879 $filename = $this->getBaseDir() . $filename;
880 if (file_exists($filename)) {
2f8082cd 881 $testDetails[2] .= " (" . ts("file '%1' found", array(1 => $filename)) . ")";
6a488035
TO
882 $this->error($testDetails);
883 }
884 }
885
627456b5 886 /**
100fef9d 887 * @param string $filename
627456b5
EM
888 * @param $testDetails
889 */
971d41b1 890 public function moveFileOutOfTheWay($filename, $testDetails) {
6a488035
TO
891 $this->testing($testDetails);
892 $filename = $this->getBaseDir() . $filename;
893 if (file_exists($filename)) {
894 if (file_exists("$filename.bak")) {
895 rm("$filename.bak");
896 }
897 rename($filename, "$filename.bak");
898 }
899 }
900
627456b5 901 /**
100fef9d 902 * @param string $filename
627456b5
EM
903 * @param $testDetails
904 * @param bool $absolute
905 */
971d41b1 906 public function requireWriteable($filename, $testDetails, $absolute = FALSE) {
6a488035
TO
907 $this->testing($testDetails);
908 if (!$absolute) {
909 $filename = $this->getBaseDir() . $filename;
910 }
911
22e263ad 912 if (!is_writable($filename)) {
6a488035
TO
913 $name = NULL;
914 if (function_exists('posix_getpwuid')) {
915 $user = posix_getpwuid(posix_geteuid());
916 $name = '- ' . $user['name'] . ' -';
917 }
918
919 if (!isset($testDetails[2])) {
920 $testDetails[2] = NULL;
921 }
2f8082cd 922 $testDetails[2] .= ts("The user account used by your web-server %1 needs to be granted write access to the following directory in order to configure the CiviCRM settings file:", array(1 => $name)) . "\n$filename";
6a488035
TO
923 $this->error($testDetails);
924 }
925 }
926
627456b5 927 /**
100fef9d 928 * @param string $moduleName
627456b5
EM
929 * @param $testDetails
930 */
971d41b1 931 public function requireApacheModule($moduleName, $testDetails) {
6a488035
TO
932 $this->testing($testDetails);
933 if (!in_array($moduleName, apache_get_modules())) {
934 $this->error($testDetails);
935 }
936 }
937
627456b5
EM
938 /**
939 * @param $server
100fef9d 940 * @param string $username
627456b5
EM
941 * @param $password
942 * @param $testDetails
943 */
971d41b1 944 public function requireMysqlConnection($server, $username, $password, $testDetails) {
6a488035
TO
945 $this->testing($testDetails);
946 $conn = @mysql_connect($server, $username, $password);
947
948 if ($conn) {
949 return TRUE;
950 }
951 else {
952 $testDetails[2] .= ": " . mysql_error();
953 $this->error($testDetails);
954 }
955 }
956
627456b5
EM
957 /**
958 * @param $server
959 * @param $testDetails
960 */
971d41b1 961 public function requireMySQLServer($server, $testDetails) {
6a488035
TO
962 $this->testing($testDetails);
963 $conn = @mysql_connect($server, NULL, NULL);
964
965 if ($conn || mysql_errno() < 2000) {
966 return TRUE;
967 }
968 else {
969 $testDetails[2] .= ": " . mysql_error();
970 $this->error($testDetails);
971 }
972 }
973
627456b5
EM
974 /**
975 * @param $version
976 * @param $testDetails
977 */
971d41b1 978 public function requireMySQLVersion($version, $testDetails) {
6a488035
TO
979 $this->testing($testDetails);
980
981 if (!mysql_get_server_info()) {
2f8082cd 982 $testDetails[2] = ts('Cannot determine the version of MySQL installed. Please ensure at least version %1 is installed.', array(1 => $version));
6a488035
TO
983 $this->warning($testDetails);
984 }
985 else {
986 list($majorRequested, $minorRequested) = explode('.', $version);
987 list($majorHas, $minorHas) = explode('.', mysql_get_server_info());
988
989 if (($majorHas > $majorRequested) || ($majorHas == $majorRequested && $minorHas >= $minorRequested)) {
990 return TRUE;
991 }
992 else {
993 $testDetails[2] .= "{$majorHas}.{$minorHas}.";
994 $this->error($testDetails);
995 }
996 }
997 }
998
627456b5
EM
999 /**
1000 * @param $server
100fef9d 1001 * @param string $username
627456b5
EM
1002 * @param $password
1003 * @param $database
1004 * @param $testDetails
1005 */
971d41b1 1006 public function requireMySQLInnoDB($server, $username, $password, $database, $testDetails) {
6a488035
TO
1007 $this->testing($testDetails);
1008 $conn = @mysql_connect($server, $username, $password);
1009 if (!$conn) {
2f8082cd 1010 $testDetails[2] .= ' ' . ts("Could not determine if MySQL has InnoDB support. Assuming no.");
6a488035
TO
1011 $this->error($testDetails);
1012 return;
1013 }
1014
1015 $innodb_support = FALSE;
1016 $result = mysql_query("SHOW ENGINES", $conn);
1017 while ($values = mysql_fetch_array($result)) {
1018 if ($values['Engine'] == 'InnoDB') {
1019 if (strtolower($values['Support']) == 'yes' ||
1020 strtolower($values['Support']) == 'default'
1021 ) {
1022 $innodb_support = TRUE;
1023 }
1024 }
1025 }
1026 if ($innodb_support) {
2f8082cd 1027 $testDetails[3] = ts('MySQL server does have InnoDB support');
6a488035
TO
1028 }
1029 else {
2f8082cd 1030 $testDetails[2] .= ' ' . ts('Could not determine if MySQL has InnoDB support. Assuming no');
6a488035
TO
1031 }
1032 }
1033
627456b5
EM
1034 /**
1035 * @param $server
100fef9d 1036 * @param string $username
627456b5
EM
1037 * @param $password
1038 * @param $database
1039 * @param $testDetails
1040 */
971d41b1 1041 public function requireMySQLTempTables($server, $username, $password, $database, $testDetails) {
6a488035
TO
1042 $this->testing($testDetails);
1043 $conn = @mysql_connect($server, $username, $password);
1044 if (!$conn) {
2f8082cd 1045 $testDetails[2] = ts('Could not login to the database.');
6a488035
TO
1046 $this->error($testDetails);
1047 return;
1048 }
1049
1050 if (!@mysql_select_db($database, $conn)) {
2f8082cd 1051 $testDetails[2] = ts('Could not select the database.');
6a488035
TO
1052 $this->error($testDetails);
1053 return;
1054 }
1055
1056 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1057 if (!$result) {
2f8082cd 1058 $testDetails[2] = ts('Could not create a temp table.');
6a488035
TO
1059 $this->error($testDetails);
1060 }
1061 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1062 }
1063
627456b5
EM
1064 /**
1065 * @param $server
100fef9d 1066 * @param string $username
627456b5
EM
1067 * @param $password
1068 * @param $database
1069 * @param $testDetails
1070 */
971d41b1 1071 public function requireMySQLTrigger($server, $username, $password, $database, $testDetails) {
6a488035
TO
1072 $this->testing($testDetails);
1073 $conn = @mysql_connect($server, $username, $password);
1074 if (!$conn) {
2f8082cd 1075 $testDetails[2] = ts('Could not login to the database.');
6a488035
TO
1076 $this->error($testDetails);
1077 return;
1078 }
1079
1080 if (!@mysql_select_db($database, $conn)) {
2f8082cd 1081 $testDetails[2] = ts('Could not select the database.');
6a488035
TO
1082 $this->error($testDetails);
1083 return;
1084 }
1085
1086 $result = mysql_query('CREATE TABLE civicrm_install_temp_table_test (test text)', $conn);
1087 if (!$result) {
2f8082cd 1088 $testDetails[2] = ts('Could not create a table in the database.');
6a488035
TO
1089 $this->error($testDetails);
1090 }
1091
1092 $result = mysql_query('CREATE TRIGGER civicrm_install_temp_table_test_trigger BEFORE INSERT ON civicrm_install_temp_table_test FOR EACH ROW BEGIN END');
1093 if (!$result) {
1094 mysql_query('DROP TABLE civicrm_install_temp_table_test');
2f8082cd 1095 $testDetails[2] = ts('Could not create a database trigger.');
6a488035
TO
1096 $this->error($testDetails);
1097 }
1098
6a488035
TO
1099 mysql_query('DROP TRIGGER civicrm_install_temp_table_test_trigger');
1100 mysql_query('DROP TABLE civicrm_install_temp_table_test');
1101 }
1102
1103
627456b5
EM
1104 /**
1105 * @param $server
100fef9d 1106 * @param string $username
627456b5
EM
1107 * @param $password
1108 * @param $database
1109 * @param $testDetails
1110 */
971d41b1 1111 public function requireMySQLLockTables($server, $username, $password, $database, $testDetails) {
6a488035
TO
1112 $this->testing($testDetails);
1113 $conn = @mysql_connect($server, $username, $password);
1114 if (!$conn) {
2f8082cd 1115 $testDetails[2] = ts('Could not connect to the database server.');
6a488035
TO
1116 $this->error($testDetails);
1117 return;
1118 }
1119
1120 if (!@mysql_select_db($database, $conn)) {
2f8082cd 1121 $testDetails[2] = ts('Could not select the database.');
6a488035
TO
1122 $this->error($testDetails);
1123 return;
1124 }
1125
1126 $result = mysql_query('CREATE TEMPORARY TABLE civicrm_install_temp_table_test (test text)', $conn);
1127 if (!$result) {
2f8082cd 1128 $testDetails[2] = ts('Could not create a table in the database.');
6a488035
TO
1129 $this->error($testDetails);
1130 return;
1131 }
1132
1133 $result = mysql_query('LOCK TABLES civicrm_install_temp_table_test WRITE', $conn);
1134 if (!$result) {
2f8082cd 1135 $testDetails[2] = ts('Could not obtain a write lock for the database table.');
6a488035
TO
1136 $this->error($testDetails);
1137 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1138 return;
1139 }
1140
1141 $result = mysql_query('UNLOCK TABLES', $conn);
1142 if (!$result) {
2f8082cd 1143 $testDetails[2] = ts('Could not release the lock for the database table.');
6a488035
TO
1144 $this->error($testDetails);
1145 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
1146 return;
1147 }
1148
1149 $result = mysql_query('DROP TEMPORARY TABLE civicrm_install_temp_table_test');
6a488035
TO
1150 }
1151
627456b5
EM
1152 /**
1153 * @param $server
100fef9d 1154 * @param string $username
627456b5
EM
1155 * @param $password
1156 * @param $testDetails
1157 */
971d41b1 1158 public function requireMySQLAutoIncrementIncrementOne($server, $username, $password, $testDetails) {
6a488035
TO
1159 $this->testing($testDetails);
1160 $conn = @mysql_connect($server, $username, $password);
1161 if (!$conn) {
2f8082cd 1162 $testDetails[2] = ts('Could not connect to the database server.');
6a488035
TO
1163 $this->error($testDetails);
1164 return;
1165 }
1166
1167 $result = mysql_query("SHOW variables like 'auto_increment_increment'", $conn);
1168 if (!$result) {
2f8082cd 1169 $testDetails[2] = ts('Could not query database server variables.');
6a488035
TO
1170 $this->error($testDetails);
1171 return;
1172 }
1173 else {
1174 $values = mysql_fetch_row($result);
1175 if ($values[1] == 1) {
2f8082cd 1176 $testDetails[3] = ts('MySQL server auto_increment_increment is 1');
6a488035
TO
1177 }
1178 else {
1179 $this->error($testDetails);
1180 }
1181 }
1182 }
1183
627456b5
EM
1184 /**
1185 * @param $server
100fef9d 1186 * @param string $username
627456b5
EM
1187 * @param $password
1188 * @param $database
1189 * @param $minValueKB
1190 * @param $testDetails
1191 */
971d41b1 1192 public function requireMySQLThreadStack($server, $username, $password, $database, $minValueKB, $testDetails) {
6a488035
TO
1193 $this->testing($testDetails);
1194 $conn = @mysql_connect($server, $username, $password);
1195 if (!$conn) {
2f8082cd 1196 $testDetails[2] = ts('Could not connect to the database server.');
6a488035
TO
1197 $this->error($testDetails);
1198 return;
1199 }
1200
1201 if (!@mysql_select_db($database, $conn)) {
2f8082cd 1202 $testDetails[2] = ts('Could not select the database.');
6a488035
TO
1203 $this->error($testDetails);
1204 return;
1205 }
1206
032c9d10 1207 $result = mysql_query("SHOW VARIABLES LIKE 'thread_stack'", $conn); // bytes => kb
6a488035 1208 if (!$result) {
2f8082cd 1209 $testDetails[2] = ts('Could not get information about the thread_stack of the database.');
6a488035 1210 $this->error($testDetails);
0db6c3e1
TO
1211 }
1212 else {
6a488035 1213 $values = mysql_fetch_row($result);
1f5f3294 1214 if ($values[1] < (1024 * $minValueKB)) {
2f8082cd 1215 $testDetails[2] = ts('MySQL "thread_stack" is %1 kb', array(1 => ($values[1] / 1024)));
6a488035
TO
1216 $this->error($testDetails);
1217 }
1218 }
1219 }
1220
627456b5
EM
1221 /**
1222 * @param $server
100fef9d 1223 * @param string $username
627456b5
EM
1224 * @param $password
1225 * @param $database
1226 * @param $testDetails
1227 * @param bool $onlyRequire
1228 */
971d41b1 1229 public function requireDatabaseOrCreatePermissions(
56fdfc52 1230 $server,
6a488035
TO
1231 $username,
1232 $password,
1233 $database,
1234 $testDetails,
1235 $onlyRequire = FALSE
1236 ) {
1237 $this->testing($testDetails);
1238 $conn = @mysql_connect($server, $username, $password);
1239
1240 $okay = NULL;
1241 if (@mysql_select_db($database)) {
1242 $okay = "Database '$database' exists";
1243 }
1244 elseif ($onlyRequire) {
2f8082cd 1245 $testDetails[2] = ts("The database: '%1' does not exist.", array(1 => $database));
6a488035
TO
1246 $this->error($testDetails);
1247 return;
1248 }
1249 else {
c4799e35
PN
1250 $query = sprintf("CREATE DATABASE %s", mysql_real_escape_string($database));
1251 if (@mysql_query($query)) {
2f8082cd 1252 $okay = ts("Able to create a new database.");
6a488035
TO
1253 }
1254 else {
2f8082cd 1255 $testDetails[2] .= " (" . ts("user '%1' doesn't have CREATE DATABASE permissions.", array(1 => $username)) . ")";
6a488035
TO
1256 $this->error($testDetails);
1257 return;
1258 }
1259 }
1260
1261 if ($okay) {
1262 $testDetails[3] = $okay;
1263 $this->testing($testDetails);
1264 }
1265 }
1266
627456b5
EM
1267 /**
1268 * @param $varNames
1269 * @param $errorMessage
1270 */
971d41b1 1271 public function requireServerVariables($varNames, $errorMessage) {
6a488035
TO
1272 //$this->testing($testDetails);
1273 foreach ($varNames as $varName) {
1274 if (!$_SERVER[$varName]) {
1275 $missing[] = '$_SERVER[' . $varName . ']';
1276 }
1277 }
1278 if (!isset($missing)) {
1279 return TRUE;
1280 }
1281 else {
2f8082cd 1282 $testDetails[2] = " (" . ts('the following PHP variables are missing: %1', array(1 => implode(", ", $missing))) . ")";
6a488035
TO
1283 $this->error($testDetails);
1284 }
1285 }
1286
627456b5
EM
1287 /**
1288 * @param $testDetails
1289 *
1290 * @return bool
1291 */
971d41b1 1292 public function isRunningApache($testDetails) {
6a488035
TO
1293 $this->testing($testDetails);
1294 if (function_exists('apache_get_modules') || stristr($_SERVER['SERVER_SIGNATURE'], 'Apache')) {
1295 return TRUE;
1296 }
1297
1298 $this->warning($testDetails);
1299 return FALSE;
1300 }
1301
627456b5
EM
1302 /**
1303 * @return string
1304 */
971d41b1 1305 public function getBaseDir() {
6a488035
TO
1306 return dirname($_SERVER['SCRIPT_FILENAME']) . CIVICRM_DIRECTORY_SEPARATOR;
1307 }
1308
627456b5
EM
1309 /**
1310 * @param $testDetails
1311 */
971d41b1 1312 public function testing($testDetails) {
6a488035
TO
1313 if (!$testDetails) {
1314 return;
1315 }
1316
1317 $section = $testDetails[0];
1318 $test = $testDetails[1];
1319
2f8082cd 1320 $message = ts("OK");
6a488035
TO
1321 if (isset($testDetails[3])) {
1322 $message .= " ($testDetails[3])";
1323 }
1324
1325 $this->tests[$section][$test] = array("good", $message);
1326 }
1327
627456b5
EM
1328 /**
1329 * @param $testDetails
1330 */
971d41b1 1331 public function error($testDetails) {
6a488035
TO
1332 $section = $testDetails[0];
1333 $test = $testDetails[1];
1334
1335 $this->tests[$section][$test] = array("error", $testDetails[2]);
1336 $this->errors[] = $testDetails;
1337 }
1338
627456b5
EM
1339 /**
1340 * @param $testDetails
1341 */
971d41b1 1342 public function warning($testDetails) {
6a488035
TO
1343 $section = $testDetails[0];
1344 $test = $testDetails[1];
1345
6a488035
TO
1346 $this->tests[$section][$test] = array("warning", $testDetails[2]);
1347 $this->warnings[] = $testDetails;
1348 }
1349
627456b5
EM
1350 /**
1351 * @return int
1352 */
971d41b1
CW
1353 public function hasErrors() {
1354 return count($this->errors);
6a488035
TO
1355 }
1356
627456b5
EM
1357 /**
1358 * @return int
1359 */
971d41b1
CW
1360 public function hasWarnings() {
1361 return count($this->warnings);
6a488035 1362 }
96025800 1363
6a488035
TO
1364}
1365
627456b5
EM
1366/**
1367 * Class Installer
1368 */
6a488035 1369class Installer extends InstallRequirements {
627456b5
EM
1370 /**
1371 * @param $server
1372 * @param $username
1373 * @param $password
1374 * @param $database
1375 */
971d41b1 1376 public function createDatabaseIfNotExists($server, $username, $password, $database) {
6a488035
TO
1377 $conn = @mysql_connect($server, $username, $password);
1378
1379 if (@mysql_select_db($database)) {
1380 // skip if database already present
1381 return;
1382 }
c4799e35
PN
1383 $query = sprintf("CREATE DATABASE %s", mysql_real_escape_string($database));
1384 if (@mysql_query($query)) {
56fdfc52 1385 }
6a488035 1386 else {
6a9514e1
ML
1387 $errorTitle = ts("Oops! Could not create database %1", array(1 => $database));
1388 $errorMsg = ts("We encountered an error when attempting to create the database. Please check your MySQL server permissions and the database name and try again.");
6a488035
TO
1389 errorDisplayPage($errorTitle, $errorMsg);
1390 }
1391 }
1392
627456b5
EM
1393 /**
1394 * @param $config
1395 *
1396 * @return mixed
1397 */
971d41b1 1398 public function install($config) {
6a488035
TO
1399 global $installDirPath;
1400
1401 // create database if does not exists
1402 $this->createDatabaseIfNotExists($config['mysql']['server'],
1403 $config['mysql']['username'],
1404 $config['mysql']['password'],
1405 $config['mysql']['database']
1406 );
1407
1408 global $installDirPath;
1409
1410 // Build database
1411 require_once $installDirPath . 'civicrm.php';
1412 civicrm_main($config);
1413
1414 if (!$this->errors) {
1415 global $installType, $installURLPath;
1416
bb216f68 1417 $registerSiteURL = "https://civicrm.org/register-site";
56de7273
ML
1418 $commonOutputMessage
1419 = "<li>" . ts("Have you registered this site at CiviCRM.org? If not, please help strengthen the CiviCRM ecosystem by taking a few minutes to <a %1>fill out the site registration form</a>. The information collected will help us prioritize improvements, target our communications and build the community. If you have a technical role for this site, be sure to check Keep in Touch to receive technical updates (a low volume mailing list).", array(1 => "href='$registerSiteURL' target='_blank'")) . "</li>"
1420 . "<li>" . ts("We have integrated KCFinder with CKEditor and TinyMCE. This allows a user to upload images. All uploaded images are public.") . "</li>";
41547a19 1421
6a488035 1422 $output = NULL;
97b8e6b2 1423
6a488035
TO
1424 if (
1425 $installType == 'drupal' &&
1426 version_compare(VERSION, '7.0-rc1') >= 0
1427 ) {
1428
1429 // clean output
1430 @ob_clean();
1431
1432 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1433 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1434 $output .= '<head>';
2f8082cd 1435 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
6a9514e1 1436 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
6a488035
TO
1437 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1438 $output .= '</head>';
1439 $output .= '<body>';
2f8082cd 1440 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
6a488035 1441 $output .= '<ul>';
6a9514e1 1442
6a488035
TO
1443 $drupalURL = civicrm_cms_base();
1444 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/people/permissions";
1445 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
6a488035 1446
6a9514e1
ML
1447 $output .= "<li>" . ts("Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$drupalPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1448 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$drupalURL'")) . "</li>";
1449 $output .= $commonOutputMessage;
6a488035
TO
1450
1451 // automatically enable CiviCRM module once it is installed successfully.
1452 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1453 global $cmsPath, $crmPath;
1454
1455 // relative / abosolute paths are not working for drupal, hence using chdir()
1456 chdir($cmsPath);
1457
97b8e6b2 1458 // Force the re-initialisation of the config singleton on the next call
1459 // since so far, we had used the Config object without loading the DB.
1460 $c = CRM_Core_Config::singleton(FALSE);
1461 $c->free();
1462
6a488035
TO
1463 include_once "./includes/bootstrap.inc";
1464 include_once "./includes/unicode.inc";
1465
1466 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1467
1468 // prevent session information from being saved.
1469 drupal_save_session(FALSE);
1470
1471 // Force the current user to anonymous.
1472 $original_user = $GLOBALS['user'];
1473 $GLOBALS['user'] = drupal_anonymous_user();
1474
1475 // explicitly setting error reporting, since we cannot handle drupal related notices
1476 error_reporting(1);
1477
1478 // rebuild modules, so that civicrm is added
1479 system_rebuild_module_data();
1480
1481 // now enable civicrm module.
1482 module_enable(array('civicrm', 'civicrmtheme'));
1483
d8a4acc0
C
1484 // clear block, page, theme, and hook caches
1485 drupal_flush_all_caches();
6a488035
TO
1486
1487 //add basic drupal permissions
1488 civicrm_install_set_drupal_perms();
1489
1490 // restore the user.
1491 $GLOBALS['user'] = $original_user;
1492 drupal_save_session(TRUE);
1493
e181e386 1494 //change the default language to one chosen
1495 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1496 civicrm_api3('Setting', 'create', array(
1497 'domain_id' => 'current_domain',
1498 'lcMessages' => $config['seedLanguage'],
1499 )
1500 );
1501 }
1502
6a488035
TO
1503 $output .= '</ul>';
1504 $output .= '</div>';
1505 $output .= '</body>';
1506 $output .= '</html>';
1507 echo $output;
1508 }
5757adf3
HD
1509 elseif (
1510 $installType == 'backdrop'
1511 ) {
1512
1513 // clean output
1514 @ob_clean();
1515
1516 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1517 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1518 $output .= '<head>';
1519 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1520 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
1521 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1522 $output .= '</head>';
1523 $output .= '<body>';
1524 $output .= '<div style="padding: 1em;"><p class="good">' . ts('CiviCRM has been successfully installed') . '</p>';
1525 $output .= '<ul>';
1526
1527 $backdropURL = civicrm_cms_base();
1528 $backdropPermissionsURL = "{$backdropURL}index.php?q=admin/config/people/permissions";
1529 $backdropURL .= "index.php?q=civicrm/admin/configtask&reset=1";
1530
1531 $output .= "<li>" . ts("Backdrop user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$backdropPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1532 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$backdropURL'")) . "</li>";
1533 $output .= $commonOutputMessage;
1534
1535 // automatically enable CiviCRM module once it is installed successfully.
1536 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1537 global $cmsPath, $crmPath;
1538
1539 // relative / abosolute paths are not working for drupal, hence using chdir()
1540 chdir($cmsPath);
1541
1542 // Force the re-initialisation of the config singleton on the next call
1543 // since so far, we had used the Config object without loading the DB.
1544 $c = CRM_Core_Config::singleton(FALSE);
1545 $c->free();
1546
1547 include_once "./core/includes/bootstrap.inc";
1548 include_once "./core/includes/unicode.inc";
1549
1550 backdrop_bootstrap(BACKDROP_BOOTSTRAP_FULL);
1551
1552 // prevent session information from being saved.
1553 backdrop_save_session(FALSE);
1554
1555 // Force the current user to anonymous.
1556 $original_user = $GLOBALS['user'];
1557 $GLOBALS['user'] = backdrop_anonymous_user();
1558
1559 // explicitly setting error reporting, since we cannot handle drupal related notices
1560 error_reporting(1);
1561
1562 // rebuild modules, so that civicrm is added
1563 system_rebuild_module_data();
1564
1565 // now enable civicrm module.
1566 module_enable(array('civicrm', 'civicrmtheme'));
1567
1568 // clear block, page, theme, and hook caches
1569 backdrop_flush_all_caches();
1570
1571 //add basic backdrop permissions
1572 civicrm_install_set_backdrop_perms();
1573
1574 // restore the user.
1575 $GLOBALS['user'] = $original_user;
1576 backdrop_save_session(TRUE);
1577
1578 //change the default language to one chosen
1579 if (isset($config['seedLanguage']) && $config['seedLanguage'] != 'en_US') {
1580 civicrm_api3('Setting', 'create', array(
1581 'domain_id' => 'current_domain',
1582 'lcMessages' => $config['seedLanguage'],
1583 )
1584 );
1585 }
1586
1587 $output .= '</ul>';
1588 $output .= '</div>';
1589 $output .= '</body>';
1590 $output .= '</html>';
1591 echo $output;
1592 }
6a488035
TO
1593 elseif ($installType == 'drupal' && version_compare(VERSION, '6.0') >= 0) {
1594 // clean output
1595 @ob_clean();
1596
1597 $output .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
1598 $output .= '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
1599 $output .= '<head>';
6a9514e1
ML
1600 $output .= '<title>' . ts('CiviCRM Installed') . '</title>';
1601 $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />';
6a488035
TO
1602 $output .= '<link rel="stylesheet" type="text/css" href="template.css" />';
1603 $output .= '</head>';
1604 $output .= '<body>';
97b8e6b2 1605 $output .= '<div style="padding: 1em;"><p class="good">' . ts("CiviCRM has been successfully installed") . '</p>';
6a488035 1606 $output .= '<ul>';
6a9514e1 1607
6a488035
TO
1608 $drupalURL = civicrm_cms_base();
1609 $drupalPermissionsURL = "{$drupalURL}index.php?q=admin/user/permissions";
1610 $drupalURL .= "index.php?q=civicrm/admin/configtask&reset=1";
6a488035 1611
6a9514e1
ML
1612 $output .= "<li>" . ts("Drupal user permissions have been automatically set - giving anonymous and authenticated users access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$drupalPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1613 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$drupalURL'")) . "</li>";
1614 $output .= $commonOutputMessage;
6a488035
TO
1615
1616 // explicitly setting error reporting, since we cannot handle drupal related notices
1617 error_reporting(1);
1618
1619 // automatically enable CiviCRM module once it is installed successfully.
1620 // so we need to Bootstrap Drupal, so that we can call drupal hooks.
1621 global $cmsPath, $crmPath;
1622
1623 // relative / abosolute paths are not working for drupal, hence using chdir()
1624 chdir($cmsPath);
1625
2f8082cd
ML
1626 // Force the re-initialisation of the config singleton on the next call
1627 // since so far, we had used the Config object without loading the DB.
1628 $c = CRM_Core_Config::singleton(FALSE);
1629 $c->free();
1630
6a488035
TO
1631 include_once "./includes/bootstrap.inc";
1632 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
1633
1634 // rebuild modules, so that civicrm is added
1635 module_rebuild_cache();
1636
1637 // now enable civicrm module.
1638 module_enable(array('civicrm'));
1639
d8a4acc0
C
1640 // clear block, page, theme, and hook caches
1641 drupal_flush_all_caches();
6a488035
TO
1642
1643 //add basic drupal permissions
1644 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)');
1645
1646 echo $output;
1647 }
1648 elseif ($installType == 'wordpress') {
6a9514e1 1649 echo '<h1>' . ts('CiviCRM Installed') . '</h1>';
97b8e6b2 1650 echo '<div style="padding: 1em;"><p style="background-color: #0C0; border: 1px #070 solid; color: white;">' . ts("CiviCRM has been successfully installed") . '</p>';
6a488035 1651 echo '<ul>';
6a488035
TO
1652
1653 $cmsURL = civicrm_cms_base();
1654 $cmsURL .= "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/configtask&reset=1";
41547a19
DL
1655 $wpPermissionsURL = "wp-admin/admin.php?page=CiviCRM&q=civicrm/admin/access/wp-permissions&reset=1";
1656
6a9514e1
ML
1657 $output .= "<li>" . ts("WordPress user permissions have been automatically set - giving Anonymous and Subscribers access to public CiviCRM forms and features. We recommend that you <a %1>review these permissions</a> to ensure that they are appropriate for your requirements (<a %2>learn more...</a>)", array(1 => "target='_blank' href='{$wpPermissionsURL}'", 2 => "target='_blank' href='http://wiki.civicrm.org/confluence/display/CRMDOC/Default+Permissions+and+Roles'")) . "</li>";
1658 $output .= "<li>" . ts("Use the <a %1>Configuration Checklist</a> to review and configure settings for your new site", array(1 => "target='_blank' href='$cmsURL'")) . "</li>";
1659 $output .= $commonOutputMessage;
41547a19 1660
1f5f3294
TO
1661 echo '</ul>';
1662 echo '</div>';
b232c132 1663
1664 $c = CRM_Core_Config::singleton(FALSE);
1665 $c->free();
7ba2c8ad
KC
1666 $wpInstallRedirect = admin_url("?page=CiviCRM&q=civicrm&reset=1");
1667 echo "<script>
1668 window.location = '$wpInstallRedirect';
1669 </script>";
1f5f3294
TO
1670 }
1671 }
6a488035
TO
1672
1673 return $this->errors;
1674 }
96025800 1675
6a488035
TO
1676}
1677
1678function civicrm_install_set_drupal_perms() {
1679 if (!function_exists('db_select')) {
1680 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)');
1681 }
1682 else {
1683 $perms = array(
1684 'access all custom data',
1685 'access uploaded files',
1686 'make online contributions',
1687 'profile create',
1688 'profile edit',
1689 'profile view',
1690 'register for events',
1691 'view event info',
1692 'view event participants',
1693 'access CiviMail subscribe/unsubscribe pages',
1694 );
1695
1696 // Adding a permission that has not yet been assigned to a module by
1697 // a hook_permission implementation results in a database error.
1698 // CRM-9042
1699 $allPerms = array_keys(module_invoke_all('permission'));
1700 foreach (array_diff($perms, $allPerms) as $perm) {
1701 watchdog('civicrm',
1702 'Cannot grant the %perm permission because it does not yet exist.',
971d41b1
CW
1703 array('%perm' => $perm),
1704 WATCHDOG_ERROR
6a488035
TO
1705 );
1706 }
1707 $perms = array_intersect($perms, $allPerms);
1708 user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, $perms);
1709 user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, $perms);
1710 }
1711}
1712
5757adf3
HD
1713function civicrm_install_set_backdrop_perms() {
1714 $perms = array(
1715 'access all custom data',
1716 'access uploaded files',
1717 'make online contributions',
1718 'profile create',
1719 'profile edit',
1720 'profile view',
1721 'register for events',
1722 'view event info',
1723 'view event participants',
1724 'access CiviMail subscribe/unsubscribe pages',
1725 );
1726
1727 // Adding a permission that has not yet been assigned to a module by
1728 // a hook_permission implementation results in a database error.
1729 // CRM-9042
1730 $allPerms = array_keys(module_invoke_all('permission'));
1731 foreach (array_diff($perms, $allPerms) as $perm) {
1732 watchdog('civicrm',
1733 'Cannot grant the %perm permission because it does not yet exist.',
1734 array('%perm' => $perm),
1735 WATCHDOG_ERROR
1736 );
1737 }
1738 $perms = array_intersect($perms, $allPerms);
1739 user_role_grant_permissions(BACKDROP_AUTHENTICATED_ROLE, $perms);
1740 user_role_grant_permissions(BACKDROP_ANONYMOUS_ROLE, $perms);
1741}
1742
627456b5
EM
1743/**
1744 * @param $cmsPath
1745 * @param $str
1746 *
1747 * @return string
1748 */
6a488035
TO
1749function getSiteDir($cmsPath, $str) {
1750 static $siteDir = '';
1751
1752 if ($siteDir) {
1753 return $siteDir;
1754 }
1755
1756 $sites = CIVICRM_DIRECTORY_SEPARATOR . 'sites' . CIVICRM_DIRECTORY_SEPARATOR;
1757 $modules = CIVICRM_DIRECTORY_SEPARATOR . 'modules' . CIVICRM_DIRECTORY_SEPARATOR;
1758 preg_match("/" . preg_quote($sites, CIVICRM_DIRECTORY_SEPARATOR) .
1759 "([\-a-zA-Z0-9_.]+)" .
1760 preg_quote($modules, CIVICRM_DIRECTORY_SEPARATOR) . "/",
1761 $_SERVER['SCRIPT_FILENAME'], $matches
1762 );
1763 $siteDir = isset($matches[1]) ? $matches[1] : 'default';
1764
1765 if (strtolower($siteDir) == 'all') {
1766 // For this case - use drupal's way of finding out multi-site directory
1767 $uri = explode(CIVICRM_DIRECTORY_SEPARATOR, $_SERVER['SCRIPT_FILENAME']);
1768 $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
1769 for ($i = count($uri) - 1; $i > 0; $i--) {
1770 for ($j = count($server); $j > 0; $j--) {
1771 $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
1772 if (file_exists($cmsPath . CIVICRM_DIRECTORY_SEPARATOR .
56fdfc52
TO
1773 'sites' . CIVICRM_DIRECTORY_SEPARATOR . $dir
1774 )) {
6a488035
TO
1775 $siteDir = $dir;
1776 return $siteDir;
1777 }
1778 }
1779 }
1780 $siteDir = 'default';
1781 }
1782
1783 return $siteDir;
1784}
1785
627456b5
EM
1786/**
1787 * @param $errorTitle
1788 * @param $errorMsg
6a9514e1 1789 * @param $showRefer
627456b5 1790 */
6a9514e1
ML
1791function errorDisplayPage($errorTitle, $errorMsg, $showRefer = TRUE) {
1792 if ($showRefer) {
1793 $docLink = CRM_Utils_System::docURL2('Installation and Upgrades', FALSE, 'Installation Guide', NULL, NULL, "wiki");
1794
1795 if (function_exists('ts')) {
1796 $errorMsg .= '<p>' . ts("<a %1>Refer to the online documentation for more information</a>", array(1 => "href='$docLink'")) . '</p>';
1797 }
1798 else {
1799 $errorMsg .= '<p>' . sprintf("<a %s>Refer to the online documentation for more information</a>", "href='$docLink'") . '</p>';
1800 }
1801 }
1802
1f5f3294 1803 include 'error.html';
6a488035
TO
1804 exit();
1805}