source: t29-www/lib/ressourceloader.php @ 301

Last change on this file since 301 was 301, checked in by sven, 7 years ago

Zwei grosse Bugfixes die einige Backendänderungen nach sich zogen:

  • Impressum: Google Maps-Karte lädt wieder. Dafür wurde endlich ein seitenspezifisches Scriptsystem geschrieben, welches im RessourceLoader verankert Scriptfiles direkt einbindet. Das ermöglicht besseres Debugging, bessere Ladezeit und eine Symmetrie zu seitenspezifischen CSS. Insbesondere aber (bislang eher dreckige) Hooks, mit denen externe Scripts eingebunden werden können, was per pagescripts.js nicht geht. pagescripts.js gibts für kleine Scripte immernoch, könnte man dann ggf. auflösen.
  • Relationale Rücklinks für Geräteseiten: Geräteseiten haben nun wie ehemals einen Rücklink auf die verweisende Seite. Dieser wird anhand ihrer Einordnung in der Navigation erlangt. Bei Seiten, die nicht klar einzuordnen waren, könnte dieses Vorgehen ggf. Fehler erzeugen. Das müsste man dann im Einzelfall überprüfen.
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1<?php
2/**
3 * t29RessourceLoader classes.
4 *
5 * The t29 ressource loading system features full caching, directory file input,
6 * OOP style file type specific functions, pre/post per file injection hooks
7 * (AOP style) and post output content filtering where compression tools for
8 * JavaScript and CSS are used.
9 *
10 * The architecture and compression technique is highly inspired by the
11 * RessourceLoader framework of MediaWiki 1.20.
12 *
13 * These classes make usage of class inheritance, heavy PHP output buffering, the
14 * t29v6 caching subsystem and the general t29v6 variable convencience.
15 *
16 * This file defines classes t29{,JavaScript,StyleSheet}RessourceLoader.
17 * Libs JavaScriptMinifier.php and CSSMin.php are included on per-method
18 * level for minification.
19 *
20 * 2012 Sven Koeppel
21 *
22 **/
23 
24/*
25// test it:
26$lib = dirname(__FILE__);
27$webroot = realpath("$lib/../");
28$js = t29RessourceLoader::create_from_type('css');
29$js->run();
30*/
31
32class t29RessourceLoader {
33        /**
34         * expects: type, cache_file, module_dir, page_dir, glob_pattern, content_types, class, modules, debug
35         **/
36        public $conf;
37       
38        const default_include_url = '/lib/loader.php'; // rel to webroot
39       
40        /**
41         * Construct with configuration array. See loader.php for contents of
42         * that array. See above for minimum elements which must be present.
43         * @param $conf Configuration array
44         **/
45        function __construct($conf) {
46                $this->conf = $conf;
47                $this->conf['filenames'] = array_map('basename', $this->conf['modules']); // filenames like foo.js
48        }
49       
50        private static $conf_for_type;
51        static function create_from_type($type, $baseconf=null) {
52                global $lib, $webroot;
53                if(!self::$conf_for_type) {
54                        define('T29_GRAB_LOADER_DEFS', true);
55                        include "$lib/loader.php";
56                        self::$conf_for_type = $conf_for_type;
57                }
58
59                $conf = call_user_func(self::$conf_for_type, $type, isset($baseconf['debug']) && $baseconf['debug']);
60                if($conf === null) return null;
61               
62                return new $conf['class']($conf);
63        }
64       
65        function get_page_specific_urls($seiten_id) {
66                global $webroot;
67                $file = sprintf("%s/%s.%s", $this->conf['page_dir'], $seiten_id, $this->conf['type']);
68                // TODO: This is hacky. Same in get_urls.
69                $file_rel2webroot = str_replace($webroot, '', $file);
70                return file_exists($file) ? array($file_rel2webroot) : array();
71        }
72       
73        function get_urls($debug=null) {
74                global $webroot;
75                if(($debug !== null && $debug) || !$this->conf['debug']) {
76                        return array(self::default_include_url . '?type=' . $this->conf['type']);
77                } else {
78                        $module_dir_rel2webroot = str_replace($webroot, '', $this->conf['module_dir']);
79                        return array_map(function($i)use($module_dir_rel2webroot){ return $module_dir_rel2webroot.$i; }, $this->conf['filenames']);
80                }
81        }
82       
83        /**
84         * Print out debug messages, only if debug switch is given.
85         **/
86        protected function print_debug($string) {
87                if($this->conf['debug'])
88                        echo $string;
89        }
90
91        /**
92         * Module hooking: By overwriting this method and looking at $mod_filename,
93         * you can inject any output before that given file.
94         *
95         * Example:
96         *  class YourRessourceLoader extends t29RessourceLoader {[
97         *     function print_before_file($file, $i) {
98         *         parent::print_before_file($file, $i);
99         *         print "Make a boo boo loading the ${i}. file named ${file}!";
100         *     }
101         *  }
102         * This will prepend that string before the output of the file.
103         *
104         * Always call the parent function when overwriting so that output is printed,
105         * too! (See example)
106         *
107         * @param $mod_filename Filename of module, like "foo.js".
108         * @param $dir_index Iteration index while traversing the directory (see run()). Not so important.
109         * @returns String that
110         **/
111        function print_before_file($mod_filename, $dir_index) {
112                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: Start of $mod_filename ***/\n\n");
113        }
114
115        /**
116         * Same as print_before_file but will append your content to the file.
117         * Obey calling parent::print_after_file at first so that corrections in
118         * the super class can be done!
119         *
120         * The implementation in t29RessourceLoader prints some newlines to make sure
121         * JavaScript oneliner comments at the end of a file won't comment out another
122         * file's first line.
123         *
124         **/
125        function print_after_file($mod_filename, $dir_index) {
126                echo "\n\n"; // JS: for being sure no former "//" comment in last line wipes out code
127                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: End of $mod_filename ***/\n\n");
128        }
129
130        /**
131         * A generic print_header function which will be called at first. Give out some
132         * stuff you want to prepend to your overall output. This method provides you a
133         * generic JS/CSS compilant message where you can give your own $title string
134         * or use no title (it will use your class name instead). If called with $title != null,
135         * the C++ style multi line comment won't be closed so you can append your own
136         * stuff.
137         **/
138        function print_header($title=null) {
139                if(!$title) $title = __CLASS__;
140                ?>
141/*!
142 * t29v6 <?=$title; ?> - http://technikum29.de/
143 * $Id: ressourceloader.php 301 2012-09-19 22:18:45Z sven $
144 *
145 * Copyright 2012, Sven Koeppel <sven@te...29.de>
146 * Licensed under any of Apache, MIT, GPL, LGPL
147 *
148 * Packed: <?php echo implode(' ', $this->conf['filenames']); ?> 
149 * Arguments: ?debug=true - skip cache and just cat everything
150 *            ?purge_cache=true - force rebuild of compressed cache file
151 * Gen Date: <?php echo date('r'), PHP_EOL;
152                if($title == __CLASS__) print " **/\n";
153        }
154       
155        /**
156         * The main run() function will print out the header and concatenate all
157         * modules contents. Expects OutputBuffering running!
158         **/
159        function run() {
160                $this->print_header();
161                $this->conf['header'] = ob_get_contents(); // for prepending it to minified code
162
163                foreach($this->conf['modules'] as $i => $mod) {
164                        $modfile = $this->conf['filenames'][$i];
165                        $this->print_before_file($modfile, $i);
166                        readfile($mod);
167                        $this->print_after_file($modfile, $i);
168                }
169        } // run
170
171        /**
172         * Overwrite compression_filter for filtering the whole output made by this
173         * class. It is used as a shutdown filter in t29Cache, see usage in loader.php.
174         * @param $output The output string fetched by OutputBuffering
175         * @returns The filtered String. The default implementation just returns $output.
176         **/
177        function compression_filter($output) {
178                return $output;
179        }
180} // class t29RessourceLoader
181
182
183class t29JavaScriptRessourceLoader extends t29RessourceLoader {
184        function print_after_file($mod_filename, $dir_index) {
185                global $lib;
186                parent::print_after_file($mod_filename, $dir_index);
187                if($mod_filename == "msg.js") {
188                        // append system messages to the special msg.js file
189                        // to inject PHP code to JS userspace.
190                        $this->print_debug("\n/*** Auto appended ***/\n");
191                        require "$lib/messages.php";
192                        echo "t29.msg.data=";
193                        echo t29Messages::create_json('/^js-/');
194                        echo ";\n";
195                }
196        }
197       
198        function get_page_specific_urls($seiten_id) {
199                $urls = parent::get_page_specific_urls($seiten_id);
200                switch($seiten_id) {
201                        case 'impressum':
202                                $urls[] = 'http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAAraTKZ5cINardZ8ITNVssKhRcOoEBtCgYLJRQznXYEV8m1M3fRRRT9wMSvFwhyo62fD3KyiwQxe5ruw';
203                                break;
204                }
205                return $urls;
206        }
207
208        function print_header($title=null) {
209                parent::print_header('JavaScript Code');
210                echo " * Depends heavily on jQuery\n **/\n";
211        }
212       
213        function compression_filter($code) {
214                global $lib;
215                // reduces code size about 1/2 - before: 23kB, after: 12kB
216                require "$lib/JavaScriptMinifier.php";
217                $minified = JavaScriptMinifier::minify($code);
218                return $this->conf['header'] . $minified;
219        }
220} // class t29JavaScriptRessourceLoader
221
222class t29StyleSheetRessourceLoader extends t29RessourceLoader {
223        function print_header($title=null) {
224                parent::print_header('StyleSheet');
225                echo " **/\n";
226        }
227
228        function compression_filter($code) {
229                global $lib;
230                require "$lib/CSSMin.php";
231                # compression: 40kb to 16kb
232                $minified = CSSMin::minify($code);
233                return $this->conf['header'] . $minified;
234               
235        }
236} // t29StyleSheetRessourceLoader
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License