Current File : /home/jvzmxxx/wiki1/extensions/Wikibase/lib/includes/Modules/SitesModuleWorker.php
<?php

namespace Wikibase\Lib;

use BagOStuff;
use MediaWikiSite;
use Site;
use SiteList;
use SiteStore;
use Wikibase\SettingsArray;
use Xml;

/**
 * @since 0.5
 *
 * @license GPL-2.0+
 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 * @author Daniel Werner < daniel.werner@wikimedia.de >
 * @author Marius Hoch < hoo@online.de >
 * @author Adrian Heine <adrian.heine@wikimedia.de>
 */
class SitesModuleWorker {

	/**
	 * How many seconds the result of self::getModifiedHash is cached.
	 */
	const SITES_HASH_CACHE_DURATION = 600; // 10 minutes

	/**
	 * @var SettingsArray
	 */
	private $settings;

	/**
	 * @var SiteStore
	 */
	private $siteStore;

	/**
	 * @var BagOStuff
	 */
	private $cache;

	/**
	 * @param SettingsArray $settings
	 * @param SiteStore $siteStore
	 * @param BagOStuff $cache
	 */
	public function __construct( SettingsArray $settings, SiteStore $siteStore, BagOStuff $cache ) {
		$this->settings = $settings;
		$this->siteStore = $siteStore;
		$this->cache = $cache;
	}

	/**
	 * @return string[]
	 */
	private function getSiteLinkGroups() {
		return $this->settings->getSetting( 'siteLinkGroups' );
	}

	/**
	 * @return string[]
	 */
	private function getSpecialSiteLinkGroups() {
		return $this->settings->getSetting( 'specialSiteLinkGroups' );
	}

	/**
	 * @return SiteList
	 */
	private function getSites() {
		return $this->siteStore->getSites();
	}

	/**
	 * Get a hash representing the sites table. This must change if e.g. new sites get added to the
	 * sites table.
	 *
	 * @return string
	 */
	private function getSitesHash() {
		$data = '';
		$sites = (array) $this->getSites();
		sort( $sites );

		/**
		 * @var Site $site
		 */
		foreach ( $sites as $site ) {
			$data .= json_encode( (array) $site );
		}

		return sha1( $data );
	}

	/**
	 * Used to propagate information about sites to JavaScript.
	 * Sites infos will be available in 'wbSiteDetails' config var.
	 * @see ResourceLoaderModule::getScript
	 *
	 * @param string $languageCode
	 *
	 * @return string
	 */
	public function getScript( $languageCode ) {
		$groups = $this->getSiteLinkGroups();
		$specialGroups = $this->getSpecialSiteLinkGroups();
		$specialPos = array_search( 'special', $groups );
		if ( $specialPos !== false ) {
			// The "special" group actually maps to multiple groups
			array_splice( $groups, $specialPos, 1, $specialGroups );
		}

		$siteDetails = array();
		/**
		 * @var MediaWikiSite $site
		 */
		foreach ( $this->getSites() as $site ) {
			if ( $this->shouldSiteBeIncluded( $site, $groups ) ) {
				$siteDetails[$site->getGlobalId()] = $this->getSiteDetails(
					$site,
					$specialGroups,
					$languageCode
				);
			}
		}

		return Xml::encodeJsCall( 'mediaWiki.config.set', array( 'wbSiteDetails', $siteDetails ) );
	}

	/**
	 * @param MediaWikiSite $site
	 * @param string[] $specialGroups
	 * @param string $languageCode
	 *
	 * @return string[]
	 */
	private function getSiteDetails( MediaWikiSite $site, array $specialGroups, $languageCode ) {
		$languageNameLookup = new LanguageNameLookup();

		$group = $site->getGroup();

		// FIXME: quickfix to allow a custom site-name / handling for the site groups which are
		// special according to the specialSiteLinkGroups setting
		if ( in_array( $group, $specialGroups ) ) {
			$languageName = $this->getSpecialSiteLanguageName( $site, $languageCode );
			$groupName = 'special';
		} else {
			$languageName = $languageNameLookup->getName( $site->getLanguageCode() );
			$groupName = $group;
		}

		// Use protocol relative URIs, as it's safe to assume that all wikis support the same protocol
		list( $pageUrl, $apiUrl ) = preg_replace(
			"/^https?:/i",
			'',
			array(
				$site->getPageUrl(),
				$site->getFileUrl( 'api.php' )
			)
		);

		//TODO: figure out which name is best
		//$localIds = $site->getLocalIds();
		//$name = empty( $localIds['equivalent'] ) ? $site->getGlobalId() : $localIds['equivalent'][0];

		return array(
				'shortName' => $languageName,
				'name' => $languageName, // use short name for both, for now
				'id' => $site->getGlobalId(),
				'pageUrl' => $pageUrl,
				'apiUrl' => $apiUrl,
				'languageCode' => $site->getLanguageCode(),
				'group' => $groupName
		);
	}

	/**
	 * @param Site $site
	 * @param string $languageCode
	 *
	 * @return string
	 */
	private function getSpecialSiteLanguageName( Site $site, $languageCode ) {
		$siteId = $site->getGlobalId();
		$messageKey = 'wikibase-sitelinks-sitename-' . $siteId;

		// @note: inLanguage needs to be called before exists and parse. See: T127872.
		$languageNameMsg = wfMessage( $messageKey )->inLanguage( $languageCode );

		return $languageNameMsg->exists() ? $languageNameMsg->parse() : $siteId;
	}

	/**
	 * Whether it's needed to add a Site to the JS variable.
	 *
	 * @param Site $site
	 * @param string[] $groups
	 *
	 * @return bool
	 */
	private function shouldSiteBeIncluded( Site $site, array $groups ) {
		return $site->getType() === Site::TYPE_MEDIAWIKI && in_array( $site->getGroup(), $groups );
	}

	/**
	 * @return string
	 */
	private function computeModifiedHash() {
		$data = array(
			$this->getSiteLinkGroups(),
			$this->getSpecialSiteLinkGroups(),
			$this->getSitesHash()
		);

		return sha1( json_encode( $data ) );
	}

	/**
	 * This returns our additions to the default definition summary.
	 * We add a hash which should change whenever either a relevant setting
	 * or the list of sites changes. Because computing this list is quite heavy and
	 * it barely changes, cache that hash for a short bit.
	 *
	 * @see ResourceLoaderModule::getDefinitionSummary
	 *
	 * @return array
	 */
	public function getDefinitionSummary() {
		$cacheKey = wfMemcKey( 'wikibase-sites-module-modified-hash' );
		$hash = $this->cache->get( $cacheKey );

		if ( $hash === false ) {
			$hash = $this->computeModifiedHash();
			$this->cache->set( $cacheKey, $hash, self::SITES_HASH_CACHE_DURATION );
		}

		return array(
			'dataHash' => $hash
		);
	}

}