From 0139ec3fe6f658d6f2a3579ad0119c53641d9617 Mon Sep 17 00:00:00 2001 From: Petr Skoda Date: Sun, 7 Feb 2010 12:50:53 +0000 Subject: [PATCH] MDL-21400 finally, gzip for JS files and proper caching - without admin UI for now (off by default) --- lib/javascript.php | 64 +++++++++++++++++++++++++++++++++++ lib/outputrequirementslib.php | 28 +++++++++++---- lib/upgradelib.php | 23 +++++++++---- lib/weblib.php | 2 +- 4 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 lib/javascript.php diff --git a/lib/javascript.php b/lib/javascript.php new file mode 100644 index 00000000000..9f75bafe394 --- /dev/null +++ b/lib/javascript.php @@ -0,0 +1,64 @@ +. + +/** + * This file is serving optimised JS + * + * @package moodlecore + * @copyright 2010 Petr Skoda (skodak) + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +// we need just the values from config.php and minlib.php +define('ABORT_AFTER_CONFIG', true); +require('../config.php'); // this stops immediately at the beginning of lib/setup.php + +$file = min_optional_param('file', '', 'SAFEPATH'); +$rev = min_optional_param('rev', 0, 'INT'); + +if (empty($file) or strpos($file, '/') !== 0 or !preg_match('/\.js$/', $file)) { + die; +} + +$jspath = $CFG->dirroot.$file; + +if (file_exists($jspath)) { + send_cached_js($jspath); +} + + +//================================================================================= +//=== utility functions == +// we are not using filelib because we need to fine tune all header +// parameters to get the best performance. + +function send_cached_js($jspath) { + $lifetime = 60*60*24*20; + + header('Content-Disposition: inline; filename="javascript.php"'); + header('Last-Modified: '. gmdate('D, d M Y H:i:s', filemtime($jspath)) .' GMT'); + header('Expires: '. gmdate('D, d M Y H:i:s', time() + $lifetime) .' GMT'); + header('Pragma: '); + header('Accept-Ranges: none'); + header('Content-Type: application/x-javascript'); + if (!min_enable_zlib_compression()) { + header('Content-Length: '.filesize($jspath)); + } + + readfile($jspath); + die; +} diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index bffad42963a..c908ad7ff31 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -194,6 +194,7 @@ class page_requirements_manager { foreach ($modules as $name=>$module) { $module['fullpath'] = $urlbase.$module['path']; // fix path to point to correct location unset($module['path']); + unset($module['skinnable']); // we load all YUI2 css automatically, this prevents weird missing css loader problems foreach(array('requires', 'optional', 'supersedes') as $fixme) { if (!empty($module[$fixme])) { $fixed = false; @@ -314,8 +315,11 @@ class page_requirements_manager { throw new coding_exception('Attept to require a JavaScript file that does not exist.', $url); } } - //return new moodle_url($CFG->httpswwwroot.'/lib/javascript.php', array('file'=>$url, 'rev'=>$CFG->jsrev)); - return new moodle_url($CFG->httpswwwroot.$url); + if (!empty($CFG->cachejs) and !empty($CFG->jsrev)) { + return new moodle_url($CFG->httpswwwroot.'/lib/javascript.php', array('file'=>$url, 'rev'=>$CFG->jsrev)); + } else { + return new moodle_url($CFG->httpswwwroot.$url); + } } else { throw new coding_exception('Invalid JS url, it has to be shortened url starting with / or moodle_url instance.', $url); } @@ -374,7 +378,7 @@ class page_requirements_manager { case 'core_calendar': $module = array('name' => 'core_calendar', 'fullpath' => '/calendar/calendar.js', - 'requires' => array('dom', 'event', 'node', 'yui2-container','event-mouseenter')); + 'requires' => array('dom', 'event', 'node', 'yui2-container', 'event-mouseenter')); break; case 'core_message': $module = array('name' => 'core_message', @@ -860,7 +864,7 @@ class page_requirements_manager { $output .= html_writer::script($js); // link our main JS file, all core stuff should be there - $output .= html_writer::script('', $CFG->httpswwwroot.'/lib/javascript-static.js'); + $output .= html_writer::script('', $this->js_fix_url('/lib/javascript-static.js')); // add variables if ($this->jsinitvariables['head']) { @@ -952,8 +956,7 @@ class page_requirements_manager { $jsinit = $this->get_javascript_init_code(); $handlersjs = $this->get_event_handler_code(); - // the global Y can be used only after it is fully loaded, that means - // from code executed from the following block + // there is no global Y, make sure it is available in your scope $js = "YUI(M.yui.loader).use('node', function(Y) {\n{$inyuijs}{$ondomreadyjs}{$jsinit}{$handlersjs}\n});"; $output .= html_writer::script($js); @@ -975,3 +978,16 @@ class page_requirements_manager { return $this->topofbodydone; } } + +/** + * Invalidate all server and client side JS caches. + * @return void + */ +function js_reset_all_caches() { + global $CFG; + require_once("$CFG->libdir/filelib.php"); + + set_config('jsrev', empty($CFG->jsrev) ? 1 : $CFG->jsrev+1); + //fulldelete("$CFG->dataroot/cache/js"); +} + diff --git a/lib/upgradelib.php b/lib/upgradelib.php index 2b825dad14f..3e83335dbe1 100644 --- a/lib/upgradelib.php +++ b/lib/upgradelib.php @@ -369,7 +369,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); $endcallback($component, true, $verbose); } else if ($installedversion < $plugin->version) { // upgrade @@ -398,7 +398,7 @@ function upgrade_plugins($type, $startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); $endcallback($component, false, $verbose); } else if ($installedversion > $plugin->version) { @@ -497,7 +497,7 @@ function upgrade_plugins_modules($startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); $endcallback($component, true, $verbose); } else if ($currmodule->version < $module->version) { @@ -525,7 +525,7 @@ function upgrade_plugins_modules($startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); remove_dir($CFG->dataroot.'/cache', true); // flush cache $endcallback($component, false, $verbose); @@ -652,7 +652,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); $endcallback($component, true, $verbose); } else if ($currblock->version < $block->version) { @@ -685,7 +685,7 @@ function upgrade_plugins_blocks($startcallback, $endcallback, $verbose) { message_update_providers($component); upgrade_plugin_mnet_functions($component); - theme_reset_all_caches(); + upgrade_reset_caches(); $endcallback($component, false, $verbose); } else if ($currblock->version > $block->version) { @@ -1241,7 +1241,7 @@ function upgrade_core($version, $verbose) { events_update_definition('moodle'); message_update_providers('moodle'); - theme_reset_all_caches(); + upgrade_reset_caches(); remove_dir($CFG->dataroot . '/cache', true); // flush cache print_upgrade_part_end('moodle', false, $verbose); @@ -1290,6 +1290,15 @@ function core_tables_exist() { } } +/** + * Invalidates browser caches and cached data in temp + * @return void + */ +function upgrade_reset_caches() { + js_reset_all_caches(); + theme_reset_all_caches(); +} + /** * upgrades the mnet rpc definitions for the given component. * this method doesn't return status, an exception will be thrown in the case of an error diff --git a/lib/weblib.php b/lib/weblib.php index ec972fb527c..1b7346bbade 100644 --- a/lib/weblib.php +++ b/lib/weblib.php @@ -3415,7 +3415,7 @@ function print_password_policy() { function create_ufo_inline($id, $args) { global $CFG; // must not use $PAGE, $THEME, $COURSE etc. because the result is cached! - + // unfortunately this ufo.js can not be cached properly because we do not have access to current $CFG either $jsoutput = html_writer::script('', $CFG->wwwroot.'/lib/ufo.js'); $jsoutput .= html_writer::script(js_writer::function_call('M.util.create_UFO_object', array($id, $args))); return $jsoutput;