Added functions to for the SCORM compliance 2004 (Sequencing and Navigation)
[moodle.git] / lib / environmentlib.php
CommitLineData
f58b518f 1<?php //$Id$
2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 2001-3001 Martin Dougiamas http://dougiamas.com //
11// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
12// //
13// This program is free software; you can redistribute it and/or modify //
14// it under the terms of the GNU General Public License as published by //
15// the Free Software Foundation; either version 2 of the License, or //
16// (at your option) any later version. //
17// //
18// This program is distributed in the hope that it will be useful, //
19// but WITHOUT ANY WARRANTY; without even the implied warranty of //
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21// GNU General Public License for more details: //
22// //
23// http://www.gnu.org/copyleft/gpl.html //
24// //
25///////////////////////////////////////////////////////////////////////////
26
27// This library includes all the necessary stuff to execute some standard
28// tests of required versions and libraries to run Moodle. It can be
29// used from the admin interface, and both at install and upgrade.
30//
31// All the info is stored in the admin/environment.xml file,
00d3a0fd 32// supporting to have an updated version in dataroot/environment
f58b518f 33
049c0f4a 34/// Add required files
35 require_once($CFG->libdir.'/xmlize.php');
36
37/// Define a buch of XML processing errors
00d3a0fd 38 define('NO_ERROR', 0);
39 define('NO_VERSION_DATA_FOUND', 1);
40 define('NO_DATABASE_SECTION_FOUND', 2);
41 define('NO_DATABASE_VENDORS_FOUND', 3);
42 define('NO_DATABASE_VENDOR_MYSQL_FOUND', 4);
43 define('NO_DATABASE_VENDOR_POSTGRES_FOUND', 5);
44 define('NO_PHP_SECTION_FOUND', 6);
45 define('NO_PHP_VERSION_FOUND', 7);
46 define('NO_PHP_EXTENSIONS_SECTION_FOUND', 8);
47 define('NO_PHP_EXTENSIONS_NAME_FOUND', 9);
48 define('NO_DATABASE_VENDOR_VERSION_FOUND', 10);
a392be33 49 define('NO_UNICODE_SECTION_FOUND', 11);
f58b518f 50
51/**
52 * This function will perform the whole check, returning
53 * true or false as final result. Also, he full array of
54 * environment_result will be returned in the parameter list.
55 * The function looks for the best version to compare and
56 * everything. This is the only function that should be called
57 * ever from the rest of Moodle.
58 * @param string version version to check.
59 * @param array results array of results checked.
60 * @return boolean true/false, depending of results
61 */
049c0f4a 62function check_moodle_environment($version, &$environment_results, $print_table=true) {
63
64 $status = true;
f58b518f 65
878d309c 66/// This are cached per request
67 static $result = true;
68 static $env_results;
69 static $cache_exists = false;
70
71/// if we have results cached, use them
72 if ($cache_exists) {
73 $environment_results = $env_results;
74/// No cache exists, calculate everything
75 } else {
76 /// Get the more recent version before the requested
77 if (!$version = get_latest_version_available($version)) {
78 $status = false;
79 }
f58b518f 80
878d309c 81 /// Perform all the checks
82 if (!($environment_results = environment_check($version)) && $status) {
83 $status = false;
84 }
f58b518f 85
878d309c 86 /// Iterate over all the results looking for some error in required items
87 /// or some error_code
88 if ($status) {
89 foreach ($environment_results as $environment_result) {
95a39282 90 if (!$environment_result->getStatus() && $environment_result->getLevel() == 'required'
91 && !$environment_result->getBypassStr()) {
92 $result = false; // required item that is not bypased
93 } else if ($environment_result->getStatus() && $environment_result->getLevel() == 'required'
94 && $environment_result->getRestrictStr()) {
95 $result = false; // required item that is restricted
96 } else if ($environment_result->getErrorCode()) {
878d309c 97 $result = false;
98 }
049c0f4a 99 }
f58b518f 100 }
878d309c 101 /// Going to end, we store environment_results to cache
102 $env_results = $environment_results;
103 $cache_exists = true;
104 } ///End of cache block
f58b518f 105
049c0f4a 106/// If we have decided to print all the information, just do it
107 if ($print_table) {
e909788d 108 print_moodle_environment($result && $status, $environment_results);
049c0f4a 109 }
110
111 return ($result && $status);
112}
113
114/**
115 * This function will print one beautiful table with all the environmental
116 * configuration and how it suits Moodle needs.
117 * @param boolean final result of the check (true/false)
118 * @param array environment_results array of results gathered
119 */
120function print_moodle_environment($result, $environment_results) {
121
122/// Get some strings
123 $strname = get_string('name');
124 $strinfo = get_string('info');
125 $strreport = get_string('report');
126 $strstatus = get_string('status');
127 $strok = get_string('ok');
128 $strerror = get_string('error');
129 $strcheck = get_string('check');
b0e2a189 130 $strbypassed = get_string('bypassed');
95a39282 131 $strrestricted = get_string('restricted');
e909788d 132 $strenvironmenterrortodo = get_string('environmenterrortodo', 'admin');
049c0f4a 133
9e2d15e5 134/// Here we'll store all the feedback found
135 $feedbacktext = '';
136
049c0f4a 137/// Table header
138 $table->head = array ($strname, $strinfo, $strreport, $strstatus);
139 $table->align = array ('center', 'center', 'left', 'center');
140 $table->wrap = array ('nowrap', '', '', 'nowrap');
141 $table->size = array ('10', 10, '100%', '10');
142 $table->width = '90%';
edc13d62 143 $table->class = 'environmenttable generaltable';
049c0f4a 144
145/// Iterate over each environment_result
146 $continue = true;
147 foreach ($environment_results as $environment_result) {
95a39282 148 $errorline = false;
149 $warningline = false;
049c0f4a 150 if ($continue) {
151 $type = $environment_result->getPart();
152 $info = $environment_result->getInfo();
153 $status = $environment_result->getStatus();
154 $error_code = $environment_result->getErrorCode();
155 /// Process Report field
878d309c 156 $rec = new stdClass();
049c0f4a 157 /// Something has gone wrong at parsing time
158 if ($error_code) {
159 $stringtouse = 'environmentxmlerror';
160 $rec->error_code = $error_code;
161 $status = $strerror;
162 $errorline = true;
163 $continue = false;
164 }
165
166 if ($continue) {
167 /// We are comparing versions
168 if ($rec->needed = $environment_result->getNeededVersion()) {
169 $rec->current = $environment_result->getCurrentVersion();
170 if ($environment_result->getLevel() == 'required') {
171 $stringtouse = 'environmentrequireversion';
172 } else {
173 $stringtouse = 'environmentrecommendversion';
174 }
175 /// We are checking installed & enabled things
176 } else {
177 if ($environment_result->getLevel() == 'required') {
178 $stringtouse = 'environmentrequireinstall';
179 } else {
180 $stringtouse = 'environmentrecommendinstall';
181 }
182 }
183 /// Calculate the status value
95a39282 184 if ($environment_result->getBypassStr() != '') { //Handle bypassed result (warning)
b0e2a189 185 $status = $strbypassed;
95a39282 186 $warningline = true;
187 } else if ($environment_result->getRestrictStr() != '') { //Handle restricted result (error)
188 $status = $strrestricted;
b0e2a189 189 $errorline = true;
95a39282 190 } else {
191 if ($status) { //Handle ok result (ok)
192 $status = $strok;
193 } else {
194 if ($environment_result->getLevel() == 'optional') {//Handle check result (warning)
195 $status = $strcheck;
196 $warningline = true;
197 } else { //Handle error result (error)
198 $status = $strcheck;
199 $errorline = true;
200 }
201 }
049c0f4a 202 }
203 }
204
205 /// Build the text
206 $report = get_string($stringtouse, 'admin', $rec);
95a39282 207 /// Format error or warning line
208 if ($errorline || $warningline) {
209 $styletoapply = $errorline? 'error':'warn';
210 $type = '<span class="'.$styletoapply.'">'.$type.'</span>';
211 $info = '<span class="'.$styletoapply.'">'.$info.'</span>';
212 $report = '<span class="'.$styletoapply.'">'.$report.'</span>';
213 $status = '<span class="'.$styletoapply.'">'.$status.'</span>';
049c0f4a 214 }
215 /// Add the row to the table
216 $table->data[] = array ($type, $info, $report, $status);
9e2d15e5 217 ///Process the feedback if necessary
218 if ($feedbackstr = $environment_result->getFeedbackStr()) {
219 $feedbacktext .= '<li class="environmenttable">'.get_string($feedbackstr, 'admin').'</li>';
220 }
b0e2a189 221 ///Process the bypass if necessary
222 if ($bypassstr = $environment_result->getBypassStr()) {
223 $feedbacktext .= '<li class="environmenttable">'.get_string($bypassstr, 'admin').'</li>';
224 }
95a39282 225 ///Process the restrict if necessary
226 if ($restrictstr = $environment_result->getRestrictStr()) {
227 $feedbacktext .= '<li class="environmenttable">'.get_string($restrictstr, 'admin').'</li>';
228 }
049c0f4a 229 }
230 }
231
232/// Print table
233 print_table($table);
e909788d 234
9e2d15e5 235/// And feedback accumulated text
236 if ($feedbacktext) {
cc60cd9b 237 print_simple_box('<ul>'.$feedbacktext.'</ul>', 'center', '90%', '', '', 'environmentbox generalbox');
9e2d15e5 238 }
239
e909788d 240/// Finally, if any error has happened, print the summary box
241 if (!$result) {
cc60cd9b 242 print_simple_box($strenvironmenterrortodo, 'center', '', '', '', 'environmentbox errorbox');
e909788d 243 }
f58b518f 244}
245
246
247/**
248 * This function will normalize any version to just a serie of numbers
249 * separated by dots. Everything else will be removed.
250 * @param string $version the original version
251 * @return string the normalized version
252 */
253function normalize_version($version) {
254/// Replace everything but numbers and dots by dots
255 $version = preg_replace('/[^\.\d]/', '.', $version);
256/// Combine multiple dots in one
257 $version = preg_replace('/(\.{2,})/', '.', $version);
258/// Trim possible leading and trailing dots
259 $version = trim($version, '.');
260
261 return $version;
262}
263
264
265/**
266 * This function will load the environment.xml file and xmlize it
267 * @return mixed the xmlized structure or false on error
268 */
269function load_environment_xml() {
270
271 global $CFG;
272
273 static $data; //Only load and xmlize once by request
274
275 if (!empty($data)) {
276 return $data;
277 }
278
00d3a0fd 279/// First of all, take a look inside $CFG->dataroot/environment/environment.xml
280 $file = $CFG->dataroot.'/environment/environment.xml';
38fca5d7 281 $internalfile = $CFG->dirroot.'/'.$CFG->admin.'/environment.xml';
282 if (!is_file($file) || !is_readable($file) || filemtime($file) < filemtime($internalfile) ||
283 !$contents = file_get_contents($file)) {
d83f8373 284 /// Fallback to fixed $CFG->admin/environment.xml
38fca5d7 285 if (!is_file($internalfile) || !is_readable($internalfile) || !$contents = file_get_contents($internalfile)) {
f58b518f 286 return false;
287 }
288 }
289/// XML the whole file
290 $data = xmlize($contents);
291
292 return $data;
293}
294
295
296/**
297 * This function will return the list of Moodle versions available
298 * @return mixed array of versions. False on error.
299 */
300function get_list_of_environment_versions ($contents) {
301
302 static $versions = array();
303
304 if (!empty($versions)) {
305 return $versions;
306 }
307
308 if (isset($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'])) {
309 foreach ($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'] as $version) {
310 $versions[] = $version['@']['version'];
311 }
312 }
313
314 return $versions;
315}
316
317
318/**
319 * This function will return the most recent version in the environment.xml
320 * file previous or equal to the version requested
321 * @param string version top version from which we start to look backwards
322 * @return string more recent version or false if not found
323 */
324function get_latest_version_available ($version) {
325
326/// Normalize the version requested
327 $version = normalize_version($version);
328
329/// Load xml file
330 if (!$contents = load_environment_xml()) {
331 return false;
332 }
333
334/// Detect available versions
335 if (!$versions = get_list_of_environment_versions($contents)) {
336 return false;
337 }
338/// First we look for exact version
339 if (in_array($version, $versions)) {
340 return $version;
341 } else {
342 $found_version = false;
343 /// Not exact match, so we are going to iterate over the list searching
344 /// for the latest version before the requested one
345 foreach ($versions as $arrversion) {
346 if (version_compare($arrversion, $version, '<')) {
347 $found_version = $arrversion;
348 }
349 }
350 }
351
352 return $found_version;
353}
354
355
356/**
357 * This function will return the xmlized data belonging to one Moodle version
358 * @return mixed the xmlized structure or false on error
359 */
360function get_environment_for_version($version) {
361
362/// Normalize the version requested
363 $version = normalize_version($version);
364
365/// Load xml file
366 if (!$contents = load_environment_xml()) {
367 return false;
368 }
369
370/// Detect available versions
371 if (!$versions = get_list_of_environment_versions($contents)) {
372 return false;
373 }
374
375/// If the version requested is available
376 if (!in_array($version, $versions)) {
377 return false;
378 }
379
380/// We now we have it. Extract from full contents.
381 $fl_arr = array_flip($versions);
382
383 return $contents['COMPATIBILITY_MATRIX']['#']['MOODLE'][$fl_arr[$version]];
384}
385
386
387/**
388 * This function will check for everything (DB, PHP and PHP extensions for now)
389 * returning an array of environment_result objects.
390 * @param string $version xml version we are going to use to test this server
391 * @return array array of results encapsulated in one environment_result object
392 */
393function environment_check($version) {
394
395/// Normalize the version requested
396 $version = normalize_version($version);
397
398 $results = array(); //To store all the results
399
a392be33 400 $results[] = environment_check_unicode($version);
f58b518f 401 $results[] = environment_check_database($version);
402 $results[] = environment_check_php($version);
403
404 $phpext_results = environment_check_php_extensions($version);
405
406 $results = array_merge ($results, $phpext_results);
407
408 return $results;
409}
410
411
412/**
413 * This function will check if php extensions requirements are satisfied
414 * @param string $version xml version we are going to use to test this server
415 * @return array array of results encapsulated in one environment_result object
416 */
417function environment_check_php_extensions($version) {
418
419 $results = array();
420
421/// Get the enviroment version we need
422 if (!$data = get_environment_for_version($version)) {
423 /// Error. No version data found
049c0f4a 424 $result = new environment_results('php_extension');
f58b518f 425 $result->setStatus(false);
426 $result->setErrorCode(NO_VERSION_DATA_FOUND);
427 return $result;
428 }
429
430/// Extract the php_extension part
431 if (!isset($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'])) {
432 /// Error. No PHP section found
049c0f4a 433 $result = new environment_results('php_extension');
f58b518f 434 $result->setStatus(false);
435 $result->setErrorCode(NO_PHP_EXTENSIONS_SECTION_FOUND);
436 return $result;
9e2d15e5 437 }
438/// Iterate over extensions checking them and creating the needed environment_results
439 foreach($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'] as $extension) {
440 $result = new environment_results('php_extension');
441 /// Check for level
442 if (isset($extension['@']['level'])) {
443 $level = $extension['@']['level'];
444 if ($level != 'optional') {
445 $level = 'required';
f58b518f 446 }
9e2d15e5 447 }
448 /// Check for extension name
449 if (!isset($extension['@']['name'])) {
450 $result->setStatus(false);
451 $result->setErrorCode(NO_PHP_EXTENSIONS_NAME_FOUND);
452 } else {
453 $extension_name = $extension['@']['name'];
454 /// The name exists. Just check if it's an installed extension
455 if (!extension_loaded($extension_name)) {
f58b518f 456 $result->setStatus(false);
f58b518f 457 } else {
9e2d15e5 458 $result->setStatus(true);
f58b518f 459 }
9e2d15e5 460 $result->setLevel($level);
461 $result->setInfo($extension_name);
f58b518f 462 }
9e2d15e5 463 /// Process messages, modifying the $result if needed.
464 process_environment_messages($extension, $result);
b0e2a189 465 /// Process bypass, modifying $result if needed.
466 process_environment_bypass($extension, $result);
95a39282 467 /// Process restrict, modifying $result if needed.
468 process_environment_restrict($extension, $result);
b0e2a189 469
9e2d15e5 470 /// Add the result to the array of results
471 $results[] = $result;
f58b518f 472 }
473
9e2d15e5 474
f58b518f 475 return $results;
476}
477
478
479/**
480 * This function will check if php requirements are satisfied
481 * @param string $version xml version we are going to use to test this server
482 * @return object results encapsulated in one environment_result object
483 */
484function environment_check_php($version) {
485
486 $result = new environment_results('php');
487
488/// Get the enviroment version we need
489 if (!$data = get_environment_for_version($version)) {
490 /// Error. No version data found
491 $result->setStatus(false);
492 $result->setErrorCode(NO_VERSION_DATA_FOUND);
493 return $result;
494 }
495
496/// Extract the php part
497 if (!isset($data['#']['PHP'])) {
498 /// Error. No PHP section found
499 $result->setStatus(false);
500 $result->setErrorCode(NO_PHP_SECTION_FOUND);
501 return $result;
502 } else {
503 /// Extract level and version
504 if (isset($data['#']['PHP']['0']['@']['level'])) {
00d3a0fd 505 $level = $data['#']['PHP']['0']['@']['level'];
f58b518f 506 if ($level != 'optional') {
507 $level = 'required';
508 }
509 }
510 if (!isset($data['#']['PHP']['0']['@']['version'])) {
511 $result->setStatus(false);
512 $result->setErrorCode(NO_PHP_VERSION_FOUND);
513 return $result;
514 } else {
515 $needed_version = $data['#']['PHP']['0']['@']['version'];
516 }
517 }
518
519/// Now search the version we are using
520 $current_version = normalize_version(phpversion());
521
522/// And finally compare them, saving results
523 if (version_compare($current_version, $needed_version, '>=')) {
524 $result->setStatus(true);
525 } else {
526 $result->setStatus(false);
f58b518f 527 }
528 $result->setLevel($level);
529 $result->setCurrentVersion($current_version);
530 $result->setNeededVersion($needed_version);
9e2d15e5 531/// Process messages, modifying the $result if needed.
532 process_environment_messages($data['#']['PHP'][0], $result);
b0e2a189 533/// Process bypass, modifying $result if needed.
534 process_environment_bypass($data['#']['PHP'][0], $result);
95a39282 535/// Process restrict, modifying $result if needed.
536 process_environment_restrict($data['#']['PHP'][0], $result);
f58b518f 537
538 return $result;
539}
540
541
a392be33 542/**
543 * This function will check if unicode database requirements are satisfied
544 * @param string $version xml version we are going to use to test this server
545 * @return object results encapsulated in one environment_result object
546 */
547function environment_check_unicode($version) {
548 global $db;
549
550 $result = new environment_results('unicode');
551
552 /// Get the enviroment version we need
553 if (!$data = get_environment_for_version($version)) {
554 /// Error. No version data found
555 $result->setStatus(false);
556 $result->setErrorCode(NO_VERSION_DATA_FOUND);
557 return $result;
558 }
559
560 /// Extract the unicode part
561
562 if (!isset($data['#']['UNICODE'])) {
563 /// Error. No DATABASE section found
564 $result->setStatus(false);
565 $result->setErrorCode(NO_UNICODE_SECTION_FOUND);
566 return $result;
567 } else {
568 /// Extract level
569 if (isset($data['#']['UNICODE']['0']['@']['level'])) {
570 $level = $data['#']['UNICODE']['0']['@']['level'];
571 if ($level != 'optional') {
572 $level = 'required';
573 }
574 }
575 }
576
577 if (!$unicodedb = setup_is_unicodedb()) {
578 $result->setStatus(false);
579 } else {
580 $result->setStatus(true);
581 }
582
583 $result->setLevel($level);
584
585/// Process messages, modifying the $result if needed.
586 process_environment_messages($data['#']['UNICODE'][0], $result);
587/// Process bypass, modifying $result if needed.
588 process_environment_bypass($data['#']['UNICODE'][0], $result);
589/// Process restrict, modifying $result if needed.
590 process_environment_restrict($data['#']['UNICODE'][0], $result);
591
592 return $result;
593}
594
f58b518f 595/**
596 * This function will check if database requirements are satisfied
597 * @param string $version xml version we are going to use to test this server
598 * @return object results encapsulated in one environment_result object
599 */
600function environment_check_database($version) {
601
602 global $db;
603
604 $result = new environment_results('database');
605
606 $vendors = array(); //Array of vendors in version
607
608/// Get the enviroment version we need
609 if (!$data = get_environment_for_version($version)) {
610 /// Error. No version data found
611 $result->setStatus(false);
612 $result->setErrorCode(NO_VERSION_DATA_FOUND);
613 return $result;
614 }
615
616/// Extract the database part
617 if (!isset($data['#']['DATABASE'])) {
618 /// Error. No DATABASE section found
619 $result->setStatus(false);
620 $result->setErrorCode(NO_DATABASE_SECTION_FOUND);
621 return $result;
622 } else {
623 /// Extract level
624 if (isset($data['#']['DATABASE']['0']['@']['level'])) {
00d3a0fd 625 $level = $data['#']['DATABASE']['0']['@']['level'];
f58b518f 626 if ($level != 'optional') {
627 $level = 'required';
628 }
629 }
630 }
631
632/// Extract DB vendors. At least 2 are mandatory (mysql & postgres)
633 if (!isset($data['#']['DATABASE']['0']['#']['VENDOR'])) {
634 /// Error. No VENDORS found
635 $result->setStatus(false);
636 $result->setErrorCode(NO_DATABASE_VENDORS_FOUND);
637 return $result;
638 } else {
639 /// Extract vendors
640 foreach ($data['#']['DATABASE']['0']['#']['VENDOR'] as $vendor) {
641 if (isset($vendor['@']['name']) && isset($vendor['@']['version'])) {
642 $vendors[$vendor['@']['name']] = $vendor['@']['version'];
9e2d15e5 643 $vendorsxml[$vendor['@']['name']] = $vendor;
f58b518f 644 }
645 }
646 }
647/// Check we have the mysql vendor version
648 if (empty($vendors['mysql'])) {
649 $result->setStatus(false);
650 $result->setErrorCode(NO_DATABASE_VENDOR_MYSQL_FOUND);
651 return $result;
652 }
653/// Check we have the postgres vendor version
654 if (empty($vendors['postgres'])) {
655 $result->setStatus(false);
656 $result->setErrorCode(NO_DATABASE_VENDOR_POSTGRES_FOUND);
657 return $result;
658 }
659
660/// Now search the version we are using (depending of vendor)
ed7656bf 661 $current_vendor = set_dbfamily();
662
f58b518f 663 $dbinfo = $db->ServerInfo();
664 $current_version = normalize_version($dbinfo['version']);
665 $needed_version = $vendors[$current_vendor];
666
e3058eb3 667/// Check we have a needed version
668 if (!$needed_version) {
669 $result->setStatus(false);
670 $result->setErrorCode(NO_DATABASE_VENDOR_VERSION_FOUND);
671 return $result;
672 }
673
f58b518f 674/// And finally compare them, saving results
675 if (version_compare($current_version, $needed_version, '>=')) {
676 $result->setStatus(true);
677 } else {
678 $result->setStatus(false);
f58b518f 679 }
680 $result->setLevel($level);
681 $result->setCurrentVersion($current_version);
682 $result->setNeededVersion($needed_version);
683 $result->setInfo($current_vendor);
684
9e2d15e5 685/// Process messages, modifying the $result if needed.
686 process_environment_messages($vendorsxml[$current_vendor], $result);
b0e2a189 687/// Process bypass, modifying $result if needed.
688 process_environment_bypass($vendorsxml[$current_vendor], $result);
95a39282 689/// Process restrict, modifying $result if needed.
690 process_environment_restrict($vendorsxml[$current_vendor], $result);
9e2d15e5 691
f58b518f 692 return $result;
693
694}
695
b0e2a189 696/**
697 * This function will post-process the result record by executing the specified
698 * function, modifying it as necessary, also a custom message will be added
699 * to the result object to be printed by the display layer.
700 * Every bypass function must be defined in this file and it'll return
701 * true/false to decide if the original test is bypassed or no. Also
702 * such bypass functions are able to directly handling the result object
703 * although it should be only under exceptional conditions.
704 *
705 * @param string xmldata containing the bypass data
95a39282 706 * @param object result object to be updated
b0e2a189 707 */
708function process_environment_bypass($xml, &$result) {
709
76bb0d20 710/// Only try to bypass if we were in error and it was required
711 if ($result->getStatus() || $result->getLevel() == 'optional') {
b0e2a189 712 return;
713 }
714
715/// It there is bypass info (function and message)
74506a51 716 if (is_array($xml['#']) && isset($xml['#']['BYPASS'][0]['@']['function']) && isset($xml['#']['BYPASS'][0]['@']['message'])) {
b0e2a189 717 $function = $xml['#']['BYPASS'][0]['@']['function'];
718 $message = $xml['#']['BYPASS'][0]['@']['message'];
719 /// Look for the function
720 if (function_exists($function)) {
721 /// Call it, and if bypass = true is returned, apply meesage
722 if ($function($result)) {
723 /// We only set the bypass message if the function itself hasn't defined it before
724 if (empty($result->getBypassStr)) {
725 $result->setBypassStr($message);
726 }
727 }
728 }
729 }
730}
731
95a39282 732/**
733 * This function will post-process the result record by executing the specified
734 * function, modifying it as necessary, also a custom message will be added
735 * to the result object to be printed by the display layer.
736 * Every restrict function must be defined in this file and it'll return
737 * true/false to decide if the original test is restricted or no. Also
738 * such restrict functions are able to directly handling the result object
739 * although it should be only under exceptional conditions.
740 *
741 * @param string xmldata containing the restrict data
742 * @param object result object to be updated
743 */
744function process_environment_restrict($xml, &$result) {
745
746/// Only try to restrict if we were not in error and it was required
747 if (!$result->getStatus() || $result->getLevel() == 'optional') {
748 return;
749 }
750/// It there is restrict info (function and message)
751 if (is_array($xml['#']) && isset($xml['#']['RESTRICT'][0]['@']['function']) && isset($xml['#']['RESTRICT'][0]['@']['message'])) {
752 $function = $xml['#']['RESTRICT'][0]['@']['function'];
753 $message = $xml['#']['RESTRICT'][0]['@']['message'];
754 /// Look for the function
755 if (function_exists($function)) {
756 /// Call it, and if restrict = true is returned, apply meesage
757 if ($function($result)) {
758 /// We only set the restrict message if the function itself hasn't defined it before
759 if (empty($result->getRestrictStr)) {
760 $result->setRestrictStr($message);
761 }
762 }
763 }
764 }
765}
766
9e2d15e5 767/**
768 * This function will detect if there is some message available to be added to the
769 * result in order to clarify enviromental details.
b0e2a189 770 * @param string xmldata containing the feedback data
9e2d15e5 771 * @param object reult object to be updated
772 */
773function process_environment_messages($xml, &$result) {
774
775/// If there is feedback info
74506a51 776 if (is_array($xml['#']) && isset($xml['#']['FEEDBACK'][0]['#'])) {
9e2d15e5 777 $feedbackxml = $xml['#']['FEEDBACK'][0]['#'];
778
779 if (!$result->status and $result->getLevel() == 'required') {
780 if (isset($feedbackxml['ON_ERROR'][0]['@']['message'])) {
781 $result->setFeedbackStr($feedbackxml['ON_ERROR'][0]['@']['message']);
782 }
783 } else if (!$result->status and $result->getLevel() == 'optional') {
784 if (isset($feedbackxml['ON_CHECK'][0]['@']['message'])) {
785 $result->setFeedbackStr($feedbackxml['ON_CHECK'][0]['@']['message']);
786 }
787 } else {
788 if (isset($feedbackxml['ON_OK'][0]['@']['message'])) {
789 $result->setFeedbackStr($feedbackxml['ON_OK'][0]['@']['message']);
790 }
791 }
792 }
793}
794
f58b518f 795
796//--- Helper Class to return results to caller ---//
797
798
799/**
800 * This class is used to return the results of the environment
801 * main functions (environment_check_xxxx)
802 */
803class environment_results {
804
049c0f4a 805 var $part; //which are we checking (database, php, php_extension)
f58b518f 806 var $status; //true/false
807 var $error_code; //integer. See constants at the beginning of the file
808 var $level; //required/optional
809 var $current_version; //current version detected
810 var $needed_version; //version needed
811 var $info; //Aux. info (DB vendor, library...)
9e2d15e5 812 var $feedback_str; //String to show on error|on check|on ok
813 var $bypass_str; //String to show if some bypass has happened
95a39282 814 var $restrict_str; //String to show if some restrict has happened
f58b518f 815
816 /**
817 * Constructor of the environment_result class. Just set default values
818 */
819 function environment_results($part) {
820 $this->part=$part;
821 $this->status=false;
049c0f4a 822 $this->error_code=NO_ERROR;
f58b518f 823 $this->level='required';
824 $this->current_version='';
825 $this->needed_version='';
826 $this->info='';
9e2d15e5 827 $this->feedback_str='';
828 $this->bypass_str='';
95a39282 829 $this->restrict_str='';
f58b518f 830 }
831
832 /**
833 * Set the status
834 * @param boolean the status (true/false)
835 */
836 function setStatus($status) {
837 $this->status=$status;
838 if ($status) {
839 $this->setErrorCode(NO_ERROR);
840 }
841 }
842
843 /**
844 * Set the error_code
845 * @param integer the error code (see constants above)
846 */
847 function setErrorCode($error_code) {
848 $this->error_code=$error_code;
849 }
850
851 /**
852 * Set the level
853 * @param string the level (required, optional)
854 */
855 function setLevel($level) {
856 $this->level=$level;
857 }
858
859 /**
860 * Set the current version
861 * @param string the current version
862 */
863 function setCurrentVersion($current_version) {
864 $this->current_version=$current_version;
865 }
866
867 /**
868 * Set the needed version
869 * @param string the needed version
870 */
871 function setNeededVersion($needed_version) {
872 $this->needed_version=$needed_version;
873 }
874
875 /**
876 * Set the auxiliary info
877 * @param string the auxiliary info
878 */
9e2d15e5 879 function setInfo($info) {
880 $this->info=$info;
881 }
882
883 /**
884 * Set the feedback string
885 * @param string the feedback string
886 */
887 function setFeedbackStr($str) {
888 $this->feedback_str=$str;
889 }
f58b518f 890
b0e2a189 891 /**
892 * Set the bypass string
893 * @param string the bypass string
894 */
895 function setBypassStr($str) {
896 $this->bypass_str=$str;
897 }
898
95a39282 899 /**
900 * Set the restrict string
901 * @param string the restrict string
902 */
903 function setRestrictStr($str) {
904 $this->restrict_str=$str;
905 }
906
f58b518f 907 /**
908 * Get the status
909 * @return boolean result
910 */
911 function getStatus() {
912 return $this->status;
913 }
914
915 /**
916 * Get the error code
917 * @return integer error code
918 */
919 function getErrorCode() {
920 return $this->error_code;
921 }
922
923 /**
924 * Get the level
925 * @return string level
926 */
927 function getLevel() {
928 return $this->level;
929 }
930
931 /**
932 * Get the current version
933 * @return string current version
934 */
935 function getCurrentVersion() {
936 return $this->current_version;
937 }
938
939 /**
940 * Get the needed version
941 * @return string needed version
942 */
943 function getNeededVersion() {
944 return $this->needed_version;
945 }
946
947 /**
948 * Get the aux info
949 * @return string info
950 */
951 function getInfo() {
952 return $this->info;
953 }
954
955 /**
956 * Get the part this result belongs to
957 * @return string part
958 */
959 function getPart() {
960 return $this->part;
961 }
9e2d15e5 962
963 /**
964 * Get the feedback string
965 * @return string feedback string
966 */
967 function getFeedbackStr() {
968 return $this->feedback_str;
969 }
b0e2a189 970
971 /**
972 * Get the bypass string
973 * @return string bypass string
974 */
975 function getBypassStr() {
976 return $this->bypass_str;
977 }
95a39282 978
979 /**
980 * Get the restrict string
981 * @return string restrict string
982 */
983 function getRestrictStr() {
984 return $this->restrict_str;
985 }
f58b518f 986}
987
9e2d15e5 988/// Here all the bypass functions are coded to be used by the environment
989/// checker. All those functions will receive the result object and will
990/// return it modified as needed (status and bypass string)
991
b0e2a189 992/**
993 * This function will bypass MySQL 4.1.16 reqs if:
994 * - We are using MySQL > 4.1.12, informing about problems with non latin chars in the future
995 *
996 * @param object result object to handle
95a39282 997 * @return boolean true/false to determinate if the bypass has to be performed (true) or no (false)
b0e2a189 998 */
999function bypass_mysql416_reqs ($result) {
1000/// See if we are running MySQL >= 4.1.12
1001 if (version_compare($result->getCurrentVersion(), '4.1.12', '>=')) {
1002 return true;
1003 }
1004
1005 return false;
1006}
1007
95a39282 1008/// Here all the restrict functions are coded to be used by the environment
1009/// checker. All those functions will receive the result object and will
1010/// return it modified as needed (status and bypass string)
1011
1012/**
1013 * This function will restrict PHP reqs if:
1014 * - We are using PHP 5.0.x, informing about the buggy version
1015 *
1016 * @param object result object to handle
1017 * @return boolean true/false to determinate if the restrict has to be performed (true) or no (false)
1018 */
1019function restrict_php50_version($result) {
1020 if (version_compare($result->getCurrentVersion(), '5.0.0', '>=')
1021 and version_compare($result->getCurrentVersion(), '5.0.99', '<')) {
1022 return true;
1023 }
1024 return false;
1025}
f58b518f 1026?>