MediaWiki
REL1_24
|
00001 <?php 00002 00031 class SiteSQLStore implements SiteStore { 00037 protected $sites = null; 00038 00042 protected $sitesTable; 00043 00047 private $cacheKey = null; 00048 00052 private $cacheTimeout = 3600; 00053 00061 public static function newInstance( ORMTable $sitesTable = null ) { 00062 return new static( $sitesTable ); 00063 } 00064 00072 protected function __construct( ORMTable $sitesTable = null ) { 00073 if ( $sitesTable === null ) { 00074 $sitesTable = $this->newSitesTable(); 00075 } 00076 00077 $this->sitesTable = $sitesTable; 00078 } 00079 00094 protected function getCacheKey() { 00095 wfProfileIn( __METHOD__ ); 00096 00097 if ( $this->cacheKey === null ) { 00098 $type = 'SiteList#' . SiteList::getSerialVersionId(); 00099 $source = $this->sitesTable->getName(); 00100 00101 if ( $this->sitesTable->getTargetWiki() !== false ) { 00102 $source = $this->sitesTable->getTargetWiki() . '.' . $source; 00103 } 00104 00105 $this->cacheKey = wfMemcKey( "$source/$type" ); 00106 } 00107 00108 wfProfileOut( __METHOD__ ); 00109 return $this->cacheKey; 00110 } 00111 00121 public function getSites( $source = 'cache' ) { 00122 wfProfileIn( __METHOD__ ); 00123 00124 if ( $source === 'cache' ) { 00125 if ( $this->sites === null ) { 00126 $cache = wfGetMainCache(); 00127 $sites = $cache->get( $this->getCacheKey() ); 00128 00129 if ( is_object( $sites ) ) { 00130 $this->sites = $sites; 00131 } else { 00132 $this->loadSites(); 00133 } 00134 } 00135 } 00136 else { 00137 $this->loadSites(); 00138 } 00139 00140 wfProfileOut( __METHOD__ ); 00141 return $this->sites; 00142 } 00143 00153 protected function siteFromRow( ORMRow $siteRow ) { 00154 wfProfileIn( __METHOD__ ); 00155 00156 $site = Site::newForType( $siteRow->getField( 'type', Site::TYPE_UNKNOWN ) ); 00157 00158 $site->setGlobalId( $siteRow->getField( 'global_key' ) ); 00159 00160 $site->setInternalId( $siteRow->getField( 'id' ) ); 00161 00162 if ( $siteRow->hasField( 'forward' ) ) { 00163 $site->setForward( $siteRow->getField( 'forward' ) ); 00164 } 00165 00166 if ( $siteRow->hasField( 'group' ) ) { 00167 $site->setGroup( $siteRow->getField( 'group' ) ); 00168 } 00169 00170 if ( $siteRow->hasField( 'language' ) ) { 00171 $site->setLanguageCode( $siteRow->getField( 'language' ) === '' 00172 ? null 00173 : $siteRow->getField( 'language' ) 00174 ); 00175 } 00176 00177 if ( $siteRow->hasField( 'source' ) ) { 00178 $site->setSource( $siteRow->getField( 'source' ) ); 00179 } 00180 00181 if ( $siteRow->hasField( 'data' ) ) { 00182 $site->setExtraData( $siteRow->getField( 'data' ) ); 00183 } 00184 00185 if ( $siteRow->hasField( 'config' ) ) { 00186 $site->setExtraConfig( $siteRow->getField( 'config' ) ); 00187 } 00188 00189 wfProfileOut( __METHOD__ ); 00190 return $site; 00191 } 00192 00202 protected function getRowFromSite( Site $site ) { 00203 $fields = array( 00204 // Site data 00205 'global_key' => $site->getGlobalId(), // TODO: check not null 00206 'type' => $site->getType(), 00207 'group' => $site->getGroup(), 00208 'source' => $site->getSource(), 00209 'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(), 00210 'protocol' => $site->getProtocol(), 00211 'domain' => strrev( $site->getDomain() ) . '.', 00212 'data' => $site->getExtraData(), 00213 00214 // Site config 00215 'forward' => $site->shouldForward(), 00216 'config' => $site->getExtraConfig(), 00217 ); 00218 00219 if ( $site->getInternalId() !== null ) { 00220 $fields['id'] = $site->getInternalId(); 00221 } 00222 00223 return new ORMRow( $this->sitesTable, $fields ); 00224 } 00225 00231 protected function loadSites() { 00232 wfProfileIn( __METHOD__ ); 00233 00234 $this->sites = new SiteList(); 00235 00236 foreach ( $this->sitesTable->select() as $siteRow ) { 00237 $this->sites[] = $this->siteFromRow( $siteRow ); 00238 } 00239 00240 // Batch load the local site identifiers. 00241 $ids = wfGetDB( $this->sitesTable->getReadDb() )->select( 00242 'site_identifiers', 00243 array( 00244 'si_site', 00245 'si_type', 00246 'si_key', 00247 ), 00248 array(), 00249 __METHOD__ 00250 ); 00251 00252 foreach ( $ids as $id ) { 00253 if ( $this->sites->hasInternalId( $id->si_site ) ) { 00254 $site = $this->sites->getSiteByInternalId( $id->si_site ); 00255 $site->addLocalId( $id->si_type, $id->si_key ); 00256 $this->sites->setSite( $site ); 00257 } 00258 } 00259 00260 $cache = wfGetMainCache(); 00261 $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout ); 00262 00263 wfProfileOut( __METHOD__ ); 00264 } 00265 00276 public function getSite( $globalId, $source = 'cache' ) { 00277 wfProfileIn( __METHOD__ ); 00278 00279 $sites = $this->getSites( $source ); 00280 00281 wfProfileOut( __METHOD__ ); 00282 return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null; 00283 } 00284 00294 public function saveSite( Site $site ) { 00295 return $this->saveSites( array( $site ) ); 00296 } 00297 00307 public function saveSites( array $sites ) { 00308 wfProfileIn( __METHOD__ ); 00309 00310 if ( empty( $sites ) ) { 00311 wfProfileOut( __METHOD__ ); 00312 return true; 00313 } 00314 00315 $dbw = $this->sitesTable->getWriteDbConnection(); 00316 00317 $dbw->startAtomic( __METHOD__ ); 00318 00319 $success = true; 00320 00321 $internalIds = array(); 00322 $localIds = array(); 00323 00324 foreach ( $sites as $site ) { 00325 if ( $site->getInternalId() !== null ) { 00326 $internalIds[] = $site->getInternalId(); 00327 } 00328 00329 $siteRow = $this->getRowFromSite( $site ); 00330 $success = $siteRow->save( __METHOD__ ) && $success; 00331 00332 foreach ( $site->getLocalIds() as $idType => $ids ) { 00333 foreach ( $ids as $id ) { 00334 $localIds[] = array( $siteRow->getId(), $idType, $id ); 00335 } 00336 } 00337 } 00338 00339 if ( $internalIds !== array() ) { 00340 $dbw->delete( 00341 'site_identifiers', 00342 array( 'si_site' => $internalIds ), 00343 __METHOD__ 00344 ); 00345 } 00346 00347 foreach ( $localIds as $localId ) { 00348 $dbw->insert( 00349 'site_identifiers', 00350 array( 00351 'si_site' => $localId[0], 00352 'si_type' => $localId[1], 00353 'si_key' => $localId[2], 00354 ), 00355 __METHOD__ 00356 ); 00357 } 00358 00359 $dbw->endAtomic( __METHOD__ ); 00360 00361 // purge cache 00362 $this->reset(); 00363 00364 wfProfileOut( __METHOD__ ); 00365 return $success; 00366 } 00367 00374 public function reset() { 00375 wfProfileIn( __METHOD__ ); 00376 // purge cache 00377 $cache = wfGetMainCache(); 00378 $cache->delete( $this->getCacheKey() ); 00379 $this->sites = null; 00380 00381 wfProfileOut( __METHOD__ ); 00382 } 00383 00391 public function clear() { 00392 wfProfileIn( __METHOD__ ); 00393 $dbw = $this->sitesTable->getWriteDbConnection(); 00394 00395 $dbw->startAtomic( __METHOD__ ); 00396 $ok = $dbw->delete( 'sites', '*', __METHOD__ ); 00397 $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok; 00398 $dbw->endAtomic( __METHOD__); 00399 00400 $this->reset(); 00401 00402 wfProfileOut( __METHOD__ ); 00403 return $ok; 00404 } 00405 00411 protected function newSitesTable() { 00412 return new ORMTable( 00413 'sites', 00414 array( 00415 'id' => 'id', 00416 00417 // Site data 00418 'global_key' => 'str', 00419 'type' => 'str', 00420 'group' => 'str', 00421 'source' => 'str', 00422 'language' => 'str', 00423 'protocol' => 'str', 00424 'domain' => 'str', 00425 'data' => 'array', 00426 00427 // Site config 00428 'forward' => 'bool', 00429 'config' => 'array', 00430 ), 00431 array( 00432 'type' => Site::TYPE_UNKNOWN, 00433 'group' => Site::GROUP_NONE, 00434 'source' => Site::SOURCE_LOCAL, 00435 'data' => array(), 00436 00437 'forward' => false, 00438 'config' => array(), 00439 'language' => '', 00440 ), 00441 'ORMRow', 00442 'site_' 00443 ); 00444 } 00445 00446 } 00447 00451 class Sites extends SiteSQLStore { 00452 00463 public static function newSite( $globalId = false ) { 00464 $site = new Site(); 00465 00466 if ( $globalId !== false ) { 00467 $site->setGlobalId( $globalId ); 00468 } 00469 00470 return $site; 00471 } 00472 00477 public static function singleton() { 00478 static $singleton; 00479 00480 if ( $singleton === null ) { 00481 $singleton = new static(); 00482 } 00483 00484 return $singleton; 00485 } 00486 00492 public function getSiteGroup( $group ) { 00493 return $this->getSites()->getGroup( $group ); 00494 } 00495 }