Merge branch 'MDL-62621-master-ixcomment' of git://github.com/mudrd8mz/moodle
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 2 Jul 2018 18:00:29 +0000 (20:00 +0200)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Mon, 2 Jul 2018 18:00:29 +0000 (20:00 +0200)
admin/classes/form/purge_caches.php [new file with mode: 0644]
admin/cli/purge_caches.php
admin/purgecaches.php
admin/settings/development.php
admin/tests/behat/purge_caches.feature [new file with mode: 0644]
admin/tool/policy/lib.php
course/classes/search/section.php
lang/en/admin.php
lib/moodlelib.php
lib/outputrenderers.php

diff --git a/admin/classes/form/purge_caches.php b/admin/classes/form/purge_caches.php
new file mode 100644 (file)
index 0000000..3151445
--- /dev/null
@@ -0,0 +1,75 @@
+<?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/>.
+
+/**
+ * Form for selective purging of caches.
+ *
+ * @package    core
+ * @copyright  2018 The Open University
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_admin\form;
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Form for selecting which caches to purge on admin/purgecaches.php
+ *
+ * @package   core
+ * @copyright 2018 The Open University
+ * @author    Mark Johnson <mark.johnson@open.ac.uk>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class purge_caches extends \moodleform {
+    /**
+     * Define a "Purge all caches" button, and a fieldset with checkboxes for selectively purging separate caches.
+     */
+    public function definition() {
+        $mform = $this->_form;
+        $mform->addElement('hidden', 'returnurl', $this->_customdata['returnurl']);
+        $mform->setType('returnurl', PARAM_LOCALURL);
+        $mform->addElement('submit', 'all', get_string('purgecaches', 'admin'));
+        $mform->addElement('header', 'purgecacheheader', get_string('purgeselectedcaches', 'admin'));
+        $checkboxes = [
+            $mform->createElement('advcheckbox', 'theme', '', get_string('purgethemecache', 'admin')),
+            $mform->createElement('advcheckbox', 'lang', '', get_string('purgelangcache', 'admin')),
+            $mform->createElement('advcheckbox', 'js', '', get_string('purgejscache', 'admin')),
+            $mform->createElement('advcheckbox', 'filter', '', get_string('purgefiltercache', 'admin')),
+            $mform->createElement('advcheckbox', 'muc', '', get_string('purgemuc', 'admin')),
+            $mform->createElement('advcheckbox', 'other', '', get_string('purgeothercaches', 'admin'))
+        ];
+        $mform->addGroup($checkboxes, 'purgeselectedoptions');
+        $mform->addElement('submit', 'purgeselectedcaches', get_string('purgeselectedcaches', 'admin'));
+    }
+
+    /**
+     * If the "Purge selected caches" button was pressed, ensure at least one cache was selected.
+     *
+     * @param array $data
+     * @param array $files
+     * @return array Error messages
+     */
+    public function validation($data, $files) {
+        $errors = [];
+        if (isset($data['purgeselectedcaches']) && empty(array_filter($data['purgeselectedoptions']))) {
+            $errors['purgeselectedoptions'] = get_string('purgecachesnoneselected', 'admin');
+        }
+        return $errors;
+    }
+}
index 64f29bd..9846b20 100644 (file)
@@ -28,7 +28,16 @@ define('CLI_SCRIPT', true);
 require(__DIR__.'/../../config.php');
 require_once($CFG->libdir.'/clilib.php');
 
-list($options, $unrecognized) = cli_get_params(array('help' => false), array('h' => 'help'));
+$longoptions = [
+    'help' => false,
+    'muc' => false,
+    'theme' => false,
+    'lang' => false,
+    'js' => false,
+    'filter' => false,
+    'other' => false
+];
+list($options, $unrecognized) = cli_get_params($longoptions, ['h' => 'help']);
 
 if ($unrecognized) {
     $unrecognized = implode("\n  ", $unrecognized);
@@ -36,20 +45,32 @@ if ($unrecognized) {
 }
 
 if ($options['help']) {
-    $help =
-"Invalidates all Moodle internal caches
+    // The indentation of this string is "wrong" but this is to avoid a extra whitespace in console output.
+    $help = <<<EOF
+Invalidates Moodle internal caches
+
+Specific caches can be defined (alone or in combination) using arguments. If none are specified,
+all caches will be purged.
 
 Options:
 -h, --help            Print out this help
+    --muc             Purge all MUC caches (includes lang cache)
+    --theme           Purge theme cache
+    --lang            Purge language string cache
+    --js              Purge JavaScript cache
+    --filter          Purge text filter cache
+    --other           Purge all file caches and other miscellaneous caches (may include MUC
+                      if using cachestore_file).
 
 Example:
-\$sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
-";
+\$ sudo -u www-data /usr/bin/php admin/cli/purge_caches.php
+
+EOF;
 
     echo $help;
     exit(0);
 }
 
-purge_all_caches();
+purge_caches(array_filter($options));
 
 exit(0);
index dd47087..b4401c4 100644 (file)
@@ -27,36 +27,43 @@ require_once('../config.php');
 require_once($CFG->libdir.'/adminlib.php');
 
 $confirm = optional_param('confirm', 0, PARAM_BOOL);
-$returnurl = optional_param('returnurl', null, PARAM_LOCALURL);
+$returnurl = optional_param('returnurl', '/admin/purgecaches.php', PARAM_LOCALURL);
+$returnurl = new moodle_url($returnurl);
 
 admin_externalpage_setup('purgecaches');
 
+$form = new core_admin\form\purge_caches(null, ['returnurl' => $returnurl]);
+
 // If we have got here as a confirmed aciton, do it.
-if ($confirm && confirm_sesskey()) {
+if ($data = $form->get_data()) {
 
     // Valid request. Purge, and redirect the user back to where they came from.
-    purge_all_caches();
+    $selected = $data->purgeselectedoptions;
+    purge_caches($selected);
 
-    if ($returnurl) {
-        $returnurl = $CFG->wwwroot . $returnurl;
+    if (isset($data->all)) {
+        $message = get_string('purgecachesfinished', 'admin');
     } else {
-        $returnurl = new moodle_url('/admin/purgecaches.php');
+        $message = get_string('purgeselectedcachesfinished', 'admin');
     }
-    redirect($returnurl, get_string('purgecachesfinished', 'admin'));
+
+} else if ($confirm && confirm_sesskey()) {
+    purge_caches();
+    $message = get_string('purgecachesfinished', 'admin');
 }
 
-// Otherwise, show a button to actually purge the caches.
-$actionurl = new moodle_url('/admin/purgecaches.php', array('sesskey'=>sesskey(), 'confirm'=>1));
-if ($returnurl) {
-    $actionurl->param('returnurl', $returnurl);
+if (isset($message)) {
+    redirect($returnurl, $message);
 }
 
+// Otherwise, show a form to actually purge the caches.
+
 echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('purgecaches', 'admin'));
+echo $OUTPUT->heading(get_string('purgecachespage', 'admin'));
 
 echo $OUTPUT->box_start('generalbox', 'notice');
 echo html_writer::tag('p', get_string('purgecachesconfirm', 'admin'));
-echo $OUTPUT->single_button($actionurl, get_string('purgecaches', 'admin'), 'post');
+echo $form->render();
 echo $OUTPUT->box_end();
 
 echo $OUTPUT->footer();
index f8dab27..cc2a620 100644 (file)
@@ -83,7 +83,8 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
         $ADMIN->add('development', new admin_externalpage('mnettestclient', new lang_string('testclient', 'mnet'), "$CFG->wwwroot/$CFG->admin/mnet/testclient.php"));
     }
 
-    $ADMIN->add('development', new admin_externalpage('purgecaches', new lang_string('purgecaches','admin'), "$CFG->wwwroot/$CFG->admin/purgecaches.php"));
+    $ADMIN->add('development', new admin_externalpage('purgecaches', new lang_string('purgecachespage', 'admin'),
+            "$CFG->wwwroot/$CFG->admin/purgecaches.php"));
 
     $ADMIN->add('development', new admin_externalpage('thirdpartylibs', new lang_string('thirdpartylibs','admin'), "$CFG->wwwroot/$CFG->admin/thirdpartylibs.php"));
 } // end of speedup
diff --git a/admin/tests/behat/purge_caches.feature b/admin/tests/behat/purge_caches.feature
new file mode 100644 (file)
index 0000000..7f1e805
--- /dev/null
@@ -0,0 +1,34 @@
+@core @core_admin
+Feature: Purge caches
+  In order to see changes to cached data
+  As a Moodle administrator
+  I want manually purge different data and file caches
+
+  Background:
+    Given I log in as "admin"
+    And I navigate to "Development > Purge caches" in site administration
+
+  Scenario: Purge all caches
+    Given I should not see "All caches were purged"
+    When I press "Purge all caches"
+    Then I should see "All caches were purged"
+
+  Scenario: Purge selected caches
+    Given I should not see "Selected caches were purged"
+    When I set the field "Themes" to "1"
+    And I press "Purge selected caches"
+    Then I should see "The selected caches were purged"
+
+  Scenario: Purge selected caches without selecting any caches
+    Given I should not see "Select one or more caches to purge"
+    When I press "Purge selected caches"
+    Then I should not see "The selected caches were purged"
+    And I should see "Select one or more caches to purge"
+
+  Scenario: Redirect back to the original page after following a Purge all caches link
+    Given I am on site homepage
+    And I should see "Available courses"
+    And I should not see "All caches were purged"
+    When I follow "Purge all caches"
+    Then I should see "All caches were purged"
+    And I should see "Available courses"
index 3073212..1fbe958 100644 (file)
@@ -83,7 +83,7 @@ function tool_policy_before_standard_html_head() {
     if (!empty($CFG->sitepolicyhandler)
             && $CFG->sitepolicyhandler == 'tool_policy'
             && empty($USER->policyagreed)
-            && isguestuser()) {
+            && (isguestuser() || !isloggedin())) {
         $output = $PAGE->get_renderer('tool_policy');
         $page = new \tool_policy\output\guestconsent();
 
index 11f6866..ce28664 100644 (file)
@@ -85,6 +85,9 @@ class section extends \core_search\base {
      * @return \core_search\document
      */
     public function get_document($record, $options = array()) {
+        global $CFG;
+        require_once($CFG->dirroot . '/course/lib.php');
+
         // Get the context, modinfo, and section.
         try {
             $context = \context_course::instance($record->course);
index 880a8c5..cf656d3 100644 (file)
@@ -979,6 +979,16 @@ $string['requires'] = 'Requires';
 $string['purgecaches'] = 'Purge all caches';
 $string['purgecachesconfirm'] = 'Moodle can cache themes, javascript, language strings, filtered text, rss feeds and many other pieces of calculated data.  Purging these caches will delete that data from the server and force browsers to refetch data, so that you can be sure you are seeing the most up-to-date values produced by the current code.  There is no danger in purging caches, but your site may appear slower for a while until the server and clients calculate new information and cache it.';
 $string['purgecachesfinished'] = 'All caches were purged.';
+$string['purgecachesnoneselected'] = 'Select one or more caches to purge';
+$string['purgecachespage'] = 'Purge caches';
+$string['purgefiltercache'] = 'Text filters';
+$string['purgejscache'] = 'JavaScript';
+$string['purgelangcache'] = 'Language strings';
+$string['purgemuc'] = 'All MUC caches';
+$string['purgeothercaches'] = 'All file and miscellaneous caches';
+$string['purgeselectedcaches'] = 'Purge selected caches';
+$string['purgeselectedcachesfinished'] = 'The selected caches were purged.';
+$string['purgethemecache'] = 'Themes';
 $string['requestcategoryselection'] = 'Enable category selection';
 $string['restorecourse'] = 'Restore course';
 $string['restorernewroleid'] = 'Restorers\' role in courses';
index 34fe56b..47cf0b1 100644 (file)
@@ -1627,18 +1627,61 @@ function get_users_from_config($value, $capability, $includeadmins = true) {
 /**
  * Invalidates browser caches and cached data in temp.
  *
- * IMPORTANT - If you are adding anything here to do with the cache directory you should also have a look at
- * {@link phpunit_util::reset_dataroot()}
- *
  * @return void
  */
 function purge_all_caches() {
-    global $CFG, $DB;
+    purge_caches();
+}
 
-    reset_text_filters_cache();
-    js_reset_all_caches();
-    theme_reset_all_caches();
-    get_string_manager()->reset_caches();
+/**
+ * Selectively invalidate different types of cache.
+ *
+ * Purges the cache areas specified.  By default, this will purge all caches but can selectively purge specific
+ * areas alone or in combination.
+ *
+ * @param bool[] $options Specific parts of the cache to purge. Valid options are:
+ *        'muc'    Purge MUC caches?
+ *        'theme'  Purge theme cache?
+ *        'lang'   Purge language string cache?
+ *        'js'     Purge javascript cache?
+ *        'filter' Purge text filter cache?
+ *        'other'  Purge all other caches?
+ */
+function purge_caches($options = []) {
+    $defaults = array_fill_keys(['muc', 'theme', 'lang', 'js', 'filter', 'other'], false);
+    if (empty(array_filter($options))) {
+        $options = array_fill_keys(array_keys($defaults), true); // Set all options to true.
+    } else {
+        $options = array_merge($defaults, array_intersect_key($options, $defaults)); // Override defaults with specified options.
+    }
+    if ($options['muc']) {
+        cache_helper::purge_all();
+    }
+    if ($options['theme']) {
+        theme_reset_all_caches();
+    }
+    if ($options['lang']) {
+        get_string_manager()->reset_caches();
+    }
+    if ($options['js']) {
+        js_reset_all_caches();
+    }
+    if ($options['filter']) {
+        reset_text_filters_cache();
+    }
+    if ($options['other']) {
+        purge_other_caches();
+    }
+}
+
+/**
+ * Purge all non-MUC caches not otherwise purged in purge_caches.
+ *
+ * IMPORTANT - If you are adding anything here to do with the cache directory you should also have a look at
+ * {@link phpunit_util::reset_dataroot()}
+ */
+function purge_other_caches() {
+    global $DB, $CFG;
     core_text::reset_caches();
     if (class_exists('core_plugin_manager')) {
         core_plugin_manager::reset_caches();
@@ -1652,7 +1695,6 @@ function purge_all_caches() {
     }
 
     $DB->reset_caches();
-    cache_helper::purge_all();
 
     // Purge all other caches: rss, simplepie, etc.
     clearstatcache();
index 5b50374..24330ac 100644 (file)
@@ -84,8 +84,20 @@ class renderer_base {
             $themename = $this->page->theme->name;
             $themerev = theme_get_revision();
 
+            // Create new localcache directory.
             $cachedir = make_localcache_directory("mustache/$themerev/$themename");
 
+            // Remove old localcache directories.
+            $mustachecachedirs = glob("{$CFG->localcachedir}/mustache/*", GLOB_ONLYDIR);
+            foreach ($mustachecachedirs as $localcachedir) {
+                $cachedrev = [];
+                preg_match("/\/mustache\/([0-9]+)$/", $localcachedir, $cachedrev);
+                $cachedrev = isset($cachedrev[1]) ? intval($cachedrev[1]) : 0;
+                if ($cachedrev > 0 && $cachedrev < $themerev) {
+                    fulldelete($localcachedir);
+                }
+            }
+
             $loader = new \core\output\mustache_filesystem_loader();
             $stringhelper = new \core\output\mustache_string_helper();
             $quotehelper = new \core\output\mustache_quote_helper();