~chroot64bit/zivios/gentoo-experimental

« back to all changes in this revision

Viewing changes to application/library/Zend/Cache/Frontend/Page.php

  • Committer: Mustafa A. Hashmi
  • Date: 2008-12-04 13:32:21 UTC
  • Revision ID: mhashmi@zivios.org-20081204133221-0nd1trunwevijj38
Inclusion of new installation framework with ties to zend layout and dojo layout

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * Zend Framework
 
4
 *
 
5
 * LICENSE
 
6
 *
 
7
 * This source file is subject to the new BSD license that is bundled
 
8
 * with this package in the file LICENSE.txt.
 
9
 * It is also available through the world-wide-web at this URL:
 
10
 * http://framework.zend.com/license/new-bsd
 
11
 * If you did not receive a copy of the license and are unable to
 
12
 * obtain it through the world-wide-web, please send an email
 
13
 * to license@zend.com so we can send you a copy immediately.
 
14
 *
 
15
 * @category   Zend
 
16
 * @package    Zend_Cache
 
17
 * @subpackage Zend_Cache_Frontend
 
18
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
19
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 
20
 */
 
21
 
 
22
 
 
23
/**
 
24
 * @see Zend_Cache_Core
 
25
 */
 
26
require_once 'Zend/Cache/Core.php';
 
27
 
 
28
 
 
29
/**
 
30
 * @package    Zend_Cache
 
31
 * @subpackage Zend_Cache_Frontend
 
32
 * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
 
33
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 
34
 */
 
35
class Zend_Cache_Frontend_Page extends Zend_Cache_Core
 
36
{
 
37
    /**
 
38
     * This frontend specific options
 
39
     *
 
40
     * ====> (boolean) http_conditional :
 
41
     * - if true, http conditional mode is on
 
42
     * WARNING : http_conditional OPTION IS NOT IMPLEMENTED FOR THE MOMENT (TODO)
 
43
     *
 
44
     * ====> (boolean) debug_header :
 
45
     * - if true, a debug text is added before each cached pages
 
46
     *
 
47
     * ====> (boolean) content_type_memorization :
 
48
     * - deprecated => use memorize_headers instead
 
49
     * - if the Content-Type header is sent after the cache was started, the
 
50
     *   corresponding value can be memorized and replayed when the cache is hit
 
51
     *   (if false (default), the frontend doesn't take care of Content-Type header)
 
52
     *
 
53
     * ====> (array) memorize_headers :
 
54
     * - an array of strings corresponding to some HTTP headers name. Listed headers
 
55
     *   will be stored with cache datas and "replayed" when the cache is hit
 
56
     *
 
57
     * ====> (array) default_options :
 
58
     * - an associative array of default options :
 
59
     *     - (boolean) cache : cache is on by default if true
 
60
     *     - (boolean) cacheWithXXXVariables  (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') :
 
61
     *       if true,  cache is still on even if there are some variables in this superglobal array
 
62
     *       if false, cache is off if there are some variables in this superglobal array
 
63
     *     - (boolean) makeIdWithXXXVariables (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') :
 
64
     *       if true, we have to use the content of this superglobal array to make a cache id
 
65
     *       if false, the cache id won't be dependent of the content of this superglobal array
 
66
     *     - (int) specific_lifetime : cache specific lifetime 
 
67
     *                                (false => global lifetime is used, null => infinite lifetime, 
 
68
     *                                 integer => this lifetime is used), this "lifetime" is probably only 
 
69
     *                                usefull when used with "regexps" array
 
70
     *     - (array) tags : array of tags (strings) 
 
71
     *     - (int) priority : integer between 0 (very low priority) and 10 (maximum priority) used by 
 
72
     *                        some particular backends
 
73
     *
 
74
     * ====> (array) regexps :
 
75
     * - an associative array to set options only for some REQUEST_URI
 
76
     * - keys are (pcre) regexps
 
77
     * - values are associative array with specific options to set if the regexp matchs on $_SERVER['REQUEST_URI']
 
78
     *   (see default_options for the list of available options)
 
79
     * - if several regexps match the $_SERVER['REQUEST_URI'], only the last one will be used
 
80
     *
 
81
     * @var array options
 
82
     */
 
83
    protected $_specificOptions = array(
 
84
        'http_conditional' => false,
 
85
        'debug_header' => false,
 
86
        'content_type_memorization' => false,
 
87
        'memorize_headers' => array(),
 
88
        'default_options' => array(
 
89
            'cache_with_get_variables' => false,
 
90
            'cache_with_post_variables' => false,
 
91
            'cache_with_session_variables' => false,
 
92
            'cache_with_files_variables' => false,
 
93
            'cache_with_cookie_variables' => false,
 
94
            'make_id_with_get_variables' => true,
 
95
            'make_id_with_post_variables' => true,
 
96
            'make_id_with_session_variables' => true,
 
97
            'make_id_with_files_variables' => true,
 
98
            'make_id_with_cookie_variables' => true,
 
99
            'cache' => true,
 
100
            'specific_lifetime' => false,
 
101
            'tags' => array(),
 
102
            'priority' => null
 
103
        ),
 
104
        'regexps' => array()
 
105
    );
 
106
 
 
107
    /**
 
108
     * Internal array to store some options
 
109
     *
 
110
     * @var array associative array of options
 
111
     */
 
112
    protected $_activeOptions = array();
 
113
 
 
114
    /**
 
115
     * If true, the page won't be cached
 
116
     *
 
117
     * @var boolean
 
118
     */
 
119
    private $_cancel = false;
 
120
 
 
121
    /**
 
122
     * Constructor
 
123
     *
 
124
     * @param  array   $options                Associative array of options
 
125
     * @param  boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
 
126
     * @throws Zend_Cache_Exception
 
127
     * @return void
 
128
     */
 
129
    public function __construct(array $options = array())
 
130
    {
 
131
        while (list($name, $value) = each($options)) {
 
132
            $name = strtolower($name);
 
133
            switch ($name) {
 
134
                case 'regexps':
 
135
                    $this->_setRegexps($value);
 
136
                    break;
 
137
                case 'default_options':
 
138
                    $this->_setDefaultOptions($value);
 
139
                    break;
 
140
                case 'content_type_memorization':
 
141
                    $this->_setContentTypeMemorization($value);
 
142
                    break;
 
143
                default:
 
144
                    $this->setOption($name, $value);
 
145
            }
 
146
        }
 
147
        if (isset($this->_specificOptions['http_conditional'])) {
 
148
            if ($this->_specificOptions['http_conditional']) {
 
149
                Zend_Cache::throwException('http_conditional is not implemented for the moment !');
 
150
            }
 
151
        }
 
152
        $this->setOption('automatic_serialization', true);
 
153
    }
 
154
 
 
155
    /**
 
156
     * Specific setter for the 'default_options' option (with some additional tests)
 
157
     *
 
158
     * @param  array $options Associative array
 
159
     * @throws Zend_Cache_Exception
 
160
     * @return void
 
161
     */
 
162
    protected function _setDefaultOptions($options)
 
163
    {
 
164
        if (!is_array($options)) {
 
165
            Zend_Cache::throwException('default_options must be an array !');
 
166
        }
 
167
        foreach ($options as $key=>$value) {
 
168
            if (!is_string($key)) {
 
169
                Zend_Cache::throwException("invalid option [$key] !");
 
170
            }
 
171
            $key = strtolower($key);
 
172
            if (isset($this->_specificOptions['default_options'][$key])) {
 
173
                $this->_specificOptions['default_options'][$key] = $value;
 
174
            }
 
175
        }
 
176
    }
 
177
 
 
178
    /**
 
179
     * Set the deprecated contentTypeMemorization option
 
180
     *
 
181
     * @param boolean $value value
 
182
     * @return void
 
183
     * @deprecated
 
184
     */
 
185
    protected function _setContentTypeMemorization($value)
 
186
    {
 
187
        $found = null;
 
188
        foreach ($this->_specificOptions['memorize_headers'] as $key => $value) {
 
189
            if (strtolower($value) == 'content-type') {
 
190
                $found = $key;
 
191
            }
 
192
        }
 
193
        if ($value) {
 
194
            if (!$found) {
 
195
                $this->_specificOptions['memorize_headers'][] = 'Content-Type';
 
196
            }
 
197
        } else {
 
198
            if ($found) {
 
199
                unset($this->_specificOptions['memorize_headers'][$found]);
 
200
            }
 
201
        }
 
202
    }
 
203
 
 
204
    /**
 
205
     * Specific setter for the 'regexps' option (with some additional tests)
 
206
     *
 
207
     * @param  array $options Associative array
 
208
     * @throws Zend_Cache_Exception
 
209
     * @return void
 
210
     */
 
211
    protected function _setRegexps($regexps)
 
212
    {
 
213
        if (!is_array($regexps)) {
 
214
            Zend_Cache::throwException('regexps option must be an array !');
 
215
        }
 
216
        foreach ($regexps as $regexp=>$conf) {
 
217
            if (!is_array($conf)) {
 
218
                Zend_Cache::throwException('regexps option must be an array of arrays !');
 
219
            }
 
220
            $validKeys = array_keys($this->_specificOptions['default_options']);
 
221
            foreach ($conf as $key=>$value) {
 
222
                if (!is_string($key)) {
 
223
                    Zend_Cache::throwException("unknown option [$key] !");
 
224
                }
 
225
                $key = strtolower($key);
 
226
                if (!in_array($key, $validKeys)) {
 
227
                    unset($regexps[$regexp][$key]);
 
228
                }
 
229
            }
 
230
        }
 
231
        $this->setOption('regexps', $regexps);
 
232
    }
 
233
 
 
234
    /**
 
235
     * Start the cache
 
236
     *
 
237
     * @param  string  $id       (optional) A cache id (if you set a value here, maybe you have to use Output frontend instead)
 
238
     * @param  boolean $doNotDie For unit testing only !
 
239
     * @return boolean True if the cache is hit (false else)
 
240
     */
 
241
    public function start($id = false, $doNotDie = false)
 
242
    {
 
243
        $this->_cancel = false;
 
244
        $lastMatchingRegexp = null;
 
245
        foreach ($this->_specificOptions['regexps'] as $regexp => $conf) {
 
246
            if (preg_match("`$regexp`", $_SERVER['REQUEST_URI'])) {
 
247
                $lastMatchingRegexp = $regexp;
 
248
            }
 
249
        }
 
250
        $this->_activeOptions = $this->_specificOptions['default_options'];
 
251
        if (!is_null($lastMatchingRegexp)) {
 
252
            $conf = $this->_specificOptions['regexps'][$lastMatchingRegexp];
 
253
            foreach ($conf as $key=>$value) {
 
254
                $this->_activeOptions[$key] = $value;
 
255
            }
 
256
        }
 
257
        if (!($this->_activeOptions['cache'])) {
 
258
            return false;
 
259
        }
 
260
        if (!$id) {
 
261
            $id = $this->_makeId();
 
262
            if (!$id) {
 
263
                return false;
 
264
            }
 
265
        }
 
266
        $array = $this->load($id);
 
267
        if ($array !== false) {
 
268
            $data = $array['data'];
 
269
            $headers = $array['headers'];
 
270
            if ($this->_specificOptions['debug_header']) {
 
271
                echo 'DEBUG HEADER : This is a cached page !';
 
272
            }
 
273
            if (!headers_sent()) {
 
274
                foreach ($headers as $key=>$headerCouple) {
 
275
                    $name = $headerCouple[0];
 
276
                    $value = $headerCouple[1];
 
277
                    header("$name: $value");
 
278
                }
 
279
            }
 
280
            echo $data;
 
281
            if ($doNotDie) {
 
282
                return true;
 
283
            }
 
284
            die();
 
285
        }
 
286
        ob_start(array($this, '_flush'));
 
287
        ob_implicit_flush(false);
 
288
        return false;
 
289
    }
 
290
 
 
291
    /**
 
292
     * Cancel the current caching process
 
293
     */
 
294
    public function cancel()
 
295
    {
 
296
        $this->_cancel = true;
 
297
    }
 
298
 
 
299
    /**
 
300
     * callback for output buffering
 
301
     * (shouldn't really be called manually)
 
302
     *
 
303
     * @param  string $data Buffered output
 
304
     * @return string Data to send to browser
 
305
     */
 
306
    public function _flush($data)
 
307
    {
 
308
        if ($this->_cancel) {
 
309
            return $data;
 
310
        }
 
311
        $contentType = null;
 
312
        $storedHeaders = array();
 
313
        $headersList = headers_list();
 
314
        foreach($this->_specificOptions['memorize_headers'] as $key=>$headerName) {
 
315
            foreach ($headersList as $headerSent) {
 
316
                $tmp = split(':', $headerSent);
 
317
                $headerSentName = trim(array_shift($tmp));
 
318
                if (strtolower($headerName) == strtolower($headerSentName)) {
 
319
                    $headerSentValue = trim(implode(':', $tmp));
 
320
                    $storedHeaders[] = array($headerSentName, $headerSentValue);
 
321
                }
 
322
            }
 
323
        }       
 
324
        $array = array(
 
325
            'data' => $data,
 
326
            'headers' => $storedHeaders
 
327
        );
 
328
        $this->save($array, null, $this->_activeOptions['tags'], $this->_activeOptions['specific_lifetime'], $this->_activeOptions['priority']);
 
329
        return $data;
 
330
    }
 
331
 
 
332
    /**
 
333
     * Make an id depending on REQUEST_URI and superglobal arrays (depending on options)
 
334
     *
 
335
     * @return mixed|false a cache id (string), false if the cache should have not to be used
 
336
     */
 
337
    protected function _makeId()
 
338
    {
 
339
        $tmp = $_SERVER['REQUEST_URI'];
 
340
        foreach (array('Get', 'Post', 'Session', 'Files', 'Cookie') as $arrayName) {
 
341
            $tmp2 = $this->_makePartialId($arrayName, $this->_activeOptions['cache_with_' . strtolower($arrayName) . '_variables'], $this->_activeOptions['make_id_with_' . strtolower($arrayName) . '_variables']);
 
342
            if ($tmp2===false) {
 
343
                return false;
 
344
            }
 
345
            $tmp = $tmp . $tmp2;
 
346
        }
 
347
        return md5($tmp);
 
348
    }
 
349
 
 
350
    /**
 
351
     * Make a partial id depending on options
 
352
     *
 
353
     * @param  string $arrayName Superglobal array name
 
354
     * @param  bool   $bool1     If true, cache is still on even if there are some variables in the superglobal array
 
355
     * @param  bool   $bool2     If true, we have to use the content of the superglobal array to make a partial id
 
356
     * @return mixed|false Partial id (string) or false if the cache should have not to be used
 
357
     */
 
358
    protected function _makePartialId($arrayName, $bool1, $bool2)
 
359
    {
 
360
        switch ($arrayName) {
 
361
        case 'Get':
 
362
            $var = $_GET;
 
363
            break;
 
364
        case 'Post':
 
365
            $var = $_POST;
 
366
            break;
 
367
        case 'Session':
 
368
            if (isset($_SESSION)) {
 
369
                $var = $_SESSION;
 
370
            } else {
 
371
                $var = null;
 
372
            }
 
373
            break;
 
374
        case 'Cookie':
 
375
            if (isset($_COOKIE)) {
 
376
                $var = $_COOKIE;
 
377
            } else {
 
378
                $var = null;
 
379
            }
 
380
            break;
 
381
        case 'Files':
 
382
            $var = $_FILES;
 
383
            break;
 
384
        default:
 
385
            return false;
 
386
        }
 
387
        if ($bool1) {
 
388
            if ($bool2) {
 
389
                return serialize($var);
 
390
            }
 
391
            return '';
 
392
        }
 
393
        if (count($var) > 0) {
 
394
            return false;
 
395
        }
 
396
        return '';
 
397
    }
 
398
 
 
399
}