[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/site/ -> SiteSQLStore.php (source)

   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  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1