MDL-59150 admin: build site theme after CLI install or upgrade
authorRyan Wyllie <ryan@moodle.com>
Mon, 19 Jun 2017 05:22:58 +0000 (05:22 +0000)
committerRyan Wyllie <ryan@moodle.com>
Tue, 18 Jul 2017 06:13:07 +0000 (06:13 +0000)
admin/cli/install.php
admin/cli/install_database.php
admin/cli/upgrade.php
lib/classes/task/build_installed_themes_task.php [new file with mode: 0644]
lib/classes/task/manager.php
lib/tests/adhoc_task_test.php
lib/tests/fixtures/task_fixtures.php
lib/upgradelib.php

index 0b6c5ca..f8876ca 100644 (file)
@@ -808,6 +808,12 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
 
 if (!$options['skip-database']) {
     install_cli_database($options, $interactive);
+    // This needs to happen at the end to ensure it occurs after all caches
+    // have been purged for the last time.
+    // This will build a cached version of the current theme for the user
+    // to immediately start browsing the site.
+    require_once($CFG->libdir.'/upgradelib.php');
+    upgrade_themes();
 } else {
     echo get_string('cliskipdatabase', 'install')."\n";
 }
index f41263e..af05fc2 100644 (file)
@@ -183,5 +183,12 @@ if (!core_plugin_manager::instance()->all_plugins_ok($version, $failed)) {
 
 install_cli_database($options, true);
 
+// This needs to happen at the end to ensure it occurs after all caches
+// have been purged for the last time.
+// This will build a cached version of the current theme for the user
+// to immediately start browsing the site.
+require_once($CFG->libdir.'/upgradelib.php');
+upgrade_themes();
+
 echo get_string('cliinstallfinished', 'install')."\n";
 exit(0); // 0 means success
index 6de2e13..6c10b9a 100644 (file)
@@ -187,5 +187,11 @@ upgrade_noncore(true);
 admin_apply_default_settings(NULL, false);
 admin_apply_default_settings(NULL, false);
 
+// This needs to happen at the end to ensure it occurs after all caches
+// have been purged for the last time.
+// This will build a cached version of the current theme for the user
+// to immediately start browsing the site.
+upgrade_themes();
+
 echo get_string('cliupgradefinished', 'admin')."\n";
 exit(0); // 0 means success
diff --git a/lib/classes/task/build_installed_themes_task.php b/lib/classes/task/build_installed_themes_task.php
new file mode 100644 (file)
index 0000000..a6195f5
--- /dev/null
@@ -0,0 +1,54 @@
+<?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/>.
+
+/**
+ * Adhoc task that builds and caches all of the site's installed themes.
+ *
+ * @package    core
+ * @copyright  2017 Ryan Wyllie <ryan@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core\task;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Class that builds and caches all of the site's installed themes.
+ *
+ * @package     core
+ * @copyright   2017 Ryan Wyllie <ryan@moodle.com>
+ * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class build_installed_themes_task extends adhoc_task {
+
+    /**
+     * Run the task.
+     */
+    public function execute() {
+        global $CFG;
+        require_once("{$CFG->libdir}/outputlib.php");
+
+        $themenames = array_keys(\core_component::get_plugin_list('theme'));
+        // Load the theme configs.
+        $themeconfigs = array_map(function($themename) {
+            return \theme_config::load($themename);
+        }, $themenames);
+
+        // Build the list of themes and cache them in local cache.
+        theme_build_css_for_themes($themeconfigs);
+    }
+}
index 60a5240..106878b 100644 (file)
@@ -353,6 +353,26 @@ class manager {
         return self::scheduled_task_from_record($record);
     }
 
+    /**
+     * This function load the adhoc tasks for a given classname.
+     *
+     * @param string $classname
+     * @return \core\task\adhoc_task[]
+     */
+    public static function get_adhoc_tasks($classname) {
+        global $DB;
+
+        if (strpos($classname, '\\') !== 0) {
+            $classname = '\\' . $classname;
+        }
+        // We are just reading - so no locks required.
+        $records = $DB->get_records('task_adhoc', array('classname' => $classname));
+
+        return array_map(function($record) {
+            return self::adhoc_task_from_record($record);
+        }, $records);
+    }
+
     /**
      * This function load the default scheduled task details for a given classname.
      *
index 1c4d70a..d1ec1d8 100644 (file)
@@ -109,4 +109,44 @@ class core_adhoc_task_testcase extends advanced_testcase {
         $task->execute();
         \core\task\manager::adhoc_task_complete($task);
     }
+
+    /**
+     * Test empty set of adhoc tasks
+     */
+    public function test_get_adhoc_tasks_empty_set() {
+        $this->resetAfterTest(true);
+
+        $this->assertEquals([], \core\task\manager::get_adhoc_tasks('\\core\\task\\adhoc_test_task'));
+    }
+
+    /**
+     * Test correct set of adhoc tasks is returned for class.
+     */
+    public function test_get_adhoc_tasks_result_set() {
+        $this->resetAfterTest(true);
+
+        for ($i = 0; $i < 3; $i++) {
+            $task = new \core\task\adhoc_test_task();
+            \core\task\manager::queue_adhoc_task($task);
+        }
+
+        for ($i = 0; $i < 3; $i++) {
+            $task = new \core\task\adhoc_test2_task();
+            \core\task\manager::queue_adhoc_task($task);
+        }
+
+        $adhoctests = \core\task\manager::get_adhoc_tasks('\\core\\task\\adhoc_test_task');
+        $adhoctest2s = \core\task\manager::get_adhoc_tasks('\\core\\task\\adhoc_test2_task');
+
+        $this->assertCount(3, $adhoctests);
+        $this->assertCount(3, $adhoctest2s);
+
+        foreach ($adhoctests as $task) {
+            $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task);
+        }
+
+        foreach ($adhoctest2s as $task) {
+            $this->assertInstanceOf('\\core\\task\\adhoc_test2_task', $task);
+        }
+    }
 }
index 6ec619f..ead5003 100644 (file)
@@ -31,6 +31,11 @@ class adhoc_test_task extends \core\task\adhoc_task {
     }
 }
 
+class adhoc_test2_task extends \core\task\adhoc_task {
+    public function execute() {
+    }
+}
+
 class scheduled_test_task extends \core\task\scheduled_task {
     public function get_name() {
         return "Test task";
index 0edd332..cf298f7 100644 (file)
@@ -1664,6 +1664,31 @@ function upgrade_language_pack($lang = null) {
     print_upgrade_separator();
 }
 
+/**
+ * Build the current theme so that the user doesn't have to wait for it
+ * to build on the first page load after the install / upgrade.
+ */
+function upgrade_themes() {
+    global $CFG;
+
+    require_once("{$CFG->libdir}/outputlib.php");
+
+    // Build the current theme so that the user can immediately
+    // browse the site without having to wait for the theme to build.
+    $themeconfig = theme_config::load($CFG->theme);
+    $direction = right_to_left() ? 'rtl' : 'ltr';
+    theme_build_css_for_themes([$themeconfig], [$direction]);
+
+    // Only queue the task if there isn't already one queued.
+    if (empty(\core\task\manager::get_adhoc_tasks('\\core\\task\\build_installed_themes_task'))) {
+        // Queue a task to build all of the site themes at some point
+        // later. These can happen offline because it doesn't block the
+        // user unless they quickly change theme.
+        $adhoctask = new \core\task\build_installed_themes_task();
+        \core\task\manager::queue_adhoc_task($adhoctask);
+    }
+}
+
 /**
  * Install core moodle tables and initialize
  * @param float $version target version