MediaWiki REL1_35
PageProps.php
Go to the documentation of this file.
1<?php
22use Wikimedia\ScopedCallback;
23
29class PageProps {
30
34 private static $instance;
35
50 public static function overrideInstance( PageProps $store = null ) {
51 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
52 throw new MWException(
53 'Cannot override ' . __CLASS__ . 'default instance in operation.'
54 );
55 }
56 $previousValue = self::$instance;
57 self::$instance = $store;
58 return new ScopedCallback( function () use ( $previousValue ) {
59 self::$instance = $previousValue;
60 } );
61 }
62
66 public static function getInstance() {
67 if ( self::$instance === null ) {
68 self::$instance = new self();
69 }
70 return self::$instance;
71 }
72
74 private const CACHE_TTL = 10; // integer; TTL in seconds
75 private const CACHE_SIZE = 100; // integer; max cached pages
76
78 private $cache = null;
79
83 private function __construct() {
84 $this->cache = new MapCacheLRU( self::CACHE_SIZE );
85 }
86
91 public function ensureCacheSize( $size ) {
92 if ( $this->cache->getMaxSize() < $size ) {
93 $this->cache->setMaxSize( $size );
94 }
95 }
96
115 public function getProperties( $titles, $propertyNames ) {
116 if ( is_array( $propertyNames ) ) {
117 $gotArray = true;
118 } else {
119 $propertyNames = [ $propertyNames ];
120 $gotArray = false;
121 }
122
123 $values = [];
124 $goodIDs = $this->getGoodIDs( $titles );
125 $queryIDs = [];
126 foreach ( $goodIDs as $pageID ) {
127 foreach ( $propertyNames as $propertyName ) {
128 $propertyValue = $this->getCachedProperty( $pageID, $propertyName );
129 if ( $propertyValue === false ) {
130 $queryIDs[] = $pageID;
131 break;
132 } elseif ( $gotArray ) {
133 $values[$pageID][$propertyName] = $propertyValue;
134 } else {
135 $values[$pageID] = $propertyValue;
136 }
137 }
138 }
139
140 if ( $queryIDs ) {
142 $result = $dbr->select(
143 'page_props',
144 [
145 'pp_page',
146 'pp_propname',
147 'pp_value'
148 ],
149 [
150 'pp_page' => $queryIDs,
151 'pp_propname' => $propertyNames
152 ],
153 __METHOD__
154 );
155
156 foreach ( $result as $row ) {
157 $pageID = $row->pp_page;
158 $propertyName = $row->pp_propname;
159 $propertyValue = $row->pp_value;
160 $this->cacheProperty( $pageID, $propertyName, $propertyValue );
161 if ( $gotArray ) {
162 $values[$pageID][$propertyName] = $propertyValue;
163 } else {
164 $values[$pageID] = $propertyValue;
165 }
166 }
167 }
168
169 return $values;
170 }
171
185 public function getAllProperties( $titles ) {
186 $values = [];
187 $goodIDs = $this->getGoodIDs( $titles );
188 $queryIDs = [];
189 foreach ( $goodIDs as $pageID ) {
190 $pageProperties = $this->getCachedProperties( $pageID );
191 if ( $pageProperties === false ) {
192 $queryIDs[] = $pageID;
193 } else {
194 $values[$pageID] = $pageProperties;
195 }
196 }
197
198 if ( $queryIDs != [] ) {
200 $result = $dbr->select(
201 'page_props',
202 [
203 'pp_page',
204 'pp_propname',
205 'pp_value'
206 ],
207 [
208 'pp_page' => $queryIDs,
209 ],
210 __METHOD__
211 );
212
213 $currentPageID = 0;
214 $pageProperties = [];
215 foreach ( $result as $row ) {
216 $pageID = $row->pp_page;
217 if ( $currentPageID != $pageID ) {
218 if ( $pageProperties ) {
219 // @phan-suppress-next-line PhanTypeMismatchArgument False positive
220 $this->cacheProperties( $currentPageID, $pageProperties );
221 $values[$currentPageID] = $pageProperties;
222 }
223 $currentPageID = $pageID;
224 $pageProperties = [];
225 }
226 $pageProperties[$row->pp_propname] = $row->pp_value;
227 }
228 if ( $pageProperties != [] ) {
229 $this->cacheProperties( $pageID, $pageProperties );
230 $values[$pageID] = $pageProperties;
231 }
232 }
233
234 return $values;
235 }
236
241 private function getGoodIDs( $titles ) {
242 $result = [];
243 if ( is_array( $titles ) ) {
244 ( new LinkBatch( $titles ) )->execute();
245
246 foreach ( $titles as $title ) {
247 $pageID = $title->getArticleID();
248 if ( $pageID > 0 ) {
249 $result[] = $pageID;
250 }
251 }
252 } else {
253 $pageID = $titles->getArticleID();
254 if ( $pageID > 0 ) {
255 $result[] = $pageID;
256 }
257 }
258 return $result;
259 }
260
268 private function getCachedProperty( $pageID, $propertyName ) {
269 if ( $this->cache->hasField( $pageID, $propertyName, self::CACHE_TTL ) ) {
270 return $this->cache->getField( $pageID, $propertyName );
271 }
272 if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
273 $pageProperties = $this->cache->getField( 0, $pageID );
274 if ( isset( $pageProperties[$propertyName] ) ) {
275 return $pageProperties[$propertyName];
276 }
277 }
278 return false;
279 }
280
287 private function getCachedProperties( $pageID ) {
288 if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
289 return $this->cache->getField( 0, $pageID );
290 }
291 return false;
292 }
293
301 private function cacheProperty( $pageID, $propertyName, $propertyValue ) {
302 $this->cache->setField( $pageID, $propertyName, $propertyValue );
303 }
304
311 private function cacheProperties( $pageID, $pageProperties ) {
312 $this->cache->clear( $pageID );
313 $this->cache->setField( 0, $pageID, $pageProperties );
314 }
315}
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition LinkBatch.php:35
MediaWiki exception.
Handles a simple LRU key/value map with a maximum number of entries.
Gives access to properties of a page.
Definition PageProps.php:29
const CACHE_SIZE
Definition PageProps.php:75
getGoodIDs( $titles)
$cache
Property cache.
Definition PageProps.php:78
static overrideInstance(PageProps $store=null)
Overrides the default instance of this class This is intended for use while testing and will fail if ...
Definition PageProps.php:50
static PageProps $instance
Definition PageProps.php:34
ensureCacheSize( $size)
Ensure that cache has at least this size.
Definition PageProps.php:91
getCachedProperty( $pageID, $propertyName)
Get a property from the cache.
cacheProperty( $pageID, $propertyName, $propertyValue)
Save a property to the cache.
getProperties( $titles, $propertyNames)
Given one or more Titles and one or more names of properties, returns an associative array mapping pa...
const CACHE_TTL
Cache parameters.
Definition PageProps.php:74
getCachedProperties( $pageID)
Get properties from the cache.
__construct()
Create a PageProps object.
Definition PageProps.php:83
cacheProperties( $pageID, $pageProperties)
Save properties to the cache.
static getInstance()
Definition PageProps.php:66
getAllProperties( $titles)
Get all page property values.
const DB_REPLICA
Definition defines.php:25