source: trunk/lib/CSS.inc.php

Last change on this file was 795, checked in by anonymous, 11 months ago

Update cache durations

File size: 6.9 KB
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * CSS.inc.css
25 *
26 * Dynamically outputs cached CSS data.
27 *
28 * @author  Quinn Comendant <quinn@strangecode.com>
29 * @version 1.2
30 */
31class CSS
32{
33
34    // Include these style sheets.
35    protected $_css_files = array('default' => array());
36
37    // CSS object parameters.
38    protected $_params = array(
39        'character_set' => 'utf-8',
40        'cache_enable' => false,
41        'cache_css' => null, // Same as above; kept for backwards compatibility.
42        'cache_seconds' => 7776000, // 90 days.
43        'strip_whitespace' => false,
44        'output_compression' => false,
45    );
46
47    /**
48     * Set (or overwrite existing) parameters by passing an array of new parameters.
49     *
50     * @access public
51     * @param  array    $params     Array of parameters (key => val pairs).
52     */
53    public function setParam($params)
54    {
55        $app =& App::getInstance();
56
57        if (isset($params) && is_array($params)) {
58            // Merge new parameters with old overriding only those passed.
59            $this->_params = array_merge($this->_params, $params);
60            // Maintaining backwards compatibility.
61            if (isset($params['cache_css']) && !isset($params['cache_enable'])) {
62                $this->_params['cache_enable'] = $params['cache_css'];
63            }
64        } else {
65            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
66        }
67    }
68
69    /**
70     * Return the value of a parameter, if it exists.
71     *
72     * @access public
73     * @param string $param        Which parameter to return.
74     * @return mixed               Configured parameter value.
75     */
76    public function getParam($param)
77    {
78        $app =& App::getInstance();
79
80        if (array_key_exists($param, $this->_params)) {
81            return $this->_params[$param];
82        } else {
83            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
84            return null;
85        }
86    }
87
88    /**
89     * Add a file-path to the array of files to include as CSS.
90     *
91     * @access  public
92     * @param   string  $file   Include path to css files.
93     * @param   mixed   $realms   Realm name string or array of realm names.
94     * @return  bool    True on success, false on failure.
95     */
96    public function setFile($file, $realms='')
97    {
98        $app =& App::getInstance();
99
100        if (!is_array($realms)) {
101            $realms = array($realms);
102        }
103
104        if ($fp = fopen($file, 'r', true)) {
105            foreach ($realms as $realm) {
106                $realm = '' == $realm ? 'default' : $realm;
107                $this->_css_files[$realm][] = $file;
108            }
109            fclose($fp);
110            return true;
111        } else {
112            $app->logMsg(sprintf('CSS file non-existent: %s', $file), LOG_ERR, __FILE__, __LINE__);
113            return false;
114        }
115    }
116
117    /**
118     * Output headers for CSS.
119     *
120     * @access  public
121     *
122     * @return  bool    False if no files have been set.
123     */
124    public function headers($realm='')
125    {
126        $app =& App::getInstance();
127
128        $realm = '' == $realm ? 'default' : $realm;
129
130        if (empty($this->_css_files[$realm])) {
131            $app->logMsg(sprintf('CSS::headers called without specifying any files.', null), LOG_WARNING, __FILE__, __LINE__);
132            return false;
133        }
134
135        // Get time of latest modified file, including this class file.
136        $files_mtime = array();
137        foreach (array_merge($this->_css_files[$realm], array(__FILE__)) as $file) {
138            $files_mtime[] = statIncludePath($file, 'mtime');
139        }
140        sort($files_mtime, SORT_NUMERIC);
141        $latest_mtime = array_pop($files_mtime);
142
143        if ($this->getParam('output_compression') && extension_loaded('zlib')) {
144            ob_start('ob_gzhandler');
145        }
146
147        header(sprintf('Content-Type: text/css; charset=%s', $this->getParam('character_set')));
148        header(sprintf('Last-Modified: %s GMT', gmdate('D, d M Y H:i:s', $latest_mtime), null));
149        if ($this->getParam('cache_enable')) {
150            header(sprintf('Cache-Control: public, max-age=%s', $this->getParam('cache_seconds')));
151            header(sprintf('Expires: %s GMT', gmdate('D, d M Y H:i:s', $latest_mtime + $this->getParam('cache_seconds'))));
152            header('Pragma: public');
153            header('Vary: Accept-Encoding');
154        } else {
155            // Disallow HTTP caching entirely. http://stackoverflow.com/a/2068407
156            header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
157            header('Pragma: no-cache'); // HTTP 1.0.
158            header('Expires: 0'); // Proxies.
159        }
160    }
161
162    /**
163     * Include CSS files specified by setFile().
164     *
165     * @access  public
166     *
167     * @return  bool    False if no files have been set.
168     */
169    public function output($realm='')
170    {
171        $app =& App::getInstance();
172
173        $realm = '' == $realm ? 'default' : $realm;
174
175        if (empty($this->_css_files[$realm])) {
176            $app->logMsg(sprintf('CSS::output called without specifying any files.', null), LOG_WARNING, __FILE__, __LINE__);
177            return false;
178        }
179
180        foreach ($this->_css_files[$realm] as $file) {
181            if ($this->getParam('strip_whitespace')) {
182                // Strip whitespace and print file.
183                echo preg_replace(
184                    array('!/\*.*?\*/!s' . $app->getParam('preg_u'), '/[\n\r]+/' . $app->getParam('preg_u'), '/([;:])\s+/m' . $app->getParam('preg_u'), '/\s*}[ \t]*/' . $app->getParam('preg_u'), '/\s*{\s*/' . $app->getParam('preg_u'), '/[ \t\n\r]*,[ \t\n\r]*/' . $app->getParam('preg_u'), '/^\s+/' . $app->getParam('preg_u')),
185                    array('', "\n", '$1', '}', '{', ',', ''), file_get_contents($file, true)
186                );
187            } else {
188                // Include file as is.
189                include $file;
190            }
191        }
192
193        if ($this->getParam('output_compression') && extension_loaded('zlib')) {
194            ob_end_flush();
195        }
196    }
197}
Note: See TracBrowser for help on using the repository browser.