]> scripts.mit.edu Git - autoinstalls/mediawiki.git/blob - includes/actions/CachedAction.php
MediaWiki 1.30.2-scripts
[autoinstalls/mediawiki.git] / includes / actions / CachedAction.php
1 <?php
2 /**
3  * Abstract action class with scaffolding for caching HTML and other values
4  * in a single blob.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  * http://www.gnu.org/copyleft/gpl.html
20  *
21  * @file
22  * @ingroup Actions
23  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
24  * @since 1.20
25  */
26
27 /**
28  * Abstract action class with scaffolding for caching HTML and other values
29  * in a single blob.
30  *
31  * Before using any of the caching functionality, call startCache.
32  * After the last call to either getCachedValue or addCachedHTML, call saveCache.
33  *
34  * To get a cached value or compute it, use getCachedValue like this:
35  * $this->getCachedValue( $callback );
36  *
37  * To add HTML that should be cached, use addCachedHTML like this:
38  * $this->addCachedHTML( $callback );
39  *
40  * The callback function is only called when needed, so do all your expensive
41  * computations here. This function should returns the HTML to be cached.
42  * It should not add anything to the PageOutput object!
43  *
44  * @ingroup Actions
45  */
46 abstract class CachedAction extends FormlessAction implements ICacheHelper {
47
48         /**
49          * CacheHelper object to which we forward the non-SpecialPage specific caching work.
50          * Initialized in startCache.
51          *
52          * @since 1.20
53          * @var CacheHelper
54          */
55         protected $cacheHelper;
56
57         /**
58          * If the cache is enabled or not.
59          *
60          * @since 1.20
61          * @var bool
62          */
63         protected $cacheEnabled = true;
64
65         /**
66          * Sets if the cache should be enabled or not.
67          *
68          * @since 1.20
69          * @param bool $cacheEnabled
70          */
71         public function setCacheEnabled( $cacheEnabled ) {
72                 $this->cacheHelper->setCacheEnabled( $cacheEnabled );
73         }
74
75         /**
76          * Initializes the caching.
77          * Should be called before the first time anything is added via addCachedHTML.
78          *
79          * @since 1.20
80          *
81          * @param int|null $cacheExpiry Sets the cache expiry, either ttl in seconds or unix timestamp.
82          * @param bool|null $cacheEnabled Sets if the cache should be enabled or not.
83          */
84         public function startCache( $cacheExpiry = null, $cacheEnabled = null ) {
85                 $this->cacheHelper = new CacheHelper();
86
87                 $this->cacheHelper->setCacheEnabled( $this->cacheEnabled );
88                 $this->cacheHelper->setOnInitializedHandler( [ $this, 'onCacheInitialized' ] );
89
90                 $keyArgs = $this->getCacheKey();
91
92                 if ( array_key_exists( 'action', $keyArgs ) && $keyArgs['action'] === 'purge' ) {
93                         unset( $keyArgs['action'] );
94                 }
95
96                 $this->cacheHelper->setCacheKey( $keyArgs );
97
98                 if ( $this->getRequest()->getText( 'action' ) === 'purge' ) {
99                         $this->cacheHelper->rebuildOnDemand();
100                 }
101
102                 $this->cacheHelper->startCache( $cacheExpiry, $cacheEnabled );
103         }
104
105         /**
106          * Get a cached value if available or compute it if not and then cache it if possible.
107          * The provided $computeFunction is only called when the computation needs to happen
108          * and should return a result value. $args are arguments that will be passed to the
109          * compute function when called.
110          *
111          * @since 1.20
112          *
113          * @param callable $computeFunction
114          * @param array|mixed $args
115          * @param string|null $key
116          *
117          * @return mixed
118          */
119         public function getCachedValue( $computeFunction, $args = [], $key = null ) {
120                 return $this->cacheHelper->getCachedValue( $computeFunction, $args, $key );
121         }
122
123         /**
124          * Add some HTML to be cached.
125          * This is done by providing a callback function that should
126          * return the HTML to be added. It will only be called if the
127          * item is not in the cache yet or when the cache has been invalidated.
128          *
129          * @since 1.20
130          *
131          * @param callable $computeFunction
132          * @param array $args
133          * @param string|null $key
134          */
135         public function addCachedHTML( $computeFunction, $args = [], $key = null ) {
136                 $html = $this->cacheHelper->getCachedValue( $computeFunction, $args, $key );
137                 $this->getOutput()->addHTML( $html );
138         }
139
140         /**
141          * Saves the HTML to the cache in case it got recomputed.
142          * Should be called after the last time anything is added via addCachedHTML.
143          *
144          * @since 1.20
145          */
146         public function saveCache() {
147                 $this->cacheHelper->saveCache();
148         }
149
150         /**
151          * Sets the time to live for the cache, in seconds or a unix timestamp
152          * indicating the point of expiry.
153          *
154          * @since 1.20
155          *
156          * @param int $cacheExpiry
157          */
158         public function setExpiry( $cacheExpiry ) {
159                 $this->cacheHelper->setExpiry( $cacheExpiry );
160         }
161
162         /**
163          * Returns the variables used to constructed the cache key in an array.
164          *
165          * @since 1.20
166          *
167          * @return array
168          */
169         protected function getCacheKey() {
170                 return [
171                         get_class( $this->page ),
172                         $this->getName(),
173                         $this->getLanguage()->getCode()
174                 ];
175         }
176
177         /**
178          * Gets called after the cache got initialized.
179          *
180          * @since 1.20
181          *
182          * @param bool $hasCached
183          */
184         public function onCacheInitialized( $hasCached ) {
185                 if ( $hasCached ) {
186                         $this->getOutput()->setSubtitle( $this->cacheHelper->getCachedNotice( $this->getContext() ) );
187                 }
188         }
189 }