[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Represents the site configuration of a wiki. 5 * Holds a list of sites (ie SiteList) and takes care 6 * of retrieving and caching site information when appropriate. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 * http://www.gnu.org/copyleft/gpl.html 22 * 23 * @since 1.21 24 * 25 * @file 26 * @ingroup Site 27 * 28 * @license GNU GPL v2+ 29 * @author Jeroen De Dauw < [email protected] > 30 */ 31 class SiteSQLStore implements SiteStore { 32 /** 33 * @since 1.21 34 * 35 * @var SiteList|null 36 */ 37 protected $sites = null; 38 39 /** 40 * @var ORMTable 41 */ 42 protected $sitesTable; 43 44 /** 45 * @var string|null 46 */ 47 private $cacheKey = null; 48 49 /** 50 * @var int 51 */ 52 private $cacheTimeout = 3600; 53 54 /** 55 * @since 1.21 56 * 57 * @param ORMTable|null $sitesTable 58 * 59 * @return SiteStore 60 */ 61 public static function newInstance( ORMTable $sitesTable = null ) { 62 return new static( $sitesTable ); 63 } 64 65 /** 66 * Constructor. 67 * 68 * @since 1.21 69 * 70 * @param ORMTable|null $sitesTable 71 */ 72 protected function __construct( ORMTable $sitesTable = null ) { 73 if ( $sitesTable === null ) { 74 $sitesTable = $this->newSitesTable(); 75 } 76 77 $this->sitesTable = $sitesTable; 78 } 79 80 /** 81 * Constructs a cache key to use for caching the list of sites. 82 * 83 * This includes the concrete class name of the site list as well as a version identifier 84 * for the list's serialization, to avoid problems when unserializing site lists serialized 85 * by an older version, e.g. when reading from a cache. 86 * 87 * The cache key also includes information about where the sites were loaded from, e.g. 88 * the name of a database table. 89 * 90 * @see SiteList::getSerialVersionId 91 * 92 * @return string The cache key. 93 */ 94 protected function getCacheKey() { 95 wfProfileIn( __METHOD__ ); 96 97 if ( $this->cacheKey === null ) { 98 $type = 'SiteList#' . SiteList::getSerialVersionId(); 99 $source = $this->sitesTable->getName(); 100 101 if ( $this->sitesTable->getTargetWiki() !== false ) { 102 $source = $this->sitesTable->getTargetWiki() . '.' . $source; 103 } 104 105 $this->cacheKey = wfMemcKey( "$source/$type" ); 106 } 107 108 wfProfileOut( __METHOD__ ); 109 return $this->cacheKey; 110 } 111 112 /** 113 * @see SiteStore::getSites 114 * 115 * @since 1.21 116 * 117 * @param string $source Either 'cache' or 'recache' 118 * 119 * @return SiteList 120 */ 121 public function getSites( $source = 'cache' ) { 122 wfProfileIn( __METHOD__ ); 123 124 if ( $source === 'cache' ) { 125 if ( $this->sites === null ) { 126 $cache = wfGetMainCache(); 127 $sites = $cache->get( $this->getCacheKey() ); 128 129 if ( is_object( $sites ) ) { 130 $this->sites = $sites; 131 } else { 132 $this->loadSites(); 133 } 134 } 135 } 136 else { 137 $this->loadSites(); 138 } 139 140 wfProfileOut( __METHOD__ ); 141 return $this->sites; 142 } 143 144 /** 145 * Returns a new Site object constructed from the provided ORMRow. 146 * 147 * @since 1.21 148 * 149 * @param ORMRow $siteRow 150 * 151 * @return Site 152 */ 153 protected function siteFromRow( ORMRow $siteRow ) { 154 wfProfileIn( __METHOD__ ); 155 156 $site = Site::newForType( $siteRow->getField( 'type', Site::TYPE_UNKNOWN ) ); 157 158 $site->setGlobalId( $siteRow->getField( 'global_key' ) ); 159 160 $site->setInternalId( $siteRow->getField( 'id' ) ); 161 162 if ( $siteRow->hasField( 'forward' ) ) { 163 $site->setForward( $siteRow->getField( 'forward' ) ); 164 } 165 166 if ( $siteRow->hasField( 'group' ) ) { 167 $site->setGroup( $siteRow->getField( 'group' ) ); 168 } 169 170 if ( $siteRow->hasField( 'language' ) ) { 171 $site->setLanguageCode( $siteRow->getField( 'language' ) === '' 172 ? null 173 : $siteRow->getField( 'language' ) 174 ); 175 } 176 177 if ( $siteRow->hasField( 'source' ) ) { 178 $site->setSource( $siteRow->getField( 'source' ) ); 179 } 180 181 if ( $siteRow->hasField( 'data' ) ) { 182 $site->setExtraData( $siteRow->getField( 'data' ) ); 183 } 184 185 if ( $siteRow->hasField( 'config' ) ) { 186 $site->setExtraConfig( $siteRow->getField( 'config' ) ); 187 } 188 189 wfProfileOut( __METHOD__ ); 190 return $site; 191 } 192 193 /** 194 * Get a new ORMRow from a Site object 195 * 196 * @since 1.22 197 * 198 * @param Site $site 199 * 200 * @return ORMRow 201 */ 202 protected function getRowFromSite( Site $site ) { 203 $fields = array( 204 // Site data 205 'global_key' => $site->getGlobalId(), // TODO: check not null 206 'type' => $site->getType(), 207 'group' => $site->getGroup(), 208 'source' => $site->getSource(), 209 'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(), 210 'protocol' => $site->getProtocol(), 211 'domain' => strrev( $site->getDomain() ) . '.', 212 'data' => $site->getExtraData(), 213 214 // Site config 215 'forward' => $site->shouldForward(), 216 'config' => $site->getExtraConfig(), 217 ); 218 219 if ( $site->getInternalId() !== null ) { 220 $fields['id'] = $site->getInternalId(); 221 } 222 223 return new ORMRow( $this->sitesTable, $fields ); 224 } 225 226 /** 227 * Fetches the site from the database and loads them into the sites field. 228 * 229 * @since 1.21 230 */ 231 protected function loadSites() { 232 wfProfileIn( __METHOD__ ); 233 234 $this->sites = new SiteList(); 235 236 foreach ( $this->sitesTable->select() as $siteRow ) { 237 $this->sites[] = $this->siteFromRow( $siteRow ); 238 } 239 240 // Batch load the local site identifiers. 241 $ids = wfGetDB( $this->sitesTable->getReadDb() )->select( 242 'site_identifiers', 243 array( 244 'si_site', 245 'si_type', 246 'si_key', 247 ), 248 array(), 249 __METHOD__ 250 ); 251 252 foreach ( $ids as $id ) { 253 if ( $this->sites->hasInternalId( $id->si_site ) ) { 254 $site = $this->sites->getSiteByInternalId( $id->si_site ); 255 $site->addLocalId( $id->si_type, $id->si_key ); 256 $this->sites->setSite( $site ); 257 } 258 } 259 260 $cache = wfGetMainCache(); 261 $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout ); 262 263 wfProfileOut( __METHOD__ ); 264 } 265 266 /** 267 * @see SiteStore::getSite 268 * 269 * @since 1.21 270 * 271 * @param string $globalId 272 * @param string $source 273 * 274 * @return Site|null 275 */ 276 public function getSite( $globalId, $source = 'cache' ) { 277 wfProfileIn( __METHOD__ ); 278 279 $sites = $this->getSites( $source ); 280 281 wfProfileOut( __METHOD__ ); 282 return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null; 283 } 284 285 /** 286 * @see SiteStore::saveSite 287 * 288 * @since 1.21 289 * 290 * @param Site $site 291 * 292 * @return bool Success indicator 293 */ 294 public function saveSite( Site $site ) { 295 return $this->saveSites( array( $site ) ); 296 } 297 298 /** 299 * @see SiteStore::saveSites 300 * 301 * @since 1.21 302 * 303 * @param Site[] $sites 304 * 305 * @return bool Success indicator 306 */ 307 public function saveSites( array $sites ) { 308 wfProfileIn( __METHOD__ ); 309 310 if ( empty( $sites ) ) { 311 wfProfileOut( __METHOD__ ); 312 return true; 313 } 314 315 $dbw = $this->sitesTable->getWriteDbConnection(); 316 317 $dbw->startAtomic( __METHOD__ ); 318 319 $success = true; 320 321 $internalIds = array(); 322 $localIds = array(); 323 324 foreach ( $sites as $site ) { 325 if ( $site->getInternalId() !== null ) { 326 $internalIds[] = $site->getInternalId(); 327 } 328 329 $siteRow = $this->getRowFromSite( $site ); 330 $success = $siteRow->save( __METHOD__ ) && $success; 331 332 foreach ( $site->getLocalIds() as $idType => $ids ) { 333 foreach ( $ids as $id ) { 334 $localIds[] = array( $siteRow->getId(), $idType, $id ); 335 } 336 } 337 } 338 339 if ( $internalIds !== array() ) { 340 $dbw->delete( 341 'site_identifiers', 342 array( 'si_site' => $internalIds ), 343 __METHOD__ 344 ); 345 } 346 347 foreach ( $localIds as $localId ) { 348 $dbw->insert( 349 'site_identifiers', 350 array( 351 'si_site' => $localId[0], 352 'si_type' => $localId[1], 353 'si_key' => $localId[2], 354 ), 355 __METHOD__ 356 ); 357 } 358 359 $dbw->endAtomic( __METHOD__ ); 360 361 // purge cache 362 $this->reset(); 363 364 wfProfileOut( __METHOD__ ); 365 return $success; 366 } 367 368 /** 369 * Purges the internal and external cache of the site list, forcing the list 370 * of sites to be re-read from the database. 371 * 372 * @since 1.21 373 */ 374 public function reset() { 375 wfProfileIn( __METHOD__ ); 376 // purge cache 377 $cache = wfGetMainCache(); 378 $cache->delete( $this->getCacheKey() ); 379 $this->sites = null; 380 381 wfProfileOut( __METHOD__ ); 382 } 383 384 /** 385 * Clears the list of sites stored in the database. 386 * 387 * @see SiteStore::clear() 388 * 389 * @return bool Success 390 */ 391 public function clear() { 392 wfProfileIn( __METHOD__ ); 393 $dbw = $this->sitesTable->getWriteDbConnection(); 394 395 $dbw->startAtomic( __METHOD__ ); 396 $ok = $dbw->delete( 'sites', '*', __METHOD__ ); 397 $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok; 398 $dbw->endAtomic( __METHOD__); 399 400 $this->reset(); 401 402 wfProfileOut( __METHOD__ ); 403 return $ok; 404 } 405 406 /** 407 * @since 1.21 408 * 409 * @return ORMTable 410 */ 411 protected function newSitesTable() { 412 return new ORMTable( 413 'sites', 414 array( 415 'id' => 'id', 416 417 // Site data 418 'global_key' => 'str', 419 'type' => 'str', 420 'group' => 'str', 421 'source' => 'str', 422 'language' => 'str', 423 'protocol' => 'str', 424 'domain' => 'str', 425 'data' => 'array', 426 427 // Site config 428 'forward' => 'bool', 429 'config' => 'array', 430 ), 431 array( 432 'type' => Site::TYPE_UNKNOWN, 433 'group' => Site::GROUP_NONE, 434 'source' => Site::SOURCE_LOCAL, 435 'data' => array(), 436 437 'forward' => false, 438 'config' => array(), 439 'language' => '', 440 ), 441 'ORMRow', 442 'site_' 443 ); 444 } 445 446 } 447 448 /** 449 * @deprecated since 1.21 450 */ 451 class Sites extends SiteSQLStore { 452 453 /** 454 * Factory for creating new site objects. 455 * 456 * @since 1.21 457 * @deprecated since 1.21 458 * 459 * @param string|bool $globalId 460 * 461 * @return Site 462 */ 463 public static function newSite( $globalId = false ) { 464 $site = new Site(); 465 466 if ( $globalId !== false ) { 467 $site->setGlobalId( $globalId ); 468 } 469 470 return $site; 471 } 472 473 /** 474 * @deprecated since 1.21 475 * @return SiteStore 476 */ 477 public static function singleton() { 478 static $singleton; 479 480 if ( $singleton === null ) { 481 $singleton = new static(); 482 } 483 484 return $singleton; 485 } 486 487 /** 488 * @deprecated since 1.21 489 * @param string $group 490 * @return SiteList 491 */ 492 public function getSiteGroup( $group ) { 493 return $this->getSites()->getGroup( $group ); 494 } 495 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |