summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php380
1 files changed, 380 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php b/www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php
new file mode 100644
index 00000000..c8580337
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/Page/PropertyPage.php
@@ -0,0 +1,380 @@
+<?php
+
+namespace SMW\Page;
+
+use Html;
+use SMW\ApplicationFactory;
+use SMW\DataValueFactory;
+use SMW\DataValues\ValueFormatters\DataValueFormatter;
+use SMW\DIProperty;
+use SMW\Message;
+use SMW\Page\ListBuilder\ListBuilder as SimpleListBuilder;
+use SMW\Page\ListBuilder\ValueListBuilder;
+use SMW\PropertyRegistry;
+use SMW\PropertySpecificationReqMsgBuilder;
+use SMW\RequestOptions;
+use SMW\Store;
+use SMW\StringCondition;
+use Title;
+use SMW\Utils\HtmlTabs;
+
+/**
+ * @license GNU GPL v2+
+ * @since 3.0
+ *
+ * @author mwjames
+ */
+class PropertyPage extends Page {
+
+ /**
+ * @var Store
+ */
+ private $store;
+
+ /**
+ * @var PropertySpecificationReqMsgBuilder
+ */
+ private $propertySpecificationReqMsgBuilder;
+
+ /**
+ * @var DIProperty
+ */
+ private $property;
+
+ /**
+ * @var DataValue
+ */
+ private $propertyValue;
+
+ /**
+ * @var ListBuilder
+ */
+ private $listBuilder;
+
+ /**
+ * @see 3.0
+ *
+ * @param Title $title
+ * @param Store $store
+ * @param PropertySpecificationReqMsgBuilder $propertySpecificationReqMsgBuilder
+ */
+ public function __construct( Title $title, Store $store, PropertySpecificationReqMsgBuilder $propertySpecificationReqMsgBuilder ) {
+ parent::__construct( $title );
+ $this->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(
+ "/" . "<section class=\"smw-property-specification\"(.*)?>([\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 = "<div>" . implode('</div><div>', $matches[2] ) . "</div>";
+ } 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
+ );
+ }
+
+}