MediaWiki
REL1_21
|
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 00196 protected function loadSites() { 00197 wfProfileIn( __METHOD__ ); 00198 00199 $this->sites = new SiteList(); 00200 00201 foreach ( $this->sitesTable->select() as $siteRow ) { 00202 $this->sites[] = $this->siteFromRow( $siteRow ); 00203 } 00204 00205 // Batch load the local site identifiers. 00206 $ids = wfGetDB( $this->sitesTable->getReadDb() )->select( 00207 'site_identifiers', 00208 array( 00209 'si_site', 00210 'si_type', 00211 'si_key', 00212 ), 00213 array(), 00214 __METHOD__ 00215 ); 00216 00217 foreach ( $ids as $id ) { 00218 if ( $this->sites->hasInternalId( $id->si_site ) ) { 00219 $site = $this->sites->getSiteByInternalId( $id->si_site ); 00220 $site->addLocalId( $id->si_type, $id->si_key ); 00221 $this->sites->setSite( $site ); 00222 } 00223 } 00224 00225 $cache = wfGetMainCache(); 00226 $cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout ); 00227 00228 wfProfileOut( __METHOD__ ); 00229 } 00230 00241 public function getSite( $globalId, $source = 'cache' ) { 00242 wfProfileIn( __METHOD__ ); 00243 00244 $sites = $this->getSites( $source ); 00245 00246 wfProfileOut( __METHOD__ ); 00247 return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null; 00248 } 00249 00259 public function saveSite( Site $site ) { 00260 return $this->saveSites( array( $site ) ); 00261 } 00262 00272 public function saveSites( array $sites ) { 00273 wfProfileIn( __METHOD__ ); 00274 00275 if ( empty( $sites ) ) { 00276 wfProfileOut( __METHOD__ ); 00277 return true; 00278 } 00279 00280 $dbw = $this->sitesTable->getWriteDbConnection(); 00281 00282 $trx = $dbw->trxLevel(); 00283 00284 if ( $trx == 0 ) { 00285 $dbw->begin( __METHOD__ ); 00286 } 00287 00288 $success = true; 00289 00290 $internalIds = array(); 00291 $localIds = array(); 00292 00293 foreach ( $sites as $site ) { 00294 $fields = array( 00295 // Site data 00296 'global_key' => $site->getGlobalId(), // TODO: check not null 00297 'type' => $site->getType(), 00298 'group' => $site->getGroup(), 00299 'source' => $site->getSource(), 00300 'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(), 00301 'protocol' => $site->getProtocol(), 00302 'domain' => strrev( $site->getDomain() ) . '.', 00303 'data' => $site->getExtraData(), 00304 00305 // Site config 00306 'forward' => $site->shouldForward(), 00307 'config' => $site->getExtraConfig(), 00308 ); 00309 00310 if ( $site->getInternalId() !== null ) { 00311 $fields['id'] = $site->getInternalId(); 00312 $internalIds[] = $site->getInternalId(); 00313 } 00314 00315 $siteRow = new ORMRow( $this->sitesTable, $fields ); 00316 $success = $siteRow->save( __METHOD__ ) && $success; 00317 00318 foreach ( $site->getLocalIds() as $idType => $ids ) { 00319 foreach ( $ids as $id ) { 00320 $localIds[] = array( $siteRow->getId(), $idType, $id ); 00321 } 00322 } 00323 } 00324 00325 if ( $internalIds !== array() ) { 00326 $dbw->delete( 00327 'site_identifiers', 00328 array( 'si_site' => $internalIds ), 00329 __METHOD__ 00330 ); 00331 } 00332 00333 foreach ( $localIds as $localId ) { 00334 $dbw->insert( 00335 'site_identifiers', 00336 array( 00337 'si_site' => $localId[0], 00338 'si_type' => $localId[1], 00339 'si_key' => $localId[2], 00340 ), 00341 __METHOD__ 00342 ); 00343 } 00344 00345 if ( $trx == 0 ) { 00346 $dbw->commit( __METHOD__ ); 00347 } 00348 00349 // purge cache 00350 $this->reset(); 00351 00352 wfProfileOut( __METHOD__ ); 00353 return $success; 00354 } 00355 00362 public function reset() { 00363 wfProfileIn( __METHOD__ ); 00364 // purge cache 00365 $cache = wfGetMainCache(); 00366 $cache->delete( $this->getCacheKey() ); 00367 $this->sites = null; 00368 00369 wfProfileOut( __METHOD__ ); 00370 } 00371 00379 public function clear() { 00380 wfProfileIn( __METHOD__ ); 00381 $dbw = $this->sitesTable->getWriteDbConnection(); 00382 00383 $trx = $dbw->trxLevel(); 00384 00385 if ( $trx == 0 ) { 00386 $dbw->begin( __METHOD__ ); 00387 } 00388 00389 $ok = $dbw->delete( 'sites', '*', __METHOD__ ); 00390 $ok = $dbw->delete( 'site_identifiers', '*', __METHOD__ ) && $ok; 00391 00392 if ( $trx == 0 ) { 00393 $dbw->commit( __METHOD__ ); 00394 } 00395 00396 $this->reset(); 00397 00398 wfProfileOut( __METHOD__ ); 00399 return $ok; 00400 } 00401 00407 protected function newSitesTable() { 00408 return new ORMTable( 00409 'sites', 00410 array( 00411 'id' => 'id', 00412 00413 // Site data 00414 'global_key' => 'str', 00415 'type' => 'str', 00416 'group' => 'str', 00417 'source' => 'str', 00418 'language' => 'str', 00419 'protocol' => 'str', 00420 'domain' => 'str', 00421 'data' => 'array', 00422 00423 // Site config 00424 'forward' => 'bool', 00425 'config' => 'array', 00426 ), 00427 array( 00428 'type' => Site::TYPE_UNKNOWN, 00429 'group' => Site::GROUP_NONE, 00430 'source' => Site::SOURCE_LOCAL, 00431 'data' => array(), 00432 00433 'forward' => false, 00434 'config' => array(), 00435 'language' => '', 00436 ), 00437 'ORMRow', 00438 'site_' 00439 ); 00440 } 00441 00442 } 00443 00447 class Sites extends SiteSQLStore { 00448 00459 public static function newSite( $globalId = false ) { 00460 $site = new Site(); 00461 00462 if ( $globalId !== false ) { 00463 $site->setGlobalId( $globalId ); 00464 } 00465 00466 return $site; 00467 } 00468 00473 public static function singleton() { 00474 static $singleton; 00475 00476 if ( $singleton === null ) { 00477 $singleton = new static(); 00478 } 00479 00480 return $singleton; 00481 } 00482 00487 public function getSiteGroup( $group ) { 00488 return $this->getSites()->getGroup( $group ); 00489 } 00490 00491 }