source: OWR/View.php @ 7c60cc

Revision 7c60cc, 11.6 KB checked in by pierre-alain <pierre-alain@…>, 6 years ago (diff)

adding theme support !

  • 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    OWR\View\Block;
39/**
40 * This object is used to render page
41 * @uses Singleton implements the singleton pattern
42 * @uses Exception the exceptions handler
43 * @uses Cache check cache directories
44 * @uses OWR\View\Utilities templates tools
45 * @package OWR
46 */
47class View extends Singleton
48{
49    /**
50    * @var float rendering time
51    * @access protected
52    */
53    static protected $_renderingTime = 0;
54
55    /**
56     * @var array list of headers
57     * @access protected
58     */
59    protected $_headers = array();
60
61    /**
62     * @var mixed instance of OWR\View\Utilities
63     * @access protected
64     */
65    protected $_utilities;
66
67    /**
68     * @var int HTTP status code
69     * @access protected
70     */
71    protected $_statusCode = 200;
72
73    protected $_blocks = array();
74
75    /**
76     * Constructor
77     * Checks cache directories and set OWR\View\Utilities instance
78     *
79     * @access protected
80     * @author Pierre-Alain Mignot <contact@openwebreader.org>
81     */
82    protected function __construct()
83    {
84        Cache::checkDir(User::iGet()->getLang());
85        $this->_utilities = Utilities::iGet();
86    }
87
88    /**
89     * Returns the specified template with the specified datas
90     *
91     * @access public
92     * @author Pierre-Alain Mignot <contact@openwebreader.org>
93     * @param string $tpl the template name
94     * @param array $datas the datas
95     * @param int $cacheTime cache time in seconds
96     * @param array $noCacheDatas the datas that are not cached but replaced on-the-fly
97     * @return string the template rendered
98     */
99    public function get($tpl, array $datas = array(), $cacheTime = null, array $noCacheDatas = array())
100    {
101        $t = microtime(true);
102        $cacheTime = (int) (isset($cacheTime) ? $cacheTime : Config::iGet()->get('cacheTime'));
103
104        if($cacheTime > 0)
105        {
106            $cachedTpl = User::iGet()->getLang() . DIRECTORY_SEPARATOR . md5($tpl . serialize($datas));
107            $contents = Cache::get($cachedTpl, $cacheTime);
108        }
109
110        if(!isset($contents) || false === $contents)
111        { // nothing found in cache
112            $contents = $this->_execute($tpl, $datas);
113
114            if($cacheTime > 0)
115            {
116                Cache::write($cachedTpl, $contents);
117            }
118        }
119
120        if(!empty($noCacheDatas))
121        {
122            foreach($noCacheDatas as $name => $value)
123            {
124                $contents = str_replace('<OWR:NOCACHE NAME=\''.$name.'\'/>', $value, $contents);
125            }
126        }
127
128        self::$_renderingTime += (float)microtime(true) - $t;
129
130        return $contents;
131    }
132
133    /**
134     * Executes specified template and returns generated content
135     *
136     * @access public
137     * @author Pierre-Alain Mignot <contact@openwebreader.org>
138     * @param string $tpl the template name
139     * @param array $datas the datas
140     * @return string the template rendered
141     */
142    protected function _execute($tpl, array $datas)
143    {
144        extract((array) $datas, EXTR_SKIP);
145        ob_start();
146        include Themes::iGet()->getPath($tpl) . $tpl . '.html';
147        return ob_get_clean();
148    }
149
150    /**
151     * Returns the added microtime of all rendering processing
152     *
153     * @access public
154     * @author Pierre-Alain Mignot <contact@openwebreader.org>
155     * @param mixed string or array to sanitize
156     * @return float $_renderingTime
157     * @static
158     */
159    static public function getTime()
160    {
161        return (float) self::$_renderingTime;
162    }
163
164    /**
165     * Adds HTTP headers
166     *
167     * @access public
168     * @author Pierre-Alain Mignot <contact@openwebreader.org>
169     * @param array $headers associated array of HTTP header
170     * @param boolean $send must-we send headers ?
171     */
172    public function addHeaders(array $headers, $send = false)
173    {
174        foreach($headers as $name=>$value)
175        {
176            $name = strtolower($name);
177            isset($this->_headers[$name]) || $this->_headers[$name] = (string) $value;
178        }
179
180        if($send) $this->sendHeaders(false);
181    }
182
183    /**
184     * Sets HTTP status code
185     *
186     * @access public
187     * @author Pierre-Alain Mignot <contact@openwebreader.org>
188     * @param int $code the code to set
189     * @param boolean $send must-we send headers ?
190     */
191    public function setStatusCode($statusCode, $send = false)
192    {
193        $statusCode = (int) $statusCode;
194        if($statusCode > $this->_statusCode)
195            $this->_statusCode = $statusCode;
196
197        if($send) $this->sendHeaders();
198    }
199
200    /**
201     * Sends HTTP headers
202     *
203     * @access public
204     * @author Pierre-Alain Mignot <contact@openwebreader.org>
205     * @param boolean $sendStatus set to false to not send HTTP status code
206     */
207    public function sendHeaders($sendStatus = true)
208    {
209        if($sendStatus)
210        {
211            switch($this->_statusCode)
212            {
213                case 100: $statusCode = 'Continue'; break;
214                case 101: $statusCode = 'Switching Protocols'; break;
215                case 200: $statusCode = 'OK'; break;
216                case 201: $statusCode = 'Created'; break;
217                case 202: $statusCode = 'Accepted'; break;
218                case 203: $statusCode = 'Non-Authoritative Information'; break;
219                case 205: $statusCode = 'Reset Content'; break;
220                case 206: $statusCode = 'Partial Content'; break;
221                case 300: $statusCode = 'Multiple Choices'; break;
222                case 301: $statusCode = 'Moved Permanently'; break;
223                case 302: $statusCode = 'Found'; break;
224                case 303: $statusCode = 'See Other'; break;
225                case 304: $statusCode = 'Not Modified'; break;
226                case 305: $statusCode = 'Use Proxy'; break;
227                case 306: $statusCode = '(Unused)'; break;
228                case 307: $statusCode = 'Temporary Redirect'; break;
229                case 400: $statusCode = 'Bad Request'; break;
230                case 401: $statusCode = 'Unauthorized'; break;
231                case 402: $statusCode = 'Payment Required'; break;
232                case 403: $statusCode = 'Forbidden'; break;
233                case 404: $statusCode = 'Not Found'; break;
234                case 405: $statusCode = 'Method Not Allowed'; break;
235                case 406: $statusCode = 'Not Acceptable'; break;
236                case 407: $statusCode = 'Proxy Authentication Required'; break;
237                case 408: $statusCode = 'Request Timeout'; break;
238                case 409: $statusCode = 'Conflict'; break;
239                case 410: $statusCode = 'Gone'; break;
240                case 411: $statusCode = 'Length Required'; break;
241                case 412: $statusCode = 'Precondition Failed'; break;
242                case 413: $statusCode = 'Request Entity Too Large'; break;
243                case 414: $statusCode = 'Request-URI Too Long'; break;
244                case 415: $statusCode = 'Unsupported Media Type'; break;
245                case 416: $statusCode = 'Requested Range Not Satisfiable'; break;
246                case 417: $statusCode = 'Expectation Failed'; break;
247                case 501: $statusCode = 'Not Implemented'; break;
248                case 502: $statusCode = 'Bad Gateway'; break;
249                case 503: $statusCode = 'Service Unavailable'; break;
250                case 504: $statusCode = 'Gateway Timeout'; break;
251                case 505: $statusCode = 'HTTP Version Not Supported'; break;
252
253                case 204: // we always return something
254                    $this->_statusCode = 200;
255                    $statusCode = 'OK';
256                    break;
257
258                case 500:
259                default:
260                    $this->_statusCode = 500;
261                    $statusCode = 'Internal Server Error';
262                    break;
263            }
264
265            if(!CLI) header('HTTP/1.1 ' . $this->_statusCode . ' ' . $statusCode);
266        }
267
268        if(!CLI)
269        {
270            foreach($this->_headers as $name=>$value)
271            {
272                header($name . ': ' . $value);
273            }
274        }
275
276        $this->_headers = array();
277    }
278
279    /**
280     * Prints the page
281     * This function tries to encode the contents
282     *
283     * @access public
284     * @author Pierre-Alain Mignot <contact@openwebreader.org>
285     * @param string $page the page to display
286     */
287    public function render($page)
288    {
289        $this->sendHeaders();
290        // try to compress the page
291        $encoding = false;
292        if(extension_loaded('zlib') && !ini_get('zlib.output_compression'))
293        {
294            if(function_exists('ob_gzhandler') && @ob_start('ob_gzhandler'))
295                $encoding = 'gzhandler';
296            elseif(!headers_sent() && isset($_SERVER['HTTP_ACCEPT_ENCODING']))
297            {
298                if(mb_strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'x-gzip', 0, 'UTF-8') !== false)
299                {
300                    $encoding = 'x-gzip';
301                }
302                elseif(mb_strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip', 0, 'UTF-8') !== false)
303                {
304                    $encoding = 'gzip';
305                }
306            }
307        }
308
309        switch($encoding)
310        {
311            case 'gzhandler':
312                @ob_implicit_flush(0);
313                echo $page;
314                @ob_end_flush();
315                break;
316            case 'gzip':
317            case 'x-gzip':
318                header('Content-Encoding: ' . $encoding);
319                ob_start();
320                echo $page;
321                $page = ob_get_clean();
322                $size = mb_strlen($page, 'UTF-8');
323                $page = gzcompress($page, 6);
324                $page = mb_substr($page, 0, $size, 'UTF-8');
325                echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
326            default:
327                echo $page;
328                flush();
329                break;
330        }
331    }
332
333    public function addBlock($name, $layout, $content, $type = 'html')
334    {
335        $this->_blocks[$layout][$name] = new Block($content, $type);
336    }
337
338    public function getBlocks($layout)
339    {
340        return isset($this->_blocks[$layout]) ? join('', $this->_blocks[$layout]) : null;
341    }
342
343    public function getBlock($name, $layout)
344    {
345        return isset($this->_blocks[$layout][$name]) ? $this->_blocks[$layout][$name] : null;
346    }
347
348    public function renderBlocks($layout)
349    {
350        $blocks = $this->getBlocks($layout);
351        if(!empty($blocks))
352            echo $blocks;
353    }
354
355    public function renderBlock($name, $layout)
356    {
357        $block = $this->getBlock($name, $layout);
358        if(!empty($block))
359            echo $block;
360    }
361
362    public function _($name)
363    {
364        return $this->_utilities->_($name);
365    }
366}
Note: See TracBrowser for help on using the repository browser.