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