client/includes/Specials/SpecialEntityUsage.php
<?php
namespace Wikibase\Client\Specials;
use HtmlArmor;
use MediaWiki\Html\Html;
use MediaWiki\HTMLForm\HTMLForm;
use MediaWiki\Languages\LanguageConverterFactory;
use MediaWiki\Linker\Linker;
use MediaWiki\SpecialPage\QueryPage;
use MediaWiki\Title\Title;
use Skin;
use Wikibase\Client\Usage\EntityUsage;
use Wikibase\DataModel\Entity\EntityId;
use Wikibase\DataModel\Entity\EntityIdParser;
use Wikibase\DataModel\Entity\EntityIdParsingException;
use Wikibase\Lib\Rdbms\ClientDomainDb;
use Wikibase\Lib\Rdbms\ClientDomainDbFactory;
/**
* A special page that lists client wiki pages that use a given entity ID from the repository, and
* which aspects each page uses.
*
* @license GPL-2.0-or-later
* @author Amir Sarabadani (ladsgroup@gmail.com)
*/
class SpecialEntityUsage extends QueryPage {
/**
* @var EntityIdParser
*/
private $idParser;
/** @var LanguageConverterFactory */
private $languageConverterFactory;
/** @var ClientDomainDb */
private $db;
/**
* @var EntityId|null
*/
private $entityId = null;
public function __construct(
LanguageConverterFactory $languageConverterFactory,
ClientDomainDbFactory $dbFactory,
EntityIdParser $idParser
) {
parent::__construct( 'EntityUsage' );
$this->idParser = $idParser;
$this->languageConverterFactory = $languageConverterFactory;
$this->db = $dbFactory->newLocalDb();
}
/**
* @see QueryPage::execute
*
* @param string|null $subPage
*/
public function execute( $subPage ) {
$entity = $this->getRequest()->getText( 'entity', $subPage ?: '' );
$this->prepareParams( $entity );
if ( $this->entityId !== null ) {
parent::execute( $subPage );
} else {
$this->setHeaders();
$this->outputHeader();
$this->getOutput()->addHTML( $this->getPageHeader() );
}
}
/**
* @param string $entity
*/
public function prepareParams( $entity ) {
if ( $entity ) {
try {
$this->entityId = $this->idParser->parse( $entity );
} catch ( EntityIdParsingException $ex ) {
$this->getOutput()->addHTML(
Html::element(
'p',
[
'class' => 'error',
],
$this->msg( 'wikibase-entityusage-invalid-id', $entity )->text()
)
);
}
}
}
/**
* @see QueryPage::getPageHeader
*
* @return string HTML
*/
public function getPageHeader() {
$formDescriptor = [
'entity' => [
'name' => 'entity',
'type' => 'text',
'id' => 'wb-entityusage-entity',
'label-message' => 'wikibase-entityusage-entity',
],
'submit' => [
'name' => '',
'type' => 'submit',
'id' => 'wikibase-entityusage-submit',
'default' => $this->msg( 'wikibase-entityusage-submit' )->text(),
],
];
if ( $this->entityId !== null ) {
$formDescriptor['entity']['default'] = $this->entityId->getSerialization();
}
return HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
->setMethod( 'get' )
->setWrapperLegendMsg( 'wikibase-entityusage-legend' )
->suppressDefaultSubmit()
->prepareForm()
->getHTML( '' );
}
/**
* @see QueryPage::getQueryInfo
*
* @return array[]
*/
public function getQueryInfo() {
$dbr = $this->db->connections()->getReadConnection();
$conds = [ 'eu_entity_id' => $this->entityId->getSerialization() ];
return $dbr->newSelectQueryBuilder()
->select( [
'value' => 'page_id',
'namespace' => 'page_namespace',
'title' => 'page_title',
'aspects' => $dbr->newSelectQueryBuilder()
->table( 'wbc_entity_usage' )
->field( 'eu_aspect' )
->where( [ 'eu_page_id = page_id' ] )
->andWhere( $conds )
->buildGroupConcatField( '|' ),
'eu_page_id',
] )
->from( 'page' )
->join( 'wbc_entity_usage', null, [ 'page_id = eu_page_id' ] )
->where( $conds )
->groupBy( 'eu_page_id' )
->getQueryInfo();
}
/**
* @see QueryPage::formatResult
*
* @param Skin $skin
* @param \stdClass $row
*
* @return string HTML
*/
public function formatResult( $skin, $row ) {
$title = Title::makeTitleSafe( $row->namespace, $row->title );
if ( !$title ) {
return Html::element(
'span',
[ 'class' => 'mw-invalidtitle' ],
Linker::getInvalidTitleDescription(
$this->getContext(),
$row->namespace,
$row->title
)
);
}
$languageConverter = $this->languageConverterFactory->getLanguageConverter();
$linkText = $languageConverter->convert( htmlspecialchars( $title->getPrefixedText() ) );
return $this->getLinkRenderer()->makeLink(
$title,
new HtmlArmor( $linkText )
) . $this->msg( 'colon-separator' )->escaped() . $this->formatAspects( $row->aspects );
}
/**
* @param string $rowAspects
*
* @return string
*/
public function formatAspects( $rowAspects ) {
$rowAspects = explode( '|', $rowAspects );
$aspects = [];
foreach ( $rowAspects as $aspect ) {
$aspect = EntityUsage::splitAspectKey( $aspect );
// Possible messages:
// wikibase-pageinfo-entity-usage-L
// wikibase-pageinfo-entity-usage-L-with-modifier
// wikibase-pageinfo-entity-usage-D
// wikibase-pageinfo-entity-usage-D-with-modifier
// wikibase-pageinfo-entity-usage-C
// wikibase-pageinfo-entity-usage-C-with-modifier
// wikibase-pageinfo-entity-usage-S
// wikibase-pageinfo-entity-usage-T
// wikibase-pageinfo-entity-usage-X
// wikibase-pageinfo-entity-usage-O
$msgKey = 'wikibase-pageinfo-entity-usage-' . $aspect[0];
if ( $aspect[1] !== null ) {
$msgKey .= '-with-modifier';
}
$aspects[] = $this->getContext()->msg( $msgKey, $aspect[1] )->parse();
}
return $this->getContext()->getLanguage()->commaList( $aspects );
}
/**
* @see QueryPage::isSyndicated
*
* @return bool
*/
public function isSyndicated() {
return false;
}
/**
* @see QueryPage::isCacheable
*
* @return bool
*/
public function isCacheable() {
return false;
}
/**
* @see QueryPage::linkParameters
*
* @return string[]
*/
public function linkParameters() {
return [ 'entity' => $this->entityId->getSerialization() ];
}
/**
* @see SpecialPage::getGroupName
*
* @return string
*/
protected function getGroupName() {
return 'pages';
}
}