[ PHPXref.com ] [ Generated: Sun Jul 20 18:45:57 2008 ] [ Moodle 1.5.3 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/lib/ -> environmentlib.php (source)

   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  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]