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

Last change on this file since 1423 was 1423, checked in by sven, 6 years ago

Startseite: Exemplarischen Slider (Karoussell) hinzugefügt, mit Platzhalterelementen.

  • Property svn:keywords set to Id
File size: 8.5 KB
RevLine 
[260]1<?php
[269]2/**
[270]3 * t29RessourceLoader classes.
[269]4 *
[271]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.
[269]9 *
[271]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 *
[269]22 **/
[273]23 
24/*
25// test it:
26$lib = dirname(__FILE__);
27$webroot = realpath("$lib/../");
28$js = t29RessourceLoader::create_from_type('css');
29$js->run();
30*/
[260]31
[269]32class t29RessourceLoader {
[271]33        /**
[357]34         * expects: type, cache_file, module_dir, page_dir, glob_pattern, content_types, class, modules, debug, host
[271]35         **/
[269]36        public $conf;
37       
[273]38        const default_include_url = '/lib/loader.php'; // rel to webroot
39       
[271]40        /**
41         * Construct with configuration array. See loader.php for contents of
42         * that array. See above for minimum elements which must be present.
[273]43         * @param $conf Configuration array
[271]44         **/
[269]45        function __construct($conf) {
46                $this->conf = $conf;
47                $this->conf['filenames'] = array_map('basename', $this->conf['modules']); // filenames like foo.js
48        }
49       
[273]50        static function create_from_type($type, $baseconf=null) {
[516]51                global $lib, $webroot, $host;
52                $conf = $host->get_ressources($type, $webroot, isset($baseconf['debug']) && $baseconf['debug']);
[273]53                if($conf === null) return null;
[516]54       
55                return new $conf['class']($conf);               
[273]56        }
57       
[301]58        function get_page_specific_urls($seiten_id) {
59                global $webroot;
60                $file = sprintf("%s/%s.%s", $this->conf['page_dir'], $seiten_id, $this->conf['type']);
61                // TODO: This is hacky. Same in get_urls.
62                $file_rel2webroot = str_replace($webroot, '', $file);
63                return file_exists($file) ? array($file_rel2webroot) : array();
64        }
65       
[357]66        /**
67         * Return a list of URLs appropriate for being included in a website. In general this
68         * should be a list with one element, like array("/lib/loader.php?type=js"), which can
69         * be directly expanded to a <script src="$1"></script> tag. Same applies for CSS.
70         * In debug mode, the list will contain all base files.
71         *
72         * The URLs are relative to the t29 web document root, that is, no host specific web prefix
73         * handling here.
74         *
75         * There is especially an issue with web prefixes and debug mode: Since clean untouched CSS/JS
76         * files are passed there, there cannot be any rewriting in progress.
77         *
78         * @returns array
79         **/
[273]80        function get_urls($debug=null) {
81                global $webroot;
82                if(($debug !== null && $debug) || !$this->conf['debug']) {
83                        return array(self::default_include_url . '?type=' . $this->conf['type']);
84                } else {
85                        $module_dir_rel2webroot = str_replace($webroot, '', $this->conf['module_dir']);
86                        return array_map(function($i)use($module_dir_rel2webroot){ return $module_dir_rel2webroot.$i; }, $this->conf['filenames']);
87                }
88        }
89       
[271]90        /**
91         * Print out debug messages, only if debug switch is given.
92         **/
93        protected function print_debug($string) {
[269]94                if($this->conf['debug'])
95                        echo $string;
96        }
[271]97
98        /**
99         * Module hooking: By overwriting this method and looking at $mod_filename,
100         * you can inject any output before that given file.
101         *
102         * Example:
103         *  class YourRessourceLoader extends t29RessourceLoader {[
104         *     function print_before_file($file, $i) {
105         *         parent::print_before_file($file, $i);
106         *         print "Make a boo boo loading the ${i}. file named ${file}!";
107         *     }
108         *  }
109         * This will prepend that string before the output of the file.
110         *
111         * Always call the parent function when overwriting so that output is printed,
112         * too! (See example)
113         *
114         * @param $mod_filename Filename of module, like "foo.js".
115         * @param $dir_index Iteration index while traversing the directory (see run()). Not so important.
116         * @returns String that
117         **/
[269]118        function print_before_file($mod_filename, $dir_index) {
119                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: Start of $mod_filename ***/\n\n");
120        }
[271]121
122        /**
123         * Same as print_before_file but will append your content to the file.
124         * Obey calling parent::print_after_file at first so that corrections in
125         * the super class can be done!
126         *
127         * The implementation in t29RessourceLoader prints some newlines to make sure
128         * JavaScript oneliner comments at the end of a file won't comment out another
129         * file's first line.
130         *
131         **/
[269]132        function print_after_file($mod_filename, $dir_index) {
133                echo "\n\n"; // JS: for being sure no former "//" comment in last line wipes out code
134                $this->print_debug("\n\n/*** t29v6-RessourceLoader[$dir_index]: End of $mod_filename ***/\n\n");
135        }
[271]136
137        /**
138         * A generic print_header function which will be called at first. Give out some
139         * stuff you want to prepend to your overall output. This method provides you a
140         * generic JS/CSS compilant message where you can give your own $title string
141         * or use no title (it will use your class name instead). If called with $title != null,
142         * the C++ style multi line comment won't be closed so you can append your own
143         * stuff.
144         **/
[269]145        function print_header($title=null) {
146                if(!$title) $title = __CLASS__;
147                ?>
[260]148/*!
[269]149 * t29v6 <?=$title; ?> - http://technikum29.de/
[260]150 * $Id: ressourceloader.php 1423 2018-01-07 00:31:58Z sven $
151 *
152 * Copyright 2012, Sven Koeppel <sven@te...29.de>
153 * Licensed under any of Apache, MIT, GPL, LGPL
154 *
[269]155 * Packed: <?php echo implode(' ', $this->conf['filenames']); ?> 
[260]156 * Arguments: ?debug=true - skip cache and just cat everything
157 *            ?purge_cache=true - force rebuild of compressed cache file
[269]158 * Gen Date: <?php echo date('r'), PHP_EOL;
159                if($title == __CLASS__) print " **/\n";
160        }
161       
[271]162        /**
163         * The main run() function will print out the header and concatenate all
164         * modules contents. Expects OutputBuffering running!
165         **/
[269]166        function run() {
167                $this->print_header();
168                $this->conf['header'] = ob_get_contents(); // for prepending it to minified code
[260]169
[269]170                foreach($this->conf['modules'] as $i => $mod) {
171                        $modfile = $this->conf['filenames'][$i];
172                        $this->print_before_file($modfile, $i);
173                        readfile($mod);
174                        $this->print_after_file($modfile, $i);
175                }
176        } // run
[264]177
[271]178        /**
179         * Overwrite compression_filter for filtering the whole output made by this
180         * class. It is used as a shutdown filter in t29Cache, see usage in loader.php.
181         * @param $output The output string fetched by OutputBuffering
182         * @returns The filtered String. The default implementation just returns $output.
183         **/
[269]184        function compression_filter($output) {
185                return $output;
186        }
187} // class t29RessourceLoader
188
[271]189
[269]190class t29JavaScriptRessourceLoader extends t29RessourceLoader {
191        function print_after_file($mod_filename, $dir_index) {
192                global $lib;
193                parent::print_after_file($mod_filename, $dir_index);
194                if($mod_filename == "msg.js") {
[271]195                        // append system messages to the special msg.js file
196                        // to inject PHP code to JS userspace.
[269]197                        $this->print_debug("\n/*** Auto appended ***/\n");
198                        require "$lib/messages.php";
199                        echo "t29.msg.data=";
[278]200                        echo t29Messages::create_json('/^js-/');
[269]201                        echo ";\n";
202                }
203        }
[301]204       
205        function get_page_specific_urls($seiten_id) {
206                $urls = parent::get_page_specific_urls($seiten_id);
207                switch($seiten_id) {
208                        case 'impressum':
209                                $urls[] = 'http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=ABQIAAAAraTKZ5cINardZ8ITNVssKhRcOoEBtCgYLJRQznXYEV8m1M3fRRRT9wMSvFwhyo62fD3KyiwQxe5ruw';
210                                break;
[1423]211                        case 'startseite':
212                                $urls[] = '/shared/js-v6/libs/flickity.pkgd.min.js'; // Caroussel-Slider
213                                break;
[301]214                }
215                return $urls;
216        }
[269]217
[285]218        function print_header($title=null) {
[269]219                parent::print_header('JavaScript Code');
220                echo " * Depends heavily on jQuery\n **/\n";
221        }
[260]222       
[269]223        function compression_filter($code) {
224                global $lib;
225                // reduces code size about 1/2 - before: 23kB, after: 12kB
226                require "$lib/JavaScriptMinifier.php";
227                $minified = JavaScriptMinifier::minify($code);
228                return $this->conf['header'] . $minified;
[260]229        }
[269]230} // class t29JavaScriptRessourceLoader
[260]231
[269]232class t29StyleSheetRessourceLoader extends t29RessourceLoader {
[285]233        function print_header($title=null) {
[271]234                parent::print_header('StyleSheet');
[269]235                echo " **/\n";
236        }
[260]237
[269]238        function compression_filter($code) {
[516]239                global $lib, $host;
[357]240                if($host->has_web_prefix)
241                        // rewrite CSS image includes
242                        $code = preg_replace('#(url\(["\']?)/#i', '\\1'.$host->web_prefix.'/', $code);
243               
244               
[269]245                require "$lib/CSSMin.php";
[270]246                # compression: 40kb to 16kb
[269]247                $minified = CSSMin::minify($code);
248                return $this->conf['header'] . $minified;
249               
250        }
[516]251} // 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