3 * Access to properties of a page.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
24 * Gives access to properties of a page.
34 private static $instance;
39 public static function getInstance() {
40 if ( self
::$instance === null ) {
41 self
::$instance = new self();
43 return self
::$instance;
46 /** Cache parameters */
47 const CACHE_TTL
= 10; // integer; TTL in seconds
48 const CACHE_SIZE
= 100; // integer; max cached pages
51 private $cache = null;
54 * Create a PageProps object
56 private function __construct() {
57 $this->cache
= new ProcessCacheLRU( self
::CACHE_SIZE
);
61 * Given one or more Titles and one or more names of properties,
62 * returns an associative array mapping page ID to property value.
63 * Pages in the provided set of Titles that do not have a value for
64 * the given properties will not appear in the returned array. If a
65 * single Title is provided, it does not need to be passed in an array,
66 * but an array will always be returned. If a single property name is
67 * provided, it does not need to be passed in an array. In that case,
68 * an associtive array mapping page ID to property value will be
69 * returned; otherwise, an associative array mapping page ID to
70 * an associative array mapping property name to property value will be
71 * returned. An empty array will be returned if no matching properties
74 * @param Title[]|Title $titles
75 * @param string[]|string $propertyNames
76 * @return array associative array mapping page ID to property value
78 public function getProperties( $titles, $propertyNames ) {
79 if ( is_array( $propertyNames ) ) {
82 $propertyNames = [ $propertyNames ];
87 $goodIDs = $this->getGoodIDs( $titles );
89 foreach ( $goodIDs as $pageID ) {
90 foreach ( $propertyNames as $propertyName ) {
91 $propertyValue = $this->getCachedProperty( $pageID, $propertyName );
92 if ( $propertyValue === false ) {
93 $queryIDs[] = $pageID;
97 $values[$pageID][$propertyName] = $propertyValue;
99 $values[$pageID] = $propertyValue;
106 $dbr = wfGetDB( DB_SLAVE
);
107 $result = $dbr->select(
115 'pp_page' => $queryIDs,
116 'pp_propname' => $propertyNames
121 foreach ( $result as $row ) {
122 $pageID = $row->pp_page
;
123 $propertyName = $row->pp_propname
;
124 $propertyValue = $row->pp_value
;
125 $this->cacheProperty( $pageID, $propertyName, $propertyValue );
127 $values[$pageID][$propertyName] = $propertyValue;
129 $values[$pageID] = $propertyValue;
138 * Get all page property values.
139 * Given one or more Titles, returns an associative array mapping page
140 * ID to an associative array mapping property names to property
141 * values. Pages in the provided set of Titles that do not have any
142 * properties will not appear in the returned array. If a single Title
143 * is provided, it does not need to be passed in an array, but an array
144 * will always be returned. An empty array will be returned if no
145 * matching properties were found.
147 * @param Title[]|Title $titles
148 * @return array associative array mapping page ID to property value array
150 public function getAllProperties( $titles ) {
152 $goodIDs = $this->getGoodIDs( $titles );
154 foreach ( $goodIDs as $pageID ) {
155 $pageProperties = $this->getCachedProperties( $pageID );
156 if ( $pageProperties === false ) {
157 $queryIDs[] = $pageID;
159 $values[$pageID] = $pageProperties;
163 if ( $queryIDs != [] ) {
164 $dbr = wfGetDB( DB_SLAVE
);
165 $result = $dbr->select(
173 'pp_page' => $queryIDs,
179 $pageProperties = [];
180 foreach ( $result as $row ) {
181 $pageID = $row->pp_page
;
182 if ( $currentPageID != $pageID ) {
183 if ( $pageProperties != [] ) {
184 $this->cacheProperties( $currentPageID, $pageProperties );
185 $values[$currentPageID] = $pageProperties;
187 $currentPageID = $pageID;
188 $pageProperties = [];
190 $pageProperties[$row->pp_propname
] = $row->pp_value
;
192 if ( $pageProperties != [] ) {
193 $this->cacheProperties( $pageID, $pageProperties );
194 $values[$pageID] = $pageProperties;
202 * @param Title[]|Title $titles
203 * @return array array of good page IDs
205 private function getGoodIDs( $titles ) {
207 if ( is_array( $titles ) ) {
208 foreach ( $titles as $title ) {
209 $pageID = $title->getArticleID();
215 $pageID = $titles->getArticleID();
224 * Get a property from the cache.
226 * @param int $pageID page ID of page being queried
227 * @param string $propertyName name of property being queried
228 * @return string|bool property value array or false if not found
230 private function getCachedProperty( $pageID, $propertyName ) {
231 if ( $this->cache
->has( $pageID, $propertyName, self
::CACHE_TTL
) ) {
232 return $this->cache
->get( $pageID, $propertyName );
234 if ( $this->cache
->has( 0, $pageID, self
::CACHE_TTL
) ) {
235 $pageProperties = $this->cache
->get( 0, $pageID );
236 if ( isset( $pageProperties[$propertyName] ) ) {
237 return $pageProperties[$propertyName];
244 * Get properties from the cache.
246 * @param int $pageID page ID of page being queried
247 * @return string|bool property value array or false if not found
249 private function getCachedProperties( $pageID ) {
250 if ( $this->cache
->has( 0, $pageID, self
::CACHE_TTL
) ) {
251 return $this->cache
->get( 0, $pageID );
257 * Save a property to the cache.
259 * @param int $pageID page ID of page being cached
260 * @param string $propertyName name of property being cached
261 * @param mixed $propertyValue value of property
263 private function cacheProperty( $pageID, $propertyName, $propertyValue ) {
264 $this->cache
->set( $pageID, $propertyName, $propertyValue );
268 * Save properties to the cache.
270 * @param int $pageID page ID of page being cached
271 * @param string[] $pageProperties associative array of page properties to be cached
273 private function cacheProperties( $pageID, $pageProperties ) {
274 $this->cache
->clear( $pageID );
275 $this->cache
->set( 0, $pageID, $pageProperties );