xref: /dokuwiki/inc/Cache/CacheRenderer.php (revision 10287e994a20d03356a34541b59ed0d513bbacaf)
1<?php
2
3namespace dokuwiki\Cache;
4
5/**
6 * Caching of data of renderer
7 */
8class CacheRenderer extends CacheParser
9{
10    /**
11     * method contains cache use decision logic
12     *
13     * @return bool               see useCache()
14     */
15    public function makeDefaultCacheDecision()
16    {
17        global $conf;
18
19        if (!parent::makeDefaultCacheDecision()) {
20            return false;
21        }
22
23        if (!isset($this->page)) {
24            return true;
25        }
26
27        // meta cache older than file it depends on?
28        if ($this->_time < @filemtime(metaFN($this->page, '.meta'))) {
29            return false;
30        }
31
32        // check current link existence is consistent with cache version
33        // first check the purgefile
34        // - if the cache is more recent than the purgefile we know no links can have been updated
35        if ($this->_time >= @filemtime($conf['cachedir'] . '/purgefile')) {
36            return true;
37        }
38
39        // for wiki pages, check metadata dependencies
40        $metadata = p_get_metadata($this->page);
41
42        if (
43            !isset($metadata['relation']['references']) ||
44            empty($metadata['relation']['references'])
45        ) {
46            return true;
47        }
48
49        foreach ($metadata['relation']['references'] as $id => $exists) {
50            if ($exists != page_exists($id, '', false)) {
51                return false;
52            }
53        }
54
55        return true;
56    }
57
58    /**
59     * Adds the wiki base URL to the cache key for rendered output
60     *
61     * Rendered output contains internal links and media sources built from
62     * DOKU_BASE, so cache entries must not be shared between requests served
63     * under a different base URL.
64     *
65     * @return string
66     */
67    protected function getEnvironmentKey()
68    {
69        if ($this->mode === 'metadata') {
70            return '';
71        }
72        return DOKU_BASE;
73    }
74
75    protected function addDependencies()
76    {
77        global $conf;
78
79        // default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
80        //    -1 : do not cache (should not be overridden)
81        //    0  : cache never expires (can be overridden) - no need to set depends['age']
82        if ($conf['cachetime'] == -1) {
83            $this->_nocache = true;
84            return;
85        } elseif ($conf['cachetime'] > 0) {
86            $this->depends['age'] = isset($this->depends['age']) ?
87                min($this->depends['age'], $conf['cachetime']) : $conf['cachetime'];
88        }
89
90        // renderer cache file dependencies ...
91        $files = [DOKU_INC . 'inc/parser/' . $this->mode . '.php'];
92
93        // page implies metadata and possibly some other dependencies
94        if (isset($this->page)) {
95            // for xhtml this will render the metadata if needed
96            $valid = p_get_metadata($this->page, 'date valid');
97            if (!empty($valid['age'])) {
98                $this->depends['age'] = isset($this->depends['age']) ?
99                    min($this->depends['age'], $valid['age']) : $valid['age'];
100            }
101        }
102
103        $this->depends['files'] = empty($this->depends['files']) ?
104            $files :
105            array_merge($files, $this->depends['files']);
106
107        parent::addDependencies();
108    }
109}
110