| [ PHPXref.com ] | [ Generated: Sun Jul 20 18:45:57 2008 ] | [ Moodle 1.5.3 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php //$Id: environmentlib.php,v 1.4.2.4 2006/01/21 00:17:19 stronk7 Exp $ 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, 32 // supporting to have an updated version in dataroot/environment 33 34 /// Add required files 35 require_once($CFG->libdir.'/xmlize.php'); 36 37 /// Define a buch of XML processing errors 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); 49 50 /** 51 * This function will perform the whole check, returning 52 * true or false as final result. Also, he full array of 53 * environment_result will be returned in the parameter list. 54 * The function looks for the best version to compare and 55 * everything. This is the only function that should be called 56 * ever from the rest of Moodle. 57 * @param string version version to check. 58 * @param array results array of results checked. 59 * @return boolean true/false, depending of results 60 */ 61 function check_moodle_environment($version, &$environment_results, $print_table=true) { 62 63 $status = true; 64 65 /// This are cached per request 66 static $result = true; 67 static $env_results; 68 static $cache_exists = false; 69 70 /// if we have results cached, use them 71 if ($cache_exists) { 72 $environment_results = $env_results; 73 /// No cache exists, calculate everything 74 } else { 75 /// Get the more recent version before the requested 76 if (!$version = get_latest_version_available($version)) { 77 $status = false; 78 } 79 80 /// Perform all the checks 81 if (!($environment_results = environment_check($version)) && $status) { 82 $status = false; 83 } 84 85 /// Iterate over all the results looking for some error in required items 86 /// or some error_code 87 if ($status) { 88 foreach ($environment_results as $environment_result) { 89 if ((!$environment_result->getStatus() && 90 $environment_result->getLevel() == 'required') || 91 $environment_result->getErrorCode()) { 92 $result = false; 93 } 94 } 95 } 96 /// Going to end, we store environment_results to cache 97 $env_results = $environment_results; 98 $cache_exists = true; 99 } ///End of cache block 100 101 /// If we have decided to print all the information, just do it 102 if ($print_table) { 103 print_moodle_environment($result && $status, $environment_results); 104 } 105 106 107 return ($result && $status); 108 } 109 110 /** 111 * This function will print one beautiful table with all the environmental 112 * configuration and how it suits Moodle needs. 113 * @param boolean final result of the check (true/false) 114 * @param array environment_results array of results gathered 115 */ 116 function print_moodle_environment($result, $environment_results) { 117 118 /// Get some strings 119 $strname = get_string('name'); 120 $strinfo = get_string('info'); 121 $strreport = get_string('report'); 122 $strstatus = get_string('status'); 123 $strok = get_string('ok'); 124 $strerror = get_string('error'); 125 $strcheck = get_string('check'); 126 $strenvironmenterrortodo = get_string('environmenterrortodo', 'admin'); 127 128 /// Table header 129 $table->head = array ($strname, $strinfo, $strreport, $strstatus); 130 $table->align = array ('center', 'center', 'left', 'center'); 131 $table->wrap = array ('nowrap', '', '', 'nowrap'); 132 $table->size = array ('10', 10, '100%', '10'); 133 $table->width = '90%'; 134 $table->class = 'environmenttable'; 135 136 /// Iterate over each environment_result 137 $continue = true; 138 foreach ($environment_results as $environment_result) { 139 $errorline = false; 140 if ($continue) { 141 $type = $environment_result->getPart(); 142 $info = $environment_result->getInfo(); 143 $status = $environment_result->getStatus(); 144 $error_code = $environment_result->getErrorCode(); 145 /// Process Report field 146 $rec = new stdClass(); 147 /// Something has gone wrong at parsing time 148 if ($error_code) { 149 $stringtouse = 'environmentxmlerror'; 150 $rec->error_code = $error_code; 151 $status = $strerror; 152 $errorline = true; 153 $continue = false; 154 } 155 156 if ($continue) { 157 /// We are comparing versions 158 if ($rec->needed = $environment_result->getNeededVersion()) { 159 $rec->current = $environment_result->getCurrentVersion(); 160 if ($environment_result->getLevel() == 'required') { 161 $stringtouse = 'environmentrequireversion'; 162 } else { 163 $stringtouse = 'environmentrecommendversion'; 164 } 165 /// We are checking installed & enabled things 166 } else { 167 if ($environment_result->getLevel() == 'required') { 168 $stringtouse = 'environmentrequireinstall'; 169 } else { 170 $stringtouse = 'environmentrecommendinstall'; 171 } 172 } 173 /// Calculate the status value 174 if (!$status and $environment_result->getLevel() == 'required') { 175 $status = $strerror; 176 $errorline = true; 177 } else if (!$status and $environment_result->getLevel() == 'optional') { 178 $status = $strcheck; 179 } else { 180 $status = $strok; 181 } 182 } 183 184 /// Build the text 185 $report = get_string($stringtouse, 'admin', $rec); 186 /// Format error line 187 if ($errorline) { 188 $type = '<span class="error">'.$type.'</span>'; 189 $info = '<span class="error">'.$info.'</span>'; 190 $report = '<span class="error">'.$report.'</span>'; 191 $status = '<span class="error">'.$status.'</span>'; 192 } 193 /// Add the row to the table 194 $table->data[] = array ($type, $info, $report, $status); 195 } 196 } 197 198 /// Print table 199 print_table($table); 200 201 /// Finally, if any error has happened, print the summary box 202 if (!$result) { 203 print_simple_box($strenvironmenterrortodo, 'center', '', '', '', 'errorbox'); 204 } 205 } 206 207 208 /** 209 * This function will normalize any version to just a serie of numbers 210 * separated by dots. Everything else will be removed. 211 * @param string $version the original version 212 * @return string the normalized version 213 */ 214 function normalize_version($version) { 215 /// Replace everything but numbers and dots by dots 216 $version = preg_replace('/[^\.\d]/', '.', $version); 217 /// Combine multiple dots in one 218 $version = preg_replace('/(\.{2,})/', '.', $version); 219 /// Trim possible leading and trailing dots 220 $version = trim($version, '.'); 221 222 return $version; 223 } 224 225 226 /** 227 * This function will load the environment.xml file and xmlize it 228 * @return mixed the xmlized structure or false on error 229 */ 230 function load_environment_xml() { 231 232 global $CFG; 233 234 static $data; //Only load and xmlize once by request 235 236 if (!empty($data)) { 237 return $data; 238 } 239 240 /// First of all, take a look inside $CFG->dataroot/environment/environment.xml 241 $file = $CFG->dataroot.'/environment/environment.xml'; 242 if (!is_file($file) || !is_readable($file) || !$contents = file_get_contents($file)) { 243 /// Fallback to fixed $CFG->admin/environment.xml 244 $file = $CFG->dirroot.'/'.$CFG->admin.'/environment.xml'; 245 if (!is_file($file) || !is_readable($file) || !$contents = file_get_contents($file)) { 246 return false; 247 } 248 } 249 /// XML the whole file 250 $data = xmlize($contents); 251 252 return $data; 253 } 254 255 256 /** 257 * This function will return the list of Moodle versions available 258 * @return mixed array of versions. False on error. 259 */ 260 function get_list_of_environment_versions ($contents) { 261 262 static $versions = array(); 263 264 if (!empty($versions)) { 265 return $versions; 266 } 267 268 if (isset($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'])) { 269 foreach ($contents['COMPATIBILITY_MATRIX']['#']['MOODLE'] as $version) { 270 $versions[] = $version['@']['version']; 271 } 272 } 273 274 return $versions; 275 } 276 277 278 /** 279 * This function will return the most recent version in the environment.xml 280 * file previous or equal to the version requested 281 * @param string version top version from which we start to look backwards 282 * @return string more recent version or false if not found 283 */ 284 function get_latest_version_available ($version) { 285 286 /// Normalize the version requested 287 $version = normalize_version($version); 288 289 /// Load xml file 290 if (!$contents = load_environment_xml()) { 291 return false; 292 } 293 294 /// Detect available versions 295 if (!$versions = get_list_of_environment_versions($contents)) { 296 return false; 297 } 298 /// First we look for exact version 299 if (in_array($version, $versions)) { 300 return $version; 301 } else { 302 $found_version = false; 303 /// Not exact match, so we are going to iterate over the list searching 304 /// for the latest version before the requested one 305 foreach ($versions as $arrversion) { 306 if (version_compare($arrversion, $version, '<')) { 307 $found_version = $arrversion; 308 } 309 } 310 } 311 312 return $found_version; 313 } 314 315 316 /** 317 * This function will return the xmlized data belonging to one Moodle version 318 * @return mixed the xmlized structure or false on error 319 */ 320 function get_environment_for_version($version) { 321 322 /// Normalize the version requested 323 $version = normalize_version($version); 324 325 /// Load xml file 326 if (!$contents = load_environment_xml()) { 327 return false; 328 } 329 330 /// Detect available versions 331 if (!$versions = get_list_of_environment_versions($contents)) { 332 return false; 333 } 334 335 /// If the version requested is available 336 if (!in_array($version, $versions)) { 337 return false; 338 } 339 340 /// We now we have it. Extract from full contents. 341 $fl_arr = array_flip($versions); 342 343 return $contents['COMPATIBILITY_MATRIX']['#']['MOODLE'][$fl_arr[$version]]; 344 } 345 346 347 /** 348 * This function will check for everything (DB, PHP and PHP extensions for now) 349 * returning an array of environment_result objects. 350 * @param string $version xml version we are going to use to test this server 351 * @return array array of results encapsulated in one environment_result object 352 */ 353 function environment_check($version) { 354 355 /// Normalize the version requested 356 $version = normalize_version($version); 357 358 $results = array(); //To store all the results 359 360 $results[] = environment_check_database($version); 361 $results[] = environment_check_php($version); 362 363 $phpext_results = environment_check_php_extensions($version); 364 365 $results = array_merge ($results, $phpext_results); 366 367 return $results; 368 } 369 370 371 /** 372 * This function will check if php extensions requirements are satisfied 373 * @param string $version xml version we are going to use to test this server 374 * @return array array of results encapsulated in one environment_result object 375 */ 376 function environment_check_php_extensions($version) { 377 378 $results = array(); 379 380 /// Get the enviroment version we need 381 if (!$data = get_environment_for_version($version)) { 382 /// Error. No version data found 383 $result = new environment_results('php_extension'); 384 $result->setStatus(false); 385 $result->setErrorCode(NO_VERSION_DATA_FOUND); 386 return $result; 387 } 388 389 /// Extract the php_extension part 390 if (!isset($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'])) { 391 /// Error. No PHP section found 392 $result = new environment_results('php_extension'); 393 $result->setStatus(false); 394 $result->setErrorCode(NO_PHP_EXTENSIONS_SECTION_FOUND); 395 return $result; 396 } else { 397 /// Iterate over extensions checking them and creating the needed environment_results 398 foreach($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'] as $extension) { 399 $result = new environment_results('php_extension'); 400 /// Check for level 401 if (isset($extension['@']['level'])) { 402 $level = $extension['@']['level']; 403 if ($level != 'optional') { 404 $level = 'required'; 405 } 406 } 407 /// Check for extension name 408 if (!isset($extension['@']['name'])) { 409 $result->setStatus(false); 410 $result->setErrorCode(NO_PHP_EXTENSIONS_NAME_FOUND); 411 } else { 412 $extension_name = $extension['@']['name']; 413 /// The name exists. Just check if it's an installed extension 414 if (!extension_loaded($extension_name)) { 415 $result->setStatus(false); 416 } else { 417 $result->setStatus(true); 418 } 419 $result->setLevel($level); 420 $result->setInfo($extension_name); 421 } 422 /// Add the result to the array of results 423 $results[] = $result; 424 } 425 } 426 427 return $results; 428 } 429 430 431 /** 432 * This function will check if php requirements are satisfied 433 * @param string $version xml version we are going to use to test this server 434 * @return object results encapsulated in one environment_result object 435 */ 436 function environment_check_php($version) { 437 438 $result = new environment_results('php'); 439 440 /// Get the enviroment version we need 441 if (!$data = get_environment_for_version($version)) { 442 /// Error. No version data found 443 $result->setStatus(false); 444 $result->setErrorCode(NO_VERSION_DATA_FOUND); 445 return $result; 446 } 447 448 /// Extract the php part 449 if (!isset($data['#']['PHP'])) { 450 /// Error. No PHP section found 451 $result->setStatus(false); 452 $result->setErrorCode(NO_PHP_SECTION_FOUND); 453 return $result; 454 } else { 455 /// Extract level and version 456 if (isset($data['#']['PHP']['0']['@']['level'])) { 457 $level = $data['#']['PHP']['0']['@']['level']; 458 if ($level != 'optional') { 459 $level = 'required'; 460 } 461 } 462 if (!isset($data['#']['PHP']['0']['@']['version'])) { 463 $result->setStatus(false); 464 $result->setErrorCode(NO_PHP_VERSION_FOUND); 465 return $result; 466 } else { 467 $needed_version = $data['#']['PHP']['0']['@']['version']; 468 } 469 } 470 471 /// Now search the version we are using 472 $current_version = normalize_version(phpversion()); 473 474 /// And finally compare them, saving results 475 if (version_compare($current_version, $needed_version, '>=')) { 476 $result->setStatus(true); 477 } else { 478 $result->setStatus(false); 479 } 480 $result->setLevel($level); 481 $result->setCurrentVersion($current_version); 482 $result->setNeededVersion($needed_version); 483 484 return $result; 485 } 486 487 488 /** 489 * This function will check if database requirements are satisfied 490 * @param string $version xml version we are going to use to test this server 491 * @return object results encapsulated in one environment_result object 492 */ 493 function environment_check_database($version) { 494 495 global $db; 496 497 $result = new environment_results('database'); 498 499 $vendors = array(); //Array of vendors in version 500 501 /// Get the enviroment version we need 502 if (!$data = get_environment_for_version($version)) { 503 /// Error. No version data found 504 $result->setStatus(false); 505 $result->setErrorCode(NO_VERSION_DATA_FOUND); 506 return $result; 507 } 508 509 /// Extract the database part 510 if (!isset($data['#']['DATABASE'])) { 511 /// Error. No DATABASE section found 512 $result->setStatus(false); 513 $result->setErrorCode(NO_DATABASE_SECTION_FOUND); 514 return $result; 515 } else { 516 /// Extract level 517 if (isset($data['#']['DATABASE']['0']['@']['level'])) { 518 $level = $data['#']['DATABASE']['0']['@']['level']; 519 if ($level != 'optional') { 520 $level = 'required'; 521 } 522 } 523 } 524 525 /// Extract DB vendors. At least 2 are mandatory (mysql & postgres) 526 if (!isset($data['#']['DATABASE']['0']['#']['VENDOR'])) { 527 /// Error. No VENDORS found 528 $result->setStatus(false); 529 $result->setErrorCode(NO_DATABASE_VENDORS_FOUND); 530 return $result; 531 } else { 532 /// Extract vendors 533 foreach ($data['#']['DATABASE']['0']['#']['VENDOR'] as $vendor) { 534 if (isset($vendor['@']['name']) && isset($vendor['@']['version'])) { 535 $vendors[$vendor['@']['name']] = $vendor['@']['version']; 536 } 537 } 538 } 539 /// Check we have the mysql vendor version 540 if (empty($vendors['mysql'])) { 541 $result->setStatus(false); 542 $result->setErrorCode(NO_DATABASE_VENDOR_MYSQL_FOUND); 543 return $result; 544 } 545 /// Check we have the postgres vendor version 546 if (empty($vendors['postgres'])) { 547 $result->setStatus(false); 548 $result->setErrorCode(NO_DATABASE_VENDOR_POSTGRES_FOUND); 549 return $result; 550 } 551 552 /// Now search the version we are using (depending of vendor) 553 $current_vendor = $db->databaseType; 554 if ($current_vendor == 'postgres7') { //Normalize a bit postgresql 555 $current_vendor ='postgres'; 556 } 557 $dbinfo = $db->ServerInfo(); 558 $current_version = normalize_version($dbinfo['version']); 559 $needed_version = $vendors[$current_vendor]; 560 561 /// Check we have a needed version 562 if (!$needed_version) { 563 $result->setStatus(false); 564 $result->setErrorCode(NO_DATABASE_VENDOR_VERSION_FOUND); 565 return $result; 566 } 567 568 /// And finally compare them, saving results 569 if (version_compare($current_version, $needed_version, '>=')) { 570 $result->setStatus(true); 571 } else { 572 $result->setStatus(false); 573 } 574 $result->setLevel($level); 575 $result->setCurrentVersion($current_version); 576 $result->setNeededVersion($needed_version); 577 $result->setInfo($current_vendor); 578 579 return $result; 580 581 } 582 583 584 //--- Helper Class to return results to caller ---// 585 586 587 /** 588 * This class is used to return the results of the environment 589 * main functions (environment_check_xxxx) 590 */ 591 class environment_results { 592 593 var $part; //which are we checking (database, php, php_extension) 594 var $status; //true/false 595 var $error_code; //integer. See constants at the beginning of the file 596 var $level; //required/optional 597 var $current_version; //current version detected 598 var $needed_version; //version needed 599 var $info; //Aux. info (DB vendor, library...) 600 601 /** 602 * Constructor of the environment_result class. Just set default values 603 */ 604 function environment_results($part) { 605 $this->part=$part; 606 $this->status=false; 607 $this->error_code=NO_ERROR; 608 $this->level='required'; 609 $this->current_version=''; 610 $this->needed_version=''; 611 $this->info=''; 612 } 613 614 /** 615 * Set the status 616 * @param boolean the status (true/false) 617 */ 618 function setStatus($status) { 619 $this->status=$status; 620 if ($status) { 621 $this->setErrorCode(NO_ERROR); 622 } 623 } 624 625 /** 626 * Set the error_code 627 * @param integer the error code (see constants above) 628 */ 629 function setErrorCode($error_code) { 630 $this->error_code=$error_code; 631 } 632 633 /** 634 * Set the level 635 * @param string the level (required, optional) 636 */ 637 function setLevel($level) { 638 $this->level=$level; 639 } 640 641 /** 642 * Set the current version 643 * @param string the current version 644 */ 645 function setCurrentVersion($current_version) { 646 $this->current_version=$current_version; 647 } 648 649 /** 650 * Set the needed version 651 * @param string the needed version 652 */ 653 function setNeededVersion($needed_version) { 654 $this->needed_version=$needed_version; 655 } 656 657 /** 658 * Set the auxiliary info 659 * @param string the auxiliary info 660 */ 661 function setInfo($info) { 662 $this->info=$info; 663 } 664 665 /** 666 * Get the status 667 * @return boolean result 668 */ 669 function getStatus() { 670 return $this->status; 671 } 672 673 /** 674 * Get the error code 675 * @return integer error code 676 */ 677 function getErrorCode() { 678 return $this->error_code; 679 } 680 681 /** 682 * Get the level 683 * @return string level 684 */ 685 function getLevel() { 686 return $this->level; 687 } 688 689 /** 690 * Get the current version 691 * @return string current version 692 */ 693 function getCurrentVersion() { 694 return $this->current_version; 695 } 696 697 /** 698 * Get the needed version 699 * @return string needed version 700 */ 701 function getNeededVersion() { 702 return $this->needed_version; 703 } 704 705 /** 706 * Get the aux info 707 * @return string info 708 */ 709 function getInfo() { 710 return $this->info; 711 } 712 713 /** 714 * Get the part this result belongs to 715 * @return string part 716 */ 717 function getPart() { 718 return $this->part; 719 } 720 } 721 722 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |