source: OWR/View.php @ d2e7d1

Revision d2e7d1, 13.0 KB checked in by pierre-alain <pierre-alain@…>, 5 years ago (diff)

Theme instead of Themes

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