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