MediaWiki  REL1_21
SiteSQLStore.php
Go to the documentation of this file.
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 }