[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/ -> environmentlib.php (source)

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


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1