From 217e523d883f31566576ffec19b742ca540f714a Mon Sep 17 00:00:00 2001 From: Philipp Memmel Date: Wed, 11 Sep 2024 15:18:14 +0200 Subject: [PATCH] Add delivering styles from database --- classes/local/hook_callbacks.php | 35 ++++++++++++++++++++++++++++++++ classes/local/utils.php | 35 ++++++++++++++++++++++++++++++++ db/caches.php | 32 +++++++++++++++++++++++++++++ db/hooks.php | 32 +++++++++++++++++++++++++++++ lib.php | 33 +++++++++++++++++++++++++++--- version.php | 2 +- 6 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 classes/local/hook_callbacks.php create mode 100644 db/caches.php create mode 100644 db/hooks.php diff --git a/classes/local/hook_callbacks.php b/classes/local/hook_callbacks.php new file mode 100644 index 0000000..11bd563 --- /dev/null +++ b/classes/local/hook_callbacks.php @@ -0,0 +1,35 @@ +. + +namespace tiny_c4l\local; + +use core\hook\output\before_http_headers; + +/** + * Class containing the hook callbacks for tiny_c4l. + * + * @package tiny_c4l + * @copyright 2024 ISB Bayern + * @author Philipp Memmel + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class hook_callbacks { + + public static function add_c4l_stylesheet_to_dom(\core\hook\output\before_http_headers $beforehttpheadershook): void { + $pluginfileurl = \moodle_url::make_pluginfile_url(SYSCONTEXTID, 'tiny_c4l', '', null, '', 'tiny_c4l_styles.css'); + $beforehttpheadershook->renderer->get_page()->requires->css($pluginfileurl); + } +} diff --git a/classes/local/utils.php b/classes/local/utils.php index f813ba2..50fca8b 100644 --- a/classes/local/utils.php +++ b/classes/local/utils.php @@ -26,6 +26,12 @@ */ class utils { + public const TINY_C4L_CACHE_AREA = 'tiny_c4l_css'; + + public const TINY_C4L_CSS_CACHE_KEY = 'css'; + + public const TINY_C4L_CSS_CACHE_REV= 'cssrev'; + public static function get_all_components(): array { global $DB; $componentrecords = $DB->get_records('tiny_c4l_component'); @@ -60,4 +66,33 @@ public static function get_all_flavors(): array { $flavors = $DB->get_records('tiny_c4l_flavor'); return array_values($flavors); } + + public static function get_complete_css_as_string(): array { + global $DB; + $cache = \cache::make('tiny_c4l', self::TINY_C4L_CACHE_AREA); + $css = ''; + if (!$cache->has(self::TINY_C4L_CSS_CACHE_REV)) { + $componentcssentries = $DB->get_fieldset('tiny_c4l_component', 'css'); + $categorycssentries = $DB->get_fieldset('tiny_c4l_compcat', 'css'); + $flavorcssentries = $DB->get_fieldset('tiny_c4l_flavor', 'css'); + $cssentries = array_merge($categorycssentries, $componentcssentries, $flavorcssentries); + $css = array_reduce($cssentries, fn($current, $add) => $current . PHP_EOL . $add, ''); + if (empty($css)) { + $css = '// This file contains the stylesheet for the tiny_c4l plugin.'; + } + $clock = \core\di::get(\core\clock::class); + $rev = $clock->time(); + $cache->set(self::TINY_C4L_CSS_CACHE_KEY, $css); + $cache->set(self::TINY_C4L_CSS_CACHE_REV, $rev); + } else { + $css = $cache->get(self::TINY_C4L_CSS_CACHE_KEY); + $rev = $cache->get(self::TINY_C4L_CSS_CACHE_REV); + } + return [$css, $rev]; + } + + public static function purge_css_cache(): void { + $cache = \cache::make('tiny_c4l', self::TINY_C4L_CACHE_AREA); + $cache->delete(self::TINY_C4L_CSS_CACHE_REV); + } } diff --git a/db/caches.php b/db/caches.php new file mode 100644 index 0000000..2f7be36 --- /dev/null +++ b/db/caches.php @@ -0,0 +1,32 @@ +. + +/** + * Cache definitions for tiny_c4l. + * + * @package tiny_c4l + * @copyright 2024 ISB Bayern + * @author Philipp Memmel + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$definitions = [ + \tiny_c4l\local\utils::TINY_C4L_CACHE_AREA => [ + 'mode' => cache_store::MODE_APPLICATION, + ], +]; diff --git a/db/hooks.php b/db/hooks.php new file mode 100644 index 0000000..d683bca --- /dev/null +++ b/db/hooks.php @@ -0,0 +1,32 @@ +. + +/** + * Hook callbacks for tiny_c4l. + * + * @package tiny_c4l + * @copyright 2024 ISB Bayern + * @author Philipp Memmel + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +defined('MOODLE_INTERNAL') || die(); + +$callbacks = [ + [ + 'hook' => \core\hook\output\before_http_headers::class, + 'callback' => \tiny_c4l\local\hook_callbacks::class . '::add_c4l_stylesheet_to_dom', + ], +]; diff --git a/lib.php b/lib.php index e85696d..a05dff7 100644 --- a/lib.php +++ b/lib.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +use tiny_c4l\local\utils; + defined('MOODLE_INTERNAL') || die(); /** @@ -33,10 +35,35 @@ function tiny_c4l_user_preferences() { $preferences = []; $preferences['c4l_components_variants'] = array( - 'type' => PARAM_RAW, - 'null' => NULL_NOT_ALLOWED, - 'default' => '' + 'type' => PARAM_RAW, + 'null' => NULL_NOT_ALLOWED, + 'default' => '' ); return $preferences; } + +/** + * Serve the requested file for the tiny_c4l plugin. + * + * @param stdClass $course the course object + * @param stdClass $cm the course module object + * @param stdClass $context the context + * @param string $filearea the name of the file area + * @param array $args extra arguments (itemid, path) + * @param bool $forcedownload whether or not force download + * @param array $options additional options affecting the file serving + * @return bool false if the file not found, just send the file otherwise and do not return anything + */ +function tiny_c4l_pluginfile( + $course, + $cm, + $context, + string $filearea, + array $args, + bool $forcedownload, + array $options +): bool { + [$css, $rev] = utils::get_complete_css_as_string(); + send_file($css, 'tiny_c4l_styles.css?rev=' . $rev, null, 0, true, false, 'text/css'); +} diff --git a/version.php b/version.php index aae01cc..dad562c 100644 --- a/version.php +++ b/version.php @@ -28,4 +28,4 @@ $plugin->release = '2.1.1'; $plugin->requires = 2022112800; $plugin->maturity = MATURITY_STABLE; -$plugin->version = 2024090302; +$plugin->version = 2024091101;