source: OWR/View.php @ 19b5ce

Revision 19b5ce, 10.6 KB checked in by pierre-alain <pierre-alain@…>, 6 years ago (diff)

add support for memcache

  • Property mode set to 100644
Line 
1<?php
2/**
3 * View class
4 *
5 * PHP 5
6 *
7 * OWR - OpenWebReader
8 *
9 * Copyright (c) 2009, Pierre-Alain Mignot
10 *
11 * Home page: http://openwebreader.org
12 *
13 * E-Mail: contact@openwebreader.org
14 *
15 * All Rights Reserved
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 *
31 * @author Pierre-Alain Mignot <contact@openwebreader.org>
32 * @copyright Copyright (c) 2009, Pierre-Alain Mignot
33 * @license http://www.gnu.org/copyleft/gpl.html
34 * @package OWR
35 */
36namespace OWR;
37use OWR\View\Utilities;
38/**
39 * This object is used to render page
40 * @uses Singleton implements the singleton pattern
41 * @uses Exception the exceptions handler
42 * @uses Cache check cache directories
43 * @uses OWR\View\Utilities templates tools
44 * @package OWR
45 */
46class View extends Singleton
47{
48    /**
49    * @var float rendering time
50    * @access protected
51    */
52    static protected $_renderingTime = 0;
53
54    /**
55     * @var array list of headers
56     * @access protected
57     */
58    protected $_headers = array();
59
60    /**
61     * @var mixed instance of OWR\View\Utilities
62     * @access protected
63     */
64    protected $_utilities;
65
66    /**
67     * @var int HTTP status code
68     * @access protected
69     */
70    protected $_statusCode = 200;
71
72    /**
73     * Constructor
74     * Checks cache directories and set OWR\View\Utilities instance
75     *
76     * @access protected
77     * @author Pierre-Alain Mignot <contact@openwebreader.org>
78     */
79    protected function __construct()
80    {
81        Cache::checkDir(User::iGet()->getLang());
82        $this->_utilities = Utilities::iGet();
83    }
84
85    /**
86     * Returns the specified template with the specified datas
87     *
88     * @access public
89     * @author Pierre-Alain Mignot <contact@openwebreader.org>
90     * @param string $tpl the template name
91     * @param array $datas the datas
92     * @param int $cacheTime cache time in seconds
93     * @param array $noCacheDatas the datas that are not cached but replaced on-the-fly
94     * @return string the template rendered
95     */
96    public function get($tpl, array $datas = array(), $cacheTime = 0, array $noCacheDatas = array())
97    {
98        $t = microtime(true);
99        $cacheTime = (int) $cacheTime;
100
101        if($cacheTime > 0)
102        {
103            $cachedTpl = User::iGet()->getLang().DIRECTORY_SEPARATOR.md5($tpl.serialize($datas));
104            $contents = Cache::get($cachedTpl, $cacheTime);
105        }
106
107        if(!isset($contents) || false === $contents)
108        { // nothing found in cache
109            $contents = $this->_execute($tpl, $datas);
110
111            if($cacheTime > 0)
112            {
113                Cache::write($cachedTpl, $contents);
114            }
115        }
116
117        if(!empty($noCacheDatas))
118        {
119            foreach($noCacheDatas as $name => $value)
120            {
121                $contents = str_replace('<OWR:NOCACHE NAME=\''.$name.'\'/>', $value, $contents);
122            }
123        }
124
125        self::$_renderingTime += (float)microtime(true) - $t;
126
127        return $contents;
128    }
129
130    /**
131     * Executes specified template and returns generated content
132     *
133     * @access public
134     * @author Pierre-Alain Mignot <contact@openwebreader.org>
135     * @param string $tpl the template name
136     * @param array $datas the datas
137     * @return string the template rendered
138     */
139    protected function _execute($tpl, array $datas)
140    {
141        extract($datas, EXTR_SKIP);
142        ob_start();
143        include HOME_PATH.'tpl'.DIRECTORY_SEPARATOR.$tpl.'.html';
144        return ob_get_clean();   
145    }
146
147    /**
148     * Returns the added microtime of all rendering processing
149     *
150     * @access public
151     * @author Pierre-Alain Mignot <contact@openwebreader.org>
152     * @param mixed string or array to sanitize
153     * @return float $_renderingTime
154     * @static
155     */
156    static public function getTime()
157    {
158        return (float) self::$_renderingTime;
159    }
160
161    /**
162     * Adds HTTP headers
163     *
164     * @access public
165     * @author Pierre-Alain Mignot <contact@openwebreader.org>
166     * @param array $headers associated array of HTTP header
167     * @param boolean $send must-we send headers ?
168     */
169    public function addHeaders(array $headers, $send = false)
170    {
171        foreach($headers as $name=>$value)
172        {
173            $name = strtolower($name);
174            isset($this->_headers[$name]) || $this->_headers[$name] = (string) $value;
175        }
176
177        if($send) $this->sendHeaders(false);
178    }
179
180    /**
181     * Sets HTTP status code
182     *
183     * @access public
184     * @author Pierre-Alain Mignot <contact@openwebreader.org>
185     * @param int $code the code to set
186     * @param boolean $send must-we send headers ?
187     */
188    public function setStatusCode($statusCode, $send = false)
189    {
190        $statusCode = (int) $statusCode;
191        if($statusCode > $this->_statusCode)
192            $this->_statusCode = $statusCode;
193
194        if($send) $this->sendHeaders();
195    }
196
197    /**
198     * Sends HTTP headers
199     *
200     * @access public
201     * @author Pierre-Alain Mignot <contact@openwebreader.org>
202     * @param boolean $sendStatus set to false to not send HTTP status code
203     */
204    public function sendHeaders($sendStatus = true)
205    {
206        if($sendStatus)
207        {
208            switch($this->_statusCode)
209            {
210                case 100: $statusCode = 'Continue'; break;
211                case 101: $statusCode = 'Switching Protocols'; break;
212                case 200: $statusCode = 'OK'; break;
213                case 201: $statusCode = 'Created'; break;
214                case 202: $statusCode = 'Accepted'; break;
215                case 203: $statusCode = 'Non-Authoritative Information'; break;
216                case 205: $statusCode = 'Reset Content'; break;
217                case 206: $statusCode = 'Partial Content'; break;
218                case 300: $statusCode = 'Multiple Choices'; break;
219                case 301: $statusCode = 'Moved Permanently'; break;
220                case 302: $statusCode = 'Found'; break;
221                case 303: $statusCode = 'See Other'; break;
222                case 304: $statusCode = 'Not Modified'; break;
223                case 305: $statusCode = 'Use Proxy'; break;
224                case 306: $statusCode = '(Unused)'; break;
225                case 307: $statusCode = 'Temporary Redirect'; break;
226                case 400: $statusCode = 'Bad Request'; break;
227                case 401: $statusCode = 'Unauthorized'; break;
228                case 402: $statusCode = 'Payment Required'; break;
229                case 403: $statusCode = 'Forbidden'; break;
230                case 404: $statusCode = 'Not Found'; break;
231                case 405: $statusCode = 'Method Not Allowed'; break;
232                case 406: $statusCode = 'Not Acceptable'; break;
233                case 407: $statusCode = 'Proxy Authentication Required'; break;
234                case 408: $statusCode = 'Request Timeout'; break;
235                case 409: $statusCode = 'Conflict'; break;
236                case 410: $statusCode = 'Gone'; break;
237                case 411: $statusCode = 'Length Required'; break;
238                case 412: $statusCode = 'Precondition Failed'; break;
239                case 413: $statusCode = 'Request Entity Too Large'; break;
240                case 414: $statusCode = 'Request-URI Too Long'; break;
241                case 415: $statusCode = 'Unsupported Media Type'; break;
242                case 416: $statusCode = 'Requested Range Not Satisfiable'; break;
243                case 417: $statusCode = 'Expectation Failed'; break;
244                case 501: $statusCode = 'Not Implemented'; break;
245                case 502: $statusCode = 'Bad Gateway'; break;
246                case 503: $statusCode = 'Service Unavailable'; break;
247                case 504: $statusCode = 'Gateway Timeout'; break;
248                case 505: $statusCode = 'HTTP Version Not Supported'; break;
249
250                case 204: // we always return something
251                    $this->_statusCode = 200;
252                    $statusCode = 'OK';
253                    break;
254
255                case 500:
256                default:
257                    $this->_statusCode = 500;
258                    $statusCode = 'Internal Server Error';
259                    break;
260            }
261
262            if(!CLI) header('HTTP/1.1 '.$this->_statusCode.' '.$statusCode);
263        }
264
265        if(!CLI)
266        {
267            foreach($this->_headers as $name=>$value)
268            {
269                header($name.': '.$value);
270            }
271        }
272
273        $this->_headers = array();
274    }
275
276    /**
277     * Prints the page
278     * This function tries to encode the contents
279     *
280     * @access public
281     * @author Pierre-Alain Mignot <contact@openwebreader.org>
282     * @param string $page the page to display
283     */
284    public function render($page)
285    {
286        $this->sendHeaders();
287        // try to compress the page
288        $encoding = false;
289        if(extension_loaded('zlib') && !ini_get('zlib.output_compression'))
290        {
291            if(function_exists('ob_gzhandler') && @ob_start('ob_gzhandler'))
292                $encoding = 'gzhandler';
293            elseif(!headers_sent() && isset($_SERVER['HTTP_ACCEPT_ENCODING']))
294            {
295                if(mb_strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip', 0, 'UTF-8') !== false)
296                {
297                    $encoding = 'x-gzip';
298                }
299                elseif(mb_strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip', 0, 'UTF-8') !== false)
300                {
301                    $encoding = 'gzip';
302                }
303            }
304        }
305
306        switch($encoding)
307        {
308            case 'gzhandler':
309                @ob_implicit_flush(0);
310                echo $page;
311                @ob_end_flush();
312                break;
313            case 'gzip':
314            case 'x-gzip':
315                header('Content-Encoding: ' . $encoding);
316                ob_start();
317                echo $page;
318                $page = ob_get_clean();
319                $size = mb_strlen($page, 'UTF-8');
320                $page = gzcompress($page, 6);
321                $page = mb_substr($page, 0, $size, 'UTF-8');
322                echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
323            default:
324                echo $page;
325                flush();
326                break;
327        }
328    }
329}
Note: See TracBrowser for help on using the repository browser.