Elgg  Version 1.11
ElggInstaller.php
Go to the documentation of this file.
1 <?php
2 
31 
32  protected $steps = array(
33  'welcome',
34  'requirements',
35  'database',
36  'settings',
37  'admin',
38  'complete',
39  );
40 
41  protected $status = array(
42  'config' => FALSE,
43  'database' => FALSE,
44  'settings' => FALSE,
45  'admin' => FALSE,
46  );
47 
48  protected $isAction = FALSE;
49 
50  protected $autoLogin = TRUE;
51 
57  private $CONFIG;
58 
62  public function __construct() {
63  global $CONFIG;
64  if (!isset($CONFIG)) {
65  $CONFIG = new stdClass;
66  }
67 
68  $this->CONFIG = $CONFIG;
69 
70  $this->isAction = isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'POST';
71 
72  $this->bootstrapConfig();
73 
74  $this->bootstrapEngine();
75 
76  _elgg_services()->setValue('session', \ElggSession::getMock());
77 
78  elgg_set_viewtype('installation');
79 
80  set_error_handler('_elgg_php_error_handler');
81  set_exception_handler('_elgg_php_exception_handler');
82 
83  _elgg_services()->translator->registerTranslations("{$this->getElggRoot()}/install/languages/", TRUE);
84  }
85 
89  private function getElggRoot() {
90  return dirname(dirname(__DIR__));
91  }
92 
101  public function run($step) {
102  global $CONFIG;
103 
104  // language needs to be set before the first call to elgg_echo()
105  $CONFIG->language = 'en';
106 
107  // check if this is a URL rewrite test coming in
108  $this->processRewriteTest();
109 
110  if (!in_array($step, $this->getSteps())) {
111  $msg = _elgg_services()->translator->translate('InstallationException:UnknownStep', array($step));
112  throw new InstallationException($msg);
113  }
114 
115  $this->setInstallStatus();
116 
118 
119  // check if this is an install being resumed
120  $this->resumeInstall($step);
121 
122  $this->finishBootstraping($step);
123 
124  $params = $this->getPostVariables();
125  $this->$step($params);
126  }
127 
135  public function setAutoLogin($flag) {
136  $this->autoLogin = (bool) $flag;
137  }
138 
157  public function batchInstall(array $params, $createHtaccess = FALSE) {
158 
159 
160  restore_error_handler();
161  restore_exception_handler();
162 
163  $defaults = array(
164  'dbhost' => 'localhost',
165  'dbprefix' => 'elgg_',
166  'language' => 'en',
167  'siteaccess' => ACCESS_PUBLIC,
168  );
169  $params = array_merge($defaults, $params);
170 
171  $requiredParams = array(
172  'dbuser',
173  'dbpassword',
174  'dbname',
175  'sitename',
176  'wwwroot',
177  'dataroot',
178  'displayname',
179  'email',
180  'username',
181  'password',
182  );
183  foreach ($requiredParams as $key) {
184  if (empty($params[$key])) {
185  $msg = _elgg_services()->translator->translate('install:error:requiredfield', array($key));
186  throw new InstallationException($msg);
187  }
188  }
189 
190  // password is passed in once
191  $params['password1'] = $params['password2'] = $params['password'];
192 
193  if ($createHtaccess) {
194  $rewriteTester = new ElggRewriteTester();
195  if (!$rewriteTester->createHtaccess($params['wwwroot'], $this->CONFIG->path)) {
196  throw new InstallationException(_elgg_services()->translator->translate('install:error:htaccess'));
197  }
198  }
199 
200  $this->setInstallStatus();
201 
202  if (!$this->status['config']) {
203  if (!$this->createSettingsFile($params)) {
204  throw new InstallationException(_elgg_services()->translator->translate('install:error:settings'));
205  }
206  }
207 
208  if (!$this->connectToDatabase()) {
209  throw new InstallationException(_elgg_services()->translator->translate('install:error:databasesettings'));
210  }
211 
212  if (!$this->status['database']) {
213  if (!$this->installDatabase()) {
214  throw new InstallationException(_elgg_services()->translator->translate('install:error:cannotloadtables'));
215  }
216  }
217 
218  // load remaining core libraries
219  $this->finishBootstraping('settings');
220 
221  if (!$this->saveSiteSettings($params)) {
222  throw new InstallationException(_elgg_services()->translator->translate('install:error:savesitesettings'));
223  }
224 
225  if (!$this->createAdminAccount($params)) {
226  throw new InstallationException(_elgg_services()->translator->translate('install:admin:cannot_create'));
227  }
228  }
229 
238  protected function render($step, $vars = array()) {
239 
240  $vars['next_step'] = $this->getNextStep($step);
241 
242  $title = _elgg_services()->translator->translate("install:$step");
243  $body = elgg_view("install/pages/$step", $vars);
245  $title,
246  $body,
247  'default',
248  array(
249  'step' => $step,
250  'steps' => $this->getSteps(),
251  )
252  );
253  exit;
254  }
255 
267  protected function welcome($vars) {
268  $this->render('welcome');
269  }
270 
280  protected function requirements($vars) {
281 
282  $report = array();
283 
284  // check PHP parameters and libraries
285  $this->checkPHP($report);
286 
287  // check URL rewriting
288  $this->checkRewriteRules($report);
289 
290  // check for existence of settings file
291  if ($this->checkSettingsFile($report) != TRUE) {
292  // no file, so check permissions on engine directory
293  $this->checkEngineDir($report);
294  }
295 
296  // check the database later
297  $report['database'] = array(array(
298  'severity' => 'info',
299  'message' => _elgg_services()->translator->translate('install:check:database')
300  ));
301 
302  // any failures?
303  $numFailures = $this->countNumConditions($report, 'failure');
304 
305  // any warnings
306  $numWarnings = $this->countNumConditions($report, 'warning');
307 
308 
309  $params = array(
310  'report' => $report,
311  'num_failures' => $numFailures,
312  'num_warnings' => $numWarnings,
313  );
314 
315  $this->render('requirements', $params);
316  }
317 
327  protected function database($submissionVars) {
328 
329  $formVars = array(
330  'dbuser' => array(
331  'type' => 'text',
332  'value' => '',
333  'required' => TRUE,
334  ),
335  'dbpassword' => array(
336  'type' => 'password',
337  'value' => '',
338  'required' => FALSE,
339  ),
340  'dbname' => array(
341  'type' => 'text',
342  'value' => '',
343  'required' => TRUE,
344  ),
345  'dbhost' => array(
346  'type' => 'text',
347  'value' => 'localhost',
348  'required' => TRUE,
349  ),
350  'dbprefix' => array(
351  'type' => 'text',
352  'value' => 'elgg_',
353  'required' => TRUE,
354  ),
355  );
356 
357  if ($this->checkSettingsFile()) {
358  // user manually created settings file so we fake out action test
359  $this->isAction = TRUE;
360  }
361 
362  if ($this->isAction) {
363  do {
364  // only create settings file if it doesn't exist
365  if (!$this->checkSettingsFile()) {
366  if (!$this->validateDatabaseVars($submissionVars, $formVars)) {
367  // error so we break out of action and serve same page
368  break;
369  }
370 
371  if (!$this->createSettingsFile($submissionVars)) {
372  break;
373  }
374  }
375 
376  // check db version and connect
377  if (!$this->connectToDatabase()) {
378  break;
379  }
380 
381  if (!$this->installDatabase()) {
382  break;
383  }
384 
385  system_message(_elgg_services()->translator->translate('install:success:database'));
386 
387  $this->continueToNextStep('database');
388  } while (FALSE); // PHP doesn't support breaking out of if statements
389  }
390 
391  $formVars = $this->makeFormSticky($formVars, $submissionVars);
392 
393  $params = array('variables' => $formVars,);
394 
395  if ($this->checkSettingsFile()) {
396  // settings file exists and we're here so failed to create database
397  $params['failure'] = TRUE;
398  }
399 
400  $this->render('database', $params);
401  }
402 
412  protected function settings($submissionVars) {
413 
414 
415  $formVars = array(
416  'sitename' => array(
417  'type' => 'text',
418  'value' => 'My New Community',
419  'required' => TRUE,
420  ),
421  'siteemail' => array(
422  'type' => 'email',
423  'value' => '',
424  'required' => FALSE,
425  ),
426  'wwwroot' => array(
427  'type' => 'url',
428  'value' => _elgg_services()->config->getSiteUrl(),
429  'required' => TRUE,
430  ),
431  'dataroot' => array(
432  'type' => 'text',
433  'value' => '',
434  'required' => TRUE,
435  ),
436  'siteaccess' => array(
437  'type' => 'access',
438  'value' => ACCESS_PUBLIC,
439  'required' => TRUE,
440  ),
441  );
442 
443  // if Apache, we give user option of having Elgg create data directory
444  //if (ElggRewriteTester::guessWebServer() == 'apache') {
445  // $formVars['dataroot']['type'] = 'combo';
446  // $this->CONFIG->translations['en']['install:settings:help:dataroot'] =
447  // $this->CONFIG->translations['en']['install:settings:help:dataroot:apache'];
448  //}
449 
450  if ($this->isAction) {
451  do {
452  //if (!$this->createDataDirectory($submissionVars, $formVars)) {
453  // break;
454  //}
455 
456  if (!$this->validateSettingsVars($submissionVars, $formVars)) {
457  break;
458  }
459 
460  if (!$this->saveSiteSettings($submissionVars)) {
461  break;
462  }
463 
464  system_message(_elgg_services()->translator->translate('install:success:settings'));
465 
466  $this->continueToNextStep('settings');
467 
468  } while (FALSE); // PHP doesn't support breaking out of if statements
469  }
470 
471  $formVars = $this->makeFormSticky($formVars, $submissionVars);
472 
473  $this->render('settings', array('variables' => $formVars));
474  }
475 
485  protected function admin($submissionVars) {
486  $formVars = array(
487  'displayname' => array(
488  'type' => 'text',
489  'value' => '',
490  'required' => TRUE,
491  ),
492  'email' => array(
493  'type' => 'email',
494  'value' => '',
495  'required' => TRUE,
496  ),
497  'username' => array(
498  'type' => 'text',
499  'value' => '',
500  'required' => TRUE,
501  ),
502  'password1' => array(
503  'type' => 'password',
504  'value' => '',
505  'required' => TRUE,
506  'pattern' => '.{6,}',
507  ),
508  'password2' => array(
509  'type' => 'password',
510  'value' => '',
511  'required' => TRUE,
512  ),
513  );
514 
515  if ($this->isAction) {
516  do {
517  if (!$this->validateAdminVars($submissionVars, $formVars)) {
518  break;
519  }
520 
521  if (!$this->createAdminAccount($submissionVars, $this->autoLogin)) {
522  break;
523  }
524 
525  system_message(_elgg_services()->translator->translate('install:success:admin'));
526 
527  $this->continueToNextStep('admin');
528 
529  } while (FALSE); // PHP doesn't support breaking out of if statements
530  }
531 
532  // bit of a hack to get the password help to show right number of characters
533 
534  $lang = _elgg_services()->translator->getCurrentLanguage();
535  $this->CONFIG->translations[$lang]['install:admin:help:password1'] =
536  sprintf($this->CONFIG->translations[$lang]['install:admin:help:password1'],
537  $this->CONFIG->min_password_length);
538 
539  $formVars = $this->makeFormSticky($formVars, $submissionVars);
540 
541  $this->render('admin', array('variables' => $formVars));
542  }
543 
549  protected function complete() {
550 
551  $params = array();
552  if ($this->autoLogin) {
553  $params['destination'] = 'admin';
554  } else {
555  $params['destination'] = 'index.php';
556  }
557 
558  $this->render('complete', $params);
559  }
560 
570  protected function getSteps() {
571  return $this->steps;
572  }
573 
581  protected function continueToNextStep($currentStep) {
582  $this->isAction = FALSE;
583  forward($this->getNextStepUrl($currentStep));
584  }
585 
593  protected function getNextStep($currentStep) {
594  $index = 1 + array_search($currentStep, $this->steps);
595  if (isset($this->steps[$index])) {
596  return $this->steps[$index];
597  } else {
598  return null;
599  }
600  }
601 
609  protected function getNextStepUrl($currentStep) {
610  $nextStep = $this->getNextStep($currentStep);
611  return _elgg_services()->config->getSiteUrl() . "install.php?step=$nextStep";
612  }
613 
620  protected function setInstallStatus() {
621 
622 
623  if (!is_readable("{$this->CONFIG->path}engine/settings.php")) {
624  return;
625  }
626 
627  $this->loadSettingsFile();
628 
629  $this->status['config'] = TRUE;
630 
631  // must be able to connect to database to jump install steps
632  $dbSettingsPass = $this->checkDatabaseSettings(
633  $this->CONFIG->dbuser,
634  $this->CONFIG->dbpass,
635  $this->CONFIG->dbname,
636  $this->CONFIG->dbhost
637  );
638  if ($dbSettingsPass == FALSE) {
639  return;
640  }
641 
642  if (!include_once("{$this->CONFIG->path}engine/lib/database.php")) {
643  throw new InstallationException(_elgg_services()->translator->translate('InstallationException:MissingLibrary', array('database.php')));
644  }
645 
646  // check that the config table has been created
647  $query = "show tables";
648  $result = _elgg_services()->db->getData($query);
649  if ($result) {
650  foreach ($result as $table) {
651  $table = (array) $table;
652  if (in_array("{$this->CONFIG->dbprefix}config", $table)) {
653  $this->status['database'] = TRUE;
654  }
655  }
656  if ($this->status['database'] == FALSE) {
657  return;
658  }
659  } else {
660  // no tables
661  return;
662  }
663 
664  // check that the config table has entries
665  $query = "SELECT COUNT(*) AS total FROM {$this->CONFIG->dbprefix}config";
666  $result = _elgg_services()->db->getData($query);
667  if ($result && $result[0]->total > 0) {
668  $this->status['settings'] = TRUE;
669  } else {
670  return;
671  }
672 
673  // check that the users entity table has an entry
674  $query = "SELECT COUNT(*) AS total FROM {$this->CONFIG->dbprefix}users_entity";
675  $result = _elgg_services()->db->getData($query);
676  if ($result && $result[0]->total > 0) {
677  $this->status['admin'] = TRUE;
678  } else {
679  return;
680  }
681  }
682 
691  protected function checkInstallCompletion($step) {
692  if ($step != 'complete') {
693  if (!in_array(FALSE, $this->status)) {
694  // install complete but someone is trying to view an install page
695  forward();
696  }
697  }
698  }
699 
708  protected function resumeInstall($step) {
709  // only do a resume from the first step
710  if ($step !== 'welcome') {
711  return;
712  }
713 
714  if ($this->status['database'] == FALSE) {
715  return;
716  }
717 
718  if ($this->status['settings'] == FALSE) {
719  forward("install.php?step=settings");
720  }
721 
722  if ($this->status['admin'] == FALSE) {
723  forward("install.php?step=admin");
724  }
725 
726  // everything appears to be set up
727  forward("install.php?step=complete");
728  }
729 
739  protected function bootstrapEngine() {
740 
741 
742  require_once $this->CONFIG->path . 'engine/load.php';
743  }
744 
754  protected function finishBootstraping($step) {
755 
756  $dbIndex = array_search('database', $this->getSteps());
757  $settingsIndex = array_search('settings', $this->getSteps());
758  $adminIndex = array_search('admin', $this->getSteps());
759  $completeIndex = array_search('complete', $this->getSteps());
760  $stepIndex = array_search($step, $this->getSteps());
761 
762  // To log in the user, we need to use the Elgg core session handling.
763  // Otherwise, use default php session handling
764  $useElggSession = ($stepIndex == $adminIndex && $this->isAction) ||
765  $stepIndex == $completeIndex;
766  if (!$useElggSession) {
767  session_name('Elgg_install');
768  session_start();
769  _elgg_services()->events->unregisterHandler('boot', 'system', 'session_init');
770  }
771 
772  if ($stepIndex > $dbIndex) {
773  // once the database has been created, load rest of engine
774 
775  $lib_dir = $this->CONFIG->path . 'engine/lib/';
776 
777  $this->loadSettingsFile();
778 
779  $lib_files = array(
780  // these want to be loaded first apparently?
781  'autoloader.php',
782  'database.php',
783  'actions.php',
784 
785  'admin.php',
786  'annotations.php',
787  'cron.php',
788  'entities.php',
789  'extender.php',
790  'filestore.php',
791  'group.php',
792  'mb_wrapper.php',
793  'memcache.php',
794  'metadata.php',
795  'metastrings.php',
796  'navigation.php',
797  'notification.php',
798  'objects.php',
799  'pagehandler.php',
800  'pam.php',
801  'plugins.php',
802  'private_settings.php',
803  'relationships.php',
804  'river.php',
805  'sites.php',
806  'statistics.php',
807  'tags.php',
808  'user_settings.php',
809  'users.php',
810  'upgrade.php',
811  'widgets.php',
812  'deprecated-1.7.php',
813  'deprecated-1.8.php',
814  'deprecated-1.9.php',
815  );
816 
817  foreach ($lib_files as $file) {
818  $path = $lib_dir . $file;
819  if (!include_once($path)) {
820  throw new InstallationException('InstallationException:MissingLibrary', array($file));
821  }
822  }
823 
824  _elgg_services()->db->setupConnections();
825  _elgg_services()->translator->registerTranslations("{$this->getElggRoot()}/languages/");
826  $this->CONFIG->language = 'en';
827 
828  if ($stepIndex > $settingsIndex) {
829  $this->CONFIG->site_guid = (int) _elgg_services()->datalist->get('default_site');
830  $this->CONFIG->site_id = $this->CONFIG->site_guid;
831  $this->CONFIG->site = get_entity($this->CONFIG->site_guid);
832  $this->CONFIG->dataroot = _elgg_services()->datalist->get('dataroot');
834  }
835 
836  _elgg_services()->events->trigger('init', 'system');
837  }
838  }
839 
845  protected function bootstrapConfig() {
846  $this->CONFIG->installer_running = true;
847 
848  $this->CONFIG->wwwroot = $this->getBaseUrl();
849  $this->CONFIG->url = $this->CONFIG->wwwroot;
850  $this->CONFIG->path = "{$this->getElggRoot()}/";
851  $this->CONFIG->viewpath = $this->CONFIG->path . 'views/';
852  $this->CONFIG->pluginspath = $this->CONFIG->path . 'mod/';
853  $this->CONFIG->context = array();
854  $this->CONFIG->entity_types = array('group', 'object', 'site', 'user');
855 
856  // required by elgg_view_page()
857  $this->CONFIG->sitename = '';
858  $this->CONFIG->sitedescription = '';
859 
860  // required by Elgg\Config::get
861  $this->CONFIG->site_guid = 1;
862  }
863 
867  private function isHttps() {
868  return (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ||
869  $_SERVER['SERVER_PORT'] == 443;
870  }
871 
880  protected function getBaseUrl() {
881  $protocol = $this->isHttps() ? 'https' : 'http';
882 
883  if (isset($_SERVER["SERVER_PORT"])) {
884  $port = ':' . $_SERVER["SERVER_PORT"];
885  } else {
886  $port = '';
887  }
888  if ($port == ':80' || $port == ':443') {
889  $port = '';
890  }
891  $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
892  $cutoff = strpos($uri, 'install.php');
893  $uri = substr($uri, 0, $cutoff);
894  $serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
895 
896  return "$protocol://{$serverName}$port{$uri}";
897  }
898 
905  protected function loadSettingsFile() {
906 
907 
908  if (!include_once("{$this->CONFIG->path}engine/settings.php")) {
909  throw new InstallationException(_elgg_services()->translator->translate('InstallationException:CannotLoadSettings'));
910  }
911  }
912 
926  protected function getPostVariables() {
927  $vars = array();
928  foreach ($_POST as $k => $v) {
929  $vars[$k] = $v;
930  }
931  return $vars;
932  }
933 
942  protected function makeFormSticky($formVars, $submissionVars) {
943  foreach ($submissionVars as $field => $value) {
944  $formVars[$field]['value'] = $value;
945  }
946  return $formVars;
947  }
948 
960  protected function checkEngineDir(&$report) {
961 
962 
963  $writable = is_writable("{$this->CONFIG->path}engine");
964  if (!$writable) {
965  $report['settings'] = array(
966  array(
967  'severity' => 'failure',
968  'message' => _elgg_services()->translator->translate('install:check:enginedir'),
969  )
970  );
971  return FALSE;
972  }
973 
974  return TRUE;
975  }
976 
984  protected function checkSettingsFile(&$report = array()) {
985 
986 
987  if (!file_exists("{$this->CONFIG->path}engine/settings.php")) {
988  return FALSE;
989  }
990 
991  if (!is_readable("{$this->CONFIG->path}engine/settings.php")) {
992  $report['settings'] = array(
993  array(
994  'severity' => 'failure',
995  'message' => _elgg_services()->translator->translate('install:check:readsettings'),
996  )
997  );
998  }
999 
1000  return TRUE;
1001  }
1002 
1010  protected function checkPHP(&$report) {
1011  $phpReport = array();
1012 
1013  $min_php_version = '5.4.0';
1014  if (version_compare(PHP_VERSION, $min_php_version, '<')) {
1015  $phpReport[] = array(
1016  'severity' => 'failure',
1017  'message' => _elgg_services()->translator->translate('install:check:php:version', array($min_php_version, PHP_VERSION))
1018  );
1019  }
1020 
1021  $this->checkPhpExtensions($phpReport);
1022 
1023  $this->checkPhpDirectives($phpReport);
1024 
1025  if (count($phpReport) == 0) {
1026  $phpReport[] = array(
1027  'severity' => 'pass',
1028  'message' => _elgg_services()->translator->translate('install:check:php:success')
1029  );
1030  }
1031 
1032  $report['php'] = $phpReport;
1033  }
1034 
1042  protected function checkPhpExtensions(&$phpReport) {
1043  $extensions = get_loaded_extensions();
1044  $requiredExtensions = array(
1045  'mysql',
1046  'json',
1047  'xml',
1048  'gd',
1049  );
1050  foreach ($requiredExtensions as $extension) {
1051  if (!in_array($extension, $extensions)) {
1052  $phpReport[] = array(
1053  'severity' => 'failure',
1054  'message' => _elgg_services()->translator->translate('install:check:php:extension', array($extension))
1055  );
1056  }
1057  }
1058 
1059  $recommendedExtensions = array(
1060  'mbstring',
1061  );
1062  foreach ($recommendedExtensions as $extension) {
1063  if (!in_array($extension, $extensions)) {
1064  $phpReport[] = array(
1065  'severity' => 'warning',
1066  'message' => _elgg_services()->translator->translate('install:check:php:extension:recommend', array($extension))
1067  );
1068  }
1069  }
1070  }
1071 
1079  protected function checkPhpDirectives(&$phpReport) {
1080  if (ini_get('open_basedir')) {
1081  $phpReport[] = array(
1082  'severity' => 'warning',
1083  'message' => _elgg_services()->translator->translate("install:check:php:open_basedir")
1084  );
1085  }
1086 
1087  if (ini_get('safe_mode')) {
1088  $phpReport[] = array(
1089  'severity' => 'warning',
1090  'message' => _elgg_services()->translator->translate("install:check:php:safe_mode")
1091  );
1092  }
1093 
1094  if (ini_get('arg_separator.output') !== '&') {
1095  $separator = htmlspecialchars(ini_get('arg_separator.output'));
1096  $msg = _elgg_services()->translator->translate("install:check:php:arg_separator", array($separator));
1097  $phpReport[] = array(
1098  'severity' => 'failure',
1099  'message' => $msg,
1100  );
1101  }
1102 
1103  if (ini_get('register_globals')) {
1104  $phpReport[] = array(
1105  'severity' => 'failure',
1106  'message' => _elgg_services()->translator->translate("install:check:php:register_globals")
1107  );
1108  }
1109 
1110  if (ini_get('session.auto_start')) {
1111  $phpReport[] = array(
1112  'severity' => 'failure',
1113  'message' => _elgg_services()->translator->translate("install:check:php:session.auto_start")
1114  );
1115  }
1116  }
1117 
1125  protected function checkRewriteRules(&$report) {
1126 
1127 
1128  $tester = new ElggRewriteTester();
1129  $url = _elgg_services()->config->getSiteUrl() . "rewrite.php";
1130  $report['rewrite'] = array($tester->run($url, $this->CONFIG->path));
1131  }
1132 
1139  protected function processRewriteTest() {
1140  if (strpos($_SERVER['REQUEST_URI'], 'rewrite.php') !== FALSE) {
1141  echo 'success';
1142  exit;
1143  }
1144  }
1145 
1154  protected function countNumConditions($report, $condition) {
1155  $count = 0;
1156  foreach ($report as $category => $checks) {
1157  foreach ($checks as $check) {
1158  if ($check['severity'] === $condition) {
1159  $count++;
1160  }
1161  }
1162  }
1163 
1164  return $count;
1165  }
1166 
1167 
1180  protected function validateDatabaseVars($submissionVars, $formVars) {
1181 
1182  foreach ($formVars as $field => $info) {
1183  if ($info['required'] == TRUE && !$submissionVars[$field]) {
1184  $name = _elgg_services()->translator->translate("install:database:label:$field");
1185  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1186  return FALSE;
1187  }
1188  }
1189 
1190  // according to postgres documentation: SQL identifiers and key words must
1191  // begin with a letter (a-z, but also letters with diacritical marks and
1192  // non-Latin letters) or an underscore (_). Subsequent characters in an
1193  // identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($).
1194  // Refs #4994
1195  if (!preg_match("/^[a-zA-Z_][\w]*$/", $submissionVars['dbprefix'])) {
1196  register_error(_elgg_services()->translator->translate('install:error:database_prefix'));
1197  return FALSE;
1198  }
1199 
1200  return $this->checkDatabaseSettings(
1201  $submissionVars['dbuser'],
1202  $submissionVars['dbpassword'],
1203  $submissionVars['dbname'],
1204  $submissionVars['dbhost']
1205  );
1206  }
1207 
1218  protected function checkDatabaseSettings($user, $password, $dbname, $host) {
1219  $config = new \Elgg\Database\Config((object)[
1220  'dbhost' => $host,
1221  'dbuser' => $user,
1222  'dbpass' => $password,
1223  'dbname' => $dbname,
1224  ]);
1225  $logger = new \Elgg\Logger(new \Elgg\PluginHooksService());
1226  $db = new \Elgg\Database($config, $logger);
1227 
1228  try {
1229  $db->getDataRow("SELECT 1");
1230  } catch (DatabaseException $e) {
1231  if (0 === strpos($e->getMessage(), "Elgg couldn't connect")) {
1232  register_error(_elgg_services()->translator->translate('install:error:databasesettings'));
1233  } else {
1234  register_error(_elgg_services()->translator->translate('install:error:nodatabase', array($dbname)));
1235  }
1236  return FALSE;
1237  }
1238 
1239  // check MySQL version - must be 5.0 or >
1240  $version = $db->getServerVersion(\Elgg\Database\Config::READ_WRITE);
1241  $required_version = 5.0;
1242  $points = explode('.', $version);
1243  if ($points[0] < $required_version) {
1244  register_error(_elgg_services()->translator->translate('install:error:oldmysql', array($version)));
1245  return FALSE;
1246  }
1247 
1248  return TRUE;
1249  }
1250 
1258  protected function createSettingsFile($params) {
1259 
1260 
1261  $templateFile = "{$this->CONFIG->path}engine/settings.example.php";
1262  $template = file_get_contents($templateFile);
1263  if (!$template) {
1264  register_error(_elgg_services()->translator->translate('install:error:readsettingsphp'));
1265  return FALSE;
1266  }
1267 
1268  foreach ($params as $k => $v) {
1269  $template = str_replace("{{" . $k . "}}", $v, $template);
1270  }
1271 
1272  $settingsFilename = "{$this->CONFIG->path}engine/settings.php";
1273  $result = file_put_contents($settingsFilename, $template);
1274  if (!$result) {
1275  register_error(_elgg_services()->translator->translate('install:error:writesettingphp'));
1276  return FALSE;
1277  }
1278 
1279  return TRUE;
1280  }
1281 
1287  protected function connectToDatabase() {
1288 
1289 
1290  if (!include_once("{$this->CONFIG->path}engine/settings.php")) {
1291  register_error('Elgg could not load the settings file. It does not exist or there is a file permissions issue.');
1292  return FALSE;
1293  }
1294 
1295  if (!include_once("{$this->CONFIG->path}engine/lib/database.php")) {
1296  register_error('Could not load database.php');
1297  return FALSE;
1298  }
1299 
1300  try {
1301  _elgg_services()->db->setupConnections();
1302  } catch (DatabaseException $e) {
1303  register_error($e->getMessage());
1304  return FALSE;
1305  }
1306 
1307  return TRUE;
1308  }
1309 
1315  protected function installDatabase() {
1316 
1317 
1318  try {
1319  _elgg_services()->db->runSqlScript("{$this->CONFIG->path}engine/schema/mysql.sql");
1320  } catch (Exception $e) {
1321  $msg = $e->getMessage();
1322  if (strpos($msg, 'already exists')) {
1323  $msg = _elgg_services()->translator->translate('install:error:tables_exist');
1324  }
1325  register_error($msg);
1326  return FALSE;
1327  }
1328 
1329  return TRUE;
1330  }
1331 
1344  protected function createDataDirectory(&$submissionVars, $formVars) {
1345  // did the user have option of Elgg creating the data directory
1346  if ($formVars['dataroot']['type'] != 'combo') {
1347  return TRUE;
1348  }
1349 
1350  // did the user select the option
1351  if ($submissionVars['dataroot'] != 'dataroot-checkbox') {
1352  return TRUE;
1353  }
1354 
1355  $dir = sanitise_filepath($submissionVars['path']) . 'data';
1356  if (file_exists($dir) || mkdir($dir, 0700)) {
1357  $submissionVars['dataroot'] = $dir;
1358  if (!file_exists("$dir/.htaccess")) {
1359  $htaccess = "Order Deny,Allow\nDeny from All\n";
1360  if (!file_put_contents("$dir/.htaccess", $htaccess)) {
1361  return FALSE;
1362  }
1363  }
1364  return TRUE;
1365  }
1366 
1367  return FALSE;
1368  }
1369 
1378  protected function validateSettingsVars($submissionVars, $formVars) {
1379 
1380 
1381  foreach ($formVars as $field => $info) {
1382  $submissionVars[$field] = trim($submissionVars[$field]);
1383  if ($info['required'] == TRUE && $submissionVars[$field] === '') {
1384  $name = _elgg_services()->translator->translate("install:settings:label:$field");
1385  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1386  return FALSE;
1387  }
1388  }
1389 
1390  // check that data root is absolute path
1391  if (stripos(PHP_OS, 'win') === 0) {
1392  if (strpos($submissionVars['dataroot'], ':') !== 1) {
1393  $msg = _elgg_services()->translator->translate('install:error:relative_path', array($submissionVars['dataroot']));
1394  register_error($msg);
1395  return FALSE;
1396  }
1397  } else {
1398  if (strpos($submissionVars['dataroot'], '/') !== 0) {
1399  $msg = _elgg_services()->translator->translate('install:error:relative_path', array($submissionVars['dataroot']));
1400  register_error($msg);
1401  return FALSE;
1402  }
1403  }
1404 
1405  // check that data root exists
1406  if (!file_exists($submissionVars['dataroot'])) {
1407  $msg = _elgg_services()->translator->translate('install:error:datadirectoryexists', array($submissionVars['dataroot']));
1408  register_error($msg);
1409  return FALSE;
1410  }
1411 
1412  // check that data root is writable
1413  if (!is_writable($submissionVars['dataroot'])) {
1414  $msg = _elgg_services()->translator->translate('install:error:writedatadirectory', array($submissionVars['dataroot']));
1415  register_error($msg);
1416  return FALSE;
1417  }
1418 
1419  if (!isset($this->CONFIG->data_dir_override) || !$this->CONFIG->data_dir_override) {
1420  // check that data root is not subdirectory of Elgg root
1421  if (stripos($submissionVars['dataroot'], $submissionVars['path']) === 0) {
1422  $msg = _elgg_services()->translator->translate('install:error:locationdatadirectory', array($submissionVars['dataroot']));
1423  register_error($msg);
1424  return FALSE;
1425  }
1426  }
1427 
1428  // check that email address is email address
1429  if ($submissionVars['siteemail'] && !is_email_address($submissionVars['siteemail'])) {
1430  $msg = _elgg_services()->translator->translate('install:error:emailaddress', array($submissionVars['siteemail']));
1431  register_error($msg);
1432  return FALSE;
1433  }
1434 
1435  // @todo check that url is a url
1436  // @note filter_var cannot be used because it doesn't work on international urls
1437 
1438  return TRUE;
1439  }
1440 
1448  protected function saveSiteSettings($submissionVars) {
1449 
1450 
1451  // ensure that file path, data path, and www root end in /
1452  $submissionVars['dataroot'] = sanitise_filepath($submissionVars['dataroot']);
1453  $submissionVars['wwwroot'] = sanitise_filepath($submissionVars['wwwroot']);
1454 
1455  $site = new ElggSite();
1456  $site->name = strip_tags($submissionVars['sitename']);
1457  $site->url = $submissionVars['wwwroot'];
1458  $site->access_id = ACCESS_PUBLIC;
1459  $site->email = $submissionVars['siteemail'];
1460  $guid = $site->save();
1461 
1462  if (!$guid) {
1463  register_error(_elgg_services()->translator->translate('install:error:createsite'));
1464  return FALSE;
1465  }
1466 
1467  // bootstrap site info
1468  $this->CONFIG->site_guid = $guid;
1469  $this->CONFIG->site_id = $guid;
1470  $this->CONFIG->site = $site;
1471 
1472  _elgg_services()->datalist->set('installed', time());
1473  _elgg_services()->datalist->set('dataroot', $submissionVars['dataroot']);
1474  _elgg_services()->datalist->set('default_site', $site->getGUID());
1475  _elgg_services()->datalist->set('version', elgg_get_version());
1476  _elgg_services()->datalist->set('simplecache_enabled', 1);
1477  _elgg_services()->datalist->set('system_cache_enabled', 1);
1478  _elgg_services()->datalist->set('simplecache_lastupdate', time());
1479 
1480  // @todo plugins might use this, but core doesn't. remove in 2.0
1481  _elgg_services()->datalist->set('path', $this->CONFIG->path);
1482 
1483  // new installations have run all the upgrades
1484  $upgrades = elgg_get_upgrade_files("{$this->CONFIG->path}engine/lib/upgrades/");
1485  _elgg_services()->datalist->set('processed_upgrades', serialize($upgrades));
1486 
1487  _elgg_services()->configTable->set('view', 'default', $site->getGUID());
1488  _elgg_services()->configTable->set('language', 'en', $site->getGUID());
1489  _elgg_services()->configTable->set('default_access', $submissionVars['siteaccess'], $site->getGUID());
1490  _elgg_services()->configTable->set('allow_registration', TRUE, $site->getGUID());
1491  _elgg_services()->configTable->set('walled_garden', FALSE, $site->getGUID());
1492  _elgg_services()->configTable->set('allow_user_default_access', '', $site->getGUID());
1493  _elgg_services()->configTable->set('default_limit', 10, $site->getGUID());
1494 
1495  $this->setSubtypeClasses();
1496 
1497  $this->enablePlugins();
1498 
1499  return TRUE;
1500  }
1501 
1507  protected function setSubtypeClasses() {
1508  add_subtype("object", "plugin", "ElggPlugin");
1509  add_subtype("object", "file", "ElggFile");
1510  add_subtype("object", "widget", "ElggWidget");
1511  add_subtype("object", "comment", "ElggComment");
1512  add_subtype("object", "elgg_upgrade", 'ElggUpgrade');
1513  }
1514 
1520  protected function enablePlugins() {
1522  $plugins = elgg_get_plugins('any');
1523  foreach ($plugins as $plugin) {
1524  if ($plugin->getManifest()) {
1525  if ($plugin->getManifest()->getActivateOnInstall()) {
1526  $plugin->activate();
1527  }
1528  if (in_array('theme', $plugin->getManifest()->getCategories())) {
1529  $plugin->setPriority('last');
1530  }
1531  }
1532  }
1533  }
1534 
1547  protected function validateAdminVars($submissionVars, $formVars) {
1548 
1549  foreach ($formVars as $field => $info) {
1550  if ($info['required'] == TRUE && !$submissionVars[$field]) {
1551  $name = _elgg_services()->translator->translate("install:admin:label:$field");
1552  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1553  return FALSE;
1554  }
1555  }
1556 
1557  if ($submissionVars['password1'] !== $submissionVars['password2']) {
1558  register_error(_elgg_services()->translator->translate('install:admin:password:mismatch'));
1559  return FALSE;
1560  }
1561 
1562  if (trim($submissionVars['password1']) == "") {
1563  register_error(_elgg_services()->translator->translate('install:admin:password:empty'));
1564  return FALSE;
1565  }
1566 
1567  $minLength = _elgg_services()->configTable->get('min_password_length');
1568  if (strlen($submissionVars['password1']) < $minLength) {
1569  register_error(_elgg_services()->translator->translate('install:admin:password:tooshort'));
1570  return FALSE;
1571  }
1572 
1573  // check that email address is email address
1574  if ($submissionVars['email'] && !is_email_address($submissionVars['email'])) {
1575  $msg = _elgg_services()->translator->translate('install:error:emailaddress', array($submissionVars['email']));
1576  register_error($msg);
1577  return FALSE;
1578  }
1579 
1580  return TRUE;
1581  }
1582 
1591  protected function createAdminAccount($submissionVars, $login = FALSE) {
1592  try {
1593  $guid = register_user(
1594  $submissionVars['username'],
1595  $submissionVars['password1'],
1596  $submissionVars['displayname'],
1597  $submissionVars['email']
1598  );
1599  } catch (Exception $e) {
1600  register_error($e->getMessage());
1601  return false;
1602  }
1603 
1604  if (!$guid) {
1605  register_error(_elgg_services()->translator->translate('install:admin:cannot_create'));
1606  return false;
1607  }
1608 
1609  $user = get_entity($guid);
1610  if (!$user instanceof ElggUser) {
1611  register_error(_elgg_services()->translator->translate('install:error:loadadmin'));
1612  return false;
1613  }
1614 
1615  elgg_set_ignore_access(TRUE);
1616  if ($user->makeAdmin() == FALSE) {
1617  register_error(_elgg_services()->translator->translate('install:error:adminaccess'));
1618  } else {
1619  _elgg_services()->datalist->set('admin_registered', 1);
1620  }
1621  elgg_set_ignore_access(false);
1622 
1623  // add validation data to satisfy user validation plugins
1624  create_metadata($guid, 'validated', TRUE, '', 0, ACCESS_PUBLIC);
1625  create_metadata($guid, 'validated_method', 'admin_user', '', 0, ACCESS_PUBLIC);
1626 
1627  if ($login) {
1629 
1630  // session.cache_limiter is unfortunately set to "" by the NativeSessionStorage constructor,
1631  // so we must capture and inject it directly.
1632  $options = [
1633  'cache_limiter' => session_cache_limiter(),
1634  ];
1636 
1637  $session = new ElggSession(new Symfony\Component\HttpFoundation\Session\Session($storage));
1638  $session->setName('Elgg');
1639  _elgg_services()->setValue('session', $session);
1640  if (login($user) == FALSE) {
1641  register_error(_elgg_services()->translator->translate('install:error:adminlogin'));
1642  }
1643  }
1644 
1645  return TRUE;
1646  }
1647 }
checkSettingsFile(&$report=array())
Check that the settings file exists.
$lib_dir
This file is used to make all of Elgg&#39;s code available without going through the boot process...
Definition: load.php:9
$plugin
elgg_get_upgrade_files($upgrade_path=null)
Returns a list of upgrade files relative to the $upgrade_path dir.
Definition: upgrade.php:53
batchInstall(array $params, $createHtaccess=FALSE)
A batch install of Elgg.
createDataDirectory(&$submissionVars, $formVars)
Site settings support methods.
setSubtypeClasses()
Register classes for core objects.
bootstrapEngine()
Bootstraping.
$table
Definition: cron.php:28
countNumConditions($report, $condition)
Count the number of failures in the requirements report.
processRewriteTest()
Check if the request is coming from the URL rewrite test on the requirements page.
if($guid==elgg_get_logged_in_user_guid()) $name
Definition: delete.php:21
finishBootstraping($step)
Load remaining engine libraries and complete bootstraping (see start.php)
$e
Definition: metadata.php:12
checkPhpDirectives(&$phpReport)
Check PHP parameters.
$lang
Definition: html.php:12
welcome($vars)
Step controllers.
$defaults
$extensions
sanitise_filepath($path, $append_slash=true)
Sanitise file paths ensuring that they begin and end with slashes etc.
Definition: elgglib.php:368
$value
Definition: longtext.php:26
setInstallStatus()
Check the different install steps for completion.
installDatabase()
Create the database tables.
checkInstallCompletion($step)
Security check to ensure the installer cannot be run after installation has finished.
getNextStep($currentStep)
Get the next step as a string.
$step
Definition: install.php:23
$guid
Removes an admin notice.
checkEngineDir(&$report)
Requirement checks support methods.
exit
Definition: reorder.php:12
requirements($vars)
Requirements controller.
elgg forward
Meant to mimic the php forward() function by simply redirecting the user to another page...
Definition: elgglib.js:419
getSteps()
Step management.
$upgrades
Lists pending upgrades.
Definition: upgrades.php:6
register_user($username, $password, $name, $email, $allow_multiple_emails=false)
Registers a user, returning false if the username already exists.
Definition: users.php:316
$report
$url
Definition: exceptions.php:24
checkPHP(&$report)
Check version of PHP, extensions, and variables.
$title
Definition: save.php:24
validateSettingsVars($submissionVars, $formVars)
Validate the site settings form variables.
resumeInstall($step)
Check if this is a case of a install being resumed and figure out where to continue from...
$params
Definition: login.php:72
$options
Definition: index.php:14
settings($submissionVars)
Site settings controller.
continueToNextStep($currentStep)
Forwards the browser to the next step.
render($step, $vars=array())
Renders the data passed by a controller.
$plugins
Save menu items.
getNextStepUrl($currentStep)
Get the URL of the next step.
add_subtype($type, $subtype, $class="")
Register with a certain type and subtype to be loaded as a specific class.
Definition: entities.php:248
elgg_set_viewtype($viewtype="")
Manually set the viewtype.
Definition: views.php:70
getBaseUrl()
Get the best guess at the base URL.
$lib_files
Definition: load.php:25
$key
Definition: summary.php:34
elgg_set_ignore_access($ignore=true)
Set if Elgg&#39;s access system should be ignored.
Definition: access.php:43
_elgg_services()
Definition: autoloader.php:14
create_metadata($entity_guid, $name, $value, $value_type= '', $owner_guid=0, $access_id=ACCESS_PRIVATE, $allow_multiple=false)
Create a new metadata object, or update an existing one.
Definition: metadata.php:65
makeFormSticky($formVars, $submissionVars)
If form is reshown, remember previously submitted variables.
$user
Definition: ban.php:13
elgg echo
Translates a string.
Definition: languages.js:43
checkPhpExtensions(&$phpReport)
Check the server&#39;s PHP extensions.
elgg global
Pointer to the global context.
Definition: elgglib.js:12
bootstrapConfig()
Set up configuration variables.
elgg_view($view, $vars=array(), $bypass=false, $ignored=false, $viewtype= '')
Return a parsed view.
Definition: views.php:354
checkRewriteRules(&$report)
Confirm that the rewrite rules are firing.
$password
Definition: login.php:25
validateDatabaseVars($submissionVars, $formVars)
Database support methods.
elgg system_message
Wrapper function for system_messages.
Definition: elgglib.js:374
createSettingsFile($params)
Writes the settings file to the engine directory.
enablePlugins()
Enable a set of default plugins.
elgg_get_plugins($status= 'active', $site_guid=null)
Returns an ordered list of plugins.
Definition: plugins.php:162
const ACCESS_PUBLIC
Definition: elgglib.php:1956
elgg_get_version($human_readable=false)
Get the current Elgg version information.
Definition: elgglib.php:976
complete()
Controller for last step.
elgg register_error
Wrapper function for system_messages.
Definition: elgglib.js:383
getPostVariables()
Action handling methods.
loadSettingsFile()
Load settings.php.
__construct()
Constructor bootstraps the Elgg engine.
admin($submissionVars)
Admin account controller.
login(\ElggUser $user, $persistent=false)
Logs in a specified .
Definition: sessions.php:320
checkDatabaseSettings($user, $password, $dbname, $host)
Confirm the settings for the database.
if(elgg_in_context('widget')) $count
Definition: pagination.php:20
createAdminAccount($submissionVars, $login=FALSE)
Create a user account for the admin.
static getMock()
Get an isolated ElggSession that does not persist between requests.
elgg_view_page($title, $body, $page_shell= 'default', $vars=array())
Assembles and outputs a full page.
Definition: views.php:437
connectToDatabase()
Bootstrap database connection before entire engine is available.
setAutoLogin($flag)
Set the auto login flag.
$handler
Definition: add.php:10
saveSiteSettings($submissionVars)
Initialize the site including site entity, plugins, and configuration.
_elgg_session_boot()
Initializes the session and checks for the remember me cookie.
Definition: sessions.php:408
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two steps
Definition: LICENSE.txt:28
is_email_address($address)
Validates an email address.
Definition: input.php:88
$session
Definition: login.php:9
database($submissionVars)
Database set up controller.
$version
Definition: version.php:14
$path
Definition: invalid.php:17
run($step)
Dispatches a request to one of the step controllers.
_elgg_generate_plugin_entities()
Discovers plugins in the plugins_path setting and creates entities for them if they don&#39;t exist...
Definition: plugins.php:75
$extension
Definition: default.php:23
get_entity($guid)
Loads and returns an entity object from a guid.
Definition: entities.php:382
if(file_exists($welcome)) $vars
Definition: upgrade.php:93
validateAdminVars($submissionVars, $formVars)
Admin account support methods.