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

Last change on this file since 285 was 285, checked in by heribert, 7 years ago

Überarbeitung der Homepage:

  • Merge-Postfixes (Umbenennungen der Dateien, etc)
  • Design-Details (hr-Linie eingeführt)
  • Bull Gamma 10 aufgespalten in andere Dateien
  • Property svn:keywords set to Id
File size: 7.1 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, 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_urls($debug=null) {
66                global $webroot;
67                if(($debug !== null && $debug) || !$this->conf['debug']) {
68                        return array(self::default_include_url . '?type=' . $this->conf['type']);
69                } else {
70                        $module_dir_rel2webroot = str_replace($webroot, '', $this->conf['module_dir']);
71                        return array_map(function($i)use($module_dir_rel2webroot){ return $module_dir_rel2webroot.$i; }, $this->conf['filenames']);
72                }
73        }
74       
75        /**
76         * Print out debug messages, only if debug switch is given.
77         **/
78        protected function print_debug($string) {
79                if($this->conf['debug'])
80                        echo $string;
81        }
82
83        /**
84         * Module hooking: By overwriting this method and looking at $mod_filename,
85         * you can inject any output before that given file.
86         *
87         * Example:
88         *  class YourRessourceLoader extends t29RessourceLoader {[
89         *     function print_before_file($file, $i) {
90         *         parent::print_before_file($file, $i);
91         *         print "Make a boo boo loading the ${i}. file named ${file}!";
92         *     }
93         *  }
94         * This will prepend that string before the output of the file.
95         *
96         * Always call the parent function when overwriting so that output is printed,
97         * too! (See example)
98         *
99         * @param $mod_filename Filename of module, like "foo.js".
100         * @param $dir_index Iteration index while traversing the directory (see run()). Not so important.
101         * @returns String that
102         **/
103        function print_before_file($mod_filename, $dir_index) {
104                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: Start of $mod_filename ***/\n\n");
105        }
106
107        /**
108         * Same as print_before_file but will append your content to the file.
109         * Obey calling parent::print_after_file at first so that corrections in
110         * the super class can be done!
111         *
112         * The implementation in t29RessourceLoader prints some newlines to make sure
113         * JavaScript oneliner comments at the end of a file won't comment out another
114         * file's first line.
115         *
116         **/
117        function print_after_file($mod_filename, $dir_index) {
118                echo "\n\n"; // JS: for being sure no former "//" comment in last line wipes out code
119                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: End of $mod_filename ***/\n\n");
120        }
121
122        /**
123         * A generic print_header function which will be called at first. Give out some
124         * stuff you want to prepend to your overall output. This method provides you a
125         * generic JS/CSS compilant message where you can give your own $title string
126         * or use no title (it will use your class name instead). If called with $title != null,
127         * the C++ style multi line comment won't be closed so you can append your own
128         * stuff.
129         **/
130        function print_header($title=null) {
131                if(!$title) $title = __CLASS__;
132                ?>
133/*!
134 * t29v6 <?=$title; ?> - http://technikum29.de/
135 * $Id: ressourceloader.php 285 2012-08-15 13:24:13Z heribert $
136 *
137 * Copyright 2012, Sven Koeppel <sven@te...29.de>
138 * Licensed under any of Apache, MIT, GPL, LGPL
139 *
140 * Packed: <?php echo implode(' ', $this->conf['filenames']); ?> 
141 * Arguments: ?debug=true - skip cache and just cat everything
142 *            ?purge_cache=true - force rebuild of compressed cache file
143 * Gen Date: <?php echo date('r'), PHP_EOL;
144                if($title == __CLASS__) print " **/\n";
145        }
146       
147        /**
148         * The main run() function will print out the header and concatenate all
149         * modules contents. Expects OutputBuffering running!
150         **/
151        function run() {
152                $this->print_header();
153                $this->conf['header'] = ob_get_contents(); // for prepending it to minified code
154
155                foreach($this->conf['modules'] as $i => $mod) {
156                        $modfile = $this->conf['filenames'][$i];
157                        $this->print_before_file($modfile, $i);
158                        readfile($mod);
159                        $this->print_after_file($modfile, $i);
160                }
161        } // run
162
163        /**
164         * Overwrite compression_filter for filtering the whole output made by this
165         * class. It is used as a shutdown filter in t29Cache, see usage in loader.php.
166         * @param $output The output string fetched by OutputBuffering
167         * @returns The filtered String. The default implementation just returns $output.
168         **/
169        function compression_filter($output) {
170                return $output;
171        }
172} // class t29RessourceLoader
173
174
175class t29JavaScriptRessourceLoader extends t29RessourceLoader {
176        function print_after_file($mod_filename, $dir_index) {
177                global $lib;
178                parent::print_after_file($mod_filename, $dir_index);
179                if($mod_filename == "msg.js") {
180                        // append system messages to the special msg.js file
181                        // to inject PHP code to JS userspace.
182                        $this->print_debug("\n/*** Auto appended ***/\n");
183                        require "$lib/messages.php";
184                        echo "t29.msg.data=";
185                        echo t29Messages::create_json('/^js-/');
186                        echo ";\n";
187                }
188        }
189
190        function print_header($title=null) {
191                parent::print_header('JavaScript Code');
192                echo " * Depends heavily on jQuery\n **/\n";
193        }
194       
195        function compression_filter($code) {
196                global $lib;
197                // reduces code size about 1/2 - before: 23kB, after: 12kB
198                require "$lib/JavaScriptMinifier.php";
199                $minified = JavaScriptMinifier::minify($code);
200                return $this->conf['header'] . $minified;
201        }
202} // class t29JavaScriptRessourceLoader
203
204class t29StyleSheetRessourceLoader extends t29RessourceLoader {
205        function print_header($title=null) {
206                parent::print_header('StyleSheet');
207                echo " **/\n";
208        }
209
210        function compression_filter($code) {
211                global $lib;
212                require "$lib/CSSMin.php";
213                # compression: 40kb to 16kb
214                $minified = CSSMin::minify($code);
215                return $this->conf['header'] . $minified;
216               
217        }
218} // 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