Elgg  Version 1.10
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', new ElggSession(new Elgg\Http\MockSessionStorage()));
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  // required by elgg_view_page()
856  $this->CONFIG->sitename = '';
857  $this->CONFIG->sitedescription = '';
858  }
859 
863  private function isHttps() {
864  return (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") ||
865  $_SERVER['SERVER_PORT'] == 443;
866  }
867 
876  protected function getBaseUrl() {
877  $protocol = $this->isHttps() ? 'https' : 'http';
878 
879  if (isset($_SERVER["SERVER_PORT"])) {
880  $port = ':' . $_SERVER["SERVER_PORT"];
881  } else {
882  $port = '';
883  }
884  if ($port == ':80' || $port == ':443') {
885  $port = '';
886  }
887  $uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
888  $cutoff = strpos($uri, 'install.php');
889  $uri = substr($uri, 0, $cutoff);
890  $serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
891 
892  return "$protocol://{$serverName}$port{$uri}";
893  }
894 
901  protected function loadSettingsFile() {
902 
903 
904  if (!include_once("{$this->CONFIG->path}engine/settings.php")) {
905  throw new InstallationException(_elgg_services()->translator->translate('InstallationException:CannotLoadSettings'));
906  }
907  }
908 
922  protected function getPostVariables() {
923  $vars = array();
924  foreach ($_POST as $k => $v) {
925  $vars[$k] = $v;
926  }
927  return $vars;
928  }
929 
938  protected function makeFormSticky($formVars, $submissionVars) {
939  foreach ($submissionVars as $field => $value) {
940  $formVars[$field]['value'] = $value;
941  }
942  return $formVars;
943  }
944 
956  protected function checkEngineDir(&$report) {
957 
958 
959  $writable = is_writable("{$this->CONFIG->path}engine");
960  if (!$writable) {
961  $report['settings'] = array(
962  array(
963  'severity' => 'failure',
964  'message' => _elgg_services()->translator->translate('install:check:enginedir'),
965  )
966  );
967  return FALSE;
968  }
969 
970  return TRUE;
971  }
972 
980  protected function checkSettingsFile(&$report = array()) {
981 
982 
983  if (!file_exists("{$this->CONFIG->path}engine/settings.php")) {
984  return FALSE;
985  }
986 
987  if (!is_readable("{$this->CONFIG->path}engine/settings.php")) {
988  $report['settings'] = array(
989  array(
990  'severity' => 'failure',
991  'message' => _elgg_services()->translator->translate('install:check:readsettings'),
992  )
993  );
994  }
995 
996  return TRUE;
997  }
998 
1006  protected function checkPHP(&$report) {
1007  $phpReport = array();
1008 
1009  $min_php_version = '5.4.0';
1010  if (version_compare(PHP_VERSION, $min_php_version, '<')) {
1011  $phpReport[] = array(
1012  'severity' => 'failure',
1013  'message' => _elgg_services()->translator->translate('install:check:php:version', array($min_php_version, PHP_VERSION))
1014  );
1015  }
1016 
1017  $this->checkPhpExtensions($phpReport);
1018 
1019  $this->checkPhpDirectives($phpReport);
1020 
1021  if (count($phpReport) == 0) {
1022  $phpReport[] = array(
1023  'severity' => 'pass',
1024  'message' => _elgg_services()->translator->translate('install:check:php:success')
1025  );
1026  }
1027 
1028  $report['php'] = $phpReport;
1029  }
1030 
1038  protected function checkPhpExtensions(&$phpReport) {
1039  $extensions = get_loaded_extensions();
1040  $requiredExtensions = array(
1041  'mysql',
1042  'json',
1043  'xml',
1044  'gd',
1045  );
1046  foreach ($requiredExtensions as $extension) {
1047  if (!in_array($extension, $extensions)) {
1048  $phpReport[] = array(
1049  'severity' => 'failure',
1050  'message' => _elgg_services()->translator->translate('install:check:php:extension', array($extension))
1051  );
1052  }
1053  }
1054 
1055  $recommendedExtensions = array(
1056  'mbstring',
1057  );
1058  foreach ($recommendedExtensions as $extension) {
1059  if (!in_array($extension, $extensions)) {
1060  $phpReport[] = array(
1061  'severity' => 'warning',
1062  'message' => _elgg_services()->translator->translate('install:check:php:extension:recommend', array($extension))
1063  );
1064  }
1065  }
1066  }
1067 
1075  protected function checkPhpDirectives(&$phpReport) {
1076  if (ini_get('open_basedir')) {
1077  $phpReport[] = array(
1078  'severity' => 'warning',
1079  'message' => _elgg_services()->translator->translate("install:check:php:open_basedir")
1080  );
1081  }
1082 
1083  if (ini_get('safe_mode')) {
1084  $phpReport[] = array(
1085  'severity' => 'warning',
1086  'message' => _elgg_services()->translator->translate("install:check:php:safe_mode")
1087  );
1088  }
1089 
1090  if (ini_get('arg_separator.output') !== '&') {
1091  $separator = htmlspecialchars(ini_get('arg_separator.output'));
1092  $msg = _elgg_services()->translator->translate("install:check:php:arg_separator", array($separator));
1093  $phpReport[] = array(
1094  'severity' => 'failure',
1095  'message' => $msg,
1096  );
1097  }
1098 
1099  if (ini_get('register_globals')) {
1100  $phpReport[] = array(
1101  'severity' => 'failure',
1102  'message' => _elgg_services()->translator->translate("install:check:php:register_globals")
1103  );
1104  }
1105 
1106  if (ini_get('session.auto_start')) {
1107  $phpReport[] = array(
1108  'severity' => 'failure',
1109  'message' => _elgg_services()->translator->translate("install:check:php:session.auto_start")
1110  );
1111  }
1112  }
1113 
1121  protected function checkRewriteRules(&$report) {
1122 
1123 
1124  $tester = new ElggRewriteTester();
1125  $url = _elgg_services()->config->getSiteUrl() . "rewrite.php";
1126  $report['rewrite'] = array($tester->run($url, $this->CONFIG->path));
1127  }
1128 
1135  protected function processRewriteTest() {
1136  if (strpos($_SERVER['REQUEST_URI'], 'rewrite.php') !== FALSE) {
1137  echo 'success';
1138  exit;
1139  }
1140  }
1141 
1150  protected function countNumConditions($report, $condition) {
1151  $count = 0;
1152  foreach ($report as $category => $checks) {
1153  foreach ($checks as $check) {
1154  if ($check['severity'] === $condition) {
1155  $count++;
1156  }
1157  }
1158  }
1159 
1160  return $count;
1161  }
1162 
1163 
1176  protected function validateDatabaseVars($submissionVars, $formVars) {
1177 
1178  foreach ($formVars as $field => $info) {
1179  if ($info['required'] == TRUE && !$submissionVars[$field]) {
1180  $name = _elgg_services()->translator->translate("install:database:label:$field");
1181  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1182  return FALSE;
1183  }
1184  }
1185 
1186  // according to postgres documentation: SQL identifiers and key words must
1187  // begin with a letter (a-z, but also letters with diacritical marks and
1188  // non-Latin letters) or an underscore (_). Subsequent characters in an
1189  // identifier or key word can be letters, underscores, digits (0-9), or dollar signs ($).
1190  // Refs #4994
1191  if (!preg_match("/^[a-zA-Z_][\w]*$/", $submissionVars['dbprefix'])) {
1192  register_error(_elgg_services()->translator->translate('install:error:database_prefix'));
1193  return FALSE;
1194  }
1195 
1196  return $this->checkDatabaseSettings(
1197  $submissionVars['dbuser'],
1198  $submissionVars['dbpassword'],
1199  $submissionVars['dbname'],
1200  $submissionVars['dbhost']
1201  );
1202  }
1203 
1214  protected function checkDatabaseSettings($user, $password, $dbname, $host) {
1215  $mysql_dblink = mysql_connect($host, $user, $password, true);
1216  if ($mysql_dblink == FALSE) {
1217  register_error(_elgg_services()->translator->translate('install:error:databasesettings'));
1218  return FALSE;
1219  }
1220 
1221  $result = mysql_select_db($dbname, $mysql_dblink);
1222 
1223  // check MySQL version - must be 5.0 or >
1224  $required_version = 5.0;
1225  $version = mysql_get_server_info();
1226  $points = explode('.', $version);
1227  if ($points[0] < $required_version) {
1228  register_error(_elgg_services()->translator->translate('install:error:oldmysql', array($version)));
1229  return FALSE;
1230  }
1231 
1232  mysql_close($mysql_dblink);
1233 
1234  if (!$result) {
1235  register_error(_elgg_services()->translator->translate('install:error:nodatabase', array($dbname)));
1236  }
1237 
1238  return $result;
1239  }
1240 
1248  protected function createSettingsFile($params) {
1249 
1250 
1251  $templateFile = "{$this->CONFIG->path}engine/settings.example.php";
1252  $template = file_get_contents($templateFile);
1253  if (!$template) {
1254  register_error(_elgg_services()->translator->translate('install:error:readsettingsphp'));
1255  return FALSE;
1256  }
1257 
1258  foreach ($params as $k => $v) {
1259  $template = str_replace("{{" . $k . "}}", $v, $template);
1260  }
1261 
1262  $settingsFilename = "{$this->CONFIG->path}engine/settings.php";
1263  $result = file_put_contents($settingsFilename, $template);
1264  if (!$result) {
1265  register_error(_elgg_services()->translator->translate('install:error:writesettingphp'));
1266  return FALSE;
1267  }
1268 
1269  return TRUE;
1270  }
1271 
1277  protected function connectToDatabase() {
1278 
1279 
1280  if (!include_once("{$this->CONFIG->path}engine/settings.php")) {
1281  register_error('Elgg could not load the settings file. It does not exist or there is a file permissions issue.');
1282  return FALSE;
1283  }
1284 
1285  if (!include_once("{$this->CONFIG->path}engine/lib/database.php")) {
1286  register_error('Could not load database.php');
1287  return FALSE;
1288  }
1289 
1290  try {
1291  _elgg_services()->db->setupConnections();
1292  } catch (DatabaseException $e) {
1293  register_error($e->getMessage());
1294  return FALSE;
1295  }
1296 
1297  return TRUE;
1298  }
1299 
1305  protected function installDatabase() {
1306 
1307 
1308  try {
1309  _elgg_services()->db->runSqlScript("{$this->CONFIG->path}engine/schema/mysql.sql");
1310  } catch (Exception $e) {
1311  $msg = $e->getMessage();
1312  if (strpos($msg, 'already exists')) {
1313  $msg = _elgg_services()->translator->translate('install:error:tables_exist');
1314  }
1315  register_error($msg);
1316  return FALSE;
1317  }
1318 
1319  return TRUE;
1320  }
1321 
1334  protected function createDataDirectory(&$submissionVars, $formVars) {
1335  // did the user have option of Elgg creating the data directory
1336  if ($formVars['dataroot']['type'] != 'combo') {
1337  return TRUE;
1338  }
1339 
1340  // did the user select the option
1341  if ($submissionVars['dataroot'] != 'dataroot-checkbox') {
1342  return TRUE;
1343  }
1344 
1345  $dir = sanitise_filepath($submissionVars['path']) . 'data';
1346  if (file_exists($dir) || mkdir($dir, 0700)) {
1347  $submissionVars['dataroot'] = $dir;
1348  if (!file_exists("$dir/.htaccess")) {
1349  $htaccess = "Order Deny,Allow\nDeny from All\n";
1350  if (!file_put_contents("$dir/.htaccess", $htaccess)) {
1351  return FALSE;
1352  }
1353  }
1354  return TRUE;
1355  }
1356 
1357  return FALSE;
1358  }
1359 
1368  protected function validateSettingsVars($submissionVars, $formVars) {
1369 
1370 
1371  foreach ($formVars as $field => $info) {
1372  $submissionVars[$field] = trim($submissionVars[$field]);
1373  if ($info['required'] == TRUE && $submissionVars[$field] === '') {
1374  $name = _elgg_services()->translator->translate("install:settings:label:$field");
1375  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1376  return FALSE;
1377  }
1378  }
1379 
1380  // check that data root is absolute path
1381  if (stripos(PHP_OS, 'win') === 0) {
1382  if (strpos($submissionVars['dataroot'], ':') !== 1) {
1383  $msg = _elgg_services()->translator->translate('install:error:relative_path', array($submissionVars['dataroot']));
1384  register_error($msg);
1385  return FALSE;
1386  }
1387  } else {
1388  if (strpos($submissionVars['dataroot'], '/') !== 0) {
1389  $msg = _elgg_services()->translator->translate('install:error:relative_path', array($submissionVars['dataroot']));
1390  register_error($msg);
1391  return FALSE;
1392  }
1393  }
1394 
1395  // check that data root exists
1396  if (!file_exists($submissionVars['dataroot'])) {
1397  $msg = _elgg_services()->translator->translate('install:error:datadirectoryexists', array($submissionVars['dataroot']));
1398  register_error($msg);
1399  return FALSE;
1400  }
1401 
1402  // check that data root is writable
1403  if (!is_writable($submissionVars['dataroot'])) {
1404  $msg = _elgg_services()->translator->translate('install:error:writedatadirectory', array($submissionVars['dataroot']));
1405  register_error($msg);
1406  return FALSE;
1407  }
1408 
1409  if (!isset($this->CONFIG->data_dir_override) || !$this->CONFIG->data_dir_override) {
1410  // check that data root is not subdirectory of Elgg root
1411  if (stripos($submissionVars['dataroot'], $submissionVars['path']) === 0) {
1412  $msg = _elgg_services()->translator->translate('install:error:locationdatadirectory', array($submissionVars['dataroot']));
1413  register_error($msg);
1414  return FALSE;
1415  }
1416  }
1417 
1418  // check that email address is email address
1419  if ($submissionVars['siteemail'] && !is_email_address($submissionVars['siteemail'])) {
1420  $msg = _elgg_services()->translator->translate('install:error:emailaddress', array($submissionVars['siteemail']));
1421  register_error($msg);
1422  return FALSE;
1423  }
1424 
1425  // @todo check that url is a url
1426  // @note filter_var cannot be used because it doesn't work on international urls
1427 
1428  return TRUE;
1429  }
1430 
1438  protected function saveSiteSettings($submissionVars) {
1439 
1440 
1441  // ensure that file path, data path, and www root end in /
1442  $submissionVars['path'] = sanitise_filepath($submissionVars['path']);
1443  $submissionVars['dataroot'] = sanitise_filepath($submissionVars['dataroot']);
1444  $submissionVars['wwwroot'] = sanitise_filepath($submissionVars['wwwroot']);
1445 
1446  $site = new ElggSite();
1447  $site->name = strip_tags($submissionVars['sitename']);
1448  $site->url = $submissionVars['wwwroot'];
1449  $site->access_id = ACCESS_PUBLIC;
1450  $site->email = $submissionVars['siteemail'];
1451  $guid = $site->save();
1452 
1453  if (!$guid) {
1454  register_error(_elgg_services()->translator->translate('install:error:createsite'));
1455  return FALSE;
1456  }
1457 
1458  // bootstrap site info
1459  $this->CONFIG->site_guid = $guid;
1460  $this->CONFIG->site_id = $guid;
1461  $this->CONFIG->site = $site;
1462 
1463  _elgg_services()->datalist->set('installed', time());
1464  _elgg_services()->datalist->set('path', $submissionVars['path']);
1465  _elgg_services()->datalist->set('dataroot', $submissionVars['dataroot']);
1466  _elgg_services()->datalist->set('default_site', $site->getGUID());
1467  _elgg_services()->datalist->set('version', elgg_get_version());
1468  _elgg_services()->datalist->set('simplecache_enabled', 1);
1469  _elgg_services()->datalist->set('system_cache_enabled', 1);
1470  _elgg_services()->datalist->set('simplecache_lastupdate', time());
1471 
1472  // new installations have run all the upgrades
1473  $upgrades = elgg_get_upgrade_files($submissionVars['path'] . 'engine/lib/upgrades/');
1474  _elgg_services()->datalist->set('processed_upgrades', serialize($upgrades));
1475 
1476  _elgg_services()->configTable->set('view', 'default', $site->getGUID());
1477  _elgg_services()->configTable->set('language', 'en', $site->getGUID());
1478  _elgg_services()->configTable->set('default_access', $submissionVars['siteaccess'], $site->getGUID());
1479  _elgg_services()->configTable->set('allow_registration', TRUE, $site->getGUID());
1480  _elgg_services()->configTable->set('walled_garden', FALSE, $site->getGUID());
1481  _elgg_services()->configTable->set('allow_user_default_access', '', $site->getGUID());
1482  _elgg_services()->configTable->set('default_limit', 10, $site->getGUID());
1483 
1484  $this->setSubtypeClasses();
1485 
1486  $this->enablePlugins();
1487 
1488  return TRUE;
1489  }
1490 
1496  protected function setSubtypeClasses() {
1497  add_subtype("object", "plugin", "ElggPlugin");
1498  add_subtype("object", "file", "ElggFile");
1499  add_subtype("object", "widget", "ElggWidget");
1500  add_subtype("object", "comment", "ElggComment");
1501  add_subtype("object", "elgg_upgrade", 'ElggUpgrade');
1502  }
1503 
1509  protected function enablePlugins() {
1511  $plugins = elgg_get_plugins('any');
1512  foreach ($plugins as $plugin) {
1513  if ($plugin->getManifest()) {
1514  if ($plugin->getManifest()->getActivateOnInstall()) {
1515  $plugin->activate();
1516  }
1517  if (in_array('theme', $plugin->getManifest()->getCategories())) {
1518  $plugin->setPriority('last');
1519  }
1520  }
1521  }
1522  }
1523 
1536  protected function validateAdminVars($submissionVars, $formVars) {
1537 
1538  foreach ($formVars as $field => $info) {
1539  if ($info['required'] == TRUE && !$submissionVars[$field]) {
1540  $name = _elgg_services()->translator->translate("install:admin:label:$field");
1541  register_error(_elgg_services()->translator->translate('install:error:requiredfield', array($name)));
1542  return FALSE;
1543  }
1544  }
1545 
1546  if ($submissionVars['password1'] !== $submissionVars['password2']) {
1547  register_error(_elgg_services()->translator->translate('install:admin:password:mismatch'));
1548  return FALSE;
1549  }
1550 
1551  if (trim($submissionVars['password1']) == "") {
1552  register_error(_elgg_services()->translator->translate('install:admin:password:empty'));
1553  return FALSE;
1554  }
1555 
1556  $minLength = _elgg_services()->configTable->get('min_password_length');
1557  if (strlen($submissionVars['password1']) < $minLength) {
1558  register_error(_elgg_services()->translator->translate('install:admin:password:tooshort'));
1559  return FALSE;
1560  }
1561 
1562  // check that email address is email address
1563  if ($submissionVars['email'] && !is_email_address($submissionVars['email'])) {
1564  $msg = _elgg_services()->translator->translate('install:error:emailaddress', array($submissionVars['email']));
1565  register_error($msg);
1566  return FALSE;
1567  }
1568 
1569  return TRUE;
1570  }
1571 
1580  protected function createAdminAccount($submissionVars, $login = FALSE) {
1581  try {
1582  $guid = register_user(
1583  $submissionVars['username'],
1584  $submissionVars['password1'],
1585  $submissionVars['displayname'],
1586  $submissionVars['email']
1587  );
1588  } catch (Exception $e) {
1589  register_error($e->getMessage());
1590  return false;
1591  }
1592 
1593  if (!$guid) {
1594  register_error(_elgg_services()->translator->translate('install:admin:cannot_create'));
1595  return false;
1596  }
1597 
1598  $user = get_entity($guid);
1599  if (!$user instanceof ElggUser) {
1600  register_error(_elgg_services()->translator->translate('install:error:loadadmin'));
1601  return false;
1602  }
1603 
1604  elgg_set_ignore_access(TRUE);
1605  if ($user->makeAdmin() == FALSE) {
1606  register_error(_elgg_services()->translator->translate('install:error:adminaccess'));
1607  } else {
1608  _elgg_services()->datalist->set('admin_registered', 1);
1609  }
1610  elgg_set_ignore_access(false);
1611 
1612  // add validation data to satisfy user validation plugins
1613  create_metadata($guid, 'validated', TRUE, '', 0, ACCESS_PUBLIC);
1614  create_metadata($guid, 'validated_method', 'admin_user', '', 0, ACCESS_PUBLIC);
1615 
1616  if ($login) {
1618  $storage = new Elgg\Http\NativeSessionStorage(array(), $handler);
1619  $session = new ElggSession($storage);
1620  $session->setName('Elgg');
1621  _elgg_services()->setValue('session', $session);
1622  if (login($user) == FALSE) {
1623  register_error(_elgg_services()->translator->translate('install:error:adminlogin'));
1624  }
1625  }
1626 
1627  return TRUE;
1628  }
1629 }
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:10
$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.
$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:29
setInstallStatus()
Check the different install steps for completion.
if(!$autoload_available) _elgg_services()
Definition: autoloader.php:20
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:19
$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
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:15
if(!$limit=(int) elgg_extract('limit', $vars, elgg_get_config('default_limit'))) $count
Definition: pagination.php:26
$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
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:2048
elgg_get_version($human_readable=false)
Get the current Elgg version information.
Definition: elgglib.php:1010
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.
createAdminAccount($submissionVars, $login=FALSE)
Create a user account for the admin.
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
$defaults
Definition: access.php:19
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.