store = $store;
$this->propertySpecificationReqMsgBuilder = $propertySpecificationReqMsgBuilder;
}
/**
* @see Page::initParameters()
*/
protected function initParameters() {
// We use a smaller limit here; property pages might become large
$this->limit = $this->getOption( 'pagingLimit' );
$this->property = DIProperty::newFromUserLabel( $this->getTitle()->getText() );
$this->propertyValue = DataValueFactory::getInstance()->newDataValueByItem( $this->property );
}
/**
* @see Page::getIntroductoryText
*
* @since 3.0
*
* @return string
*/
protected function getIntroductoryText() {
$redirectTarget = $this->store->getRedirectTarget( $this->property );
if ( !$redirectTarget->equals( $this->property ) ) {
return '';
}
$this->propertySpecificationReqMsgBuilder->setSemanticData(
$this->fetchSemanticDataFromEditInfo()
);
$this->propertySpecificationReqMsgBuilder->check(
$this->property
);
return $this->propertySpecificationReqMsgBuilder->getMessage();
}
/**
* @see Page::isLockedView
*
* @since 3.0
*
* @return boolean
*/
protected function isLockedView() {
return $this->propertySpecificationReqMsgBuilder->reqLock();
}
/**
* @see Page::getRedirectTargetURL
*
* @since 3.0
*
* @return string|boolean
*/
protected function getRedirectTargetURL() {
$label = $this->getTitle()->getText();
$property = new DIProperty(
PropertyRegistry::getInstance()->findPropertyIdByLabel( $label )
);
// Ensure to redirect to `Property:Modification date` and not using
// a possible user contextualized version such as `Property:Date de modification`
$canonicalLabel = $property->getCanonicalLabel();
if ( $canonicalLabel !== '' && $label !== $canonicalLabel ) {
return $property->getCanonicalDiWikiPage()->getTitle()->getFullURL();
}
return false;
}
/**
* Returns the HTML which is added to $wgOut after the article text.
*
* @return string
*/
protected function getHtml() {
if ( !$this->store->getRedirectTarget( $this->property )->equals( $this->property ) ) {
return '';
}
$context = $this->getContext();
$languageCode = $context->getLanguage()->getCode();
$html = '';
$matches = [];
$context->getOutput()->addModuleStyles( 'ext.smw.page.styles' );
$context->getOutput()->addModules( 'smw.property.page' );
$context->getOutput()->setPageTitle(
$this->propertyValue->getFormattedLabel( DataValueFormatter::WIKI_LONG )
);
$this->listBuilder = new SimpleListBuilder(
$this->store
);
$this->listBuilder->setLanguageCode(
$languageCode
);
$this->listBuilder->isUserDefined(
$this->property->isUserDefined()
);
if ( $this->mParserOutput instanceof \ParserOutput ) {
preg_match_all(
"/" . "([\s\S]*?)<\/section>" . "/m",
$this->mParserOutput->getText(),
$matches
);
}
$isFirst = true;
$htmlTabs = new HtmlTabs();
$htmlTabs->setGroup( 'property' );
$html = $this->makeValueList( $languageCode );
$isFirst = $html === '';
$htmlTabs->tab( 'smw-property-value', $this->msg( 'smw-property-tab-usage' ) . $this->getUsageCount(), [ 'hide' => $html === '' ] );
$htmlTabs->content( 'smw-property-value', $html );
// Redirects
list( $html, $itemCount ) = $this->makeList( 'redirect', '_REDI', true );
$isFirst = $isFirst && $html === '';
$htmlTabs->tab( 'smw-property-redi', $this->msg( 'smw-property-tab-redirects' ) . $itemCount, [ 'hide' => $html === '' ] );
$htmlTabs->content( 'smw-property-redi', $html );
// Subproperties
list( $html, $itemCount ) = $this->makeList( 'subproperty', '_SUBP', true );
$isFirst = $isFirst && $html === '';
$htmlTabs->tab( 'smw-property-subp', $this->msg( 'smw-property-tab-subproperties' ) . $itemCount, [ 'hide' => $html === '' ] );
$htmlTabs->content( 'smw-property-subp', $html );
// Improperty values
list( $html, $itemCount ) = $this->makeList( 'error', '_ERRP', false );
$isFirst = $isFirst && $html === '';
$htmlTabs->tab( 'smw-property-errp', $this->msg( 'smw-property-tab-errors' ) . $itemCount, [ 'hide' => $html === '', 'class' => 'smw-tab-warning' ] );
$htmlTabs->content( 'smw-property-errp', $html );
if ( isset( $matches[2] ) && $matches[2] !== [] ) {
$html = "" . implode('
', $matches[2] ) . "
";
} else {
$html = '';
}
$htmlTabs->tab(
'smw-property-spec',
$this->msg( 'smw-property-tab-specification' ),
[
'hide' => $html === '',
'class' => $isFirst ? 'smw-tab-spec' : 'smw-tab-spec smw-tab-right'
]
);
$htmlTabs->content( 'smw-property-spec', $html );
$html = $htmlTabs->buildHTML(
[ 'class' => 'smw-property clearfix' ]
);
return $html;
}
private function fetchSemanticDataFromEditInfo() {
$applicationFactory = ApplicationFactory::getInstance();
if ( $this->getPage()->getRevision() === null ) {
return null;
}
$editInfoProvider = $applicationFactory->newMwCollaboratorFactory()->newEditInfoProvider(
$this->getPage(),
$this->getPage()->getRevision()
);
return $editInfoProvider->fetchSemanticData();
}
private function makeList( $key, $propertyKey, $checkProperty = true ) {
// Ignore the list when a filter is present
if ( $this->getContext()->getRequest()->getVal( 'filter', '' ) !== '' ) {
return [ '', '' ];
}
$propertyListLimit = $this->getOption( 'smwgPropertyListLimit' );
$listLimit = $propertyListLimit[$key];
$requestOptions = new RequestOptions();
$requestOptions->sort = true;
$requestOptions->ascending = true;
// +1 look ahead
$requestOptions->setLimit(
$listLimit + 1
);
$this->listBuilder->setListLimit(
$listLimit
);
$this->listBuilder->setListHeader(
'smw-propertylist-' . $key
);
$this->listBuilder->checkProperty(
$checkProperty
);
$html = $this->listBuilder->createHtml(
new DIProperty( $propertyKey ),
$this->getDataItem(),
$requestOptions
);
$itemCount = Html::rawElement(
'span',
[
'class' => 'item-count'
],
$this->listBuilder->getItemCount()
);
return [ $html, $itemCount ];
}
private function makeValueList( $languageCode ) {
$request = $this->getContext()->getRequest();
$valueListBuilder = new ValueListBuilder(
$this->store
);
$valueListBuilder->setLanguageCode(
$languageCode
);
$valueListBuilder->setPagingLimit(
$this->getOption( 'pagingLimit' )
);
$valueListBuilder->setMaxPropertyValues(
$this->getOption( 'smwgMaxPropertyValues' )
);
return $valueListBuilder->createHtml(
$this->property,
$this->getDataItem(),
[
'limit' => $request->getVal( 'limit', $this->getOption( 'pagingLimit' ) ),
'offset' => $request->getVal( 'offset', '0' ),
'from' => $request->getVal( 'from', '' ),
'until' => $request->getVal( 'until', '' ),
'filter' => $request->getVal( 'filter', '' )
]
);
}
private function msg( $params, $type = Message::TEXT, $lang = Message::USER_LANGUAGE ) {
return Message::get( $params, $type, $lang );
}
private function getUsageCount() {
$requestOptions = new RequestOptions();
$requestOptions->setLimit( 1 );
// Label that corresponds to the display and sort characteristics
if ( $this->property->isUserDefined() ) {
$searchLabel = $this->propertyValue->getSearchLabel();
} else {
$searchLabel = $this->property->getKey();
$requestOptions->setOption( RequestOptions::SEARCH_FIELD, 'smw_title' );
}
$requestOptions->addStringCondition( $searchLabel, StringCondition::COND_EQ );
$cachedLookupList = $this->store->getPropertiesSpecial( $requestOptions );
$usageList = $cachedLookupList->fetchList();
if ( !$usageList || $usageList === [] ) {
return '';
}
$usage = end( $usageList );
$usageCount = $usage[1];
$date = $this->getContext()->getLanguage()->timeanddate( $cachedLookupList->getTimestamp() );
$countMsg = Message::get( [ 'smw-property-indicator-last-count-update', $date ] );
$indicatorClass = ( $usageCount < 25000 ? ( $usageCount > 5000 ? ' moderate' : '' ) : ' high' );
return Html::rawElement(
'span',
[
'title' => $countMsg,
'class' => 'usage-count' . $indicatorClass
],
$usageCount
);
}
}