Merge branch 'MDL-28466-master' of git://github.com/danpoltawski/moodle
authorMarina Glancy <marina@moodle.com>
Mon, 15 Jul 2013 03:07:37 +0000 (13:07 +1000)
committerMarina Glancy <marina@moodle.com>
Mon, 15 Jul 2013 03:07:37 +0000 (13:07 +1000)
15 files changed:
admin/cli/alternative_component_cache.php [new file with mode: 0644]
admin/cli/install.php
admin/tool/behat/cli/init.php
admin/tool/behat/cli/util.php
admin/tool/phpunit/cli/init.php
admin/tool/phpunit/cli/util.php
cache/classes/loaders.php
install.php
lib/classes/component.php
lib/csslib.php
lib/db/caches.php
lib/phpunit/bootstrap.php
lib/pluginlib.php
mod/workshop/allocation/manual/lib.php
version.php

diff --git a/admin/cli/alternative_component_cache.php b/admin/cli/alternative_component_cache.php
new file mode 100644 (file)
index 0000000..6b3d454
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * This hack is intended for clustered sites that do not want
+ * to use shared cachedir for component cache.
+ *
+ * This file needs to be called after any change in PHP files in dataroot,
+ * that is before upgrade and install.
+ *
+ * @package   core
+ * @copyright 2013 Petr Skoda (skodak)  {@link http://skodak.org}
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+
+define('CLI_SCRIPT', true);
+define('ABORT_AFTER_CONFIG', true); // We need just the values from config.php.
+define('CACHE_DISABLE_ALL', true); // This prevents reading of existing caches.
+define('IGNORE_COMPONENT_CACHE', true);
+
+require(__DIR__.'/../../config.php');
+require_once($CFG->libdir.'/clilib.php');
+
+// Now get cli options.
+list($options, $unrecognized) = cli_get_params(
+    array(
+        'file'    => false,
+        'rebuild' => false,
+        'print'   => false,
+        'help'    => false
+    ),
+    array(
+        'h' => 'help'
+    )
+);
+
+if ($unrecognized) {
+    $unrecognized = implode("\n  ", $unrecognized);
+    cli_error(get_string('cliunknowoption', 'admin', $unrecognized), 2);
+}
+
+if (!$options['rebuild'] and !$options['file'] and !$options['print']) {
+    $help =
+"Create alternative component cache file
+
+Options:
+-h, --help            Print out this help
+--rebuild             Rebuild \$CFG->alternative_component_cache file
+--file=filepath       Save component cache to file
+--print               Print component cache file content
+
+Example:
+\$ php admin/cli/rebuild_alternative_component_cache.php --rebuild
+";
+
+    echo $help;
+    exit(0);
+}
+
+error_reporting(E_ALL | E_STRICT);
+ini_set('display_errors', 1);
+
+$content = core_component::get_cache_content();
+
+if ($options['print']) {
+    echo $content;
+    exit(0);
+}
+
+if ($options['rebuild']) {
+    if (empty($CFG->alternative_component_cache)) {
+        fwrite(STDERR, 'config.php does not contain $CFG->alternative_component_cache setting');
+        fwrite(STDERR, "\n");
+        exit(2);
+    }
+    $target = $CFG->alternative_component_cache;
+} else {
+    $target = $options['file'];
+}
+
+if (!$target) {
+    fwrite(STDERR, "Invalid target file $target");
+    fwrite(STDERR, "\n");
+    exit(1);
+}
+
+$bytes = file_put_contents($target, $content);
+
+if (!$bytes) {
+    fwrite(STDERR, "Error writing to $target");
+    fwrite(STDERR, "\n");
+    exit(1);
+}
+
+// Success.
+echo "File $target was updated\n";
+exit(0);
index f0bee31..c2d08d1 100644 (file)
@@ -139,6 +139,8 @@ define('CACHE_DISABLE_ALL', true);
 
 define('PHPUNIT_TEST', false);
 
+define('IGNORE_COMPONENT_CACHE', true);
+
 // Check that PHP is of a sufficient version
 if (version_compare(phpversion(), "5.3.3") < 0) {
     $phpversion = phpversion();
index 9ac6931..5547b56 100644 (file)
@@ -34,6 +34,7 @@ if (function_exists('opcache_reset')) {
 
 // Is not really necessary but adding it as is a CLI_SCRIPT.
 define('CLI_SCRIPT', true);
+define('CACHE_DISABLE_ALL', true);
 
 // Basic functions.
 require_once(__DIR__ . '/../../../../lib/clilib.php');
index b28f4fc..cef4ea7 100644 (file)
@@ -84,6 +84,7 @@ define('BEHAT_UTIL', true);
 define('CLI_SCRIPT', true);
 define('ABORT_AFTER_CONFIG', true);
 define('NO_OUTPUT_BUFFERING', true);
+define('IGNORE_COMPONENT_CACHE', true);
 
 error_reporting(E_ALL | E_STRICT);
 ini_set('display_errors', '1');
index a3d875d..eb807ee 100644 (file)
@@ -32,6 +32,8 @@ if (function_exists('opcache_reset')) {
     opcache_reset();
 }
 
+define('IGNORE_COMPONENT_CACHE', true);
+
 require_once(__DIR__.'/../../../../lib/clilib.php');
 require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
 require_once(__DIR__.'/../../../../lib/testing/lib.php');
index 035ce7b..be593a2 100644 (file)
@@ -28,6 +28,8 @@ if (isset($_SERVER['REMOTE_ADDR'])) {
     die; // no access from web!
 }
 
+define('IGNORE_COMPONENT_CACHE', true);
+
 require_once(__DIR__.'/../../../../lib/clilib.php');
 require_once(__DIR__.'/../../../../lib/phpunit/bootstraplib.php');
 require_once(__DIR__.'/../../../../lib/testing/lib.php');
index 6f4e680..da8fe67 100644 (file)
@@ -117,6 +117,8 @@ class cache implements cache_loader {
     /**
      * An array containing just the keys being used in the persist cache.
      * This seems redundant perhaps but is used when managing the size of the persist cache.
+     * Items are added to the end of the array and the when we need to reduce the size of the cache we use the
+     * key that is first on this array.
      * @var array
      */
     private $persistkeys = array();
@@ -965,6 +967,15 @@ class cache implements cache_loader {
             if ($this->perfdebug) {
                 cache_helper::record_cache_hit('** static persist **', $this->definition->get_id());
             }
+            if ($this->persistmaxsize > 1 && $this->persistcount > 1) {
+                // Check to see if this is the last item on the persist keys array.
+                if (end($this->persistkeys) !== $key) {
+                    // It isn't the last item.
+                    // Move the item to the end of the array so that it is last to be removed.
+                    unset($this->persistkeys[$key]);
+                    $this->persistkeys[$key] = $key;
+                }
+            }
             return $result;
         } else {
             if ($this->perfdebug) {
@@ -989,6 +1000,7 @@ class cache implements cache_loader {
         $this->persistcache[$key] = $data;
         if ($this->persistmaxsize !== false) {
             $this->persistcount++;
+            $this->persistkeys[$key] = $key;
             if ($this->persistcount > $this->persistmaxsize) {
                 $dropkey = array_shift($this->persistkeys);
                 unset($this->persistcache[$dropkey]);
index 950b39a..f591b00 100644 (file)
@@ -47,6 +47,7 @@ define('CLI_SCRIPT', false); // prevents some warnings later
 define('AJAX_SCRIPT', false); // prevents some warnings later
 define('CACHE_DISABLE_ALL', true); // Disables caching.. just in case.
 define('PHPUNIT_TEST', false);
+define('IGNORE_COMPONENT_CACHE', true);
 
 // Servers should define a default timezone in php.ini, but if they don't then make sure something is defined.
 // This is a quick hack.  Ideally we should ask the admin for a value.  See MDL-22625 for more on this.
index 0c7a8fa..29391cd 100644 (file)
@@ -79,20 +79,44 @@ class core_component {
             return;
         }
 
-        if (PHPUNIT_TEST or !empty($CFG->early_install_lang) or
-                (defined('BEHAT_UTIL') and BEHAT_UTIL) or
-                (defined('BEHAT_TEST') and BEHAT_TEST)) {
-            // 1/ Do not bother storing the file for unit tests,
-            //    we need fresh copy for each execution and
-            //    later we keep it in memory.
-            // 2/ We can not write to dataroot in installer yet.
+        if (defined('IGNORE_COMPONENT_CACHE') and IGNORE_COMPONENT_CACHE) {
             self::fill_all_caches();
             return;
         }
 
-        // Note: cachedir MUST be shared by all servers in a cluster, sorry guys...
-        //       MUC should use classloading, we can not depend on it here.
-        $cachefile = "$CFG->cachedir/core_component.php";
+        if (!empty($CFG->alternative_component_cache)) {
+            // Hack for heavily clustered sites that want to manage component cache invalidation manually.
+            $cachefile = $CFG->alternative_component_cache;
+
+            if (file_exists($cachefile)) {
+                if (CACHE_DISABLE_ALL) {
+                    // Verify the cache state only on upgrade pages.
+                    $content = self::get_cache_content();
+                    if (sha1_file($cachefile) !== sha1($content)) {
+                        die('Outdated component cache file defined in $CFG->alternative_component_cache, can not continue');
+                    }
+                    return;
+                }
+                $cache = array();
+                include($cachefile);
+                self::$plugintypes = $cache['plugintypes'];
+                self::$plugins     = $cache['plugins'];
+                self::$subsystems  = $cache['subsystems'];
+                self::$classmap    = $cache['classmap'];
+                return;
+            }
+
+            if (!is_writable(dirname($cachefile))) {
+                die('Can not create alternative component cache file defined in $CFG->alternative_component_cache, can not continue');
+            }
+
+            // Lets try to create the file, it might be in some writable directory or a local cache dir.
+
+        } else {
+            // Note: $CFG->cachedir MUST be shared by all servers in a cluster,
+            //       use $CFG->alternative_component_cache if you do not like it.
+            $cachefile = "$CFG->cachedir/core_component.php";
+        }
 
         if (!CACHE_DISABLE_ALL and !self::is_developer()) {
             // 1/ Use the cache only outside of install and upgrade.
@@ -105,7 +129,7 @@ class core_component {
                 } else if (!isset($cache['plugintypes']) or !isset($cache['plugins']) or !isset($cache['subsystems']) or !isset($cache['classmap'])) {
                     // Something is very wrong.
                 } else if ($cache['plugintypes']['mod'] !== "$CFG->dirroot/mod") {
-                    // Dirroot was changed.
+                    // $CFG->dirroot was changed.
                 } else {
                     // The cache looks ok, let's use it.
                     self::$plugintypes = $cache['plugintypes'];
@@ -114,17 +138,12 @@ class core_component {
                     self::$classmap    = $cache['classmap'];
                     return;
                 }
+                // Note: we do not verify $CFG->admin here intentionally,
+                //       they must visit admin/index.php after any change.
             }
         }
 
-        $cachedir = dirname($cachefile);
-        if (!is_dir($cachedir)) {
-            mkdir($cachedir, $CFG->directorypermissions, true);
-        }
-
         if (!isset(self::$plugintypes)) {
-            self::fill_all_caches();
-
             // This needs to be atomic and self-fixing as much as possible.
 
             $content = self::get_cache_content();
@@ -132,9 +151,15 @@ class core_component {
                 if (sha1_file($cachefile) === sha1($content)) {
                     return;
                 }
+                // Stale cache detected!
                 unlink($cachefile);
             }
 
+            $cachedir = dirname($cachefile);
+            if (!is_dir($cachedir)) {
+                mkdir($cachedir, $CFG->directorypermissions, true);
+            }
+
             if ($fp = @fopen($cachefile.'.tmp', 'xb')) {
                 fwrite($fp, $content);
                 fclose($fp);
@@ -157,11 +182,16 @@ class core_component {
     protected static function is_developer() {
         global $CFG;
 
-        if (!isset($CFG->config_php_settings['debug'])) {
+        if (isset($CFG->config_php_settings['debug'])) {
+            // Standard moodle script.
+            $debug = (int)$CFG->config_php_settings['debug'];
+        } else if (isset($CFG->debug)) {
+            // Usually script with ABORT_AFTER_CONFIG.
+            $debug = (int)$CFG->debug;
+        } else {
             return false;
         }
 
-        $debug = (int)$CFG->config_php_settings['debug'];
         if ($debug & E_ALL and $debug & E_STRICT) {
             return true;
         }
@@ -172,9 +202,15 @@ class core_component {
     /**
      * Create cache file content.
      *
+     * @private this is intended for $CFG->alternative_component_cache only.
+     *
      * @return string
      */
-    protected static function get_cache_content() {
+    public static function get_cache_content() {
+        if (!isset(self::$plugintypes)) {
+            self::fill_all_caches();
+        }
+
         $cache = array(
             'subsystems'  => self::$subsystems,
             'plugintypes' => self::$plugintypes,
index 50ca446..37c5f3f 100644 (file)
@@ -312,6 +312,11 @@ function css_minify_css($files) {
         return '';
     }
 
+    // We do not really want any 304 here!
+    // There does not seem to be any better way to prevent them here.
+    unset($_SERVER['HTTP_IF_NONE_MATCH']);
+    unset($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+
     set_include_path($CFG->libdir . '/minify/lib' . PATH_SEPARATOR . get_include_path());
     require_once('Minify.php');
 
@@ -340,7 +345,7 @@ function css_minify_css($files) {
     $error = 'unknown';
     try {
         $result = Minify::serve('Files', $options);
-        if ($result['success']) {
+        if ($result['success'] and $result['statusCode'] == 200) {
             return $result['content'];
         }
     } catch (Exception $e) {
index 90fd929..980837e 100644 (file)
@@ -30,12 +30,13 @@ $definitions = array(
 
     // Used to store processed lang files.
     // The keys used are the component of the string file.
+    // The persistent max size has been based upon student access of the site.
     'string' => array(
         'mode' => cache_store::MODE_APPLICATION,
         'simplekeys' => true,
         'simpledata' => true,
         'persistent' => true,
-        'persistentmaxsize' => 3
+        'persistentmaxsize' => 30
     ),
 
     // Used to store database meta information.
@@ -48,7 +49,7 @@ $definitions = array(
             'dbfamily'
         ),
         'persistent' => true,
-        'persistentmaxsize' => 2
+        'persistentmaxsize' => 15
     ),
 
     // Event invalidation cache.
@@ -78,7 +79,7 @@ $definitions = array(
 
     // HTML Purifier cache
     // This caches the html purifier cleaned text. This is done because the text is usually cleaned once for every user
-    // and context combo. Text caching handles caching for the combonation, this cache is responsible for caching the
+    // and context combo. Text caching handles caching for the combination, this cache is responsible for caching the
     // cleaned text which is shareable.
     'htmlpurifier' => array(
         'mode' => cache_store::MODE_APPLICATION,
index 0593812..6dee621 100644 (file)
@@ -40,6 +40,10 @@ if (ini_get('opcache.enable') and strtolower(ini_get('opcache.enable')) !== 'off
     }
 }
 
+if (!defined('IGNORE_COMPONENT_CACHE')) {
+    define('IGNORE_COMPONENT_CACHE', true);
+}
+
 require_once(__DIR__.'/bootstraplib.php');
 require_once(__DIR__.'/../testing/lib.php');
 require_once(__DIR__.'/classes/autoloader.php');
index fb6ff3b..fd4c32b 100644 (file)
@@ -824,6 +824,7 @@ class plugin_manager {
 
             'tinymce' => array(
                 'ctrlhelp', 'dragmath', 'moodleemoticon', 'moodleimage', 'moodlemedia', 'moodlenolink', 'spellchecker',
+                'pdw', 'wrap'
             ),
 
             'theme' => array(
index 5e00ac4..3b62b76 100644 (file)
@@ -243,7 +243,7 @@ class workshop_manual_allocator implements workshop_allocator {
         $reviewers = array();
         if ($submissions) {
             list($submissionids, $params) = $DB->get_in_or_equal(array_keys($submissions), SQL_PARAMS_NAMED);
-            $picturefields = user_picture::fields('r', array(), 'reviewerid')
+            $picturefields = user_picture::fields('r', array(), 'reviewerid');
             $sql = "SELECT a.id AS assessmentid, a.submissionid, $picturefields,
                            s.id AS submissionid, s.authorid
                       FROM {workshop_assessments} a
index 09445b7..8920a08 100644 (file)
@@ -29,7 +29,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$version  = 2013071200.00;              // YYYYMMDD      = weekly release date of this DEV branch
+$version  = 2013071500.00;              // YYYYMMDD      = weekly release date of this DEV branch
                                         //         RR    = release increments - 00 in DEV branches
                                         //           .XX = incremental changes