This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Elgg Installer. |
||
5 | * Controller for installing Elgg. Supports both web-based on CLI installation. |
||
6 | * |
||
7 | * This controller steps the user through the install process. The method for |
||
8 | * each step handles both the GET and POST requests. There is no XSS/CSRF protection |
||
9 | * on the POST processing since the installer is only run once by the administrator. |
||
10 | * |
||
11 | * The installation process can be resumed by hitting the first page. The installer |
||
12 | * will try to figure out where to pick up again. |
||
13 | * |
||
14 | * All the logic for the installation process is in this class, but it depends on |
||
15 | * the core libraries. To do this, we selectively load a subset of the core libraries |
||
16 | * for the first few steps and then load the entire engine once the database and |
||
17 | * site settings are configured. In addition, this controller does its own session |
||
18 | * handling until the database is setup. |
||
19 | * |
||
20 | * There is an aborted attempt in the code at creating the data directory for |
||
21 | * users as a subdirectory of Elgg's root. The idea was to protect this directory |
||
22 | * through a .htaccess file. The problem is that a malicious user can upload a |
||
23 | * .htaccess of his own that overrides the protection for his user directory. The |
||
24 | * best solution is server level configuration that turns off AllowOverride for the |
||
25 | * data directory. See ticket #3453 for discussion on this. |
||
26 | * |
||
27 | * @package Elgg.Core |
||
28 | * @subpackage Installer |
||
29 | */ |
||
30 | class ElggInstaller { |
||
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 | |||
52 | /** |
||
53 | * Global Elgg configuration |
||
54 | * |
||
55 | * @var \stdClass |
||
56 | */ |
||
57 | private $CONFIG; |
||
58 | |||
59 | /** |
||
60 | * Constructor bootstraps the Elgg engine |
||
61 | */ |
||
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 | |||
86 | /** |
||
87 | * @return string The absolute path to Elgg's root directory |
||
88 | */ |
||
89 | private function getElggRoot() { |
||
90 | return dirname(dirname(__DIR__)); |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * Dispatches a request to one of the step controllers |
||
95 | * |
||
96 | * @param string $step The installation step to run |
||
97 | * |
||
98 | * @return void |
||
99 | * @throws InstallationException |
||
100 | */ |
||
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 | |||
117 | $this->checkInstallCompletion($step); |
||
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 | |||
128 | /** |
||
129 | * Set the auto login flag |
||
130 | * |
||
131 | * @param bool $flag Auto login |
||
132 | * |
||
133 | * @return void |
||
134 | */ |
||
135 | public function setAutoLogin($flag) { |
||
136 | $this->autoLogin = (bool) $flag; |
||
137 | } |
||
138 | |||
139 | /** |
||
140 | * A batch install of Elgg |
||
141 | * |
||
142 | * All required parameters must be passed in as an associative array. See |
||
143 | * $requiredParams for a list of them. This creates the necessary files, |
||
144 | * loads the database, configures the site settings, and creates the admin |
||
145 | * account. If it fails, an exception is thrown. It does not check any of |
||
146 | * the requirements as the multiple step web installer does. |
||
147 | * |
||
148 | * If the settings.php file exists, it will use that rather than the parameters |
||
149 | * passed to this function. |
||
150 | * |
||
151 | * @param array $params Array of key value pairs |
||
152 | * @param bool $createHtaccess Should .htaccess be created |
||
153 | * |
||
154 | * @return void |
||
155 | * @throws InstallationException |
||
156 | */ |
||
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 | View Code Duplication | 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 | View Code Duplication | 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 | |||
230 | /** |
||
231 | * Renders the data passed by a controller |
||
232 | * |
||
233 | * @param string $step The current step |
||
234 | * @param array $vars Array of vars to pass to the view |
||
235 | * |
||
236 | * @return void |
||
237 | */ |
||
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); |
||
244 | echo elgg_view_page( |
||
245 | $title, |
||
246 | $body, |
||
247 | 'default', |
||
248 | array( |
||
249 | 'step' => $step, |
||
250 | 'steps' => $this->getSteps(), |
||
251 | ) |
||
252 | ); |
||
253 | exit; |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Step controllers |
||
258 | */ |
||
259 | |||
260 | /** |
||
261 | * Welcome controller |
||
262 | * |
||
263 | * @param array $vars Not used |
||
264 | * |
||
265 | * @return void |
||
266 | */ |
||
267 | protected function welcome($vars) { |
||
268 | $this->render('welcome'); |
||
269 | } |
||
270 | |||
271 | /** |
||
272 | * Requirements controller |
||
273 | * |
||
274 | * Checks version of php, libraries, permissions, and rewrite rules |
||
275 | * |
||
276 | * @param array $vars Vars |
||
277 | * |
||
278 | * @return void |
||
279 | */ |
||
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) { |
||
0 ignored issues
–
show
|
|||
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 | |||
318 | /** |
||
319 | * Database set up controller |
||
320 | * |
||
321 | * Creates the settings.php file and creates the database tables |
||
322 | * |
||
323 | * @param array $submissionVars Submitted form variables |
||
324 | * |
||
325 | * @return void |
||
326 | */ |
||
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 | |||
403 | /** |
||
404 | * Site settings controller |
||
405 | * |
||
406 | * Sets the site name, URL, data directory, etc. |
||
407 | * |
||
408 | * @param array $submissionVars Submitted vars |
||
409 | * |
||
410 | * @return void |
||
411 | */ |
||
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 | View Code Duplication | 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 | |||
476 | /** |
||
477 | * Admin account controller |
||
478 | * |
||
479 | * Creates an admin user account |
||
480 | * |
||
481 | * @param array $submissionVars Submitted vars |
||
482 | * |
||
483 | * @return void |
||
484 | */ |
||
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 | View Code Duplication | 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 | |||
544 | /** |
||
545 | * Controller for last step |
||
546 | * |
||
547 | * @return void |
||
548 | */ |
||
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 | |||
561 | /** |
||
562 | * Step management |
||
563 | */ |
||
564 | |||
565 | /** |
||
566 | * Get an array of steps |
||
567 | * |
||
568 | * @return array |
||
569 | */ |
||
570 | protected function getSteps() { |
||
571 | return $this->steps; |
||
572 | } |
||
573 | |||
574 | /** |
||
575 | * Forwards the browser to the next step |
||
576 | * |
||
577 | * @param string $currentStep Current installation step |
||
578 | * |
||
579 | * @return void |
||
580 | */ |
||
581 | protected function continueToNextStep($currentStep) { |
||
582 | $this->isAction = FALSE; |
||
583 | forward($this->getNextStepUrl($currentStep)); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Get the next step as a string |
||
588 | * |
||
589 | * @param string $currentStep Current installation step |
||
590 | * |
||
591 | * @return string |
||
592 | */ |
||
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 | |||
602 | /** |
||
603 | * Get the URL of the next step |
||
604 | * |
||
605 | * @param string $currentStep Current installation step |
||
606 | * |
||
607 | * @return string |
||
608 | */ |
||
609 | protected function getNextStepUrl($currentStep) { |
||
610 | $nextStep = $this->getNextStep($currentStep); |
||
611 | return _elgg_services()->config->getSiteUrl() . "install.php?step=$nextStep"; |
||
612 | } |
||
613 | |||
614 | /** |
||
615 | * Check the different install steps for completion |
||
616 | * |
||
617 | * @return void |
||
618 | * @throws InstallationException |
||
619 | */ |
||
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) { |
||
0 ignored issues
–
show
|
|||
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) { |
||
0 ignored issues
–
show
The expression
$result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
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) { |
||
0 ignored issues
–
show
|
|||
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) { |
||
0 ignored issues
–
show
The expression
$result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
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) { |
||
0 ignored issues
–
show
The expression
$result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
677 | $this->status['admin'] = TRUE; |
||
678 | } else { |
||
679 | return; |
||
680 | } |
||
681 | } |
||
682 | |||
683 | /** |
||
684 | * Security check to ensure the installer cannot be run after installation |
||
685 | * has finished. If this is detected, the viewer is sent to the front page. |
||
686 | * |
||
687 | * @param string $step Installation step to check against |
||
688 | * |
||
689 | * @return void |
||
690 | */ |
||
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 | |||
700 | /** |
||
701 | * Check if this is a case of a install being resumed and figure |
||
702 | * out where to continue from. Returns the best guess on the step. |
||
703 | * |
||
704 | * @param string $step Installation step to resume from |
||
705 | * |
||
706 | * @return string |
||
707 | */ |
||
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 | |||
730 | /** |
||
731 | * Bootstraping |
||
732 | */ |
||
733 | |||
734 | /** |
||
735 | * Load the essential libraries of the engine |
||
736 | * |
||
737 | * @return void |
||
738 | */ |
||
739 | protected function bootstrapEngine() { |
||
740 | |||
741 | |||
742 | require_once $this->CONFIG->path . 'engine/load.php'; |
||
743 | } |
||
744 | |||
745 | /** |
||
746 | * Load remaining engine libraries and complete bootstraping (see start.php) |
||
747 | * |
||
748 | * @param string $step Which step to boot strap for. Required because |
||
749 | * boot strapping is different until the DB is populated. |
||
750 | * |
||
751 | * @return void |
||
752 | * @throws InstallationException |
||
753 | */ |
||
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'); |
||
833 | _elgg_session_boot(); |
||
834 | } |
||
835 | |||
836 | _elgg_services()->events->trigger('init', 'system'); |
||
837 | } |
||
838 | } |
||
839 | |||
840 | /** |
||
841 | * Set up configuration variables |
||
842 | * |
||
843 | * @return void |
||
844 | */ |
||
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 | |||
864 | /** |
||
865 | * @return bool Whether the install process is encrypted. |
||
866 | */ |
||
867 | private function isHttps() { |
||
868 | return (!empty($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") || |
||
869 | $_SERVER['SERVER_PORT'] == 443; |
||
870 | } |
||
871 | |||
872 | /** |
||
873 | * Get the best guess at the base URL |
||
874 | * |
||
875 | * @note Cannot use current_page_url() because it depends on $this->CONFIG->wwwroot |
||
876 | * @todo Should this be a core function? |
||
877 | * |
||
878 | * @return string |
||
879 | */ |
||
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 | |||
899 | /** |
||
900 | * Load settings.php |
||
901 | * |
||
902 | * @return void |
||
903 | * @throws InstallationException |
||
904 | */ |
||
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 | |||
913 | /** |
||
914 | * Action handling methods |
||
915 | */ |
||
916 | |||
917 | /** |
||
918 | * Return an associative array of post variables |
||
919 | * (could be selective based on expected variables) |
||
920 | * |
||
921 | * Does not filter as person installing the site should not be attempting |
||
922 | * XSS attacks. If filtering is added, it should not be done for passwords. |
||
923 | * |
||
924 | * @return array |
||
925 | */ |
||
926 | protected function getPostVariables() { |
||
927 | $vars = array(); |
||
928 | foreach ($_POST as $k => $v) { |
||
929 | $vars[$k] = $v; |
||
930 | } |
||
931 | return $vars; |
||
932 | } |
||
933 | |||
934 | /** |
||
935 | * If form is reshown, remember previously submitted variables |
||
936 | * |
||
937 | * @param array $formVars Vars int he form |
||
938 | * @param array $submissionVars Submitted vars |
||
939 | * |
||
940 | * @return array |
||
941 | */ |
||
942 | protected function makeFormSticky($formVars, $submissionVars) { |
||
943 | foreach ($submissionVars as $field => $value) { |
||
944 | $formVars[$field]['value'] = $value; |
||
945 | } |
||
946 | return $formVars; |
||
947 | } |
||
948 | |||
949 | /** |
||
950 | * Requirement checks support methods |
||
951 | */ |
||
952 | |||
953 | /** |
||
954 | * Check that the engine dir is writable |
||
955 | * |
||
956 | * @param array &$report The requirements report object |
||
957 | * |
||
958 | * @return bool |
||
959 | */ |
||
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 | |||
977 | /** |
||
978 | * Check that the settings file exists |
||
979 | * |
||
980 | * @param array &$report The requirements report array |
||
981 | * |
||
982 | * @return bool |
||
983 | */ |
||
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 | |||
1003 | /** |
||
1004 | * Check version of PHP, extensions, and variables |
||
1005 | * |
||
1006 | * @param array &$report The requirements report array |
||
1007 | * |
||
1008 | * @return void |
||
1009 | */ |
||
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 | |||
1035 | /** |
||
1036 | * Check the server's PHP extensions |
||
1037 | * |
||
1038 | * @param array &$phpReport The PHP requirements report array |
||
1039 | * |
||
1040 | * @return void |
||
1041 | */ |
||
1042 | protected function checkPhpExtensions(&$phpReport) { |
||
1043 | $extensions = get_loaded_extensions(); |
||
1044 | $requiredExtensions = array( |
||
1045 | 'mysql', |
||
1046 | 'json', |
||
1047 | 'xml', |
||
1048 | 'gd', |
||
1049 | ); |
||
1050 | View Code Duplication | 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 | View Code Duplication | 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 | |||
1072 | /** |
||
1073 | * Check PHP parameters |
||
1074 | * |
||
1075 | * @param array &$phpReport The PHP requirements report array |
||
1076 | * |
||
1077 | * @return void |
||
1078 | */ |
||
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 | |||
1118 | /** |
||
1119 | * Confirm that the rewrite rules are firing |
||
1120 | * |
||
1121 | * @param array &$report The requirements report array |
||
1122 | * |
||
1123 | * @return void |
||
1124 | */ |
||
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 | |||
1133 | /** |
||
1134 | * Check if the request is coming from the URL rewrite test on the |
||
1135 | * requirements page. |
||
1136 | * |
||
1137 | * @return void |
||
1138 | */ |
||
1139 | protected function processRewriteTest() { |
||
1140 | if (strpos($_SERVER['REQUEST_URI'], 'rewrite.php') !== FALSE) { |
||
1141 | echo 'success'; |
||
1142 | exit; |
||
1143 | } |
||
1144 | } |
||
1145 | |||
1146 | /** |
||
1147 | * Count the number of failures in the requirements report |
||
1148 | * |
||
1149 | * @param array $report The requirements report array |
||
1150 | * @param string $condition 'failure' or 'warning' |
||
1151 | * |
||
1152 | * @return int |
||
1153 | */ |
||
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 | |||
1168 | /** |
||
1169 | * Database support methods |
||
1170 | */ |
||
1171 | |||
1172 | /** |
||
1173 | * Validate the variables for the database step |
||
1174 | * |
||
1175 | * @param array $submissionVars Submitted vars |
||
1176 | * @param array $formVars Vars in the form |
||
1177 | * |
||
1178 | * @return bool |
||
1179 | */ |
||
1180 | protected function validateDatabaseVars($submissionVars, $formVars) { |
||
1181 | |||
1182 | View Code Duplication | 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 | |||
1208 | /** |
||
1209 | * Confirm the settings for the database |
||
1210 | * |
||
1211 | * @param string $user Username |
||
1212 | * @param string $password Password |
||
1213 | * @param string $dbname Database name |
||
1214 | * @param string $host Host |
||
1215 | * |
||
1216 | * @return bool |
||
1217 | */ |
||
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 | |||
1251 | /** |
||
1252 | * Writes the settings file to the engine directory |
||
1253 | * |
||
1254 | * @param array $params Array of inputted params from the user |
||
1255 | * |
||
1256 | * @return bool |
||
1257 | */ |
||
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 | |||
1282 | /** |
||
1283 | * Bootstrap database connection before entire engine is available |
||
1284 | * |
||
1285 | * @return bool |
||
1286 | */ |
||
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 | |||
1310 | /** |
||
1311 | * Create the database tables |
||
1312 | * |
||
1313 | * @return bool |
||
1314 | */ |
||
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 | |||
1332 | /** |
||
1333 | * Site settings support methods |
||
1334 | */ |
||
1335 | |||
1336 | /** |
||
1337 | * Create the data directory if requested |
||
1338 | * |
||
1339 | * @param array &$submissionVars Submitted vars |
||
1340 | * @param array $formVars Variables in the form |
||
1341 | * |
||
1342 | * @return bool |
||
1343 | */ |
||
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 | |||
1370 | /** |
||
1371 | * Validate the site settings form variables |
||
1372 | * |
||
1373 | * @param array $submissionVars Submitted vars |
||
1374 | * @param array $formVars Vars in the form |
||
1375 | * |
||
1376 | * @return bool |
||
1377 | */ |
||
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 | View Code Duplication | 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 | View Code Duplication | } 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 | View Code Duplication | 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 | View Code Duplication | 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 | View Code Duplication | 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 | View Code Duplication | 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 | |||
1441 | /** |
||
1442 | * Initialize the site including site entity, plugins, and configuration |
||
1443 | * |
||
1444 | * @param array $submissionVars Submitted vars |
||
1445 | * |
||
1446 | * @return bool |
||
1447 | */ |
||
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()); |
||
0 ignored issues
–
show
|
|||
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 | |||
1502 | /** |
||
1503 | * Register classes for core objects |
||
1504 | * |
||
1505 | * @return void |
||
1506 | */ |
||
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 | |||
1515 | /** |
||
1516 | * Enable a set of default plugins |
||
1517 | * |
||
1518 | * @return void |
||
1519 | */ |
||
1520 | protected function enablePlugins() { |
||
1521 | _elgg_generate_plugin_entities(); |
||
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 | |||
1535 | /** |
||
1536 | * Admin account support methods |
||
1537 | */ |
||
1538 | |||
1539 | /** |
||
1540 | * Validate account form variables |
||
1541 | * |
||
1542 | * @param array $submissionVars Submitted vars |
||
1543 | * @param array $formVars Form vars |
||
1544 | * |
||
1545 | * @return bool |
||
1546 | */ |
||
1547 | protected function validateAdminVars($submissionVars, $formVars) { |
||
1548 | |||
1549 | View Code Duplication | 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 | View Code Duplication | 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 | |||
1583 | /** |
||
1584 | * Create a user account for the admin |
||
1585 | * |
||
1586 | * @param array $submissionVars Submitted vars |
||
1587 | * @param bool $login Login in the admin user? |
||
1588 | * |
||
1589 | * @return bool |
||
1590 | */ |
||
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) { |
||
0 ignored issues
–
show
|
|||
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); |
||
0 ignored issues
–
show
TRUE is of type boolean , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
1625 | create_metadata($guid, 'validated_method', 'admin_user', '', 0, ACCESS_PUBLIC); |
||
1626 | |||
1627 | if ($login) { |
||
1628 | $handler = new Elgg\Http\DatabaseSessionHandler(_elgg_services()->db); |
||
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 | ]; |
||
1635 | $storage = new Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage($options, $handler); |
||
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) { |
||
0 ignored issues
–
show
|
|||
1641 | register_error(_elgg_services()->translator->translate('install:error:adminlogin')); |
||
1642 | } |
||
1643 | } |
||
1644 | |||
1645 | return TRUE; |
||
1646 | } |
||
1647 | } |
||
1648 |
When comparing two booleans, it is generally considered safer to use the strict comparison operator.