MediaWiki REL1_37
PageProps.php
Go to the documentation of this file.
1<?php
27
33class PageProps {
34
37
40
42 private const CACHE_TTL = 10; // integer; TTL in seconds
43 private const CACHE_SIZE = 100; // integer; max cached pages
44
46 private $cache;
47
51 public static function getInstance() {
52 return MediaWikiServices::getInstance()->getPageProps();
53 }
54
59 public function __construct(
60 LinkBatchFactory $linkBatchFactory,
61 ILoadBalancer $loadBalancer
62 ) {
63 $this->linkBatchFactory = $linkBatchFactory;
64 $this->loadBalancer = $loadBalancer;
65 $this->cache = new MapCacheLRU( self::CACHE_SIZE );
66 }
67
72 public function ensureCacheSize( $size ) {
73 if ( $this->cache->getMaxSize() < $size ) {
74 $this->cache->setMaxSize( $size );
75 }
76 }
77
96 public function getProperties( $titles, $propertyNames ) {
97 if ( is_array( $propertyNames ) ) {
98 $gotArray = true;
99 } else {
100 $propertyNames = [ $propertyNames ];
101 $gotArray = false;
102 }
103
104 $values = [];
105 $goodIDs = $this->getGoodIDs( $titles );
106 $queryIDs = [];
107 foreach ( $goodIDs as $pageID ) {
108 foreach ( $propertyNames as $propertyName ) {
109 $propertyValue = $this->getCachedProperty( $pageID, $propertyName );
110 if ( $propertyValue === false ) {
111 $queryIDs[] = $pageID;
112 break;
113 } elseif ( $gotArray ) {
114 $values[$pageID][$propertyName] = $propertyValue;
115 } else {
116 $values[$pageID] = $propertyValue;
117 }
118 }
119 }
120
121 if ( $queryIDs ) {
122 $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
123 $result = $dbr->select(
124 'page_props',
125 [
126 'pp_page',
127 'pp_propname',
128 'pp_value'
129 ],
130 [
131 'pp_page' => $queryIDs,
132 'pp_propname' => $propertyNames
133 ],
134 __METHOD__
135 );
136
137 foreach ( $result as $row ) {
138 $pageID = $row->pp_page;
139 $propertyName = $row->pp_propname;
140 $propertyValue = $row->pp_value;
141 $this->cache->setField( $pageID, $propertyName, $propertyValue );
142 if ( $gotArray ) {
143 $values[$pageID][$propertyName] = $propertyValue;
144 } else {
145 $values[$pageID] = $propertyValue;
146 }
147 }
148 }
149
150 return $values;
151 }
152
166 public function getAllProperties( $titles ) {
167 $values = [];
168 $goodIDs = $this->getGoodIDs( $titles );
169 $queryIDs = [];
170 foreach ( $goodIDs as $pageID ) {
171 $pageProperties = $this->getCachedProperties( $pageID );
172 if ( $pageProperties === false ) {
173 $queryIDs[] = $pageID;
174 } else {
175 $values[$pageID] = $pageProperties;
176 }
177 }
178
179 if ( $queryIDs != [] ) {
180 $dbr = $this->loadBalancer->getConnectionRef( DB_REPLICA );
181 $result = $dbr->select(
182 'page_props',
183 [
184 'pp_page',
185 'pp_propname',
186 'pp_value'
187 ],
188 [
189 'pp_page' => $queryIDs,
190 ],
191 __METHOD__
192 );
193
194 $currentPageID = 0;
195 $pageProperties = [];
196 foreach ( $result as $row ) {
197 $pageID = $row->pp_page;
198 if ( $currentPageID != $pageID ) {
199 if ( $pageProperties ) {
200 // @phan-suppress-next-line PhanTypeMismatchArgument False positive
201 $this->cacheProperties( $currentPageID, $pageProperties );
202 $values[$currentPageID] = $pageProperties;
203 }
204 $currentPageID = $pageID;
205 $pageProperties = [];
206 }
207 $pageProperties[$row->pp_propname] = $row->pp_value;
208 }
209 if ( $pageProperties != [] ) {
210 $this->cacheProperties( $pageID, $pageProperties );
211 $values[$pageID] = $pageProperties;
212 }
213 }
214
215 return $values;
216 }
217
222 private function getGoodIDs( $titles ) {
223 $result = [];
224 if ( is_iterable( $titles ) ) {
225 if ( $titles instanceof TitleArray ||
226 ( is_array( $titles ) && reset( $titles ) instanceof Title
227 ) ) {
228 // If the first element is a Title, assume all elements are Titles,
229 // and pre-fetch their IDs using a batch query. For PageIdentityValues
230 // or PageStoreRecords, this is not necessary, since they already
231 // know their ID.
232 $this->linkBatchFactory->newLinkBatch( $titles )->execute();
233 }
234
235 foreach ( $titles as $title ) {
236 // Until we only allow ProperPageIdentity, Title objects
237 // can deceive us with an unexpected Special page
238 if ( $title->canExist() ) {
239 $pageID = $title->getId();
240 if ( $pageID > 0 ) {
241 $result[] = $pageID;
242 }
243 }
244 }
245 } else {
246 // Until we only allow ProperPageIdentity, Title objects
247 // can deceive us with an unexpected Special page
248 if ( $titles->canExist() ) {
249 $pageID = $titles->getId();
250 if ( $pageID > 0 ) {
251 $result[] = $pageID;
252 }
253 }
254 }
255 return $result;
256 }
257
265 private function getCachedProperty( $pageID, $propertyName ) {
266 if ( $this->cache->hasField( $pageID, $propertyName, self::CACHE_TTL ) ) {
267 return $this->cache->getField( $pageID, $propertyName );
268 }
269 if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
270 $pageProperties = $this->cache->getField( 0, $pageID );
271 if ( isset( $pageProperties[$propertyName] ) ) {
272 return $pageProperties[$propertyName];
273 }
274 }
275 return false;
276 }
277
284 private function getCachedProperties( $pageID ) {
285 if ( $this->cache->hasField( 0, $pageID, self::CACHE_TTL ) ) {
286 return $this->cache->getField( 0, $pageID );
287 }
288 return false;
289 }
290
297 private function cacheProperties( $pageID, $pageProperties ) {
298 $this->cache->clear( $pageID );
299 $this->cache->setField( 0, $pageID, $pageProperties );
300 }
301}
Handles a simple LRU key/value map with a maximum number of entries.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Gives access to properties of a page.
Definition PageProps.php:33
__construct(LinkBatchFactory $linkBatchFactory, ILoadBalancer $loadBalancer)
Definition PageProps.php:59
const CACHE_SIZE
Definition PageProps.php:43
getGoodIDs( $titles)
ILoadBalancer $loadBalancer
Definition PageProps.php:39
ensureCacheSize( $size)
Ensure that cache has at least this size.
Definition PageProps.php:72
getCachedProperty( $pageID, $propertyName)
Get a property from the cache.
getProperties( $titles, $propertyNames)
Given one or more Titles and one or more names of properties, returns an associative array mapping pa...
Definition PageProps.php:96
const CACHE_TTL
Cache parameters.
Definition PageProps.php:42
LinkBatchFactory $linkBatchFactory
Definition PageProps.php:36
getCachedProperties( $pageID)
Get properties from the cache.
cacheProperties( $pageID, $pageProperties)
Save properties to the cache.
static getInstance()
Definition PageProps.php:51
getAllProperties( $titles)
Get all page property values.
MapCacheLRU $cache
Definition PageProps.php:46
The TitleArray class only exists to provide the newFromResult method at pre- sent.
Represents a title within MediaWiki.
Definition Title.php:48
Interface for objects (potentially) representing an editable wiki page.
Database cluster connection, tracking, load balancing, and transaction manager interface.
const DB_REPLICA
Definition defines.php:25