weekly release 2.8dev
[moodle.git] / lib / environmentlib.php
CommitLineData
c030b5ee 1<?php
2
16ae0853 3// This file is part of Moodle - http://moodle.org/
4//
c030b5ee 5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
f58b518f 9//
c030b5ee 10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
16ae0853 14//
c030b5ee 15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * This library includes all the necessary stuff to execute some standard
20 * tests of required versions and libraries to run Moodle. It can be
21 * used from the admin interface, and both at install and upgrade.
22 *
23 * All the info is stored in the admin/environment.xml file,
24 * supporting to have an updated version in dataroot/environment
25 *
78bfb562
PS
26 * @copyright (C) 2001-3001 Eloy Lafuente (stronk7) {@link http://contiento.com}
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 * @package core
29 * @subpackage admin
c030b5ee 30 */
f58b518f 31
78bfb562
PS
32defined('MOODLE_INTERNAL') || die();
33
049c0f4a 34/// Add required files
c030b5ee 35/**
78bfb562 36 * Include the necessary
c030b5ee 37 */
049c0f4a 38 require_once($CFG->libdir.'/xmlize.php');
39
78bfb562 40/// Define a bunch of XML processing errors
c030b5ee 41 /** XML Processing Error */
00d3a0fd 42 define('NO_ERROR', 0);
c030b5ee 43 /** XML Processing Error */
00d3a0fd 44 define('NO_VERSION_DATA_FOUND', 1);
c030b5ee 45 /** XML Processing Error */
00d3a0fd 46 define('NO_DATABASE_SECTION_FOUND', 2);
c030b5ee 47 /** XML Processing Error */
00d3a0fd 48 define('NO_DATABASE_VENDORS_FOUND', 3);
c030b5ee 49 /** XML Processing Error */
00d3a0fd 50 define('NO_DATABASE_VENDOR_MYSQL_FOUND', 4);
c030b5ee 51 /** XML Processing Error */
00d3a0fd 52 define('NO_DATABASE_VENDOR_POSTGRES_FOUND', 5);
c030b5ee 53 /** XML Processing Error */
00d3a0fd 54 define('NO_PHP_SECTION_FOUND', 6);
c030b5ee 55 /** XML Processing Error */
00d3a0fd 56 define('NO_PHP_VERSION_FOUND', 7);
c030b5ee 57 /** XML Processing Error */
00d3a0fd 58 define('NO_PHP_EXTENSIONS_SECTION_FOUND', 8);
c030b5ee 59 /** XML Processing Error */
00d3a0fd 60 define('NO_PHP_EXTENSIONS_NAME_FOUND', 9);
c030b5ee 61 /** XML Processing Error */
00d3a0fd 62 define('NO_DATABASE_VENDOR_VERSION_FOUND', 10);
c030b5ee 63 /** XML Processing Error */
a392be33 64 define('NO_UNICODE_SECTION_FOUND', 11);
c030b5ee 65 /** XML Processing Error */
bac40536 66 define('NO_CUSTOM_CHECK_FOUND', 12);
c030b5ee 67 /** XML Processing Error */
bac40536 68 define('CUSTOM_CHECK_FILE_MISSING', 13);
c030b5ee 69 /** XML Processing Error */
bac40536 70 define('CUSTOM_CHECK_FUNCTION_MISSING', 14);
c030b5ee 71 /** XML Processing Error */
c808379e 72 define('NO_PHP_SETTINGS_NAME_FOUND', 15);
d9b9ef5d
EL
73 /** XML Processing Error */
74 define('INCORRECT_FEEDBACK_FOR_REQUIRED', 16);
75 /** XML Processing Error */
76 define('INCORRECT_FEEDBACK_FOR_OPTIONAL', 17);
f58b518f 77
829fa074 78/// Define algorithm used to select the xml file
c030b5ee 79 /** To select the newer file available to perform checks */
16ae0853 80 define('ENV_SELECT_NEWER', 0);
c030b5ee 81 /** To enforce the use of the file under dataroot */
16ae0853 82 define('ENV_SELECT_DATAROOT', 1);
c030b5ee 83 /** To enforce the use of the file under admin (release) */
16ae0853 84 define('ENV_SELECT_RELEASE', 2);
829fa074 85
f58b518f 86/**
cc359566 87 * This function checks all the requirements defined in environment.xml.
c030b5ee 88 *
89 * @staticvar bool $result
90 * @staticvar array $env_results
91 * @staticvar bool $cache_exists
cc359566 92 *
c030b5ee 93 * @param string $version version to check.
c030b5ee 94 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use. Default ENV_SELECT_NEWER (BC)
cc359566
TH
95 * @return array with two elements. The first element true/false, depending on
96 * on whether the check passed. The second element is an array of environment_results
97 * objects that has detailed information about the checks and which ones passed.
f58b518f 98 */
cc359566 99function check_moodle_environment($version, $env_select = ENV_SELECT_NEWER) {
049c0f4a 100
101 $status = true;
f58b518f 102
878d309c 103/// This are cached per request
104 static $result = true;
105 static $env_results;
106 static $cache_exists = false;
107
108/// if we have results cached, use them
109 if ($cache_exists) {
110 $environment_results = $env_results;
111/// No cache exists, calculate everything
112 } else {
113 /// Get the more recent version before the requested
829fa074 114 if (!$version = get_latest_version_available($version, $env_select)) {
878d309c 115 $status = false;
116 }
f58b518f 117
878d309c 118 /// Perform all the checks
829fa074 119 if (!($environment_results = environment_check($version, $env_select)) && $status) {
878d309c 120 $status = false;
121 }
f58b518f 122
878d309c 123 /// Iterate over all the results looking for some error in required items
124 /// or some error_code
125 if ($status) {
126 foreach ($environment_results as $environment_result) {
95a39282 127 if (!$environment_result->getStatus() && $environment_result->getLevel() == 'required'
128 && !$environment_result->getBypassStr()) {
129 $result = false; // required item that is not bypased
130 } else if ($environment_result->getStatus() && $environment_result->getLevel() == 'required'
131 && $environment_result->getRestrictStr()) {
132 $result = false; // required item that is restricted
133 } else if ($environment_result->getErrorCode()) {
878d309c 134 $result = false;
135 }
049c0f4a 136 }
f58b518f 137 }
878d309c 138 /// Going to end, we store environment_results to cache
139 $env_results = $environment_results;
140 $cache_exists = true;
141 } ///End of cache block
f58b518f 142
cc359566 143 return array($result && $status, $environment_results);
f58b518f 144}
145
146
16ae0853 147/**
148 * Returns array of critical errors in plain text format
149 * @param array $environment_results array of results gathered
150 * @return array errors
151 */
152function environment_get_errors($environment_results) {
153 global $CFG;
154 $errors = array();
155
156 // Iterate over each environment_result
157 foreach ($environment_results as $environment_result) {
158 $type = $environment_result->getPart();
159 $info = $environment_result->getInfo();
160 $status = $environment_result->getStatus();
161 $error_code = $environment_result->getErrorCode();
162
365a5941 163 $a = new stdClass();
16ae0853 164 if ($error_code) {
165 $a->error_code = $error_code;
166 $errors[] = array($info, get_string('environmentxmlerror', 'admin', $a));
167 return $errors;
168 }
169
170 /// Calculate the status value
171 if ($environment_result->getBypassStr() != '') {
172 // not interesting
173 continue;
174 } else if ($environment_result->getRestrictStr() != '') {
175 // error
176 } else {
177 if ($status) {
178 // ok
179 continue;
180 } else {
181 if ($environment_result->getLevel() == 'optional') {
182 // just a warning
183 continue;
184 } else {
185 // error
186 }
187 }
188 }
189
190 // We are comparing versions
365a5941 191 $rec = new stdClass();
16ae0853 192 if ($rec->needed = $environment_result->getNeededVersion()) {
193 $rec->current = $environment_result->getCurrentVersion();
194 if ($environment_result->getLevel() == 'required') {
195 $stringtouse = 'environmentrequireversion';
196 } else {
197 $stringtouse = 'environmentrecommendversion';
198 }
199 // We are checking installed & enabled things
200 } else if ($environment_result->getPart() == 'custom_check') {
201 if ($environment_result->getLevel() == 'required') {
202 $stringtouse = 'environmentrequirecustomcheck';
203 } else {
204 $stringtouse = 'environmentrecommendcustomcheck';
205 }
206 } else if ($environment_result->getPart() == 'php_setting') {
207 if ($status) {
208 $stringtouse = 'environmentsettingok';
209 } else if ($environment_result->getLevel() == 'required') {
210 $stringtouse = 'environmentmustfixsetting';
211 } else {
212 $stringtouse = 'environmentshouldfixsetting';
213 }
214 } else {
215 if ($environment_result->getLevel() == 'required') {
216 $stringtouse = 'environmentrequireinstall';
217 } else {
218 $stringtouse = 'environmentrecommendinstall';
219 }
220 }
221 $report = get_string($stringtouse, 'admin', $rec);
222
223 // Here we'll store all the feedback found
224 $feedbacktext = '';
225 // Append the feedback if there is some
226 $feedbacktext .= $environment_result->strToReport($environment_result->getFeedbackStr(), 'error');
227 // Append the restrict if there is some
228 $feedbacktext .= $environment_result->strToReport($environment_result->getRestrictStr(), 'error');
229
230 $report .= html_to_text($feedbacktext);
231
232 if ($environment_result->getPart() == 'custom_check'){
233 $errors[] = array($info, $report);
234 } else {
235 $errors[] = array(($info !== '' ? "$type $info" : $type), $report);
236 }
237 }
238
239 return $errors;
240}
241
242
f58b518f 243/**
244 * This function will normalize any version to just a serie of numbers
245 * separated by dots. Everything else will be removed.
c030b5ee 246 *
f58b518f 247 * @param string $version the original version
248 * @return string the normalized version
249 */
250function normalize_version($version) {
16ae0853 251
4fa6cb47 252/// 1.9 Beta 2 should be read 1.9 on enviromental checks, not 1.9.2
253/// we can discard everything after the first space
254 $version = trim($version);
255 $versionarr = explode(" ",$version);
256 if (!empty($versionarr)) {
257 $version = $versionarr[0];
258 }
f58b518f 259/// Replace everything but numbers and dots by dots
260 $version = preg_replace('/[^\.\d]/', '.', $version);
261/// Combine multiple dots in one
262 $version = preg_replace('/(\.{2,})/', '.', $version);
263/// Trim possible leading and trailing dots
264 $version = trim($version, '.');
265
266 return $version;
267}
268
269
270/**
271 * This function will load the environment.xml file and xmlize it
c030b5ee 272 *
273 * @global object
274 * @staticvar mixed $data
275 * @uses ENV_SELECT_NEWER
276 * @uses ENV_SELECT_DATAROOT
277 * @uses ENV_SELECT_RELEASE
278 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use. Default ENV_SELECT_NEWER (BC)
f58b518f 279 * @return mixed the xmlized structure or false on error
280 */
829fa074 281function load_environment_xml($env_select=ENV_SELECT_NEWER) {
770fef0a 282
f58b518f 283 global $CFG;
284
285 static $data; //Only load and xmlize once by request
286
287 if (!empty($data)) {
288 return $data;
289 }
290
00d3a0fd 291/// First of all, take a look inside $CFG->dataroot/environment/environment.xml
292 $file = $CFG->dataroot.'/environment/environment.xml';
38fca5d7 293 $internalfile = $CFG->dirroot.'/'.$CFG->admin.'/environment.xml';
829fa074 294 switch ($env_select) {
295 case ENV_SELECT_NEWER:
296 if (!is_file($file) || !is_readable($file) || filemtime($file) < filemtime($internalfile) ||
297 !$contents = file_get_contents($file)) {
298 /// Fallback to fixed $CFG->admin/environment.xml
299 if (!is_file($internalfile) || !is_readable($internalfile) || !$contents = file_get_contents($internalfile)) {
300 return false;
301 }
302 }
303 break;
304 case ENV_SELECT_DATAROOT:
305 if (!is_file($file) || !is_readable($file) || !$contents = file_get_contents($file)) {
306 return false;
307 }
308 break;
309 case ENV_SELECT_RELEASE:
310 if (!is_file($internalfile) || !is_readable($internalfile) || !$contents = file_get_contents($internalfile)) {
311 return false;
312 }
313 break;
f58b518f 314 }
315/// XML the whole file
316 $data = xmlize($contents);
317
318 return $data;
319}
320
321
322/**
323 * This function will return the list of Moodle versions available
c030b5ee 324 *
325 * @staticvar array $versions
f58b518f 326 * @return mixed array of versions. False on error.
327 */
328function get_list_of_environment_versions ($contents) {
329
330 static $versions = array();
331
332 if (!empty($versions)) {
333 return $versions;
334 }
335
336 if (isset($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'])) {
337 foreach ($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'] as $version) {
338 $versions[] = $version['@']['version'];
339 }
340 }
341
342 return $versions;
343}
344
345
346/**
347 * This function will return the most recent version in the environment.xml
348 * file previous or equal to the version requested
c030b5ee 349 *
350 * @param string $version top version from which we start to look backwards
351 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
352 * @return string|bool string more recent version or false if not found
f58b518f 353 */
829fa074 354function get_latest_version_available ($version, $env_select) {
f58b518f 355
356/// Normalize the version requested
357 $version = normalize_version($version);
358
359/// Load xml file
829fa074 360 if (!$contents = load_environment_xml($env_select)) {
f58b518f 361 return false;
362 }
363
364/// Detect available versions
365 if (!$versions = get_list_of_environment_versions($contents)) {
366 return false;
367 }
368/// First we look for exact version
369 if (in_array($version, $versions)) {
370 return $version;
371 } else {
372 $found_version = false;
373 /// Not exact match, so we are going to iterate over the list searching
374 /// for the latest version before the requested one
375 foreach ($versions as $arrversion) {
376 if (version_compare($arrversion, $version, '<')) {
377 $found_version = $arrversion;
378 }
379 }
380 }
381
382 return $found_version;
383}
384
385
770fef0a 386/**
f58b518f 387 * This function will return the xmlized data belonging to one Moodle version
c030b5ee 388 *
389 * @param string $version top version from which we start to look backwards
390 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
f58b518f 391 * @return mixed the xmlized structure or false on error
392 */
829fa074 393function get_environment_for_version($version, $env_select) {
770fef0a 394
f58b518f 395/// Normalize the version requested
396 $version = normalize_version($version);
397
398/// Load xml file
829fa074 399 if (!$contents = load_environment_xml($env_select)) {
f58b518f 400 return false;
401 }
402
403/// Detect available versions
404 if (!$versions = get_list_of_environment_versions($contents)) {
405 return false;
406 }
407
408/// If the version requested is available
409 if (!in_array($version, $versions)) {
410 return false;
411 }
412
413/// We now we have it. Extract from full contents.
414 $fl_arr = array_flip($versions);
770fef0a 415
f58b518f 416 return $contents['COMPATIBILITY_MATRIX']['#']['MOODLE'][$fl_arr[$version]];
417}
418
419
770fef0a 420/**
f58b518f 421 * This function will check for everything (DB, PHP and PHP extensions for now)
422 * returning an array of environment_result objects.
c030b5ee 423 *
424 * @global object
f58b518f 425 * @param string $version xml version we are going to use to test this server
c030b5ee 426 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
f58b518f 427 * @return array array of results encapsulated in one environment_result object
428 */
829fa074 429function environment_check($version, $env_select) {
7f2d3ec0 430 global $CFG;
431
f58b518f 432/// Normalize the version requested
433 $version = normalize_version($version);
434
435 $results = array(); //To store all the results
436
7f2d3ec0 437/// Only run the moodle versions checker on upgrade, not on install
90509582 438 if (!empty($CFG->version)) {
829fa074 439 $results[] = environment_check_moodle($version, $env_select);
7f2d3ec0 440 }
829fa074 441 $results[] = environment_check_unicode($version, $env_select);
442 $results[] = environment_check_database($version, $env_select);
443 $results[] = environment_check_php($version, $env_select);
f58b518f 444
6c0e5cd1
PS
445 if ($result = environment_check_pcre_unicode($version, $env_select)) {
446 $results[] = $result;
447 }
448
829fa074 449 $phpext_results = environment_check_php_extensions($version, $env_select);
bac40536 450 $results = array_merge($results, $phpext_results);
f58b518f 451
829fa074 452 $phpsetting_results = environment_check_php_settings($version, $env_select);
c808379e 453 $results = array_merge($results, $phpsetting_results);
454
829fa074 455 $custom_results = environment_custom_checks($version, $env_select);
bac40536 456 $results = array_merge($results, $custom_results);
f58b518f 457
458 return $results;
459}
460
461
462/**
463 * This function will check if php extensions requirements are satisfied
c030b5ee 464 *
465 * @uses NO_VERSION_DATA_FOUND
466 * @uses NO_PHP_EXTENSIONS_SECTION_FOUND
467 * @uses NO_PHP_EXTENSIONS_NAME_FOUND
f58b518f 468 * @param string $version xml version we are going to use to test this server
c030b5ee 469 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
f58b518f 470 * @return array array of results encapsulated in one environment_result object
471 */
829fa074 472function environment_check_php_extensions($version, $env_select) {
f58b518f 473
474 $results = array();
475
476/// Get the enviroment version we need
829fa074 477 if (!$data = get_environment_for_version($version, $env_select)) {
f58b518f 478 /// Error. No version data found
049c0f4a 479 $result = new environment_results('php_extension');
f58b518f 480 $result->setStatus(false);
481 $result->setErrorCode(NO_VERSION_DATA_FOUND);
c33b83e7 482 return array($result);
f58b518f 483 }
484
485/// Extract the php_extension part
486 if (!isset($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'])) {
487 /// Error. No PHP section found
049c0f4a 488 $result = new environment_results('php_extension');
f58b518f 489 $result->setStatus(false);
490 $result->setErrorCode(NO_PHP_EXTENSIONS_SECTION_FOUND);
c33b83e7 491 return array($result);
9e2d15e5 492 }
493/// Iterate over extensions checking them and creating the needed environment_results
494 foreach($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'] as $extension) {
495 $result = new environment_results('php_extension');
496 /// Check for level
bac40536 497 $level = get_level($extension);
9e2d15e5 498 /// Check for extension name
499 if (!isset($extension['@']['name'])) {
500 $result->setStatus(false);
501 $result->setErrorCode(NO_PHP_EXTENSIONS_NAME_FOUND);
502 } else {
503 $extension_name = $extension['@']['name'];
504 /// The name exists. Just check if it's an installed extension
505 if (!extension_loaded($extension_name)) {
f58b518f 506 $result->setStatus(false);
f58b518f 507 } else {
9e2d15e5 508 $result->setStatus(true);
f58b518f 509 }
9e2d15e5 510 $result->setLevel($level);
511 $result->setInfo($extension_name);
f58b518f 512 }
bac40536 513
514 /// Do any actions defined in the XML file.
515 process_environment_result($extension, $result);
b0e2a189 516
9e2d15e5 517 /// Add the result to the array of results
518 $results[] = $result;
f58b518f 519 }
520
9e2d15e5 521
f58b518f 522 return $results;
523}
524
c808379e 525/**
526 * This function will check if php extensions requirements are satisfied
c030b5ee 527 *
528 * @uses NO_VERSION_DATA_FOUND
529 * @uses NO_PHP_SETTINGS_NAME_FOUND
c808379e 530 * @param string $version xml version we are going to use to test this server
c030b5ee 531 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
c808379e 532 * @return array array of results encapsulated in one environment_result object
533 */
829fa074 534function environment_check_php_settings($version, $env_select) {
c808379e 535
536 $results = array();
537
538/// Get the enviroment version we need
829fa074 539 if (!$data = get_environment_for_version($version, $env_select)) {
c808379e 540 /// Error. No version data found
541 $result = new environment_results('php_setting');
542 $result->setStatus(false);
543 $result->setErrorCode(NO_VERSION_DATA_FOUND);
5f014173
PS
544 $results[] = $result;
545 return $results;
c808379e 546 }
547
548/// Extract the php_setting part
549 if (!isset($data['#']['PHP_SETTINGS']['0']['#']['PHP_SETTING'])) {
550 /// No PHP section found - ignore
551 return $results;
552 }
553/// Iterate over settings checking them and creating the needed environment_results
554 foreach($data['#']['PHP_SETTINGS']['0']['#']['PHP_SETTING'] as $setting) {
555 $result = new environment_results('php_setting');
556 /// Check for level
557 $level = get_level($setting);
558 $result->setLevel($level);
559 /// Check for extension name
560 if (!isset($setting['@']['name'])) {
561 $result->setStatus(false);
562 $result->setErrorCode(NO_PHP_SETTINGS_NAME_FOUND);
563 } else {
564 $setting_name = $setting['@']['name'];
565 $setting_value = $setting['@']['value'];
566 $result->setInfo($setting_name);
567
568 if ($setting_name == 'memory_limit') {
569 $current = ini_get('memory_limit');
570 if ($current == -1) {
571 $result->setStatus(true);
572 } else {
573 $current = get_real_size($current);
574 $minlimit = get_real_size($setting_value);
575 if ($current < $minlimit) {
576 @ini_set('memory_limit', $setting_value);
577 $current = ini_get('memory_limit');
578 $current = get_real_size($current);
579 }
580 $result->setStatus($current >= $minlimit);
581 }
582
583 } else {
584 $current = ini_get_bool($setting_name);
585 /// The name exists. Just check if it's an installed extension
586 if ($current == $setting_value) {
587 $result->setStatus(true);
588 } else {
589 $result->setStatus(false);
590 }
591 }
592 }
593
594 /// Do any actions defined in the XML file.
595 process_environment_result($setting, $result);
596
597 /// Add the result to the array of results
598 $results[] = $result;
599 }
600
601
602 return $results;
603}
604
bac40536 605/**
606 * This function will do the custom checks.
c030b5ee 607 *
608 * @global object
609 * @uses CUSTOM_CHECK_FUNCTION_MISSING
610 * @uses CUSTOM_CHECK_FILE_MISSING
611 * @uses NO_CUSTOM_CHECK_FOUND
bac40536 612 * @param string $version xml version we are going to use to test this server.
c030b5ee 613 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
bac40536 614 * @return array array of results encapsulated in environment_result objects.
615 */
829fa074 616function environment_custom_checks($version, $env_select) {
bac40536 617 global $CFG;
618
619 $results = array();
620
eae02f59 621/// Get current Moodle version (release) for later compare
b08a7225 622 $release = isset($CFG->release) ? $CFG->release : $version; /// In case $CFG fails (at install) use $version
623 $current_version = normalize_version($release);
eae02f59 624
bac40536 625/// Get the enviroment version we need
829fa074 626 if (!$data = get_environment_for_version($version, $env_select)) {
bac40536 627 /// Error. No version data found - but this will already have been reported.
628 return $results;
629 }
630
631/// Extract the CUSTOM_CHECKS part
632 if (!isset($data['#']['CUSTOM_CHECKS']['0']['#']['CUSTOM_CHECK'])) {
633 /// No custom checks found - not a problem
634 return $results;
635 }
636
637/// Iterate over extensions checking them and creating the needed environment_results
638 foreach($data['#']['CUSTOM_CHECKS']['0']['#']['CUSTOM_CHECK'] as $check) {
639 $result = new environment_results('custom_check');
640
641 /// Check for level
642 $level = get_level($check);
643
644 /// Check for extension name
645 if (isset($check['@']['file']) && isset($check['@']['function'])) {
646 $file = $CFG->dirroot . '/' . $check['@']['file'];
bac40536 647 $function = $check['@']['function'];
648 if (is_readable($file)) {
649 include_once($file);
650 if (function_exists($function)) {
651 $result->setLevel($level);
652 $result->setInfo($function);
653 $result = $function($result);
654 } else {
eae02f59 655 /// Only show error for current version (where function MUST exist)
656 /// else, we are performing custom checks against future versiosn
657 /// and function MAY not exist, so it doesn't cause error, just skip
658 /// custom check by returning null. MDL-15939
659 if (version_compare($current_version, $version, '>=')) {
660 $result->setStatus(false);
661 $result->setInfo($function);
662 $result->setErrorCode(CUSTOM_CHECK_FUNCTION_MISSING);
663 } else {
664 $result = null;
665 }
bac40536 666 }
667 } else {
eae02f59 668 /// Only show error for current version (where function MUST exist)
669 /// else, we are performing custom checks against future versiosn
670 /// and function MAY not exist, so it doesn't cause error, just skip
671 /// custom check by returning null. MDL-15939
672 if (version_compare($current_version, $version, '>=')) {
673 $result->setStatus(false);
674 $result->setInfo($function);
675 $result->setErrorCode(CUSTOM_CHECK_FILE_MISSING);
676 } else {
677 $result = null;
678 }
bac40536 679 }
680 } else {
681 $result->setStatus(false);
682 $result->setErrorCode(NO_CUSTOM_CHECK_FOUND);
683 }
684
685 if (!is_null($result)) {
686 /// Do any actions defined in the XML file.
687 process_environment_result($check, $result);
770fef0a 688
bac40536 689 /// Add the result to the array of results
690 $results[] = $result;
691 }
692 }
693
694 return $results;
695}
f58b518f 696
7f2d3ec0 697/**
698 * This function will check if Moodle requirements are satisfied
c030b5ee 699 *
700 * @uses NO_VERSION_DATA_FOUND
7f2d3ec0 701 * @param string $version xml version we are going to use to test this server
c030b5ee 702 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
7f2d3ec0 703 * @return object results encapsulated in one environment_result object
704 */
829fa074 705function environment_check_moodle($version, $env_select) {
7f2d3ec0 706
707 $result = new environment_results('moodle');
708
709/// Get the enviroment version we need
829fa074 710 if (!$data = get_environment_for_version($version, $env_select)) {
7f2d3ec0 711 /// Error. No version data found
712 $result->setStatus(false);
713 $result->setErrorCode(NO_VERSION_DATA_FOUND);
714 return $result;
715 }
716
717/// Extract the moodle part
718 if (!isset($data['@']['requires'])) {
719 $needed_version = '1.0'; /// Default to 1.0 if no moodle requires is found
720 } else {
721 /// Extract required moodle version
722 $needed_version = $data['@']['requires'];
723 }
724
725/// Now search the version we are using
01264131
PS
726 $release = get_config('', 'release');
727 $current_version = normalize_version($release);
728 if (strpos($release, 'dev') !== false) {
729 // when final version is required, dev is NOT enough!
730 $current_version = $current_version - 0.1;
731 }
7f2d3ec0 732
733/// And finally compare them, saving results
734 if (version_compare($current_version, $needed_version, '>=')) {
735 $result->setStatus(true);
736 } else {
737 $result->setStatus(false);
738 }
739 $result->setLevel('required');
01264131 740 $result->setCurrentVersion($release);
7f2d3ec0 741 $result->setNeededVersion($needed_version);
742
743 return $result;
744}
745
f58b518f 746/**
747 * This function will check if php requirements are satisfied
c030b5ee 748 *
749 * @uses NO_VERSION_DATA_FOUND
750 * @uses NO_PHP_SECTION_FOUND
751 * @uses NO_PHP_VERSION_FOUND
f58b518f 752 * @param string $version xml version we are going to use to test this server
c030b5ee 753 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
f58b518f 754 * @return object results encapsulated in one environment_result object
755 */
829fa074 756function environment_check_php($version, $env_select) {
f58b518f 757
758 $result = new environment_results('php');
759
760/// Get the enviroment version we need
829fa074 761 if (!$data = get_environment_for_version($version, $env_select)) {
f58b518f 762 /// Error. No version data found
763 $result->setStatus(false);
764 $result->setErrorCode(NO_VERSION_DATA_FOUND);
765 return $result;
766 }
767
768/// Extract the php part
769 if (!isset($data['#']['PHP'])) {
770 /// Error. No PHP section found
771 $result->setStatus(false);
772 $result->setErrorCode(NO_PHP_SECTION_FOUND);
773 return $result;
774 } else {
775 /// Extract level and version
bac40536 776 $level = get_level($data['#']['PHP']['0']);
f58b518f 777 if (!isset($data['#']['PHP']['0']['@']['version'])) {
778 $result->setStatus(false);
779 $result->setErrorCode(NO_PHP_VERSION_FOUND);
780 return $result;
781 } else {
782 $needed_version = $data['#']['PHP']['0']['@']['version'];
783 }
784 }
785
786/// Now search the version we are using
787 $current_version = normalize_version(phpversion());
788
789/// And finally compare them, saving results
790 if (version_compare($current_version, $needed_version, '>=')) {
791 $result->setStatus(true);
792 } else {
793 $result->setStatus(false);
f58b518f 794 }
770fef0a 795 $result->setLevel($level);
f58b518f 796 $result->setCurrentVersion($current_version);
797 $result->setNeededVersion($needed_version);
bac40536 798
799/// Do any actions defined in the XML file.
800 process_environment_result($data['#']['PHP'][0], $result);
f58b518f 801
802 return $result;
803}
804
6c0e5cd1
PS
805/**
806 * Looks for buggy PCRE implementation, we need unicode support in Moodle...
807 * @param string $version xml version we are going to use to test this server
808 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
809 * @return stdClass results encapsulated in one environment_result object, null if irrelevant
810 */
811function environment_check_pcre_unicode($version, $env_select) {
812 $result = new environment_results('pcreunicode');
813
814 // Get the environment version we need
815 if (!$data = get_environment_for_version($version, $env_select)) {
816 // Error. No version data found!
817 $result->setStatus(false);
818 $result->setErrorCode(NO_VERSION_DATA_FOUND);
819 return $result;
820 }
821
822 if (!isset($data['#']['PCREUNICODE'])) {
823 return null;
824 }
825
826 $level = get_level($data['#']['PCREUNICODE']['0']);
827 $result->setLevel($level);
828
829 if (!function_exists('preg_match')) {
830 // The extension test fails instead.
831 return null;
832
833 } else if (@preg_match('/\pL/u', 'a') and @preg_match('/á/iu', 'Á')) {
834 $result->setStatus(true);
835
836 } else {
837 $result->setStatus(false);
838 }
839
840 // Do any actions defined in the XML file.
841 process_environment_result($data['#']['PCREUNICODE'][0], $result);
842
843 return $result;
844}
f58b518f 845
a392be33 846/**
847 * This function will check if unicode database requirements are satisfied
c030b5ee 848 *
849 * @global object
850 * @uses NO_VERSION_DATA_FOUND
851 * @uses NO_UNICODE_SECTION_FOUND
a392be33 852 * @param string $version xml version we are going to use to test this server
c030b5ee 853 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
a392be33 854 * @return object results encapsulated in one environment_result object
855 */
829fa074 856function environment_check_unicode($version, $env_select) {
fd0e6640 857 global $DB;
a392be33 858
859 $result = new environment_results('unicode');
860
861 /// Get the enviroment version we need
829fa074 862 if (!$data = get_environment_for_version($version, $env_select)) {
a392be33 863 /// Error. No version data found
864 $result->setStatus(false);
865 $result->setErrorCode(NO_VERSION_DATA_FOUND);
866 return $result;
867 }
868
869 /// Extract the unicode part
870
871 if (!isset($data['#']['UNICODE'])) {
7f2d3ec0 872 /// Error. No UNICODE section found
a392be33 873 $result->setStatus(false);
874 $result->setErrorCode(NO_UNICODE_SECTION_FOUND);
875 return $result;
876 } else {
877 /// Extract level
bac40536 878 $level = get_level($data['#']['UNICODE']['0']);
a392be33 879 }
880
f33e1ed4 881 if (!$unicodedb = $DB->setup_is_unicodedb()) {
a392be33 882 $result->setStatus(false);
883 } else {
884 $result->setStatus(true);
885 }
886
887 $result->setLevel($level);
888
bac40536 889/// Do any actions defined in the XML file.
890 process_environment_result($data['#']['UNICODE'][0], $result);
a392be33 891
892 return $result;
893}
894
f58b518f 895/**
896 * This function will check if database requirements are satisfied
c030b5ee 897 *
898 * @global object
899 * @uses NO_VERSION_DATA_FOUND
900 * @uses NO_DATABASE_SECTION_FOUND
901 * @uses NO_DATABASE_VENDORS_FOUND
902 * @uses NO_DATABASE_VENDOR_MYSQL_FOUND
903 * @uses NO_DATABASE_VENDOR_POSTGRES_FOUND
904 * @uses NO_DATABASE_VENDOR_VERSION_FOUND
f58b518f 905 * @param string $version xml version we are going to use to test this server
c030b5ee 906 * @param int $env_select one of ENV_SELECT_NEWER | ENV_SELECT_DATAROOT | ENV_SELECT_RELEASE decide xml to use.
f58b518f 907 * @return object results encapsulated in one environment_result object
908 */
829fa074 909function environment_check_database($version, $env_select) {
f58b518f 910
f33e1ed4 911 global $DB;
f58b518f 912
913 $result = new environment_results('database');
914
915 $vendors = array(); //Array of vendors in version
916
917/// Get the enviroment version we need
829fa074 918 if (!$data = get_environment_for_version($version, $env_select)) {
f58b518f 919 /// Error. No version data found
920 $result->setStatus(false);
921 $result->setErrorCode(NO_VERSION_DATA_FOUND);
922 return $result;
923 }
924
925/// Extract the database part
926 if (!isset($data['#']['DATABASE'])) {
927 /// Error. No DATABASE section found
928 $result->setStatus(false);
929 $result->setErrorCode(NO_DATABASE_SECTION_FOUND);
930 return $result;
931 } else {
932 /// Extract level
bac40536 933 $level = get_level($data['#']['DATABASE']['0']);
f58b518f 934 }
935
936/// Extract DB vendors. At least 2 are mandatory (mysql & postgres)
937 if (!isset($data['#']['DATABASE']['0']['#']['VENDOR'])) {
938 /// Error. No VENDORS found
939 $result->setStatus(false);
940 $result->setErrorCode(NO_DATABASE_VENDORS_FOUND);
941 return $result;
942 } else {
943 /// Extract vendors
944 foreach ($data['#']['DATABASE']['0']['#']['VENDOR'] as $vendor) {
945 if (isset($vendor['@']['name']) && isset($vendor['@']['version'])) {
946 $vendors[$vendor['@']['name']] = $vendor['@']['version'];
9e2d15e5 947 $vendorsxml[$vendor['@']['name']] = $vendor;
f58b518f 948 }
949 }
950 }
951/// Check we have the mysql vendor version
952 if (empty($vendors['mysql'])) {
953 $result->setStatus(false);
954 $result->setErrorCode(NO_DATABASE_VENDOR_MYSQL_FOUND);
955 return $result;
956 }
957/// Check we have the postgres vendor version
958 if (empty($vendors['postgres'])) {
959 $result->setStatus(false);
960 $result->setErrorCode(NO_DATABASE_VENDOR_POSTGRES_FOUND);
961 return $result;
962 }
963
964/// Now search the version we are using (depending of vendor)
17601a7e 965 $current_vendor = $DB->get_dbvendor();
ed7656bf 966
f33e1ed4 967 $dbinfo = $DB->get_server_info();
f58b518f 968 $current_version = normalize_version($dbinfo['version']);
969 $needed_version = $vendors[$current_vendor];
970
e3058eb3 971/// Check we have a needed version
972 if (!$needed_version) {
973 $result->setStatus(false);
974 $result->setErrorCode(NO_DATABASE_VENDOR_VERSION_FOUND);
975 return $result;
976 }
977
f58b518f 978/// And finally compare them, saving results
979 if (version_compare($current_version, $needed_version, '>=')) {
980 $result->setStatus(true);
981 } else {
982 $result->setStatus(false);
f58b518f 983 }
770fef0a 984 $result->setLevel($level);
f58b518f 985 $result->setCurrentVersion($current_version);
986 $result->setNeededVersion($needed_version);
1dd74afe 987 $result->setInfo($current_vendor . ' (' . $dbinfo['description'] . ')');
f58b518f 988
bac40536 989/// Do any actions defined in the XML file.
990 process_environment_result($vendorsxml[$current_vendor], $result);
9e2d15e5 991
f58b518f 992 return $result;
993
994}
995
b0e2a189 996/**
997 * This function will post-process the result record by executing the specified
998 * function, modifying it as necessary, also a custom message will be added
999 * to the result object to be printed by the display layer.
1000 * Every bypass function must be defined in this file and it'll return
1001 * true/false to decide if the original test is bypassed or no. Also
1002 * such bypass functions are able to directly handling the result object
1003 * although it should be only under exceptional conditions.
1004 *
1005 * @param string xmldata containing the bypass data
95a39282 1006 * @param object result object to be updated
c030b5ee 1007 * @return void
b0e2a189 1008 */
1009function process_environment_bypass($xml, &$result) {
1010
76bb0d20 1011/// Only try to bypass if we were in error and it was required
1012 if ($result->getStatus() || $result->getLevel() == 'optional') {
b0e2a189 1013 return;
1014 }
1015
1016/// It there is bypass info (function and message)
74506a51 1017 if (is_array($xml['#']) && isset($xml['#']['BYPASS'][0]['@']['function']) && isset($xml['#']['BYPASS'][0]['@']['message'])) {
b0e2a189 1018 $function = $xml['#']['BYPASS'][0]['@']['function'];
1019 $message = $xml['#']['BYPASS'][0]['@']['message'];
1020 /// Look for the function
1021 if (function_exists($function)) {
1022 /// Call it, and if bypass = true is returned, apply meesage
1023 if ($function($result)) {
1024 /// We only set the bypass message if the function itself hasn't defined it before
1025 if (empty($result->getBypassStr)) {
1026 $result->setBypassStr($message);
1027 }
1028 }
1029 }
1030 }
1031}
1032
95a39282 1033/**
1034 * This function will post-process the result record by executing the specified
1035 * function, modifying it as necessary, also a custom message will be added
1036 * to the result object to be printed by the display layer.
1037 * Every restrict function must be defined in this file and it'll return
1038 * true/false to decide if the original test is restricted or no. Also
1039 * such restrict functions are able to directly handling the result object
1040 * although it should be only under exceptional conditions.
1041 *
1042 * @param string xmldata containing the restrict data
1043 * @param object result object to be updated
c030b5ee 1044 * @return void
95a39282 1045 */
1046function process_environment_restrict($xml, &$result) {
1047
1048/// Only try to restrict if we were not in error and it was required
1049 if (!$result->getStatus() || $result->getLevel() == 'optional') {
1050 return;
1051 }
1052/// It there is restrict info (function and message)
1053 if (is_array($xml['#']) && isset($xml['#']['RESTRICT'][0]['@']['function']) && isset($xml['#']['RESTRICT'][0]['@']['message'])) {
1054 $function = $xml['#']['RESTRICT'][0]['@']['function'];
1055 $message = $xml['#']['RESTRICT'][0]['@']['message'];
1056 /// Look for the function
1057 if (function_exists($function)) {
1058 /// Call it, and if restrict = true is returned, apply meesage
1059 if ($function($result)) {
1060 /// We only set the restrict message if the function itself hasn't defined it before
1061 if (empty($result->getRestrictStr)) {
1062 $result->setRestrictStr($message);
1063 }
1064 }
1065 }
1066 }
1067}
1068
9e2d15e5 1069/**
1070 * This function will detect if there is some message available to be added to the
1071 * result in order to clarify enviromental details.
c030b5ee 1072 *
d9b9ef5d
EL
1073 * @uses INCORRECT_FEEDBACK_FOR_REQUIRED
1074 * @uses INCORRECT_FEEDBACK_FOR_OPTIONAL
b0e2a189 1075 * @param string xmldata containing the feedback data
9e2d15e5 1076 * @param object reult object to be updated
1077 */
1078function process_environment_messages($xml, &$result) {
1079
1080/// If there is feedback info
74506a51 1081 if (is_array($xml['#']) && isset($xml['#']['FEEDBACK'][0]['#'])) {
9e2d15e5 1082 $feedbackxml = $xml['#']['FEEDBACK'][0]['#'];
1083
d9b9ef5d
EL
1084 // Detect some incorrect feedback combinations.
1085 if ($result->getLevel() == 'required' and isset($feedbackxml['ON_CHECK'])) {
1086 $result->setStatus(false);
1087 $result->setErrorCode(INCORRECT_FEEDBACK_FOR_REQUIRED);
1088 } else if ($result->getLevel() == 'optional' and isset($feedbackxml['ON_ERROR'])) {
1089 $result->setStatus(false);
1090 $result->setErrorCode(INCORRECT_FEEDBACK_FOR_OPTIONAL);
1091 }
1092
9e2d15e5 1093 if (!$result->status and $result->getLevel() == 'required') {
1094 if (isset($feedbackxml['ON_ERROR'][0]['@']['message'])) {
1095 $result->setFeedbackStr($feedbackxml['ON_ERROR'][0]['@']['message']);
1096 }
1097 } else if (!$result->status and $result->getLevel() == 'optional') {
1098 if (isset($feedbackxml['ON_CHECK'][0]['@']['message'])) {
1099 $result->setFeedbackStr($feedbackxml['ON_CHECK'][0]['@']['message']);
1100 }
1101 } else {
1102 if (isset($feedbackxml['ON_OK'][0]['@']['message'])) {
1103 $result->setFeedbackStr($feedbackxml['ON_OK'][0]['@']['message']);
1104 }
1105 }
1106 }
1107}
1108
f58b518f 1109
1110//--- Helper Class to return results to caller ---//
1111
1112
770fef0a 1113/**
c030b5ee 1114 * Helper Class to return results to caller
1115 *
1116 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
1117 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
1118 * @package moodlecore
f58b518f 1119 */
1120class environment_results {
c030b5ee 1121 /**
1122 * @var string Which are we checking (database, php, php_extension, php_extension)
1123 */
1124 var $part;
1125 /**
e4c20157 1126 * @var bool true means the test passed and all is OK. false means it failed.
c030b5ee 1127 */
1128 var $status;
1129 /**
1130 * @var integer See constants at the beginning of the file
1131 */
1132 var $error_code;
1133 /**
1134 * @var string required/optional
1135 */
1136 var $level;
1137 /**
1138 * @var string current version detected
1139 */
1140 var $current_version;
1141 /**
1142 * @var string version needed
1143 */
1144 var $needed_version;
1145 /**
1146 * @var string Aux. info (DB vendor, library...)
1147 */
1148 var $info;
1149 /**
1150 * @var string String to show on error|on check|on ok
1151 */
1152 var $feedback_str;
1153 /**
1154 * @var string String to show if some bypass has happened
1155 */
1156 var $bypass_str;
1157 /**
1158 * @var string String to show if some restrict has happened
1159 */
1160 var $restrict_str;
f58b518f 1161
1162 /**
1163 * Constructor of the environment_result class. Just set default values
c030b5ee 1164 *
1165 * @param string $part
f58b518f 1166 */
1167 function environment_results($part) {
1168 $this->part=$part;
1169 $this->status=false;
049c0f4a 1170 $this->error_code=NO_ERROR;
f58b518f 1171 $this->level='required';
1172 $this->current_version='';
1173 $this->needed_version='';
1174 $this->info='';
9e2d15e5 1175 $this->feedback_str='';
1176 $this->bypass_str='';
95a39282 1177 $this->restrict_str='';
f58b518f 1178 }
1179
1180 /**
1181 * Set the status
c030b5ee 1182 *
e4c20157 1183 * @param bool $testpassed true means the test passed and all is OK. false means it failed.
f58b518f 1184 */
e4c20157
TH
1185 function setStatus($testpassed) {
1186 $this->status = $testpassed;
1187 if ($testpassed) {
f58b518f 1188 $this->setErrorCode(NO_ERROR);
1189 }
1190 }
1191
1192 /**
1193 * Set the error_code
c030b5ee 1194 *
1195 * @param integer $error_code the error code (see constants above)
f58b518f 1196 */
1197 function setErrorCode($error_code) {
1198 $this->error_code=$error_code;
1199 }
1200
1201 /**
1202 * Set the level
c030b5ee 1203 *
1204 * @param string $level the level (required, optional)
f58b518f 1205 */
1206 function setLevel($level) {
1207 $this->level=$level;
1208 }
1209
1210 /**
1211 * Set the current version
c030b5ee 1212 *
1213 * @param string $current_version the current version
f58b518f 1214 */
1215 function setCurrentVersion($current_version) {
1216 $this->current_version=$current_version;
1217 }
1218
1219 /**
1220 * Set the needed version
c030b5ee 1221 *
1222 * @param string $needed_version the needed version
f58b518f 1223 */
1224 function setNeededVersion($needed_version) {
1225 $this->needed_version=$needed_version;
1226 }
1227
1228 /**
1229 * Set the auxiliary info
c030b5ee 1230 *
1231 * @param string $info the auxiliary info
f58b518f 1232 */
9e2d15e5 1233 function setInfo($info) {
1234 $this->info=$info;
1235 }
770fef0a 1236
9e2d15e5 1237 /**
1238 * Set the feedback string
c030b5ee 1239 *
1240 * @param mixed $str the feedback string that will be fetched from the admin lang file.
afb36bca 1241 * pass just the string or pass an array of params for get_string
1242 * You always should put your string in admin.php but a third param is useful
1243 * to pass an $a object / string to get_string
9e2d15e5 1244 */
1245 function setFeedbackStr($str) {
1246 $this->feedback_str=$str;
1247 }
f58b518f 1248
afb36bca 1249
b0e2a189 1250 /**
1251 * Set the bypass string
c030b5ee 1252 *
1253 * @param string $str the bypass string that will be fetched from the admin lang file.
afb36bca 1254 * pass just the string or pass an array of params for get_string
1255 * You always should put your string in admin.php but a third param is useful
1256 * to pass an $a object / string to get_string
b0e2a189 1257 */
1258 function setBypassStr($str) {
1259 $this->bypass_str=$str;
1260 }
1261
95a39282 1262 /**
1263 * Set the restrict string
c030b5ee 1264 *
1265 * @param string $str the restrict string that will be fetched from the admin lang file.
afb36bca 1266 * pass just the string or pass an array of params for get_string
1267 * You always should put your string in admin.php but a third param is useful
1268 * to pass an $a object / string to get_string
95a39282 1269 */
1270 function setRestrictStr($str) {
1271 $this->restrict_str=$str;
1272 }
1273
f58b518f 1274 /**
1275 * Get the status
c030b5ee 1276 *
e4c20157 1277 * @return bool true means the test passed and all is OK. false means it failed.
f58b518f 1278 */
1279 function getStatus() {
1280 return $this->status;
1281 }
1282
1283 /**
1284 * Get the error code
c030b5ee 1285 *
f58b518f 1286 * @return integer error code
1287 */
1288 function getErrorCode() {
1289 return $this->error_code;
1290 }
1291
1292 /**
1293 * Get the level
c030b5ee 1294 *
f58b518f 1295 * @return string level
1296 */
1297 function getLevel() {
1298 return $this->level;
1299 }
1300
1301 /**
770fef0a 1302 * Get the current version
c030b5ee 1303 *
f58b518f 1304 * @return string current version
1305 */
1306 function getCurrentVersion() {
1307 return $this->current_version;
1308 }
1309
1310 /**
1311 * Get the needed version
c030b5ee 1312 *
f58b518f 1313 * @return string needed version
1314 */
1315 function getNeededVersion() {
1316 return $this->needed_version;
1317 }
1318
1319 /**
1320 * Get the aux info
c030b5ee 1321 *
f58b518f 1322 * @return string info
1323 */
1324 function getInfo() {
1325 return $this->info;
1326 }
1327
1328 /**
1329 * Get the part this result belongs to
c030b5ee 1330 *
f58b518f 1331 * @return string part
1332 */
1333 function getPart() {
1334 return $this->part;
1335 }
9e2d15e5 1336
1337 /**
1338 * Get the feedback string
c030b5ee 1339 *
afb36bca 1340 * @return mixed feedback string (can be an array of params for get_string or a single string to fetch from
1341 * admin.php lang file).
9e2d15e5 1342 */
1343 function getFeedbackStr() {
1344 return $this->feedback_str;
1345 }
b0e2a189 1346
1347 /**
1348 * Get the bypass string
c030b5ee 1349 *
afb36bca 1350 * @return mixed bypass string (can be an array of params for get_string or a single string to fetch from
1351 * admin.php lang file).
b0e2a189 1352 */
1353 function getBypassStr() {
1354 return $this->bypass_str;
1355 }
95a39282 1356
1357 /**
1358 * Get the restrict string
c030b5ee 1359 *
afb36bca 1360 * @return mixed restrict string (can be an array of params for get_string or a single string to fetch from
1361 * admin.php lang file).
95a39282 1362 */
1363 function getRestrictStr() {
1364 return $this->restrict_str;
1365 }
afb36bca 1366
1367 /**
16ae0853 1368 * @todo Document this function
c030b5ee 1369 *
afb36bca 1370 * @param mixed $string params for get_string, either a string to fetch from admin.php or an array of
1371 * params for get_string.
1372 * @param string $class css class(es) for message.
1373 * @return string feedback string fetched from lang file wrapped in p tag with class $class or returns
1374 * empty string if $string is empty.
1375 */
1376 function strToReport($string, $class){
1377 if (!empty($string)){
1378 if (is_array($string)){
1379 $str = call_user_func_array('get_string', $string);
1380 } else {
1381 $str = get_string($string, 'admin');
1382 }
1383 return '<p class="'.$class.'">'.$str.'</p>';
1384 } else {
1385 return '';
1386 }
1387 }
f58b518f 1388}
1389
95a39282 1390/// Here all the restrict functions are coded to be used by the environment
1391/// checker. All those functions will receive the result object and will
1392/// return it modified as needed (status and bypass string)
1393
bac40536 1394/**
1395 * @param array $element the element from the environment.xml file that should have
1396 * either a level="required" or level="optional" attribute.
c030b5ee 1397 * @return string "required" or "optional".
bac40536 1398 */
1399function get_level($element) {
1400 $level = 'required';
1401 if (isset($element['@']['level'])) {
1402 $level = $element['@']['level'];
1403 if (!in_array($level, array('required', 'optional'))) {
7f2d3ec0 1404 debugging('The level of a check in the environment.xml file must be "required" or "optional".', DEBUG_DEVELOPER);
bac40536 1405 $level = 'required';
1406 }
1407 } else {
1408 debugging('Checks in the environment.xml file must have a level="required" or level="optional" attribute.', DEBUG_DEVELOPER);
1409 }
1410 return $level;
1411}
1412
1413/**
1414 * Once the result has been determined, look in the XML for any
1415 * messages, or other things that should be done depending on the outcome.
c030b5ee 1416 *
bac40536 1417 * @param array $element the element from the environment.xml file which
1418 * may have children defining what should be done with the outcome.
1419 * @param object $result the result of the test, which may be modified by
1420 * this function as specified in the XML.
1421 */
1422function process_environment_result($element, &$result) {
1423/// Process messages, modifying the $result if needed.
1424 process_environment_messages($element, $result);
1425/// Process bypass, modifying $result if needed.
1426 process_environment_bypass($element, $result);
1427/// Process restrict, modifying $result if needed.
1428 process_environment_restrict($element, $result);
1429}