MDL-9616 - Custom checks in environment.xml
authortjhunt <tjhunt>
Fri, 27 Apr 2007 17:15:24 +0000 (17:15 +0000)
committertjhunt <tjhunt>
Fri, 27 Apr 2007 17:15:24 +0000 (17:15 +0000)
admin/environment.xml
lang/en_utf8/admin.php
lib/environmentlib.php
question/upgrade.php [new file with mode: 0644]

index cbbe57a..4665102 100644 (file)
       </PHP_EXTENSION>
     </PHP_EXTENSIONS>
   </MOODLE>
+  <MOODLE version="1.9">
+    <UNICODE level="required">
+      <FEEDBACK>
+        <ON_ERROR message="unicoderequired" />
+      </FEEDBACK>
+    </UNICODE>
+    <DATABASE level="required">
+      <VENDOR name="mysql" version="4.1.16">
+        <FEEDBACK>
+          <ON_ERROR message="mysql416required" />
+        </FEEDBACK>
+        <BYPASS function="bypass_mysql416_reqs" message="mysql416bypassed" />
+      </VENDOR>
+      <VENDOR name="postgres" version="7.4" />
+      <VENDOR name="mssql" version="9.0" />
+      <VENDOR name="odbc_mssql" version="9.0" />
+      <VENDOR name="mssql_n" version="9.0" />
+      <VENDOR name="oracle" version="9.0" />
+    </DATABASE>
+    <PHP version="4.3.0" level="required">
+      <RESTRICT function="restrict_php50_version" message="php50restricted" />
+    </PHP>
+    <PHP_EXTENSIONS>
+      <PHP_EXTENSION name="iconv" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="iconvrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="mbstring" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="mbstringrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="curl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="curlrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="openssl" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="opensslrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+      <PHP_EXTENSION name="tokenizer" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="tokenizerrecommended" />
+        </FEEDBACK>
+      </PHP_EXTENSION>
+    </PHP_EXTENSIONS>
+    <CUSTOM_CHECKS>
+      <CUSTOM_CHECK file="question/upgrade.php" function="question_check_no_rqp_questions" level="optional">
+        <FEEDBACK>
+          <ON_CHECK message="qtyperqpwillberemoved" />
+          <ON_OK message="qtyperqpwillberemovedanyway" />
+        </FEEDBACK>
+      </CUSTOM_CHECK>
+    </CUSTOM_CHECKS>
+  </MOODLE>
 </COMPATIBILITY_MATRIX>
index 596226d..cebc205 100644 (file)
@@ -506,6 +506,8 @@ $string['riskspamshort'] = 'Spam risk';
 $string['riskxss'] = 'Users could add files and texts that allow cross-site scripting (XSS)';
 $string['riskxssshort'] = 'XSS risk';
 $string['runclamavonupload'] = 'Use clam AV on uploaded files';
+$string['qtyperqpwillberemoved'] = 'During the upgrade, the RQP question type will be removed. You were not using this quetsion type, so this should not cause you any problems.';
+$string['qtyperqpwillberemovedanyway'] = 'During the upgrade, the RQP question type will be removed. You have some RQP questions in your database, and these will stop working unless you reinstall the code from http://moodle.org/mod/data/view.php?d=13&rid=797 before continuing with the upgrade.';
 $string['savechanges'] = 'Save Changes';
 $string['search'] = 'Search';
 $string['searchresults'] = 'Search Results';
index d94724b..7c02f77 100644 (file)
@@ -47,6 +47,9 @@
     define('NO_PHP_EXTENSIONS_NAME_FOUND',       9);
     define('NO_DATABASE_VENDOR_VERSION_FOUND',  10);
     define('NO_UNICODE_SECTION_FOUND',          11);
+    define('NO_CUSTOM_CHECK_FOUND',             12);
+    define('CUSTOM_CHECK_FILE_MISSING',         13);
+    define('CUSTOM_CHECK_FUNCTION_MISSING',     14);
 
 /**
  * This function will perform the whole check, returning
@@ -135,6 +138,7 @@ function print_moodle_environment($result, $environment_results) {
     $feedbacktext = '';
 
 /// Table header
+    $table = new stdClass;
     $table->head  = array ($strname, $strinfo, $strreport, $strstatus);
     $table->align = array ('center', 'center', 'left', 'center');
     $table->wrap  = array ('nowrap', '', '', 'nowrap');
@@ -402,8 +406,10 @@ function environment_check($version) {
     $results[] = environment_check_php($version);
 
     $phpext_results = environment_check_php_extensions($version);
+    $results = array_merge($results, $phpext_results);
 
-    $results = array_merge ($results, $phpext_results);
+    $custom_results = environment_custom_checks($version);
+    $results = array_merge($results, $custom_results);
 
     return $results;
 }
@@ -439,12 +445,7 @@ function environment_check_php_extensions($version) {
     foreach($data['#']['PHP_EXTENSIONS']['0']['#']['PHP_EXTENSION'] as $extension) {
         $result = new environment_results('php_extension');
     /// Check for level
-        if (isset($extension['@']['level'])) {
-            $level = $extension['@']['level'];
-            if ($level != 'optional') {
-                $level = 'required';
-            }
-        }
+        $level = get_level($extension);
     /// Check for extension name
         if (!isset($extension['@']['name'])) {
             $result->setStatus(false);
@@ -460,12 +461,9 @@ function environment_check_php_extensions($version) {
             $result->setLevel($level);
             $result->setInfo($extension_name);
         }
-    /// Process messages, modifying the $result if needed.
-        process_environment_messages($extension, $result);
-    /// Process bypass, modifying $result if needed.
-        process_environment_bypass($extension, $result);
-    /// Process restrict, modifying $result if needed.
-        process_environment_restrict($extension, $result);
+
+    /// Do any actions defined in the XML file.
+        process_environment_result($extension, $result);
 
     /// Add the result to the array of results
         $results[] = $result;
@@ -475,6 +473,70 @@ function environment_check_php_extensions($version) {
     return $results;
 }
 
+/**
+ * This function will do the custom checks.
+ * @param string $version xml version we are going to use to test this server.
+ * @return array array of results encapsulated in environment_result objects.
+ */
+function environment_custom_checks($version) {
+    global $CFG;
+
+    $results = array();
+
+/// Get the enviroment version we need
+    if (!$data = get_environment_for_version($version)) {
+    /// Error. No version data found - but this will already have been reported.
+        return $results;
+    }
+
+/// Extract the CUSTOM_CHECKS part
+    if (!isset($data['#']['CUSTOM_CHECKS']['0']['#']['CUSTOM_CHECK'])) {
+    /// No custom checks found - not a problem
+        return $results;
+    }
+
+/// Iterate over extensions checking them and creating the needed environment_results
+    foreach($data['#']['CUSTOM_CHECKS']['0']['#']['CUSTOM_CHECK'] as $check) {
+        $result = new environment_results('custom_check');
+
+    /// Check for level
+        $level = get_level($check);
+
+    /// Check for extension name
+        if (isset($check['@']['file']) && isset($check['@']['function'])) {
+            $file = $CFG->dirroot . '/' . $check['@']['file'];
+            echo $file;
+            $function = $check['@']['function'];
+            if (is_readable($file)) {
+                include_once($file);
+                if (function_exists($function)) {
+                    $result->setLevel($level);
+                    $result->setInfo($function);
+                    $result = $function($result);
+                } else {
+                    $result->setStatus(false);
+                    $result->setErrorCode(CUSTOM_CHECK_FUNCTION_MISSING);
+                }
+            } else {
+                $result->setStatus(false);
+                $result->setErrorCode(CUSTOM_CHECK_FILE_MISSING);
+            }
+        } else {
+            $result->setStatus(false);
+            $result->setErrorCode(NO_CUSTOM_CHECK_FOUND);
+        }
+
+        if (!is_null($result)) {
+        /// Do any actions defined in the XML file.
+            process_environment_result($check, $result);
+    
+        /// Add the result to the array of results
+            $results[] = $result;
+        }
+    }
+
+    return $results;
+}
 
 /**
  * This function will check if php requirements are satisfied
@@ -501,12 +563,7 @@ function environment_check_php($version) {
         return $result;
     } else {
     /// Extract level and version
-        if (isset($data['#']['PHP']['0']['@']['level'])) {
-            $level = $data['#']['PHP']['0']['@']['level'];
-            if ($level != 'optional') {
-                $level = 'required';
-            }
-        }
+        $level = get_level($data['#']['PHP']['0']);
         if (!isset($data['#']['PHP']['0']['@']['version'])) {
             $result->setStatus(false);
             $result->setErrorCode(NO_PHP_VERSION_FOUND);
@@ -528,12 +585,9 @@ function environment_check_php($version) {
     $result->setLevel($level);   
     $result->setCurrentVersion($current_version);
     $result->setNeededVersion($needed_version);
-/// Process messages, modifying the $result if needed.
-    process_environment_messages($data['#']['PHP'][0], $result);
-/// Process bypass, modifying $result if needed.
-    process_environment_bypass($data['#']['PHP'][0], $result);
-/// Process restrict, modifying $result if needed.
-    process_environment_restrict($data['#']['PHP'][0], $result);
+
+/// Do any actions defined in the XML file.
+    process_environment_result($data['#']['PHP'][0], $result);
 
     return $result;
 }
@@ -566,12 +620,7 @@ function environment_check_unicode($version) {
         return $result;
     } else {
     /// Extract level
-        if (isset($data['#']['UNICODE']['0']['@']['level'])) {
-            $level = $data['#']['UNICODE']['0']['@']['level'];
-            if ($level != 'optional') {
-                $level = 'required';
-            }
-        }
+        $level = get_level($data['#']['UNICODE']['0']);
     }
 
     if (!$unicodedb = setup_is_unicodedb()) {
@@ -582,12 +631,8 @@ function environment_check_unicode($version) {
 
     $result->setLevel($level);
 
-/// Process messages, modifying the $result if needed.
-    process_environment_messages($data['#']['UNICODE'][0], $result);
-/// Process bypass, modifying $result if needed.
-    process_environment_bypass($data['#']['UNICODE'][0], $result);
-/// Process restrict, modifying $result if needed.
-    process_environment_restrict($data['#']['UNICODE'][0], $result);
+/// Do any actions defined in the XML file.
+    process_environment_result($data['#']['UNICODE'][0], $result);
 
     return $result;
 }
@@ -621,12 +666,7 @@ function environment_check_database($version) {
         return $result;
     } else {
     /// Extract level
-        if (isset($data['#']['DATABASE']['0']['@']['level'])) {
-            $level = $data['#']['DATABASE']['0']['@']['level'];
-            if ($level != 'optional') {
-                $level = 'required';
-            }
-        }
+        $level = get_level($data['#']['DATABASE']['0']);
     }
 
 /// Extract DB vendors. At least 2 are mandatory (mysql & postgres)
@@ -682,12 +722,8 @@ function environment_check_database($version) {
     $result->setNeededVersion($needed_version);
     $result->setInfo($current_vendor);
 
-/// Process messages, modifying the $result if needed.
-    process_environment_messages($vendorsxml[$current_vendor], $result);
-/// Process bypass, modifying $result if needed.
-    process_environment_bypass($vendorsxml[$current_vendor], $result);
-/// Process restrict, modifying $result if needed.
-    process_environment_restrict($vendorsxml[$current_vendor], $result);
+/// Do any actions defined in the XML file.
+    process_environment_result($vendorsxml[$current_vendor], $result);
 
     return $result;
 
@@ -1023,4 +1059,40 @@ function restrict_php50_version($result) {
     }
     return false;
 }
+
+/**
+ * @param array $element the element from the environment.xml file that should have
+ *      either a level="required" or level="optional" attribute.
+ * @read string "required" or "optional".
+ */
+function get_level($element) {
+    $level = 'required';
+    if (isset($element['@']['level'])) {
+        $level = $element['@']['level'];
+        if (!in_array($level, array('required', 'optional'))) {
+            debugging('The level of a check in the environment.xml file must be "required" or level="optional".', DEBUG_DEVELOPER);
+            $level = 'required';
+        }
+    } else {
+        debugging('Checks in the environment.xml file must have a level="required" or level="optional" attribute.', DEBUG_DEVELOPER);
+    }
+    return $level;
+}
+
+/**
+ * Once the result has been determined, look in the XML for any
+ * messages, or other things that should be done depending on the outcome.
+ * @param array $element the element from the environment.xml file which
+ *      may have children defining what should be done with the outcome.
+ * @param object $result the result of the test, which may be modified by
+ *      this function as specified in the XML.
+ */
+function process_environment_result($element, &$result) {
+/// Process messages, modifying the $result if needed.
+    process_environment_messages($element, $result);
+/// Process bypass, modifying $result if needed.
+    process_environment_bypass($element, $result);
+/// Process restrict, modifying $result if needed.
+    process_environment_restrict($element, $result);
+}
 ?>
diff --git a/question/upgrade.php b/question/upgrade.php
new file mode 100644 (file)
index 0000000..ddf329c
--- /dev/null
@@ -0,0 +1,35 @@
+<?php
+/**
+ * This file contains dtabase upgrade code that is called from lib/db/upgrade.php,
+ * and also check methods that can be used for pre-install checks via
+ * admin/environment.php and lib/environmentlib.php.
+ *
+ * @copyright &copy; 2007 The Open University
+ * @author T.J.Hunt@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package package_name
+ *//** */
+
+/**
+ * This test is becuase the RQP question type was included in core
+ * up to and including Moodle 1.8, and was removed before Moodle 1.9.
+ * 
+ * Therefore, we want to check whether any rqp questions exist in the database
+ * before doing the upgrade. However, the check is not relevant if that 
+ * question type was never installed, or if the person has chosen to 
+ * manually reinstall the rqp question type from contrib.
+ * 
+ * @param $version the version to test.
+ * @return null if the test is irrelevant, or true or false depending on whether the test passes.
+ */
+function question_check_no_rqp_questions($result) {
+    global $CFG;
+
+    if (empty($CFG->qtype_rqp_version) || is_dir($CFG->dirroot . '/question/type/rqp')) {
+        return null;
+    } else {
+        $result->setStatus(count_records('question', 'qtype', 'rqp') == 0);
+    }
+    return $result;
+}
+?>