Design improvements to sites code
authorjeroendedauw <jeroendedauw@gmail.com>
Fri, 18 Jan 2013 09:34:14 +0000 (10:34 +0100)
committerjeroendedauw <jeroendedauw@gmail.com>
Tue, 22 Jan 2013 14:39:23 +0000 (15:39 +0100)
Change-Id: I08ffa6a97093abbe85169f664b97498c5f39bf8e

19 files changed:
includes/AutoLoader.php
includes/site/MediaWikiSite.php
includes/site/Site.php
includes/site/SiteArray.php [deleted file]
includes/site/SiteList.php
includes/site/SiteObject.php [deleted file]
includes/site/SiteSQLStore.php [new file with mode: 0644]
includes/site/SiteStore.php [new file with mode: 0644]
includes/site/Sites.php [deleted file]
includes/site/SitesTable.php [deleted file]
tests/TestsAutoLoader.php
tests/phpunit/includes/site/MediaWikiSiteTest.php
tests/phpunit/includes/site/SiteArrayTest.php [deleted file]
tests/phpunit/includes/site/SiteListTest.php
tests/phpunit/includes/site/SiteObjectTest.php [deleted file]
tests/phpunit/includes/site/SiteSQLStoreTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SiteTest.php [new file with mode: 0644]
tests/phpunit/includes/site/SitesTest.php [deleted file]
tests/phpunit/includes/site/TestSites.php

index 5eb497d..c188975 100644 (file)
@@ -883,11 +883,12 @@ $wgAutoloadLocalClasses = array(
        # includes/site
        'MediaWikiSite' => 'includes/site/MediaWikiSite.php',
        'Site' => 'includes/site/Site.php',
-       'SiteArray' => 'includes/site/SiteArray.php',
+       'SiteObject' => 'includes/site/Site.php',
+       'SiteArray' => 'includes/site/SiteList.php',
        'SiteList' => 'includes/site/SiteList.php',
-       'SiteObject' => 'includes/site/SiteObject.php',
-       'Sites' => 'includes/site/Sites.php',
-       'SitesTable' => 'includes/site/SitesTable.php',
+       'SiteSQLStore' => 'includes/site/SiteSQLStore.php',
+       'Sites' => 'includes/site/SiteSQLStore.php',
+       'SiteStore' => 'includes/site/SiteStore.php',
 
        # includes/specials
        'ActiveUsersPager' => 'includes/specials/SpecialActiveusers.php',
index b2e2e71..d4613aa 100644 (file)
  *
  * @ingroup Site
  */
-class MediaWikiSite extends SiteObject {
+class MediaWikiSite extends Site {
 
        const PATH_FILE = 'file_path';
        const PATH_PAGE = 'page_path';
 
        /**
         * @since 1.21
+        * @deprecated Just use the constructor or the factory Site::newForType
         *
         * @param integer $globalId
         *
         * @return MediaWikiSite
         */
        public static function newFromGlobalId( $globalId ) {
-               return SitesTable::singleton()->newRow( array(
-                       'type' => Site::TYPE_MEDIAWIKI,
-                       'global_key' => $globalId,
-               ), true );
+               $site = new static();
+               $site->setGlobalId( $globalId );
+               return $site;
+       }
+
+       /**
+        * Constructor.
+        *
+        * @since 1.21
+        *
+        * @param string $type
+        */
+       public function __construct( $type = self::TYPE_MEDIAWIKI ) {
+               parent::__construct( $type );
        }
 
        /**
@@ -167,7 +178,7 @@ class MediaWikiSite extends SiteObject {
         * @param array $externalData A reply from the API on a external server.
         * @param string $pageTitle Identifies the page at the external site, needing normalization.
         *
-        * @return array|false a 'page' structure representing the page identified by $pageTitle.
+        * @return array|boolean a 'page' structure representing the page identified by $pageTitle.
         */
        private static function extractPageRecord( $externalData, $pageTitle ) {
                // If there is a special case with only one returned page
@@ -290,16 +301,16 @@ class MediaWikiSite extends SiteObject {
        }
 
        /**
-        * @see Site::getPagePath
+        * @see Site::getPageUrl
         *
         * This implementation returns a URL constructed using the path returned by getLinkPath().
-        * In addition to the default behaviour implemented by SiteObject::getPageUrl(), this
+        * In addition to the default behaviour implemented by Site::getPageUrl(), this
         * method converts the $pageName to DBKey-format by replacing spaces with underscores
         * before using it in the URL.
         *
         * @since 1.21
         *
-        * @param $pagename string: Page name (default: false)
+        * @param string|boolean $pageName Page name or false (default: false)
         *
         * @return string
         */
@@ -325,7 +336,7 @@ class MediaWikiSite extends SiteObject {
         *
         * @since 1.21
         *
-        * @param string|false $path
+        * @param string|boolean $path
         *
         * @return string
         */
index 200a006..b11f2b2 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Interface for site objects.
+ * Represents a single site.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,7 +26,7 @@
  * @license GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-interface Site {
+class Site {
 
        const TYPE_UNKNOWN = 'unknown';
        const TYPE_MEDIAWIKI = 'mediawiki';
@@ -38,42 +38,130 @@ interface Site {
 
        const SOURCE_LOCAL = 'local';
 
+       const PATH_LINK = 'link';
+
        /**
-        * Returns the global site identifier (ie enwiktionary).
+        * @since 1.21
         *
+        * @var string|null
+        */
+       protected $globalId = null;
+
+       /**
         * @since 1.21
         *
-        * @return string
+        * @var string
         */
-       public function getGlobalId();
+       protected $type = self::TYPE_UNKNOWN;
 
        /**
-        * Sets the global site identifier (ie enwiktionary).
+        * @since 1.21
         *
+        * @var string
+        */
+       protected $group = self::GROUP_NONE;
+
+       /**
         * @since 1.21
         *
-        * @param string $globalId
+        * @var string
         */
-       public function setGlobalId( $globalId );
+       protected $source = self::SOURCE_LOCAL;
 
        /**
-        * Returns the type of the site (ie mediawiki).
+        * @since 1.21
+        *
+        * @var string|null
+        */
+       protected $languageCode = null;
+
+       /**
+        * Holds the local ids for this site.
+        * local id type => [ ids for this type (strings) ]
         *
         * @since 1.21
         *
-        * @return string
+        * @var array[]
         */
-       public function getType();
+       protected $localIds = array();
 
        /**
-        * Sets the type of the site (ie mediawiki).
-        * TODO: remove, we cannot change this after instantiation
+        * @since 1.21
+        *
+        * @var array
+        */
+       protected $extraData = array();
+
+       /**
+        * @since 1.21
+        *
+        * @var array
+        */
+       protected $extraConfig = array();
+
+       /**
+        * @since 1.21
+        *
+        * @var bool
+        */
+       protected $forward = false;
+
+       /**
+        * @since 1.21
+        *
+        * @var int|null
+        */
+       protected $internalId = null;
+
+       /**
+        * Constructor.
         *
         * @since 1.21
         *
         * @param string $type
         */
-       public function setType( $type );
+       public function __construct( $type = self::TYPE_UNKNOWN ) {
+               $this->type = $type;
+       }
+
+       /**
+        * Returns the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @return string|null
+        */
+       public function getGlobalId() {
+               return $this->globalId;
+       }
+
+       /**
+        * Sets the global site identifier (ie enwiktionary).
+        *
+        * @since 1.21
+        *
+        * @param string|null $globalId
+        *
+        * @throws MWException
+        */
+       public function setGlobalId( $globalId ) {
+               if ( $globalId !== null && !is_string( $globalId ) ) {
+                       throw new MWException( '$globalId needs to be string or null' );
+               }
+
+               $this->globalId = $globalId;
+       }
+
+       /**
+        * Returns the type of the site (ie mediawiki).
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getType() {
+               return $this->type;
+       }
 
        /**
         * Gets the type of the site (ie wikipedia).
@@ -82,7 +170,9 @@ interface Site {
         *
         * @return string
         */
-       public function getGroup();
+       public function getGroup() {
+               return $this->group;
+       }
 
        /**
         * Sets the type of the site (ie wikipedia).
@@ -90,8 +180,16 @@ interface Site {
         * @since 1.21
         *
         * @param string $group
+        *
+        * @throws MWException
         */
-       public function setGroup( $group );
+       public function setGroup( $group ) {
+               if ( !is_string( $group ) ) {
+                       throw new MWException( '$group needs to be a string' );
+               }
+
+               $this->group = $group;
+       }
 
        /**
         * Returns the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
@@ -100,7 +198,9 @@ interface Site {
         *
         * @return string
         */
-       public function getSource();
+       public function getSource() {
+               return $this->source;
+       }
 
        /**
         * Sets the source of the site data (ie 'local', 'wikidata', 'my-magical-repo').
@@ -108,18 +208,46 @@ interface Site {
         * @since 1.21
         *
         * @param string $source
+        *
+        * @throws MWException
         */
-       public function setSource( $source );
+       public function setSource( $source ) {
+               if ( !is_string( $source ) ) {
+                       throw new MWException( '$source needs to be a string' );
+               }
+
+               $this->source = $source;
+       }
 
        /**
-        * Returns the protocol of the site, ie 'http://', 'irc://', '//'
-        * Or false if it's not known.
+        * Gets if site.tld/path/key:pageTitle should forward users to  the page on
+        * the actual site, where "key" is the local identifier.
         *
         * @since 1.21
         *
-        * @return string|false
+        * @return boolean
         */
-       public function getProtocol();
+       public function shouldForward() {
+               return $this->forward;
+       }
+
+       /**
+        * Sets if site.tld/path/key:pageTitle should forward users to  the page on
+        * the actual site, where "key" is the local identifier.
+        *
+        * @since 1.21
+        *
+        * @param boolean $shouldForward
+        *
+        * @throws MWException
+        */
+       public function setForward( $shouldForward ) {
+               if ( !is_bool( $shouldForward ) ) {
+                       throw new MWException( '$shouldForward needs to be a boolean' );
+               }
+
+               $this->forward = $shouldForward;
+       }
 
        /**
         * Returns the domain of the site, ie en.wikipedia.org
@@ -127,9 +255,95 @@ interface Site {
         *
         * @since 1.21
         *
-        * @return string|false
+        * @return string|null
+        */
+       public function getDomain() {
+               $path = $this->getLinkPath();
+
+               if ( $path === null ) {
+                       return null;
+               }
+
+               return parse_url( $path, PHP_URL_HOST );
+       }
+
+       /**
+        * Returns the protocol of the site.
+        *
+        * @since 1.21
+        *
+        * @throws MWException
+        * @return string
         */
-       public function getDomain();
+       public function getProtocol() {
+               $path = $this->getLinkPath();
+
+               if ( $path === null ) {
+                       return '';
+               }
+
+               $protocol = parse_url( $path, PHP_URL_SCHEME );
+
+               // Malformed URL
+               if ( $protocol === false ) {
+                       throw new MWException( "failed to parse URL '$path'" );
+               }
+
+               // No schema
+               if ( $protocol === null ) {
+                       // Used for protocol relative URLs
+                       $protocol = '';
+               }
+
+               return $protocol;
+       }
+
+       /**
+        * Sets the path used to construct links with.
+        * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
+        *
+        * @param string $fullUrl
+        *
+        * @since 1.21
+        *
+        * @throws MWException
+        */
+       public function setLinkPath( $fullUrl ) {
+               $type = $this->getLinkPathType();
+
+               if ( $type === null ) {
+                       throw new MWException( "This Site does not support link paths." );
+               }
+
+               $this->setPath( $type, $fullUrl );
+       }
+
+       /**
+        * Returns the path used to construct links with or false if there is no such path.
+        *
+        * Shall be equivalent to getPath( getLinkPathType() ).
+        *
+        * @return string|null
+        */
+       public function getLinkPath() {
+               $type = $this->getLinkPathType();
+               return $type === null ? null: $this->getPath( $type );
+       }
+
+       /**
+        * Returns the main path type, that is the type of the path that should generally be used to construct links
+        * to the target site.
+        *
+        * This default implementation returns Site::PATH_LINK as the default path type. Subclasses can override this
+        * to define a different default path type, or return false to disable site links.
+        *
+        * @since 1.21
+        *
+        * @return string|null
+        */
+       public function getLinkPathType() {
+               return self::PATH_LINK;
+       }
 
        /**
         * Returns the full URL for the given page on the site.
@@ -138,161 +352,248 @@ interface Site {
         * This generated URL is usually based upon the path returned by getLinkPath(),
         * but this is not a requirement.
         *
+        * This implementation returns a URL constructed using the path returned by getLinkPath().
+        *
         * @since 1.21
-        * @see Site::getLinkPath()
         *
-        * @param bool|String $page
+        * @param bool|String $pageName
         *
-        * @return string|false
+        * @return string|boolean false
         */
-       public function getPageUrl( $page = false );
+       public function getPageUrl( $pageName = false ) {
+               $url = $this->getLinkPath();
+
+               if ( $url === false ) {
+                       return false;
+               }
+
+               if ( $pageName !== false ) {
+                       $url = str_replace( '$1', rawurlencode( $pageName ), $url ) ;
+               }
+
+               return $url;
+       }
 
        /**
-        * Returns language code of the sites primary language.
-        * Or false if it's not known.
+        * Returns $pageName without changes.
+        * Subclasses may override this to apply some kind of normalization.
+        *
+        * @see Site::normalizePageName
         *
         * @since 1.21
         *
-        * @return string|false
+        * @param string $pageName
+        *
+        * @return string
         */
-       public function getLanguageCode();
+       public function normalizePageName( $pageName ) {
+               return $pageName;
+       }
 
        /**
-        * Sets language code of the sites primary language.
+        * Returns the type specific fields.
         *
         * @since 1.21
         *
-        * @param string $languageCode
+        * @return array
         */
-       public function setLanguageCode( $languageCode );
+       public function getExtraData() {
+               return $this->extraData;
+       }
 
        /**
-        * Returns the normalized, canonical form of the given page name.
-        * How normalization is performed or what the properties of a normalized name are depends on the site.
-        * The general contract of this method is that the normalized form shall refer to the same content
-        * as the original form, and any other page name referring to the same content will have the same normalized form.
+        * Sets the type specific fields.
+        *
+        * @since 1.21
         *
-        * Note that this method may call out to the target site to perform the normalization, so it may be slow
-        * and fail due to IO errors.
+        * @param array $extraData
+        */
+       public function setExtraData( array $extraData ) {
+               $this->extraData = $extraData;
+       }
+
+       /**
+        * Returns the type specific config.
         *
         * @since 1.21
         *
-        * @param string $pageName
+        * @return array
+        */
+       public function getExtraConfig() {
+               return $this->extraConfig;
+       }
+
+       /**
+        * Sets the type specific config.
+        *
+        * @since 1.21
         *
-        * @return string the normalized page name
+        * @param array $extraConfig
         */
-       public function normalizePageName( $pageName );
+       public function setExtraConfig( array $extraConfig ) {
+               $this->extraConfig = $extraConfig;
+       }
 
        /**
-        * Returns the interwiki link identifiers that can be used for this site.
+        * Returns language code of the sites primary language.
+        * Or null if it's not known.
         *
         * @since 1.21
         *
-        * @return array of string
+        * @return string|null
         */
-       public function getInterwikiIds();
+       public function getLanguageCode() {
+               return $this->languageCode;
+       }
 
        /**
-        * Returns the equivalent link identifiers that can be used to make
-        * the site show up in interfaces such as the "language links" section.
+        * Sets language code of the sites primary language.
         *
         * @since 1.21
         *
-        * @return array of string
+        * @param string $languageCode
         */
-       public function getNavigationIds();
+       public function setLanguageCode( $languageCode ) {
+               $this->languageCode = $languageCode;
+       }
 
        /**
-        * Adds an local identifier to the site.
+        * Returns the set internal identifier for the site.
         *
         * @since 1.21
         *
-        * @param string $type The type of the identifier, element of the Site::ID_ enum
-        * @param string $identifier
+        * @return string|null
         */
-       public function addLocalId( $type, $identifier );
+       public function getInternalId() {
+               return $this->internalId;
+       }
 
        /**
-        * Adds an interwiki id to the site.
+        * Sets the internal identifier for the site.
+        * This typically is a primary key in a db table.
         *
         * @since 1.21
         *
-        * @param string $identifier
+        * @param int|null $internalId
         */
-       public function addInterwikiId( $identifier );
+       public function setInternalId( $internalId = null ) {
+               $this->internalId = $internalId;
+       }
 
        /**
-        * Adds a navigation id to the site.
+        * Adds a local identifier.
         *
         * @since 1.21
         *
+        * @param string $type
         * @param string $identifier
         */
-       public function addNavigationId( $identifier );
+       public function addLocalId( $type, $identifier ) {
+               if ( $this->localIds === false ) {
+                       $this->localIds = array();
+               }
+
+               if ( !array_key_exists( $type, $this->localIds ) ) {
+                       $this->localIds[$type] = array();
+               }
+
+               if ( !in_array( $identifier, $this->localIds[$type] ) ) {
+                       $this->localIds[$type][] = $identifier;
+               }
+       }
 
        /**
-        * Saves the site.
+        * Adds an interwiki id to the site.
         *
         * @since 1.21
         *
-        * @param string|null $functionName
+        * @param string $identifier
         */
-       public function save( $functionName = null );
+       public function addInterwikiId( $identifier ) {
+               $this->addLocalId( self::ID_INTERWIKI, $identifier );
+       }
 
        /**
-        * Returns the internal ID of the site.
+        * Adds a navigation id to the site.
         *
         * @since 1.21
         *
-        * @return integer
+        * @param string $identifier
         */
-       public function getInternalId();
+       public function addNavigationId( $identifier ) {
+               $this->addLocalId( self::ID_EQUIVALENT, $identifier );
+       }
 
        /**
-        * Sets the provided url as path of the specified type.
+        * Returns the interwiki link identifiers that can be used for this site.
         *
         * @since 1.21
         *
-        * @param string $pathType
-        * @param string $fullUrl
+        * @return string[]
         */
-       public function setPath( $pathType, $fullUrl );
+       public function getInterwikiIds() {
+               return array_key_exists( self::ID_INTERWIKI, $this->localIds ) ? $this->localIds[self::ID_INTERWIKI] : array();
+       }
 
        /**
-        * Returns the path of the provided type or false if there is no such path.
+        * Returns the equivalent link identifiers that can be used to make
+        * the site show up in interfaces such as the "language links" section.
         *
         * @since 1.21
         *
-        * @param string $pathType
+        * @return string[]
+        */
+       public function getNavigationIds() {
+               return array_key_exists( self::ID_EQUIVALENT, $this->localIds ) ? $this->localIds[self::ID_EQUIVALENT] : array();
+       }
+
+       /**
+        * Returns all local ids
+        *
+        * @since 1.21
         *
-        * @return string|false
+        * @return array[]
         */
-       public function getPath( $pathType );
+       public function getLocalIds() {
+               return $this->localIds;
+       }
 
        /**
         * Sets the path used to construct links with.
         * Shall be equivalent to setPath( getLinkPathType(), $fullUrl ).
         *
+        * @since 1.21
+        *
+        * @param string $pathType
         * @param string $fullUrl
         *
-        * @since 1.21
+        * @throws MWException
         */
-       public function setLinkPath( $fullUrl );
+       public function setPath( $pathType, $fullUrl ) {
+               if ( !is_string( $fullUrl ) ) {
+                       throw new MWException( '$fullUrl needs to be a string' );
+               }
 
-       /**
-        * Returns the path used to construct links with or false if there is no such path.
-        * Shall be equivalent to getPath( getLinkPathType() ).
-        *
-        * @return string|false
-        */
-       public function getLinkPath();
+               if ( !array_key_exists( 'paths', $this->extraData ) ) {
+                       $this->extraData['paths'] = array();
+               }
+
+               $this->extraData['paths'][$pathType] = $fullUrl;
+       }
 
        /**
-        * Returns the path type used to construct links with.
+        * Returns the path of the provided type or false if there is no such path.
+        *
+        * @since 1.21
+        *
+        * @param string $pathType
         *
-        * @return string|false
+        * @return string|null
         */
-       public function getLinkPathType();
+       public function getPath( $pathType ) {
+               $paths = $this->getAllPaths();
+               return array_key_exists( $pathType, $paths ) ? $paths[$pathType] : null;
+       }
 
        /**
         * Returns the paths as associative array.
@@ -300,9 +601,11 @@ interface Site {
         *
         * @since 1.21
         *
-        * @return array of string
+        * @return string[]
         */
-       public function getAllPaths();
+       public function getAllPaths() {
+               return array_key_exists( 'paths', $this->extraData ) ? $this->extraData['paths'] : array();
+       }
 
        /**
         * Removes the path of the provided type if it's set.
@@ -311,6 +614,34 @@ interface Site {
         *
         * @param string $pathType
         */
-       public function removePath( $pathType );
+       public function removePath( $pathType ) {
+               if ( array_key_exists( 'paths', $this->extraData ) ) {
+                       unset( $this->extraData['paths'][$pathType] );
+               }
+       }
 
-}
\ No newline at end of file
+       // TODO: config
+
+       /**
+        * @since 1.21
+        *
+        * @param string $siteType
+        *
+        * @return Site
+        */
+       public static function newForType( $siteType ) {
+               global $wgSiteTypes;
+
+               if ( array_key_exists( $siteType, $wgSiteTypes ) ) {
+                       return new $wgSiteTypes[$siteType]();
+               }
+
+               return new Site();
+       }
+
+}
+
+/**
+ * @deprecated
+ */
+class SiteObject extends Site {}
\ No newline at end of file
diff --git a/includes/site/SiteArray.php b/includes/site/SiteArray.php
deleted file mode 100644 (file)
index 5d2c86b..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-<?php
-
-/**
- * Implementation of SiteList using GenericArrayObject.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteArray extends GenericArrayObject implements SiteList {
-       /**
-        * Update this version number when the SiteArray format
-        * changes in an incompatible way
-        *
-        * @since 1.21
-        *
-        * @var integer
-        */
-       const CACHE_VERSION = 1;
-
-       /**
-        * Version number of the SiteArray format of the currently used object
-        *
-        * @since 1.21
-        *
-        * @var integer
-        */
-       public $cacheVersion = self::CACHE_VERSION;
-
-       /**
-        * Internal site identifiers pointing to their sites offset value.
-        *
-        * @since 1.21
-        *
-        * @var array of integer
-        */
-       protected $byInternalId = array();
-
-       /**
-        * Global site identifiers pointing to their sites offset value.
-        *
-        * @since 1.21
-        *
-        * @var array of string
-        */
-       protected $byGlobalId = array();
-
-       /**
-        * @see GenericArrayObject::getObjectType
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getObjectType() {
-               return 'Site';
-       }
-
-       /**
-        * @see GenericArrayObject::preSetElement
-        *
-        * @since 1.21
-        *
-        * @param int|string $index
-        * @param Site $site
-        *
-        * @return boolean
-        */
-       protected function preSetElement( $index, $site ) {
-               if ( $this->hasSite( $site->getGlobalId() ) ) {
-                       $this->removeSite( $site->getGlobalId() );
-               }
-
-               $this->byGlobalId[$site->getGlobalId()] = $index;
-               $this->byInternalId[$site->getInternalId()] = $index;
-
-               return true;
-       }
-
-       /**
-        * @see ArrayObject::offsetUnset()
-        *
-        * @since 1.21
-        *
-        * @param mixed $index
-        */
-       public function offsetUnset( $index ) {
-               if ( $this->offsetExists( $index ) ) {
-                       /**
-                        * @var Site $site
-                        */
-                       $site = $this->offsetGet( $index );
-
-                       unset( $this->byGlobalId[$site->getGlobalId()] );
-                       unset( $this->byInternalId[$site->getInternalId()] );
-               }
-
-               parent::offsetUnset( $index );
-       }
-
-       /**
-        * @see SiteList::getGlobalIdentifiers
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function getGlobalIdentifiers() {
-               return array_keys( $this->byGlobalId );
-       }
-
-       /**
-        * @see SiteList::hasSite
-        *
-        * @param string $globalSiteId
-        *
-        * @return boolean
-        */
-       public function hasSite( $globalSiteId ) {
-               return array_key_exists( $globalSiteId, $this->byGlobalId );
-       }
-
-       /**
-        * @see SiteList::getSite
-        *
-        * @since 1.21
-        *
-        * @param string $globalSiteId
-        *
-        * @return Site
-        */
-       public function getSite( $globalSiteId ) {
-               return $this->offsetGet( $this->byGlobalId[$globalSiteId] );
-       }
-
-       /**
-        * @see SiteList::removeSite
-        *
-        * @since 1.21
-        *
-        * @param string $globalSiteId
-        */
-       public function removeSite( $globalSiteId ) {
-               $this->offsetUnset( $this->byGlobalId[$globalSiteId] );
-       }
-
-       /**
-        * @see SiteList::isEmpty
-        *
-        * @since 1.21
-        *
-        * @return boolean
-        */
-       public function isEmpty() {
-               return $this->byGlobalId === array();
-       }
-
-       /**
-        * @see SiteList::hasInternalId
-        *
-        * @param integer $id
-        *
-        * @return boolean
-        */
-       public function hasInternalId( $id ) {
-               return array_key_exists( $id, $this->byInternalId );
-       }
-
-       /**
-        * @see SiteList::getSiteByInternalId
-        *
-        * @since 1.21
-        *
-        * @param integer $id
-        *
-        * @return Site
-        */
-       public function getSiteByInternalId( $id ) {
-               return $this->offsetGet( $this->byInternalId[$id] );
-       }
-
-       /**
-        * @see SiteList::removeSiteByInternalId
-        *
-        * @since 1.21
-        *
-        * @param integer $id
-        */
-       public function removeSiteByInternalId( $id ) {
-               $this->offsetUnset( $this->byInternalId[$id] );
-       }
-
-       /**
-        * @see SiteList::setSite
-        *
-        * @since 1.21
-        *
-        * @param Site $site
-        */
-       public function setSite( Site $site ) {
-               $this[] = $site;
-       }
-
-       /**
-        * @see GenericArrayObject::getSerializationData
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       protected function getSerializationData() {
-               return array_merge(
-                       parent::getSerializationData(),
-                       array(
-                               'cacheVersion' => self::CACHE_VERSION,
-                               'internalIds' => $this->byInternalId,
-                               'globalIds' => $this->byGlobalId,
-                       )
-               );
-       }
-
-       /**
-        * @see GenericArrayObject::unserialize
-        *
-        * @since 1.21
-        *
-        * @param string $serialization
-        *
-        * @return array
-        */
-       public function unserialize( $serialization ) {
-               $serializationData = parent::unserialize( $serialization );
-
-               $this->cacheVersion = $serializationData['cacheVersion'];
-               $this->byInternalId = $serializationData['internalIds'];
-               $this->byGlobalId = $serializationData['globalIds'];
-
-               return $serializationData;
-       }
-
-}
index 6273364..35e11a1 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Interface for lists of Site objects.
+ * Collection of Site objects.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * @license GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
+class SiteList extends GenericArrayObject {
+
+       /**
+        * Internal site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of integer
+        */
+       protected $byInternalId = array();
+
+       /**
+        * Global site identifiers pointing to their sites offset value.
+        *
+        * @since 1.21
+        *
+        * @var array of string
+        */
+       protected $byGlobalId = array();
+
+       /**
+        * @see GenericArrayObject::getObjectType
+        *
+        * @since 1.21
+        *
+        * @return string
+        */
+       public function getObjectType() {
+               return 'Site';
+       }
+
+       /**
+        * @see GenericArrayObject::preSetElement
+        *
+        * @since 1.21
+        *
+        * @param int|string $index
+        * @param Site $site
+        *
+        * @return boolean
+        */
+       protected function preSetElement( $index, $site ) {
+               if ( $this->hasSite( $site->getGlobalId() ) ) {
+                       $this->removeSite( $site->getGlobalId() );
+               }
+
+               $this->byGlobalId[$site->getGlobalId()] = $index;
+               $this->byInternalId[$site->getInternalId()] = $index;
+
+               return true;
+       }
+
+       /**
+        * @see ArrayObject::offsetUnset()
+        *
+        * @since 1.21
+        *
+        * @param mixed $index
+        */
+       public function offsetUnset( $index ) {
+               if ( $this->offsetExists( $index ) ) {
+                       /**
+                        * @var Site $site
+                        */
+                       $site = $this->offsetGet( $index );
+
+                       unset( $this->byGlobalId[$site->getGlobalId()] );
+                       unset( $this->byInternalId[$site->getInternalId()] );
+               }
+
+               parent::offsetUnset( $index );
+       }
 
        /**
         * Returns all the global site identifiers.
@@ -36,7 +107,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return array
         */
-       public function getGlobalIdentifiers();
+       public function getGlobalIdentifiers() {
+               return array_keys( $this->byGlobalId );
+       }
 
        /**
         * Returns if the list contains the site with the provided global site identifier.
@@ -45,7 +118,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return boolean
         */
-       public function hasSite( $globalSiteId );
+       public function hasSite( $globalSiteId ) {
+               return array_key_exists( $globalSiteId, $this->byGlobalId );
+       }
 
        /**
         * Returns the Site with the provided global site identifier.
@@ -57,7 +132,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return Site
         */
-       public function getSite( $globalSiteId );
+       public function getSite( $globalSiteId ) {
+               return $this->offsetGet( $this->byGlobalId[$globalSiteId] );
+       }
 
        /**
         * Removes the site with the specified global site identifier.
@@ -67,7 +144,20 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param string $globalSiteId
         */
-       public function removeSite( $globalSiteId );
+       public function removeSite( $globalSiteId ) {
+               $this->offsetUnset( $this->byGlobalId[$globalSiteId] );
+       }
+
+       /**
+        * Returns if the list contains no sites.
+        *
+        * @since 1.21
+        *
+        * @return boolean
+        */
+       public function isEmpty() {
+               return $this->byGlobalId === array();
+       }
 
        /**
         * Returns if the list contains the site with the provided site id.
@@ -76,7 +166,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return boolean
         */
-       public function hasInternalId( $id );
+       public function hasInternalId( $id ) {
+               return array_key_exists( $id, $this->byInternalId );
+       }
 
        /**
         * Returns the Site with the provided site id.
@@ -88,7 +180,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @return Site
         */
-       public function getSiteByInternalId( $id );
+       public function getSiteByInternalId( $id ) {
+               return $this->offsetGet( $this->byInternalId[$id] );
+       }
 
        /**
         * Removes the site with the specified site id.
@@ -98,7 +192,9 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param integer $id
         */
-       public function removeSiteByInternalId( $id );
+       public function removeSiteByInternalId( $id ) {
+               $this->offsetUnset( $this->byInternalId[$id] );
+       }
 
        /**
         * Sets a site in the list. If the site was not there,
@@ -108,15 +204,72 @@ interface SiteList extends Countable, Traversable, Serializable, ArrayAccess {
         *
         * @param Site $site
         */
-       public function setSite( Site $site );
+       public function setSite( Site $site ) {
+               $this[] = $site;
+       }
 
        /**
-        * Returns if the site list contains no sites.
+        * Returns the sites that are in the provided group.
         *
         * @since 1.21
         *
-        * @return boolean
+        * @param string $groupName
+        *
+        * @return SiteList
+        */
+       public function getGroup( $groupName ) {
+               $group = new self();
+
+               /**
+                * @var \Site $site
+                */
+               foreach ( $this as $site ) {
+                       if ( $site->getGroup() === $groupName ) {
+                               $group[] = $site;
+                       }
+               }
+
+               return $group;
+       }
+
+       /**
+        * @see GenericArrayObject::getSerializationData
+        *
+        * @since 1.21
+        *
+        * @return array
         */
-       public function isEmpty();
+       protected function getSerializationData() {
+               return array_merge(
+                       parent::getSerializationData(),
+                       array(
+                               'internalIds' => $this->byInternalId,
+                               'globalIds' => $this->byGlobalId,
+                       )
+               );
+       }
 
-}
\ No newline at end of file
+       /**
+        * @see GenericArrayObject::unserialize
+        *
+        * @since 1.21
+        *
+        * @param string $serialization
+        *
+        * @return array
+        */
+       public function unserialize( $serialization ) {
+               $serializationData = parent::unserialize( $serialization );
+
+               $this->byInternalId = $serializationData['internalIds'];
+               $this->byGlobalId = $serializationData['globalIds'];
+
+               return $serializationData;
+       }
+
+}
+
+/**
+ * @deprecated
+ */
+class SiteArray extends SiteList {}
\ No newline at end of file
diff --git a/includes/site/SiteObject.php b/includes/site/SiteObject.php
deleted file mode 100644 (file)
index 217f860..0000000
+++ /dev/null
@@ -1,570 +0,0 @@
-<?php
-
-/**
- * Class representing a single site.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- * @author Daniel Werner
- */
-class SiteObject extends ORMRow implements Site {
-
-       const PATH_LINK = 'link';
-
-       /**
-        * Holds the local ids for this site.
-        * You can obtain them via @see getLocalIds
-        *
-        * @since 1.21
-        *
-        * @var array|false
-        */
-       protected $localIds = false;
-
-       /**
-        * @see Site::getGlobalId
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getGlobalId() {
-               return $this->getField( 'global_key' );
-       }
-
-       /**
-        * @see Site::setGlobalId
-        *
-        * @since 1.21
-        *
-        * @param string $globalId
-        */
-       public function setGlobalId( $globalId ) {
-               $this->setField( 'global_key', $globalId );
-       }
-
-       /**
-        * @see Site::getType
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getType() {
-               return $this->getField( 'type' );
-       }
-
-       /**
-        * @see Site::setType
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        */
-       public function setType( $type ) {
-               $this->setField( 'type', $type );
-       }
-
-       /**
-        * @see Site::getGroup
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getGroup() {
-               return $this->getField( 'group' );
-       }
-
-       /**
-        * @see Site::setGroup
-        *
-        * @since 1.21
-        *
-        * @param string $group
-        */
-       public function setGroup( $group ) {
-               $this->setField( 'group', $group );
-       }
-
-       /**
-        * @see Site::getSource
-        *
-        * @since 1.21
-        *
-        * @return string
-        */
-       public function getSource() {
-               return $this->getField( 'source' );
-       }
-
-       /**
-        * @see Site::setSource
-        *
-        * @since 1.21
-        *
-        * @param string $source
-        */
-       public function setSource( $source ) {
-               $this->setField( 'source', $source );
-       }
-
-       /**
-        * @see Site::getDomain
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getDomain() {
-               $path = $this->getLinkPath();
-
-               if ( $path === false ) {
-                       return false;
-               }
-
-               return parse_url( $path, PHP_URL_HOST );
-       }
-
-       /**
-        * @see Site::getProtocol
-        *
-        * @since 1.21
-        *
-        * @throws MWException
-        * @return string|false
-        */
-       public function getProtocol() {
-               $path = $this->getLinkPath();
-
-               if ( $path === false ) {
-                       return '';
-               }
-
-               $protocol = parse_url( $path, PHP_URL_SCHEME );
-
-               // Malformed URL
-               if ( $protocol === false ) {
-                       throw new MWException( "failed to parse URL $path" );
-               }
-
-               // No schema
-               if ( $protocol === null ) {
-                       // Used for protocol relative URLs
-                       $protocol = '';
-               }
-
-               return $protocol;
-       }
-
-       /**
-        * Sets the path used to construct links with.
-        * @see Site::setLinkPath
-        *
-        * @param string $fullUrl
-        *
-        * @since 1.21
-        *
-        * @throws MWException
-        */
-       public function setLinkPath( $fullUrl ) {
-               $type = $this->getLinkPathType();
-
-               if ( $type === false ) {
-                       throw new MWException( "This SiteObject does not support link paths." );
-               }
-
-               $this->setPath( $type, $fullUrl );
-       }
-
-       /**
-        * Returns the path path used to construct links with or false if there is no such path.
-        *
-        * @see Site::getLinkPath
-        *
-        * @return string|false
-        */
-       public function getLinkPath() {
-               $type = $this->getLinkPathType();
-               return $type === false ? false : $this->getPath( $type );
-       }
-
-       /**
-        * @see Site::getLinkPathType
-        *
-        * Returns the main path type, that is the type of the path that should generally be used to construct links
-        * to the target site.
-        *
-        * This default implementation returns SiteObject::PATH_LINK as the default path type. Subclasses can override this
-        * to define a different default path type, or return false to disable site links.
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getLinkPathType() {
-               return self::PATH_LINK;
-       }
-
-       /**
-        * @see Site::getPageUrl
-        *
-        * This implementation returns a URL constructed using the path returned by getLinkPath().
-        *
-        * @since 1.21
-        *
-        * @param bool|String $pageName
-        *
-        * @return string|false
-        */
-       public function getPageUrl( $pageName = false ) {
-               $url = $this->getLinkPath();
-
-               if ( $url === false ) {
-                       return false;
-               }
-
-               if ( $pageName !== false ) {
-                       $url = str_replace( '$1', rawurlencode( $pageName ), $url ) ;
-               }
-
-               return $url;
-       }
-
-       /**
-        * Returns $pageName without changes.
-        * Subclasses may override this to apply some kind of normalization.
-        *
-        * @see Site::normalizePageName
-        *
-        * @since 1.21
-        *
-        * @param string $pageName
-        *
-        * @return string
-        */
-       public function normalizePageName( $pageName ) {
-               return $pageName;
-       }
-
-       /**
-        * Returns the value of a type specific field, or the value
-        * of the $default parameter in case it's not set.
-        *
-        * @since 1.21
-        *
-        * @param string $fieldName
-        * @param mixed $default
-        *
-        * @return array
-        */
-       protected function getExtraData( $fieldName, $default = null ) {
-               $data = $this->getField( 'data', array() );
-               return array_key_exists( $fieldName,$data ) ? $data[$fieldName] : $default;
-       }
-
-       /**
-        * Sets the value of a type specific field.
-        * @since 1.21
-        *
-        * @param string $fieldName
-        * @param mixed $value
-        */
-       protected function setExtraData( $fieldName, $value = null ) {
-               $data = $this->getField( 'data', array() );
-               $data[$fieldName] = $value;
-               $this->setField( 'data', $data );
-       }
-
-       /**
-        * @see Site::getLanguageCode
-        *
-        * @since 1.21
-        *
-        * @return string|false
-        */
-       public function getLanguageCode() {
-               return $this->getField( 'language', false );
-       }
-
-       /**
-        * @see Site::setLanguageCode
-        *
-        * @since 1.21
-        *
-        * @param string $languageCode
-        */
-       public function setLanguageCode( $languageCode ) {
-               $this->setField( 'language', $languageCode );
-       }
-
-       /**
-        * Returns the local identifiers of this site.
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        *
-        * @return array
-        */
-       protected function getLocalIds( $type ) {
-               if ( $this->localIds === false ) {
-                       $this->loadLocalIds();
-               }
-
-               return array_key_exists( $type, $this->localIds ) ? $this->localIds[$type] : array();
-       }
-
-       /**
-        * Loads the local ids for the site.
-        *
-        * @since 1.21
-        */
-       protected function loadLocalIds() {
-               $dbr = wfGetDB( $this->getTable()->getReadDb() );
-
-               $ids = $dbr->select(
-                       'site_identifiers',
-                       array(
-                               'si_type',
-                               'si_key',
-                       ),
-                       array(
-                               'si_site' => $this->getId(),
-                       ),
-                       __METHOD__
-               );
-
-               $this->localIds = array();
-
-               foreach ( $ids as $id ) {
-                       $this->addLocalId( $id->si_type, $id->si_key );
-               }
-       }
-
-       /**
-        * Adds a local identifier.
-        *
-        * @since 1.21
-        *
-        * @param string $type
-        * @param string $identifier
-        */
-       public function addLocalId( $type, $identifier ) {
-               if ( $this->localIds === false ) {
-                       $this->localIds = array();
-               }
-
-               if ( !array_key_exists( $type, $this->localIds ) ) {
-                       $this->localIds[$type] = array();
-               }
-
-               if ( !in_array( $identifier, $this->localIds[$type] ) ) {
-                       $this->localIds[$type][] = $identifier;
-               }
-       }
-
-       /**
-        * @see Site::addInterwikiId
-        *
-        * @since 1.21
-        *
-        * @param string $identifier
-        */
-       public function addInterwikiId( $identifier ) {
-               $this->addLocalId( 'interwiki', $identifier );
-       }
-
-       /**
-        * @see Site::addNavigationId
-        *
-        * @since 1.21
-        *
-        * @param string $identifier
-        */
-       public function addNavigationId( $identifier ) {
-               $this->addLocalId( 'equivalent', $identifier );
-       }
-
-       /**
-        * @see Site::getInterwikiIds
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getInterwikiIds() {
-               return $this->getLocalIds( 'interwiki' );
-       }
-
-       /**
-        * @see Site::getNavigationIds
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getNavigationIds() {
-               return $this->getLocalIds( 'equivalent' );
-       }
-
-       /**
-        * @see Site::getInternalId
-        *
-        * @since 1.21
-        *
-        * @return integer
-        */
-       public function getInternalId() {
-               return $this->getId();
-       }
-
-       /**
-        * @see IORMRow::save
-        * @see Site::save
-        *
-        * @since 1.21
-        *
-        * @param string|null $functionName
-        *
-        * @return boolean Success indicator
-        */
-       public function save( $functionName = null ) {
-               $dbw = $this->table->getWriteDbConnection();
-
-               $trx = $dbw->trxLevel();
-
-               if ( $trx == 0 ) {
-                       $dbw->begin( __METHOD__ );
-               }
-
-               $this->setField( 'protocol', $this->getProtocol() );
-               $this->setField( 'domain', strrev( $this->getDomain() ) . '.' );
-
-               $existedAlready = $this->hasIdField();
-
-               $success = parent::save( $functionName );
-
-               if ( $success && $existedAlready ) {
-                       $dbw->delete(
-                               'site_identifiers',
-                               array( 'si_site' => $this->getId() ),
-                               __METHOD__
-                       );
-               }
-
-               if ( $success && $this->localIds !== false ) {
-                       foreach ( $this->localIds as $type => $ids ) {
-                               foreach ( $ids as $id ) {
-                                       $dbw->insert(
-                                               'site_identifiers',
-                                               array(
-                                                       'si_site' => $this->getId(),
-                                                       'si_type' => $type,
-                                                       'si_key' => $id,
-                                               ),
-                                               __METHOD__
-                                       );
-                               }
-                       }
-               }
-
-               if ( $trx == 0 ) {
-                       $dbw->commit( __METHOD__ );
-               }
-
-               return $success;
-       }
-
-       /**
-        * @since 1.21
-        *
-        * @see ORMRow::onRemoved
-        */
-       protected function onRemoved() {
-               $dbw = $this->table->getWriteDbConnection();
-
-               $dbw->delete(
-                       'site_identifiers',
-                       array(
-                               'si_site' => $this->getId()
-                       ),
-                       __METHOD__
-               );
-
-               parent::onRemoved();
-       }
-
-       /**
-        * @see Site::setPath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        * @param string $fullUrl
-        */
-       public function setPath( $pathType, $fullUrl ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               $paths[$pathType] = $fullUrl;
-               $this->setExtraData( 'paths', $paths );
-       }
-
-       /**
-        * @see Sitres::getPath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        *
-        * @return string|false
-        */
-       public function getPath( $pathType ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               return array_key_exists( $pathType, $paths ) ? $paths[$pathType] : false;
-       }
-
-       /**
-        * @see Sitres::getAll
-        *
-        * @since 1.21
-        *
-        * @return array of string
-        */
-       public function getAllPaths() {
-               return $this->getExtraData( 'paths', array() );
-       }
-
-       /**
-        * @see Sitres::removePath
-        *
-        * @since 1.21
-        *
-        * @param string $pathType
-        */
-       public function removePath( $pathType ) {
-               $paths = $this->getExtraData( 'paths', array() );
-               unset( $paths[$pathType] );
-               $this->setExtraData( 'paths', $paths );
-       }
-
-}
diff --git a/includes/site/SiteSQLStore.php b/includes/site/SiteSQLStore.php
new file mode 100644 (file)
index 0000000..724f115
--- /dev/null
@@ -0,0 +1,375 @@
+<?php
+
+/**
+ * Represents the site configuration of a wiki.
+ * Holds a list of sites (ie SiteList) and takes care
+ * of retrieving and caching site information when appropriate.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.21
+ *
+ * @file
+ * @ingroup Site
+ *
+ * @license GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteSQLStore implements SiteStore {
+
+       /**
+        * @since 1.21
+        *
+        * @var SiteList|null
+        */
+       protected $sites = null;
+
+       /**
+        * @var ORMTable
+        */
+       protected $sitesTable;
+
+       /**
+        * @since 1.21
+        *
+        * @param ORMTable|null $sitesTable
+        *
+        * @return SiteStore
+        */
+       public static function newInstance( ORMTable $sitesTable = null ) {
+               return new static( $sitesTable );
+       }
+
+       /**
+        * Constructor.
+        *
+        * @since 1.21
+        *
+        * @param ORMTable|null $sitesTable
+        */
+       protected function __construct( ORMTable $sitesTable = null ) {
+               if ( $sitesTable === null ) {
+                       $sitesTable = $this->newSitesTable();
+               }
+
+               $this->sitesTable = $sitesTable;
+       }
+
+       /**
+        * @see SiteStore::getSites
+        *
+        * @since 1.21
+        *
+        * @param string $source either 'cache' or 'recache'
+        *
+        * @return SiteList
+        */
+       public function getSites( $source = 'cache' ) {
+               if ( $source === 'cache' ) {
+                       if ( $this->sites === null ) {
+                               $cache = wfGetMainCache();
+                               $sites = $cache->get( wfMemcKey( 'SiteList' ) );
+
+                               if ( is_object( $sites ) ) {
+                                       $this->sites = $sites;
+                               } else {
+                                       $this->loadSites();
+                               }
+                       }
+               }
+               else {
+                       $this->loadSites();
+               }
+
+               return $this->sites;
+       }
+
+       /**
+        * Returns a new Site object constructed from the provided ORMRow.
+        *
+        * @since 1.21
+        *
+        * @param ORMRow $siteRow
+        *
+        * @return Site
+        */
+       protected function siteFromRow( ORMRow $siteRow ) {
+               $site = Site::newForType( $siteRow->getField( 'type', Site::TYPE_UNKNOWN ) );
+
+               $site->setGlobalId( $siteRow->getField( 'global_key' ) );
+
+               if ( $siteRow->hasField( 'forward' ) ) {
+                       $site->setForward( $siteRow->getField( 'forward' ) );
+               }
+
+               if ( $siteRow->hasField( 'group' ) ) {
+                       $site->setGroup( $siteRow->getField( 'group' ) );
+               }
+
+               if ( $siteRow->hasField( 'language' ) ) {
+                       $site->setLanguageCode( $siteRow->getField( 'language' ) === '' ? null : $siteRow->getField( 'language' ) );
+               }
+
+               if ( $siteRow->hasField( 'source' ) ) {
+                       $site->setSource( $siteRow->getField( 'source' ) );
+               }
+
+               if ( $siteRow->hasField( 'data' ) ) {
+                       $site->setExtraData( $siteRow->getField( 'data' ) );
+               }
+
+               if ( $siteRow->hasField( 'config' ) ) {
+                       $site->setExtraConfig( $siteRow->getField( 'config' ) );
+               }
+
+               return $site;
+       }
+
+       /**
+        * Fetches the site from the database and loads them into the sites field.
+        *
+        * @since 1.21
+        */
+       protected function loadSites() {
+               $this->sites = new SiteList();
+
+               foreach ( $this->sitesTable->select() as $siteRow ) {
+                       $this->sites[] = $this->siteFromRow( $siteRow );
+               }
+
+               // Batch load the local site identifiers.
+               $ids = wfGetDB( $this->sitesTable->getReadDb() )->select(
+                       'site_identifiers',
+                       array(
+                               'si_site',
+                               'si_type',
+                               'si_key',
+                       ),
+                       array(),
+                       __METHOD__
+               );
+
+               foreach ( $ids as $id ) {
+                       if ( $this->sites->hasInternalId( $id->si_site ) ) {
+                               $site = $this->sites->getSiteByInternalId( $id->si_site );
+                               $site->addLocalId( $id->si_type, $id->si_key );
+                               $this->sites->setSite( $site );
+                       }
+               }
+
+               $cache = wfGetMainCache();
+               $cache->set( wfMemcKey( 'SiteList' ), $this->sites );
+       }
+
+       /**
+        * @see SiteStore::getSite
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        * @param string $source
+        *
+        * @return Site|null
+        */
+       public function getSite( $globalId, $source = 'cache' ) {
+               $sites = $this->getSites( $source );
+
+               return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null;
+       }
+
+       /**
+        * @see SiteStore::saveSite
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSite( Site $site ) {
+               return $this->saveSites( array( $site ) );
+       }
+
+       /**
+        * @see SiteStore::saveSites
+        *
+        * @since 1.21
+        *
+        * @param Site[] $sites
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSites( array $sites ) {
+               if ( empty( $sites ) ) {
+                       return true;
+               }
+
+               $dbw = $this->sitesTable->getWriteDbConnection();
+
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
+
+               $success = true;
+
+               $internalIds = array();
+               $localIds = array();
+
+               foreach ( $sites as $site ) {
+                       $fields = array(
+                               // Site data
+                               'global_key' => $site->getGlobalId(), // TODO: check not null
+                               'type' => $site->getType(),
+                               'group' => $site->getGroup(),
+                               'source' => $site->getSource(),
+                               'language' => $site->getLanguageCode() === null ? '' : $site->getLanguageCode(),
+                               'protocol' => $site->getProtocol(),
+                               'domain' => strrev( $site->getDomain() ) . '.',
+                               'data' => $site->getExtraData(),
+
+                               // Site config
+                               'forward' => $site->shouldForward(),
+                               'config' => $site->getExtraConfig(),
+                       );
+
+                       if ( $site->getInternalId() !== null ) {
+                               $fields['id'] = $site->getInternalId();
+                               $internalIds[] = $site->getInternalId();
+                       }
+
+                       $siteRow = new ORMRow( $this->sitesTable, $fields );
+                       $success = $siteRow->save( __METHOD__ ) && $success;
+
+                       foreach ( $site->getLocalIds() as $idType => $ids ) {
+                               foreach ( $ids as $id ) {
+                                       $localIds[] = array( $siteRow->getId(), $idType, $id );
+                               }
+                       }
+               }
+
+               if ( $internalIds !== array() ) {
+                       $dbw->delete(
+                               'site_identifiers',
+                               array( 'si_site' => $internalIds ),
+                               __METHOD__
+                       );
+               }
+
+               foreach ( $localIds as $localId ) {
+                       $dbw->insert(
+                               'site_identifiers',
+                               array(
+                                       'si_site' => $localId[0],
+                                       'si_type' => $localId[1],
+                                       'si_key' => $localId[2],
+                               ),
+                               __METHOD__
+                       );
+               }
+
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
+
+               return $success;
+       }
+
+       /**
+        * @since 1.21
+        *
+        * @return ORMTable
+        */
+       protected function newSitesTable() {
+               return new ORMTable(
+                       'sites',
+                       array(
+                               'id' => 'id',
+
+                               // Site data
+                               'global_key' => 'str',
+                               'type' => 'str',
+                               'group' => 'str',
+                               'source' => 'str',
+                               'language' => 'str',
+                               'protocol' => 'str',
+                               'domain' => 'str',
+                               'data' => 'array',
+
+                               // Site config
+                               'forward' => 'bool',
+                               'config' => 'array',
+                       ),
+                       array(
+                               'type' => Site::TYPE_UNKNOWN,
+                               'group' => Site::GROUP_NONE,
+                               'source' => Site::SOURCE_LOCAL,
+                               'data' => array(),
+
+                               'forward' => false,
+                               'config' => array(),
+                               'language' => '',
+                       ),
+                       'ORMRow',
+                       'site_'
+               );
+       }
+
+}
+
+/**
+ * @deprecated
+ */
+class Sites extends SiteSQLStore {
+
+       /**
+        * Factory for creating new site objects.
+        *
+        * @since 1.21
+        * @deprecated
+        *
+        * @param string|boolean false $globalId
+        *
+        * @return Site
+        */
+       public static function newSite( $globalId = false ) {
+               $site = new Site();
+
+               if ( $globalId !== false ) {
+                       $site->setGlobalId( $globalId );
+               }
+
+               return $site;
+       }
+
+       /**
+        * @deprecated
+        * @return SiteStore
+        */
+       public static function singleton() {
+               return new static();
+       }
+
+       /**
+        * @deprecated
+        * @return SiteList
+        */
+       public function getSiteGroup( $group ) {
+               return $this->getSites()->getGroup( $group );
+       }
+
+}
\ No newline at end of file
diff --git a/includes/site/SiteStore.php b/includes/site/SiteStore.php
new file mode 100644 (file)
index 0000000..2091f3c
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+interface SiteStore {
+
+       /**
+        * Saves the provided site.
+        *
+        * @since 1.21
+        *
+        * @param Site $site
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSite( Site $site );
+
+       /**
+        * Saves the provided sites.
+        *
+        * @since 1.21
+        *
+        * @param Site[] $sites
+        *
+        * @return boolean Success indicator
+        */
+       public function saveSites( array $sites );
+
+       /**
+        * Returns the site with provided global id, or null if there is no such site.
+        *
+        * @since 1.21
+        *
+        * @param string $globalId
+        * @param string $source either 'cache' or 'recache'.
+        * If 'cache', the values are allowed (but not obliged) to come from a cache.
+        *
+        * @return Site|null
+        */
+       public function getSite( $globalId, $source = 'cache' );
+
+       /**
+        * Returns a list of all sites. By default this site is
+        * fetched from the cache, which can be changed to loading
+        * the list from the database using the $useCache parameter.
+        *
+        * @since 1.21
+        *
+        * @param string $source either 'cache' or 'recache'.
+        * If 'cache', the values are allowed (but not obliged) to come from a cache.
+        *
+        * @return SiteList
+        */
+       public function getSites( $source = 'cache' );
+
+}
\ No newline at end of file
diff --git a/includes/site/Sites.php b/includes/site/Sites.php
deleted file mode 100644 (file)
index a67d474..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-
-/**
- * Represents the site configuration of a wiki.
- * Holds a list of sites (ie SiteList) and takes care
- * of retrieving and caching site information when appropriate.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class Sites {
-
-       /**
-        * @since 1.21
-        * @var SiteList|null
-        */
-       protected $sites = null;
-
-       /**
-        * Constructor.
-        *
-        * @since 1.21
-        */
-       protected function __construct() {}
-
-       /**
-        * Returns an instance of Sites.
-        *
-        * @since 1.21
-        *
-        * @return Sites
-        */
-       public static function singleton() {
-               static $instance = false;
-
-               if ( $instance === false ) {
-                       $instance = new static();
-               }
-
-               return $instance;
-       }
-
-       /**
-        * Factory for creating new site objects.
-        *
-        * @since 1.21
-        *
-        * @param string|boolean false $globalId
-        *
-        * @return Site
-        */
-       public static function newSite( $globalId = false ) {
-               /**
-                * @var Site $site
-                */
-               $site = SitesTable::singleton()->newRow( array(), true );
-
-               if ( $globalId !== false ) {
-                       $site->setGlobalId( $globalId );
-               }
-
-               return $site;
-       }
-
-       /**
-        * Returns a list of all sites. By default this site is
-        * fetched from the cache, which can be changed to loading
-        * the list from the database using the $useCache parameter.
-        *
-        * @since 1.21
-        *
-        * @param string $source either 'cache' or 'recache'
-        *
-        * @return SiteList
-        */
-       public function getSites( $source = 'cache' ) {
-               if ( $source === 'cache' ) {
-                       if ( $this->sites === null ) {
-                               $cache = wfGetMainCache();
-                               $sites = $cache->get( wfMemcKey( 'SiteList' ) );
-
-                               if ( is_object( $sites ) && isset( $sites->cacheVersion ) && $sites->cacheVersion === SiteArray::CACHE_VERSION ) {
-                                       $this->sites = $sites;
-                               } else {
-                                       $this->loadSites();
-                               }
-                       }
-               }
-               else {
-                       $this->loadSites();
-               }
-
-               return $this->sites;
-       }
-
-       /**
-        * Returns a list of sites in the given group. Calling getGroup() on any of
-        * the sites in the resulting SiteList shall return $group.
-        *
-        * @since 1.21
-        *
-        * @param string $group th group to get.
-        *
-        * @return SiteList
-        */
-       public function getSiteGroup( $group ) {
-               $sites = self::getSites();
-
-               $siteGroup = new SiteArray();
-
-               /* @var Site $site */
-               foreach ( $sites as $site ) {
-                       if ( $site->getGroup() == $group ) {
-                               $siteGroup->append( $site );
-                       }
-               }
-
-               return $siteGroup;
-       }
-
-       /**
-        * Fetches the site from the database and loads them into the sites field.
-        *
-        * @since 1.21
-        */
-       protected function loadSites() {
-               $this->sites = new SiteArray( SitesTable::singleton()->select() );
-
-               // Batch load the local site identifiers.
-               $dbr = wfGetDB( SitesTable::singleton()->getReadDb() );
-
-               $ids = $dbr->select(
-                       'site_identifiers',
-                       array(
-                               'si_site',
-                               'si_type',
-                               'si_key',
-                       ),
-                       array(),
-                       __METHOD__
-               );
-
-               foreach ( $ids as $id ) {
-                       if ( $this->sites->hasInternalId( $id->si_site ) ) {
-                               $site = $this->sites->getSiteByInternalId( $id->si_site );
-                               $site->addLocalId( $id->si_type, $id->si_key );
-                               $this->sites->setSite( $site );
-                       }
-               }
-
-               $cache = wfGetMainCache();
-               $cache->set( wfMemcKey( 'SiteList' ), $this->sites );
-       }
-
-       /**
-        * Returns the site with provided global id, or false if there is no such site.
-        *
-        * @since 1.21
-        *
-        * @param string $globalId
-        * @param string $source
-        *
-        * @return Site|false
-        */
-       public function getSite( $globalId, $source = 'cache' ) {
-               $sites = $this->getSites( $source );
-
-               return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : false;
-       }
-
-}
diff --git a/includes/site/SitesTable.php b/includes/site/SitesTable.php
deleted file mode 100644 (file)
index bb12740..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * Represents the sites database table.
- * All access to this table should be done through this class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.21
- *
- * @file
- * @ingroup Site
- *
- * @license GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SitesTable extends ORMTable {
-
-       /**
-        * @see IORMTable::getName()
-        * @since 1.21
-        * @return string
-        */
-       public function getName() {
-               return 'sites';
-       }
-
-       /**
-        * @see IORMTable::getFieldPrefix()
-        * @since 1.21
-        * @return string
-        */
-       public function getFieldPrefix() {
-               return 'site_';
-       }
-
-       /**
-        * @see IORMTable::getRowClass()
-        * @since 1.21
-        * @return string
-        */
-       public function getRowClass() {
-               return 'SiteObject';
-       }
-
-       /**
-        * @see IORMTable::getFields()
-        * @since 1.21
-        * @return array
-        */
-       public function getFields() {
-               return array(
-                       'id' => 'id',
-
-                       // Site data
-                       'global_key' => 'str',
-                       'type' => 'str',
-                       'group' => 'str',
-                       'source' => 'str',
-                       'language' => 'str',
-                       'protocol' => 'str',
-                       'domain' => 'str',
-                       'data' => 'array',
-
-                       // Site config
-                       'forward' => 'bool',
-                       'config' => 'array',
-               );
-       }
-
-       /**
-        * @see IORMTable::getDefaults()
-        * @since 1.21
-        * @return array
-        */
-       public function getDefaults() {
-               return array(
-                       'type' => Site::TYPE_UNKNOWN,
-                       'group' => Site::GROUP_NONE,
-                       'source' => Site::SOURCE_LOCAL,
-                       'data' => array(),
-
-                       'forward' => false,
-                       'config' => array(),
-                       'language' => 'en', // XXX: can we default to '' instead?
-               );
-       }
-
-       /**
-        * Returns the class name for the provided site type.
-        *
-        * @since 1.21
-        *
-        * @param integer $siteType
-        *
-        * @return string
-        */
-       protected static function getClassForType( $siteType ) {
-               global $wgSiteTypes;
-               return array_key_exists( $siteType, $wgSiteTypes ) ? $wgSiteTypes[$siteType] : 'SiteObject';
-       }
-
-       /**
-        * Factory method to construct a new Site instance.
-        *
-        * @since 1.21
-        *
-        * @param array $data
-        * @param boolean $loadDefaults
-        *
-        * @return Site
-        */
-       public function newRow( array $data, $loadDefaults = false ) {
-               if ( !array_key_exists( 'type', $data ) ) {
-                       $data['type'] = Site::TYPE_UNKNOWN;
-               }
-
-               $class = static::getClassForType( $data['type'] );
-
-               return new $class( $this, $data, $loadDefaults );
-       }
-
-}
\ No newline at end of file
index 8373b51..30b9f94 100644 (file)
@@ -77,7 +77,7 @@ $wgAutoloadClasses += array(
        'GenericArrayObjectTest' => "$testDir/phpunit/includes/libs/GenericArrayObjectTest.php",
 
        # tests/phpunit/includes/site
-       'SiteObjectTest' => "$testDir/phpunit/includes/site/SiteObjectTest.php",
+       'SiteTest' => "$testDir/phpunit/includes/site/SiteTest.php",
        'TestSites' => "$testDir/phpunit/includes/site/TestSites.php",
 
        # tests/phpunit/languages
index 208ab1e..0cecdee 100644 (file)
  * @ingroup Test
  *
  * @group Site
- * @group Database
  *
  * @licence GNU GPL v2+
  * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  */
-class MediaWikiSiteTest extends SiteObjectTest {
-
-       public function setUp() {
-               parent::setUp();
-
-               static $hasSites = false;
-
-               if ( !$hasSites ) {
-                       TestSites::insertIntoDb();
-                       $hasSites = true;
-               }
-       }
-
-       public function testFactoryConstruction() {
-               $this->assertInstanceOf( 'MediaWikiSite', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
-               $this->assertInstanceOf( 'Site', MediaWikiSite::newFromGlobalId( 'enwiki' ) );
-               $this->assertInstanceOf( 'MediaWikiSite', SitesTable::singleton()->newRow( array( 'type' => Site::TYPE_MEDIAWIKI ) ) );
-       }
+class MediaWikiSiteTest extends SiteTest {
 
        public function testNormalizePageTitle() {
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'enwiki' );
 
                //NOTE: this does not actually call out to the enwiki site to perform the normalization,
                //      but uses a local Title object to do so. This is hardcoded on SiteLink::normalizePageTitle
@@ -73,8 +56,7 @@ class MediaWikiSiteTest extends SiteObjectTest {
         * @dataProvider fileUrlProvider
         */
        public function testGetFileUrl( $url, $filePath, $pathArgument, $expected ) {
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
-
+               $site = new MediaWikiSite();
                $site->setFilePath( $url . $filePath );
 
                $this->assertEquals( $expected, $site->getFileUrl( $pathArgument ) );
@@ -97,10 +79,9 @@ class MediaWikiSiteTest extends SiteObjectTest {
         * @dataProvider provideGetPageUrl
         */
        public function testGetPageUrl( $path, $page, $expected ) {
-               /* @var MediaWikiSite $site */
-               $site = MediaWikiSite::newFromGlobalId( 'enwiki' );
-
+               $site = new MediaWikiSite();
                $site->setLinkPath( $path );
+
                $this->assertContains( $path, $site->getPageUrl() );
                $this->assertContains( $expected, $site->getPageUrl( $page ) );
        }
diff --git a/tests/phpunit/includes/site/SiteArrayTest.php b/tests/phpunit/includes/site/SiteArrayTest.php
deleted file mode 100644 (file)
index 613f63f..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-<?php
-
-/**
- * Tests for the SiteArray class.
- * The tests for methods defined in the SiteList interface are in SiteListTest.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *Both
- * Bith
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteArrayTest extends GenericArrayObjectTest {
-
-       /**
-        * @see GenericArrayObjectTest::elementInstancesProvider
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function elementInstancesProvider() {
-               $sites = TestSites::getSites();
-
-               $siteArrays = array();
-
-               $siteArrays[] = $sites;
-
-               $siteArrays[] = array( array_shift( $sites ) );
-
-               $siteArrays[] = array( array_shift( $sites ), array_shift( $sites ) );
-
-               return $this->arrayWrap( $siteArrays );
-       }
-
-       /**
-        * @see GenericArrayObjectTest::getInstanceClass
-        *
-        * @since 1.21
-        *
-        * @return array
-        */
-       public function getInstanceClass() {
-               return 'SiteArray';
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        *
-        * @since 1.21
-        *
-        * @param SiteArray $list
-        */
-       public function testSerializationMore( SiteArray $list ) {
-               $serialization = serialize( $list );
-               /**
-                * @var SiteArray $copy
-                */
-               $copy = unserialize( $serialization );
-
-               $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() );
-
-               /**
-                * @var Site $site
-                */
-               foreach ( $list as $site ) {
-                       $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) );
-               }
-       }
-
-}
\ No newline at end of file
index bb8367f..7b88212 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 /**
- * Tests for the SiteList implementing classes.
+ * Tests for the SiteList class.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@ class SiteListTest extends MediaWikiTestCase {
                $listInstances = array();
 
                foreach ( $sitesArrays as $sitesArray ) {
-                       $listInstances[] = new SiteArray( $sitesArray[0] );
+                       $listInstances[] = new SiteList( $sitesArray[0] );
                }
 
                return $this->arrayWrap( $listInstances );
@@ -164,5 +164,28 @@ class SiteListTest extends MediaWikiTestCase {
                $this->assertArrayEquals( $expected, $identifiers );
        }
 
+       /**
+        * @dataProvider siteListProvider
+        *
+        * @since 1.21
+        *
+        * @param SiteList $list
+        */
+       public function testSerialization( SiteList $list ) {
+               $serialization = serialize( $list );
+               /**
+                * @var SiteArray $copy
+                */
+               $copy = unserialize( $serialization );
+
+               $this->assertArrayEquals( $list->getGlobalIdentifiers(), $copy->getGlobalIdentifiers() );
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $list as $site ) {
+                       $this->assertTrue( $copy->hasInternalId( $site->getInternalId() ) );
+               }
+       }
 
 }
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SiteObjectTest.php b/tests/phpunit/includes/site/SiteObjectTest.php
deleted file mode 100644 (file)
index 207f46c..0000000
+++ /dev/null
@@ -1,294 +0,0 @@
-<?php
-
-/**
- * Tests for the SiteObject class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SiteObjectTest extends ORMRowTest {
-
-       /**
-        * @see ORMRowTest::getRowClass
-        * @since 1.21
-        * @return string
-        */
-       protected function getRowClass() {
-               return 'SiteObject';
-       }
-
-       /**
-        * @see ORMRowTest::getTableInstance
-        * @since 1.21
-        * @return IORMTable
-        */
-       protected function getTableInstance() {
-               return SitesTable::singleton();
-       }
-
-       /**
-        * @see ORMRowTest::constructorTestProvider
-        * @since 1.21
-        * @return array
-        */
-       public function constructorTestProvider() {
-               $argLists = array();
-
-               $argLists[] = array( 'global_key' => 'foo' );
-
-               $argLists[] = array( 'global_key' => 'bar', 'type' => Site::TYPE_MEDIAWIKI );
-
-               $constructorArgs = array();
-
-               foreach ( $argLists as $argList ) {
-                       $constructorArgs[] = array( $argList, true );
-               }
-
-               return $constructorArgs;
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetInterwikiIds( Site $site ) {
-               $this->assertInternalType( 'array', $site->getInterwikiIds() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetNavigationIds( Site $site ) {
-               $this->assertInternalType( 'array', $site->getNavigationIds() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testAddNavigationId( Site $site ) {
-               $site->addNavigationId( 'foobar' );
-               $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testAddInterwikiId( Site $site ) {
-               $site->addInterwikiId( 'foobar' );
-               $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetLanguageCode( Site $site ) {
-               $this->assertTypeOrFalse( 'string', $site->getLanguageCode() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetLanguageCode( Site $site ) {
-               $site->setLanguageCode( 'en' );
-               $this->assertEquals( 'en', $site->getLanguageCode() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testNormalizePageName( Site $site ) {
-               $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetGlobalId( Site $site ) {
-               $this->assertInternalType( 'string', $site->getGlobalId() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetGlobalId( Site $site ) {
-               $site->setGlobalId( 'foobar' );
-               $this->assertEquals( 'foobar', $site->getGlobalId() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetType( Site $site ) {
-               $this->assertInternalType( 'string', $site->getType() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetPath( Site $site ) {
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'page_path' ) );
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'file_path' ) );
-               $this->assertTypeOrFalse( 'string', $site->getPath( 'foobar' ) );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testGetAllPaths( Site $site ) {
-               $this->assertInternalType( 'array', $site->getAllPaths() );
-       }
-
-       /**
-        * @dataProvider instanceProvider
-        * @param Site $site
-        */
-       public function testSetAndRemovePath( Site $site ) {
-               $count = count( $site->getAllPaths() );
-
-               $site->setPath( 'spam', 'http://www.wikidata.org/$1' );
-               $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' );
-               $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' );
-
-               $this->assertEquals( $count + 2, count( $site->getAllPaths() ) );
-
-               $this->assertInternalType( 'string', $site->getPath( 'foobar' ) );
-               $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) );
-
-               $site->removePath( 'spam' );
-               $site->removePath( 'foobar' );
-
-               $this->assertEquals( $count, count( $site->getAllPaths() ) );
-
-               $this->assertFalse( $site->getPath( 'foobar' ) );
-               $this->assertFalse( $site->getPath( 'spam' ) );
-       }
-
-       public function testSetLinkPath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-               $path = "TestPath/$1";
-
-               $site->setLinkPath( $path );
-               $this->assertEquals( $path, $site->getLinkPath() );
-       }
-
-       public function testGetLinkPathType() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $path = 'TestPath/$1';
-               $site->setLinkPath( $path );
-               $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) );
-
-               $path = 'AnotherPath/$1';
-               $site->setPath( $site->getLinkPathType(), $path );
-               $this->assertEquals( $path, $site->getLinkPath() );
-       }
-
-       public function testSetPath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $path = 'TestPath/$1';
-               $site->setPath( 'foo', $path );
-
-               $this->assertEquals( $path, $site->getPath( 'foo' ) );
-       }
-
-       public function testProtocolRelativePath() {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               $type = $site->getLinkPathType();
-               $path = '//acme.com/'; // protocol-relative URL
-               $site->setPath( $type, $path );
-
-               $this->assertEquals( '', $site->getProtocol() );
-       }
-
-       public function provideGetPageUrl() {
-               //NOTE: the assumption that the URL is built by replacing $1
-               //      with the urlencoded version of $page
-               //      is true for SiteObject but not guaranteed for subclasses.
-               //      Subclasses need to override this provider appropriately.
-
-               return array(
-                       array( #0
-                               'http://acme.test/TestPath/$1',
-                               'Foo',
-                               '/TestPath/Foo',
-                       ),
-                       array( #1
-                               'http://acme.test/TestScript?x=$1&y=bla',
-                               'Foo',
-                               'TestScript?x=Foo&y=bla',
-                       ),
-                       array( #2
-                               'http://acme.test/TestPath/$1',
-                               'foo & bar/xyzzy (quux-shmoox?)',
-                               '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29',
-                       ),
-               );
-       }
-
-       /**
-        * @dataProvider provideGetPageUrl
-        */
-       public function testGetPageUrl( $path, $page, $expected ) {
-               /* @var SiteObject $site */
-               $site = $this->getRowInstance( $this->getMockFields(), false );
-
-               //NOTE: the assumption that getPageUrl is based on getLinkPath
-               //      is true for SiteObject but not guaranteed for subclasses.
-               //      Subclasses need to override this test case appropriately.
-               $site->setLinkPath( $path );
-               $this->assertContains( $path, $site->getPageUrl() );
-
-               $this->assertContains( $expected, $site->getPageUrl( $page ) );
-       }
-
-       protected function assertTypeOrFalse( $type, $value ) {
-               if ( $value === false ) {
-                       $this->assertTrue( true );
-               }
-               else {
-                       $this->assertInternalType( $type, $value );
-               }
-       }
-
-}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SiteSQLStoreTest.php b/tests/phpunit/includes/site/SiteSQLStoreTest.php
new file mode 100644 (file)
index 0000000..58a4e1f
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * Tests for the SiteSQLStore class.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ * @group Database
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteSQLStoreTest extends MediaWikiTestCase {
+
+       public function testGetSites() {
+               $expectedSites = TestSites::getSites();
+               TestSites::insertIntoDb();
+
+               $sitesTable = SiteSQLStore::newInstance();
+
+               $sites = $sitesTable->getSites();
+
+               $this->assertInstanceOf( 'SiteList', $sites );
+
+               /**
+                * @var Site $site
+                */
+               foreach ( $sites as $site ) {
+                       $this->assertInstanceOf( 'Site', $site );
+               }
+
+               foreach ( $expectedSites as $site ) {
+                       if ( $site->getGlobalId() !== null ) {
+                               $this->assertTrue( $sites->hasSite( $site->getGlobalId() ) );
+                       }
+               }
+       }
+
+       public function testSaveSites() {
+               $sitesTable = SiteSQLStore::newInstance();
+
+               $sites = array();
+
+               $site = new Site();
+               $site->setGlobalId( 'ertrywuutr' );
+               $site->setLanguageCode( 'en' );
+               $sites[] = $site;
+
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'sdfhxujgkfpth' );
+               $site->setLanguageCode( 'nl' );
+               $sites[] = $site;
+
+               $this->assertTrue( $sitesTable->saveSites( $sites ) );
+
+               $site = $sitesTable->getSite( 'ertrywuutr', 'nocache' );
+               $this->assertInstanceOf( 'Site', $site );
+               $this->assertEquals( 'en', $site->getLanguageCode() );
+
+               $site = $sitesTable->getSite( 'sdfhxujgkfpth', 'nocache' );
+               $this->assertInstanceOf( 'Site', $site );
+               $this->assertEquals( 'nl', $site->getLanguageCode() );
+       }
+
+}
diff --git a/tests/phpunit/includes/site/SiteTest.php b/tests/phpunit/includes/site/SiteTest.php
new file mode 100644 (file)
index 0000000..0336a51
--- /dev/null
@@ -0,0 +1,267 @@
+<?php
+
+/**
+ * Tests for the Site class.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 1.21
+ *
+ * @ingroup Site
+ * @ingroup Test
+ *
+ * @group Site
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class SiteTest extends MediaWikiTestCase {
+
+       public function instanceProvider() {
+               $instances = array();
+
+               $instances[] = new Site();
+
+               $site = new Site();
+               $site->setGlobalId( 'enwiki' );
+               $site->setInternalId( 42 );
+               $instances[] = $site;
+
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'nlwiki' );
+               $site->setLanguageCode( 'nl' );
+               $instances[] = $site;
+
+               return $this->arrayWrap( $instances );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetInterwikiIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getInterwikiIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetNavigationIds( Site $site ) {
+               $this->assertInternalType( 'array', $site->getNavigationIds() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddNavigationId( Site $site ) {
+               $site->addNavigationId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getNavigationIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testAddInterwikiId( Site $site ) {
+               $site->addInterwikiId( 'foobar' );
+               $this->assertTrue( in_array( 'foobar', $site->getInterwikiIds(), true ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetLanguageCode( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getLanguageCode(), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetLanguageCode( Site $site ) {
+               $site->setLanguageCode( 'en' );
+               $this->assertEquals( 'en', $site->getLanguageCode() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testNormalizePageName( Site $site ) {
+               $this->assertInternalType( 'string', $site->normalizePageName( 'Foobar' ) );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetGlobalId( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getGlobalId(), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetGlobalId( Site $site ) {
+               $site->setGlobalId( 'foobar' );
+               $this->assertEquals( 'foobar', $site->getGlobalId() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetType( Site $site ) {
+               $this->assertInternalType( 'string', $site->getType() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetPath( Site $site ) {
+               $this->assertTypeOrValue( 'string', $site->getPath( 'page_path' ), null );
+               $this->assertTypeOrValue( 'string', $site->getPath( 'file_path' ), null );
+               $this->assertTypeOrValue( 'string', $site->getPath( 'foobar' ), null );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testGetAllPaths( Site $site ) {
+               $this->assertInternalType( 'array', $site->getAllPaths() );
+       }
+
+       /**
+        * @dataProvider instanceProvider
+        * @param Site $site
+        */
+       public function testSetAndRemovePath( Site $site ) {
+               $count = count( $site->getAllPaths() );
+
+               $site->setPath( 'spam', 'http://www.wikidata.org/$1' );
+               $site->setPath( 'spam', 'http://www.wikidata.org/foo/$1' );
+               $site->setPath( 'foobar', 'http://www.wikidata.org/bar/$1' );
+
+               $this->assertEquals( $count + 2, count( $site->getAllPaths() ) );
+
+               $this->assertInternalType( 'string', $site->getPath( 'foobar' ) );
+               $this->assertEquals( 'http://www.wikidata.org/foo/$1', $site->getPath( 'spam' ) );
+
+               $site->removePath( 'spam' );
+               $site->removePath( 'foobar' );
+
+               $this->assertEquals( $count, count( $site->getAllPaths() ) );
+
+               $this->assertNull( $site->getPath( 'foobar' ) );
+               $this->assertNull( $site->getPath( 'spam' ) );
+       }
+
+       public function testSetLinkPath() {
+               $site = new Site();
+               $path = "TestPath/$1";
+
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testGetLinkPathType() {
+               $site = new Site();
+
+               $path = 'TestPath/$1';
+               $site->setLinkPath( $path );
+               $this->assertEquals( $path, $site->getPath( $site->getLinkPathType() ) );
+
+               $path = 'AnotherPath/$1';
+               $site->setPath( $site->getLinkPathType(), $path );
+               $this->assertEquals( $path, $site->getLinkPath() );
+       }
+
+       public function testSetPath() {
+               $site = new Site();
+
+               $path = 'TestPath/$1';
+               $site->setPath( 'foo', $path );
+
+               $this->assertEquals( $path, $site->getPath( 'foo' ) );
+       }
+
+       public function testProtocolRelativePath() {
+               $site = new Site();
+
+               $type = $site->getLinkPathType();
+               $path = '//acme.com/'; // protocol-relative URL
+               $site->setPath( $type, $path );
+
+               $this->assertEquals( '', $site->getProtocol() );
+       }
+
+       public function provideGetPageUrl() {
+               //NOTE: the assumption that the URL is built by replacing $1
+               //      with the urlencoded version of $page
+               //      is true for Site but not guaranteed for subclasses.
+               //      Subclasses need to override this provider appropriately.
+
+               return array(
+                       array( #0
+                               'http://acme.test/TestPath/$1',
+                               'Foo',
+                               '/TestPath/Foo',
+                       ),
+                       array( #1
+                               'http://acme.test/TestScript?x=$1&y=bla',
+                               'Foo',
+                               'TestScript?x=Foo&y=bla',
+                       ),
+                       array( #2
+                               'http://acme.test/TestPath/$1',
+                               'foo & bar/xyzzy (quux-shmoox?)',
+                               '/TestPath/foo%20%26%20bar%2Fxyzzy%20%28quux-shmoox%3F%29',
+                       ),
+               );
+       }
+
+       /**
+        * @dataProvider provideGetPageUrl
+        */
+       public function testGetPageUrl( $path, $page, $expected ) {
+               $site = new Site();
+
+               //NOTE: the assumption that getPageUrl is based on getLinkPath
+               //      is true for Site but not guaranteed for subclasses.
+               //      Subclasses need to override this test case appropriately.
+               $site->setLinkPath( $path );
+               $this->assertContains( $path, $site->getPageUrl() );
+
+               $this->assertContains( $expected, $site->getPageUrl( $page ) );
+       }
+
+       protected function assertTypeOrFalse( $type, $value ) {
+               if ( $value === false ) {
+                       $this->assertTrue( true );
+               }
+               else {
+                       $this->assertInternalType( $type, $value );
+               }
+       }
+
+}
\ No newline at end of file
diff --git a/tests/phpunit/includes/site/SitesTest.php b/tests/phpunit/includes/site/SitesTest.php
deleted file mode 100644 (file)
index 7675d42..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-/**
- * Tests for the Sites class.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @since 1.21
- *
- * @ingroup Site
- * @ingroup Test
- *
- * @group Site
- * @group Database
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class SitesTest extends MediaWikiTestCase {
-
-       public function setUp() {
-               parent::setUp();
-               TestSites::insertIntoDb();
-       }
-
-       public function testSingleton() {
-               $this->assertInstanceOf( 'Sites', Sites::singleton() );
-               $this->assertTrue( Sites::singleton() === Sites::singleton() );
-       }
-
-       public function testGetSites() {
-               $this->assertInstanceOf( 'SiteList', Sites::singleton()->getSites() );
-       }
-
-
-       public function testGetSite() {
-               $count = 0;
-               $sites = Sites::singleton()->getSites();
-
-               /**
-                * @var Site $site
-                */
-               foreach ( $sites as $site ) {
-                       $this->assertInstanceOf( 'Site', $site );
-
-                       $this->assertEquals(
-                               $site,
-                               Sites::singleton()->getSite( $site->getGlobalId() )
-                       );
-
-                       if ( ++$count > 100 ) {
-                               break;
-                       }
-               }
-       }
-
-       public function testNewSite() {
-               $this->assertInstanceOf( 'Site', Sites::newSite() );
-               $this->assertInstanceOf( 'Site', Sites::newSite( 'enwiki' ) );
-       }
-
-       public function testGetGroup() {
-               $wikipedias = Sites::singleton()->getSiteGroup( "wikipedia" );
-
-               $this->assertFalse( $wikipedias->isEmpty() );
-
-               /* @var Site $site */
-               foreach ( $wikipedias as $site ) {
-                       $this->assertEquals( 'wikipedia', $site->getGroup() );
-               }
-       }
-
-}
index 6003a8d..d9861cd 100644 (file)
@@ -39,21 +39,22 @@ class TestSites {
        public static function getSites() {
                $sites = array();
 
-               $site = Sites::newSite( 'foobar' );
+               $site = new Site();
+               $site->setGlobalId( 'foobar' );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'enwiktionary' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'enwiktionary' );
                $site->setGroup( 'wiktionary' );
-               $site->setType( Site::TYPE_MEDIAWIKI );
                $site->setLanguageCode( 'en' );
                $site->addNavigationId( 'enwiktionary' );
                $site->setPath( MediaWikiSite::PATH_PAGE, "https://en.wiktionary.org/wiki/$1" );
                $site->setPath( MediaWikiSite::PATH_FILE, "https://en.wiktionary.org/w/$1" );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'dewiktionary' );
+               $site = new MediaWikiSite();
+               $site->setGlobalId( 'dewiktionary' );
                $site->setGroup( 'wiktionary' );
-               $site->setType( Site::TYPE_MEDIAWIKI );
                $site->setLanguageCode( 'de' );
                $site->addInterwikiId( 'dewiktionary' );
                $site->addInterwikiId( 'wiktionaryde' );
@@ -61,9 +62,9 @@ class TestSites {
                $site->setPath( MediaWikiSite::PATH_FILE, "https://de.wiktionary.org/w/$1" );
                $sites[] = $site;
 
-               $site = Sites::newSite( 'spam' );
+               $site = new Site();
+               $site->setGlobalId( 'spam' );
                $site->setGroup( 'spam' );
-               $site->setType( Site::TYPE_UNKNOWN );
                $site->setLanguageCode( 'en' );
                $site->addNavigationId( 'spam' );
                $site->addNavigationId( 'spamz' );
@@ -72,9 +73,9 @@ class TestSites {
                $sites[] = $site;
 
                foreach ( array( 'en', 'de', 'nl', 'sv', 'sr', 'no', 'nn' ) as $langCode ) {
-                       $site = Sites::newSite( $langCode . 'wiki' );
+                       $site = new MediaWikiSite();
+                       $site->setGlobalId( $langCode . 'wiki' );
                        $site->setGroup( 'wikipedia' );
-                       $site->setType( Site::TYPE_MEDIAWIKI );
                        $site->setLanguageCode( $langCode );
                        $site->addInterwikiId( $langCode );
                        $site->addNavigationId( $langCode );
@@ -94,21 +95,21 @@ class TestSites {
        public static function insertIntoDb() {
                $dbw = wfGetDB( DB_MASTER );
 
-               $dbw->begin( __METHOD__ );
+               $trx = $dbw->trxLevel();
+
+               if ( $trx == 0 ) {
+                       $dbw->begin( __METHOD__ );
+               }
 
                $dbw->delete( 'sites', '*', __METHOD__ );
                $dbw->delete( 'site_identifiers', '*', __METHOD__ );
 
-               /**
-                * @var Site $site
-                */
-               foreach ( TestSites::getSites() as $site ) {
-                       $site->save();
-               }
+               $sitesTable = SiteSQLStore::newInstance();
+               $sitesTable->saveSites( TestSites::getSites() );
 
-               $dbw->commit( __METHOD__ );
-
-               Sites::singleton()->getSites( false ); // re-cache
+               if ( $trx == 0 ) {
+                       $dbw->commit( __METHOD__ );
+               }
        }
 
 }
\ No newline at end of file