| Current File : /home/jvzmxxx/wiki/extensions/Wikibase/client/includes/Hooks/OtherProjectsSidebarGenerator.php |
<?php
namespace Wikibase\Client\Hooks;
use Hooks;
use Site;
use SiteStore;
use Title;
use Wikibase\DataModel\SiteLink;
use Wikibase\DataModel\Entity\ItemId;
use Wikibase\Lib\Store\SiteLinkLookup;
/**
* Outputs a sidebar section for other project links.
*
* @since 0.5
*
* @license GPL-2.0+
* @author Thomas Pellissier Tanon
* @author Marius Hoch < hoo@online.de >
*/
class OtherProjectsSidebarGenerator {
/**
* @var string
*/
private $localSiteId;
/**
* @var SiteLinkLookup
*/
private $siteLinkLookup;
/**
* @var SiteStore
*/
private $siteStore;
/**
* @var string[]
*/
private $siteIdsToOutput;
/**
* @param string $localSiteId
* @param SiteLinkLookup $siteLinkLookup
* @param SiteStore $siteStore
* @param string[] $siteIdsToOutput
*/
public function __construct(
$localSiteId,
SiteLinkLookup $siteLinkLookup,
SiteStore $siteStore,
array $siteIdsToOutput
) {
$this->localSiteId = $localSiteId;
$this->siteLinkLookup = $siteLinkLookup;
$this->siteStore = $siteStore;
$this->siteIdsToOutput = $siteIdsToOutput;
}
/**
* @param Title $title
*
* @return array[] Array of arrays of attributes describing sidebar links, sorted by the site's
* group and global ids.
*/
public function buildProjectLinkSidebar( Title $title ) {
$itemId = $this->siteLinkLookup->getItemIdForLink(
$this->localSiteId,
$title->getPrefixedText()
);
if ( !$itemId ) {
return array();
}
$sidebar = $this->buildPreliminarySidebarFromSiteLinks( $this->getSiteLinks( $itemId ) );
$sidebar = $this->runHook( $itemId, $sidebar );
return $this->sortAndFlattenSidebar( $sidebar );
}
/**
* @param ItemId $itemId
* @param array $sidebar
*
* @return array
*/
private function runHook( ItemId $itemId, array $sidebar ) {
$newSidebar = $sidebar;
Hooks::run( 'WikibaseClientOtherProjectsSidebar', array( $itemId, &$newSidebar ) );
if ( $newSidebar === $sidebar ) {
return $sidebar;
}
if ( !is_array( $newSidebar ) || !$this->isValidSidebar( $newSidebar ) ) {
wfLogWarning( 'Other projects sidebar data invalid after hook run.' );
return $sidebar;
}
return $newSidebar;
}
/**
* @param array $sidebar
* @return bool
*/
private function isValidSidebar( array $sidebar ) {
// Make sure all required array keys are set and are string.
foreach ( $sidebar as $siteGroup => $perSiteGroup ) {
if ( !is_string( $siteGroup ) || !is_array( $perSiteGroup ) ) {
return false;
}
foreach ( $perSiteGroup as $siteId => $perSite ) {
if ( !is_string( $siteId )
|| !isset( $perSite['msg'] )
|| !isset( $perSite['class'] )
|| !isset( $perSite['href'] )
|| !is_string( $perSite['msg'] )
|| !is_string( $perSite['class'] )
|| !is_string( $perSite['href'] )
) {
return false;
}
}
}
return true;
}
/**
* @param SiteLink[] $siteLinks
*
* @return array[] Arrays of link attributes indexed by site group and by global site id.
*/
private function buildPreliminarySidebarFromSiteLinks( array $siteLinks ) {
$linksByGroup = array();
foreach ( $siteLinks as $siteLink ) {
if ( !in_array( $siteLink->getSiteId(), $this->siteIdsToOutput ) ) {
continue;
}
$site = $this->siteStore->getSite( $siteLink->getSiteId() );
if ( $site !== null ) {
$group = $site->getGroup();
$globalId = $site->getGlobalId();
// Index by site group and global id
$linksByGroup[$group][$globalId] = $this->buildSidebarLink( $siteLink, $site );
}
}
return $linksByGroup;
}
/**
* The arrays of link attributes are indexed by site group and by global site id.
* Sort them by both and then return the flattened array.
*
* @param array[] $linksByGroup
*
* @return array[] Array of arrays of attributes describing sidebar links, sorted by the site's
* group and global ids.
*/
private function sortAndFlattenSidebar( array $linksByGroup ) {
$result = array();
ksort( $linksByGroup ); // Sort by group id
foreach ( $linksByGroup as $linksPerGroup ) {
ksort( $linksPerGroup ); // Sort individual arrays by global site id
$result = array_merge( $result, array_values( $linksPerGroup ) );
}
return $result;
}
/**
* @param ItemId $itemId
*
* @return SiteLink[]
*/
private function getSiteLinks( ItemId $itemId ) {
return $this->siteLinkLookup->getSiteLinksForItem( $itemId );
}
/**
* @param SiteLink $siteLink
* @param Site $site
*
* @return string[] Array of attributes describing a sidebar link.
*/
private function buildSidebarLink( SiteLink $siteLink, Site $site ) {
// Messages in the WikimediaMessages extension (as of 2015-03-31):
// wikibase-otherprojects-commons
// wikibase-otherprojects-testwikidata
// wikibase-otherprojects-wikidata
// wikibase-otherprojects-wikinews
// wikibase-otherprojects-wikipedia
// wikibase-otherprojects-wikiquote
// wikibase-otherprojects-wikisource
// wikibase-otherprojects-wikivoyage
$attributes = array(
'msg' => 'wikibase-otherprojects-' . $site->getGroup(),
'class' => 'wb-otherproject-link wb-otherproject-' . $site->getGroup(),
'href' => $site->getPageUrl( $siteLink->getPageName() )
);
$siteLanguageCode = $site->getLanguageCode();
if ( $siteLanguageCode !== null ) {
$attributes['hreflang'] = $siteLanguageCode;
}
return $attributes;
}
}