792 lines
23 KiB
PHP
792 lines
23 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Html\Html;
|
|
use MediaWiki\MediaWikiServices;
|
|
use MediaWiki\Parser\Sanitizer;
|
|
use SMW\DIWikiPage;
|
|
use SMW\Localizer\Localizer;
|
|
use SMW\Localizer\Message;
|
|
use SMW\MediaWiki\Pipetrick;
|
|
use SMW\Services\ServicesFactory as ApplicationFactory;
|
|
use SMW\Utils\Image;
|
|
|
|
/**
|
|
* @ingroup SMWDataValues
|
|
*/
|
|
|
|
/**
|
|
* This datavalue implements special processing suitable for defining
|
|
* wikipages as values of properties.
|
|
*
|
|
* The class can support general wiki pages, or pages of a fixed
|
|
* namespace, Whether a namespace is fixed is decided based on the
|
|
* type ID when the object is constructed.
|
|
*
|
|
* The short display simulates the behavior of the MediaWiki "pipe trick"
|
|
* but always includes fragments. This can be overwritten by setting a
|
|
* caption, which is also done by default when generating a value from user
|
|
* input. The long display always includes all relevant information. Only if a
|
|
* fixed namespace is used for the datatype, the namespace prefix is omitted.
|
|
* This behavior has changed in SMW 1.7: up to this time, short displays have
|
|
* always included the namespace and long displays used the pipe trick, leading
|
|
* to a paradoxical confusion of "long" and "short".
|
|
*
|
|
* @author Nikolas Iwan
|
|
* @author Markus Krötzsch
|
|
* @ingroup SMWDataValues
|
|
*/
|
|
class SMWWikiPageValue extends SMWDataValue {
|
|
|
|
/**
|
|
* Whether text transformation should be suppressed or not.
|
|
*/
|
|
const NO_TEXT_TRANSFORMATION = 'no.text.transformation';
|
|
|
|
/**
|
|
* Whether images should be displayed as media or simple link.
|
|
*/
|
|
const NO_IMAGE = 'no.image';
|
|
|
|
/**
|
|
* Whether to use the short form or not.
|
|
*/
|
|
const SHORT_FORM = 'form/short';
|
|
|
|
/**
|
|
* Whether to use the prefixed form or not.
|
|
*/
|
|
const PREFIXED_FORM = 'form/prefixed';
|
|
|
|
/**
|
|
* Fragment text for user-specified title. Not stored, but kept for
|
|
* printout on page.
|
|
* @var string
|
|
*/
|
|
protected $m_fragment = '';
|
|
|
|
/**
|
|
* Full titletext with prefixes, including interwiki prefix.
|
|
* Set to empty string if not computed yet.
|
|
* @var string
|
|
*/
|
|
protected $m_prefixedtext = '';
|
|
|
|
/**
|
|
* Cache for the related MW page ID.
|
|
* Set to -1 if not computed yet.
|
|
* @var int
|
|
*/
|
|
protected $m_id = -1;
|
|
|
|
/**
|
|
* Cache for the related MW title object.
|
|
* Set to null if not computed yet.
|
|
* @var Title
|
|
*/
|
|
protected $m_title = null;
|
|
|
|
/**
|
|
* If this has a value other than NS_MAIN, the datavalue will only
|
|
* accept pages in this namespace. This field is initialized when
|
|
* creating the object (based on the type id or base on the preference
|
|
* of some subclass); it is not usually changed afterwards.
|
|
* @var int
|
|
*/
|
|
protected $m_fixNamespace = NS_MAIN;
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $linkAttributes = [];
|
|
|
|
/**
|
|
* @var array
|
|
*/
|
|
protected $queryParameters = [];
|
|
|
|
public function __construct( $typeid ) {
|
|
parent::__construct( $typeid );
|
|
switch ( $typeid ) {
|
|
case '_wpp':
|
|
case '__sup':
|
|
$this->m_fixNamespace = SMW_NS_PROPERTY;
|
|
break;
|
|
case '_wpc':
|
|
case '__suc':
|
|
case '__sin':
|
|
$this->m_fixNamespace = NS_CATEGORY;
|
|
break;
|
|
case '_wps':
|
|
$this->m_fixNamespace = SMW_NS_SCHEMA;
|
|
break;
|
|
case '_wpu':
|
|
$this->m_fixNamespace = NS_USER;
|
|
break;
|
|
default: // case '_wpg':
|
|
$this->m_fixNamespace = NS_MAIN;
|
|
}
|
|
}
|
|
|
|
protected function parseUserValue( $value ) {
|
|
$localizer = Localizer::getInstance();
|
|
$titleFactory = MediaWikiServices::getInstance()->getTitleFactory();
|
|
|
|
// support inputs like " [[Test]] ";
|
|
// note that this only works when SMW_PARSER_LINV is set
|
|
$value = ltrim( rtrim( (string)$value, ' ]' ), ' [' );
|
|
|
|
// #1066, Manipulate the output only for when the value has no caption
|
|
// assigned and only if a single :Foo is being present, ::Foo is not permitted
|
|
if ( $this->m_caption === false && isset( $value[2] ) && $value[0] === ':' && $value[1] !== ':' ) {
|
|
$value = substr( $value, 1 );
|
|
}
|
|
|
|
if ( $this->m_caption === false ) {
|
|
$this->m_caption = $value;
|
|
}
|
|
|
|
if ( $value === '' && !$this->getOption( self::OPT_QUERY_CONTEXT ) ) {
|
|
$this->addErrorMsg( [ 'smw-datavalue-wikipage-empty' ], Message::ESCAPED );
|
|
return;
|
|
}
|
|
|
|
// #1701 If the DV is part of a Description and an approximate search
|
|
// (e.g. ~foo* / ~Foo*) then use the value as-is and avoid being
|
|
// transformed by the Title object
|
|
// If the vaue contains a valid NS then use the Title to create a correct
|
|
// instance to distinguish [[~Foo*]] from [[Help:~Foo*]]
|
|
if ( $this->getOption( self::OPT_QUERY_COMP_CONTEXT ) || $this->getOption( self::OPT_QUERY_CONTEXT ) ) {
|
|
|
|
$title = $titleFactory->newFromText( $value, $this->m_fixNamespace );
|
|
|
|
// T:P0427 If the user value says `ab c*` then make sure to use this one
|
|
// instead of the transformed DBKey which would be `Ab c*`
|
|
if ( $title !== null && $title->getNamespace() === NS_MAIN && $this->getOption( 'isCapitalLinks' ) === false ) {
|
|
return $this->m_dataitem = new DIWikiPage( $value, NS_MAIN );
|
|
// If we know that it is a wikipage in a query context and the wiki
|
|
// requires `isCapitalLinks` then use the standard transformation so
|
|
// they appear as standard links even though the user input was `abc`.
|
|
// T:P0902 (`[[Help:]]`)
|
|
} elseif ( $title !== null ) {
|
|
return $this->m_dataitem = DIWikiPage::newFromTitle( $title );
|
|
} elseif ( !$localizer->getNsIndex( substr( $value, 0, -1 ) ) ) {
|
|
return $this->m_dataitem = new DIWikiPage( $value, NS_MAIN );
|
|
}
|
|
}
|
|
|
|
if ( $value[0] == '#' ) {
|
|
if ( $this->m_contextPage === null ) {
|
|
$this->addErrorMsg( [ 'smw-datavalue-wikipage-missing-fragment-context', $value ] );
|
|
return;
|
|
} else {
|
|
$this->m_title = $titleFactory->makeTitle( $this->m_contextPage->getNamespace(),
|
|
$this->m_contextPage->getDBkey(), substr( $value, 1 ),
|
|
$this->m_contextPage->getInterwiki() );
|
|
}
|
|
} else {
|
|
$this->m_title = $titleFactory->newFromText( $value, $this->m_fixNamespace );
|
|
}
|
|
|
|
$property = $this->getProperty();
|
|
|
|
/// TODO: Escape the text so users can see punctuation problems (bug 11666).
|
|
if ( $this->m_title === null && $property !== null ) {
|
|
$this->addErrorMsg( [ 'smw-datavalue-wikipage-property-invalid-title', $property->getLabel(), $value ] );
|
|
} elseif ( $this->m_title === null ) {
|
|
$this->addErrorMsg( [ 'smw-datavalue-wikipage-invalid-title', $value ] );
|
|
} elseif ( ( $this->m_fixNamespace != NS_MAIN ) &&
|
|
( $this->m_fixNamespace != $this->m_title->getNamespace() ) ) {
|
|
$this->addErrorMsg( [ 'smw_wrong_namespace', $localizer->getNsText( $this->m_fixNamespace ) ] );
|
|
} else {
|
|
$this->m_fragment = str_replace( ' ', '_', $this->m_title->getFragment() );
|
|
$this->m_prefixedtext = '';
|
|
$this->m_id = -1; // unset id
|
|
$this->m_dataitem = DIWikiPage::newFromTitle( $this->m_title, $this->m_typeid );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @see SMWDataValue::loadDataItem()
|
|
* @param $dataItem SMWDataItem
|
|
* @return bool
|
|
*/
|
|
protected function loadDataItem( SMWDataItem $dataItem ) {
|
|
if ( $dataItem->getDIType() == SMWDataItem::TYPE_CONTAINER ) {
|
|
// might throw an exception, we just pass it through
|
|
$dataItem = $dataItem->getSemanticData()->getSubject();
|
|
}
|
|
|
|
if ( $dataItem->getDIType() !== SMWDataItem::TYPE_WIKIPAGE ) {
|
|
return false;
|
|
}
|
|
|
|
$this->m_dataitem = $dataItem;
|
|
$this->m_id = -1;
|
|
$this->m_title = null;
|
|
$this->m_fragment = (string)$dataItem->getSubobjectName();
|
|
$this->m_prefixedtext = '';
|
|
$this->m_caption = false; // this class can handle this
|
|
$this->linkAttributes = [];
|
|
|
|
if ( ( $this->m_fixNamespace != NS_MAIN ) &&
|
|
( $this->m_fixNamespace != $dataItem->getNamespace() ) ) {
|
|
$this->addErrorMsg(
|
|
[
|
|
'smw_wrong_namespace',
|
|
Localizer::getInstance()->getNsText( $this->m_fixNamespace )
|
|
]
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @since 2.4
|
|
*
|
|
* @param array $linkAttributes
|
|
*/
|
|
public function setLinkAttributes( array $linkAttributes ) {
|
|
$this->linkAttributes = $linkAttributes;
|
|
}
|
|
|
|
/**
|
|
* @since 2.5
|
|
*
|
|
* @param array $queryParameters
|
|
*/
|
|
public function setQueryParameters( array $queryParameters ) {
|
|
$this->queryParameters = $queryParameters;
|
|
}
|
|
|
|
/**
|
|
* Display the value on a wiki page. This is used to display the value
|
|
* in the place where it was annotated on a wiki page. The desired
|
|
* behavior is that the display in this case looks as if no property
|
|
* annotation had been given, i.e. an annotation [[property::page|foo]]
|
|
* should display like [[page|foo]] in MediaWiki. But this should lead
|
|
* to a link, not to a category assignment. This means that:
|
|
*
|
|
* (1) If Image: is used (instead of Media:) then let MediaWiki embed
|
|
* the image.
|
|
*
|
|
* (2) If Category: is used, treat it as a page and link to it (do not
|
|
* categorize the page)
|
|
*
|
|
* (3) Preserve everything given after "|" for display (caption, image
|
|
* parameters, ...)
|
|
*
|
|
* (4) Use the (default) caption for display. When the value comes from
|
|
* user input, this includes the full value that one would also see in
|
|
* MediaWiki.
|
|
*
|
|
* @param null $linked mixed generate links if not null or false
|
|
* @return string
|
|
*/
|
|
public function getShortWikiText( $linked = null ) {
|
|
if ( $linked === null || $linked === false ||
|
|
$this->m_outformat == '-' || !$this->isValid() ||
|
|
$this->m_caption === '' ) {
|
|
$text = $this->m_caption !== false ? $this->m_caption : $this->getWikiValue();
|
|
|
|
// #4037
|
|
if ( $this->linkAttributes !== [] ) {
|
|
$text = Html::rawElement(
|
|
'span',
|
|
$this->linkAttributes,
|
|
$text
|
|
);
|
|
}
|
|
|
|
return $text;
|
|
}
|
|
|
|
$noImage = $this->getOption( self::NO_IMAGE, false );
|
|
|
|
if ( $this->m_outformat == 'noimage' ) {
|
|
$noImage = true;
|
|
}
|
|
|
|
if ( Image::isImage( $this->m_dataitem ) && $this->m_dataitem->getInterwiki() === '' && !$noImage ) {
|
|
$linkEscape = '';
|
|
$sanitizedHtml = Sanitizer::removeSomeTags( $this->m_outformat );
|
|
$options = $this->m_outformat === false ? 'frameless|border|text-top|' : str_replace( ';', '|', $sanitizedHtml );
|
|
$defaultCaption = '|' . $this->getShortCaptionText() . '|' . $options;
|
|
} else {
|
|
$linkEscape = ':';
|
|
$defaultCaption = '|' . $this->getShortCaptionText();
|
|
}
|
|
|
|
if ( $this->m_caption === false ) {
|
|
$link = '[[' . $linkEscape . $this->getWikiLinkTarget() . $defaultCaption . ']]';
|
|
} else {
|
|
$link = '[[' . $linkEscape . $this->getWikiLinkTarget() . '|' . $this->m_caption . ']]';
|
|
}
|
|
|
|
if ( $this->m_fragment !== '' ) {
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity';
|
|
}
|
|
|
|
if ( $this->linkAttributes !== [] ) {
|
|
$link = Html::rawElement(
|
|
'span',
|
|
$this->linkAttributes,
|
|
$link
|
|
);
|
|
}
|
|
|
|
return $link;
|
|
}
|
|
|
|
/**
|
|
* Display the value as in getShortWikiText() but create HTML.
|
|
* The only difference is that images are not embedded.
|
|
*
|
|
* @param Linker|null $linker mixed the Linker object to use or null if no linking is desired
|
|
* @return string
|
|
*/
|
|
public function getShortHTMLText( $linker = null ) {
|
|
if ( $this->m_fragment !== '' ) {
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity';
|
|
}
|
|
|
|
// init the Title object, may reveal hitherto unnoticed errors:
|
|
if ( $linker !== null && $linker !== false &&
|
|
$this->m_caption !== '' && $this->m_outformat != '-' ) {
|
|
$this->getTitle();
|
|
}
|
|
|
|
if ( $linker === null || $linker === false || !$this->isValid() ||
|
|
$this->m_outformat == '-' || $this->m_caption === '' ) {
|
|
|
|
$caption = $this->m_caption === false ? $this->getWikiValue() : $this->m_caption;
|
|
return Sanitizer::removeSomeTags( $caption );
|
|
}
|
|
|
|
$caption = $this->m_caption === false ? $this->getShortCaptionText() : $this->m_caption;
|
|
$caption = Sanitizer::removeSomeTags( $caption );
|
|
|
|
if ( $this->getNamespace() == NS_MEDIA ) { // this extra case *is* needed
|
|
return $linker->makeMediaLinkObj( $this->getTitle(), $caption );
|
|
}
|
|
|
|
return $linker->link(
|
|
$this->getTitle(),
|
|
$caption,
|
|
$this->linkAttributes,
|
|
$this->queryParameters
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Display the "long" value on a wiki page. This behaves largely like
|
|
* getShortWikiText() but does not use the caption. Instead, it always
|
|
* takes the long display form (wiki value).
|
|
*
|
|
* @param null $linked mixed if true the result will be linked
|
|
* @return string
|
|
*/
|
|
public function getLongWikiText( $linked = null ) {
|
|
if ( !$this->isValid() ) {
|
|
return $this->getErrorText();
|
|
}
|
|
|
|
$noImage = $this->getOption( self::NO_IMAGE, false );
|
|
|
|
if ( $this->m_outformat == 'noimage' ) {
|
|
$noImage = true;
|
|
}
|
|
|
|
if ( $linked === null || $linked === false || $this->m_outformat == '-' ) {
|
|
return $this->getWikiValue();
|
|
} elseif ( Image::isImage( $this->m_dataitem ) && $this->m_dataitem->getInterwiki() === '' && !$noImage ) {
|
|
// Embed images and other files
|
|
// Note that the embedded file links to the image, hence needs no additional link text.
|
|
// There should not be a linebreak after an impage, just like there is no linebreak after
|
|
// other values (whether formatted or not).
|
|
return '[[' . $this->getWikiLinkTarget() . '|' .
|
|
$this->getLongCaptionText() . '|frameless|border|text-top]]';
|
|
}
|
|
|
|
$link = '[[:' . $this->getWikiLinkTarget() . '|' . $this->getLongCaptionText() . ']]';
|
|
|
|
if ( $this->m_fragment !== '' ) {
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity';
|
|
}
|
|
|
|
if ( $this->linkAttributes !== [] ) {
|
|
$link = Html::rawElement(
|
|
'span',
|
|
$this->linkAttributes,
|
|
$link
|
|
);
|
|
}
|
|
|
|
return $link;
|
|
}
|
|
|
|
/**
|
|
* Display the "long" value in HTML. This behaves largely like
|
|
* getLongWikiText() but does not embed images.
|
|
*
|
|
* @param null $linker mixed if a Linker is given, the result will be linked
|
|
* @return string
|
|
*/
|
|
public function getLongHTMLText( $linker = null ) {
|
|
if ( $this->m_fragment !== '' ) {
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity';
|
|
}
|
|
|
|
// init the Title object, may reveal hitherto unnoticed errors:
|
|
if ( $linker !== null && ( $this->m_outformat != '-' ) ) {
|
|
$this->getTitle();
|
|
}
|
|
|
|
if ( !$this->isValid() ) {
|
|
return $this->getErrorText();
|
|
}
|
|
|
|
$sanitizerCallback = [ Sanitizer::class, 'removeSomeTags' ];
|
|
|
|
if ( $linker === null || $linker === false || $this->m_outformat == '-' ) {
|
|
return call_user_func( $sanitizerCallback, $this->getWikiValue() );
|
|
} elseif ( $this->getNamespace() == NS_MEDIA ) { // this extra case is really needed
|
|
return $linker->makeMediaLinkObj(
|
|
$this->getTitle(),
|
|
call_user_func( $sanitizerCallback, $this->getLongCaptionText() )
|
|
);
|
|
}
|
|
|
|
// all others use default linking, no embedding of images here
|
|
return $linker->link(
|
|
$this->getTitle(),
|
|
call_user_func( $sanitizerCallback, $this->getLongCaptionText() ),
|
|
$this->linkAttributes,
|
|
$this->queryParameters
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Return a string that could be used in an in-page property assignment
|
|
* for setting this value. This does not include initial ":" for
|
|
* escaping things like Category: links since the property value does
|
|
* not include such escapes either. Fragment information is included.
|
|
* Namespaces are omitted if a fixed namespace is used, since they are
|
|
* not needed in this case when making a property assignment.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getWikiValue() {
|
|
if ( $this->getOption( self::SHORT_FORM, false ) ) {
|
|
$text = $this->getText();
|
|
} elseif ( $this->getOption( self::PREFIXED_FORM, false ) ) {
|
|
$text = $this->getPrefixedText();
|
|
} elseif (
|
|
in_array( $this->getTypeID(), [ '_wpp', '_wps', '_wpu', '__sup', '__sin', '__suc', '__con' ] ) ||
|
|
$this->m_fixNamespace === NS_MAIN
|
|
) {
|
|
$text = $this->getPrefixedText();
|
|
} else {
|
|
$text = $this->getText();
|
|
}
|
|
|
|
return $text . ( $this->m_fragment !== '' ? "#{$this->m_fragment}" : '' );
|
|
}
|
|
|
|
public function getHash() {
|
|
return $this->isValid() ? $this->getPrefixedText() : implode( "\t", $this->getErrors() );
|
|
}
|
|
|
|
/**
|
|
* Create links to mapping services based on a wiki-editable message.
|
|
* The parameters available to the message are:
|
|
* $1: urlencoded article name (no namespace)
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function getServiceLinkParams() {
|
|
if ( $this->isValid() ) {
|
|
return [ rawurlencode( str_replace( '_', ' ', $this->m_dataitem->getDBkey() ) ) ];
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
///// special interface for wiki page values
|
|
|
|
/**
|
|
* @deprecated since 3.1 use getDataItem()->getTitle() instead
|
|
*
|
|
* Return according Title object or null if no valid value was set.
|
|
* null can be returned even if this object returns true for isValid(),
|
|
* since the latter function does not check whether MediaWiki can really
|
|
* make a Title out of the given data.
|
|
* However, isValid() will return false *after* this function failed in
|
|
* trying to create a title.
|
|
*
|
|
* @return Title
|
|
*/
|
|
public function getTitle() {
|
|
if ( $this->m_title !== null ) {
|
|
return $this->m_title;
|
|
}
|
|
|
|
if ( $this->isValid() ) {
|
|
|
|
if ( ( $title = $this->m_dataitem->getTitle() ) !== null ) {
|
|
return $this->m_title = $title;
|
|
}
|
|
|
|
// #3278, Special handling of `>` in the user namespace
|
|
// added a prefix to users that originate from imported content
|
|
if (
|
|
$this->m_dataitem->getNamespace() === NS_USER &&
|
|
strpos( $this->m_dataitem->getDBkey(), '>' ) !== false ) {
|
|
|
|
$this->setOption( self::OPT_DISABLE_INFOLINKS, true );
|
|
|
|
$this->m_title = MediaWikiServices::getInstance()->getTitleFactory()->newFromText(
|
|
$this->m_dataitem->getDBkey()
|
|
);
|
|
|
|
return $this->m_title;
|
|
}
|
|
}
|
|
|
|
$errArg = $this->m_caption;
|
|
|
|
if ( $this->isValid() ) {
|
|
$ns = Localizer::getInstance()->getNsText(
|
|
$this->m_dataitem->getNamespace()
|
|
);
|
|
|
|
$errArg = "$ns:" . $this->m_dataitem->getDBkey();
|
|
}
|
|
|
|
// Should not normally happen, but anyway ...
|
|
$this->addErrorMsg( [ 'smw_notitle', $errArg ] );
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.1
|
|
*
|
|
* Get MediaWiki's ID for this value or 0 if not available.
|
|
*
|
|
* @return integer
|
|
*/
|
|
private function getArticleID() {
|
|
if ( $this->m_id === false ) {
|
|
$this->m_id = $this->getTitle() !== null ? $this->m_title->getArticleID() : 0;
|
|
}
|
|
|
|
return $this->m_id;
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.1
|
|
*
|
|
* Get namespace constant for this value.
|
|
*
|
|
* @return integer
|
|
*/
|
|
private function getNamespace() {
|
|
return $this->m_dataitem->getNamespace();
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.1
|
|
*
|
|
* Get DBKey for this value. Subclasses that allow for values that do not
|
|
* correspond to wiki pages may choose a DB key that is not a legal title
|
|
* DB key but rather another suitable internal ID. Thus it is not suitable
|
|
* to use this method in places where only MediaWiki Title keys are allowed.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getDBkey() {
|
|
return $this->m_dataitem->getDBkey();
|
|
}
|
|
|
|
/**
|
|
* Get text label for this value, just like Title::getText().
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getText() {
|
|
if ( $this->getOption( self::NO_TEXT_TRANSFORMATION, false ) ) {
|
|
return $this->m_dataitem->getDBkey();
|
|
}
|
|
|
|
return str_replace( '_', ' ', $this->m_dataitem->getDBkey() );
|
|
}
|
|
|
|
/**
|
|
* Get the prefixed text for this value, including a localized namespace
|
|
* prefix.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getPrefixedText() {
|
|
if ( $this->m_prefixedtext !== '' ) {
|
|
return $this->m_prefixedtext;
|
|
}
|
|
|
|
// In case something went wrong (invalid NS etc.), hint the ID to aid the
|
|
// investigation
|
|
if ( $this->m_dataitem !== null && $this->m_dataitem->getId() > 0 ) {
|
|
$this->m_prefixedtext = 'NO_VALID_VALUE (ID: ' . $this->m_dataitem->getId() . ')';
|
|
} else {
|
|
$this->m_prefixedtext = 'NO_VALID_VALUE';
|
|
}
|
|
|
|
if ( $this->isValid() ) {
|
|
$nstext = Localizer::getInstance()->getNsText( $this->m_dataitem->getNamespace() );
|
|
$this->m_prefixedtext =
|
|
( $this->m_dataitem->getInterwiki() !== '' ? $this->m_dataitem->getInterwiki() . ':' : '' ) .
|
|
( $nstext !== '' ? "$nstext:" : '' ) . $this->getText();
|
|
}
|
|
|
|
return $this->m_prefixedtext;
|
|
}
|
|
|
|
/**
|
|
* @deprecated since 3.1
|
|
*
|
|
* Get interwiki prefix or empty string.
|
|
*
|
|
* @return string
|
|
*/
|
|
private function getInterwiki() {
|
|
return $this->m_dataitem->getInterwiki();
|
|
}
|
|
|
|
/**
|
|
* @see SMWDataValue::getPreferredCaption
|
|
*
|
|
* @since 2.4
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getPreferredCaption() {
|
|
if ( ( $preferredCaption = parent::getPreferredCaption() ) !== '' && $preferredCaption !== false ) {
|
|
return $preferredCaption;
|
|
}
|
|
|
|
$preferredCaption = $this->getDisplayTitle();
|
|
|
|
if ( $preferredCaption === '' && $this->getOption( 'prefixed.preferred.caption' ) ) {
|
|
$preferredCaption = $this->getPrefixedText();
|
|
} elseif ( $preferredCaption === '' ) {
|
|
$preferredCaption = $this->getText();
|
|
}
|
|
|
|
return $preferredCaption;
|
|
}
|
|
|
|
/**
|
|
* Get a short caption used to label this value. In particular, this
|
|
* omits namespace and interwiki prefixes (similar to the MediaWiki
|
|
* "pipe trick"). Fragments are included unless they start with an
|
|
* underscore (used for generated fragment names that are not helpful
|
|
* for users and that might change easily).
|
|
*
|
|
* @since 1.7
|
|
* @return string
|
|
*/
|
|
protected function getShortCaptionText() {
|
|
if ( $this->m_fragment !== '' && $this->m_fragment[0] != '_' ) {
|
|
$fragmentText = '#' . str_replace( '_', ' ', $this->m_fragment );
|
|
} else {
|
|
$fragmentText = '';
|
|
}
|
|
|
|
if ( $this->m_caption && $this->m_caption !== '' ) {
|
|
return $this->m_caption;
|
|
}
|
|
|
|
$displayTitle = $this->getDisplayTitle();
|
|
|
|
if ( $displayTitle === '' ) {
|
|
$displayTitle = $this->getText();
|
|
}
|
|
|
|
// #3945 (Remove context as per pipe trick)
|
|
if ( $this->hasFeature( SMW_DV_WPV_PIPETRICK ) ) {
|
|
$displayTitle = Pipetrick::apply( $displayTitle );
|
|
}
|
|
|
|
return $displayTitle . $fragmentText;
|
|
}
|
|
|
|
/**
|
|
* Get a long caption used to label this value. In particular, this
|
|
* includes namespace and interwiki prefixes, while fragments are only
|
|
* included if they do not start with an underscore (used for generated
|
|
* fragment names that are not helpful for users and that might change
|
|
* easily).
|
|
*
|
|
* @since 1.7
|
|
* @return string
|
|
*/
|
|
protected function getLongCaptionText() {
|
|
if ( $this->m_fragment !== '' && $this->m_fragment[0] != '_' ) {
|
|
$fragmentText = '#' . str_replace( '_', ' ', $this->m_fragment );
|
|
} else {
|
|
$fragmentText = '';
|
|
}
|
|
|
|
if ( $this->m_caption && $this->m_caption !== '' ) {
|
|
return $this->m_caption;
|
|
}
|
|
|
|
$displayTitle = $this->getDisplayTitle();
|
|
|
|
if ( $displayTitle === '' ) {
|
|
$displayTitle = $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText() : $this->getText();
|
|
}
|
|
|
|
return $displayTitle . $fragmentText;
|
|
}
|
|
|
|
/**
|
|
* Compute a text that can be used in wiki text to link to this
|
|
* datavalue. Processing includes some escaping and adding the
|
|
* fragment.
|
|
*
|
|
* @since 1.7
|
|
* @return string
|
|
*/
|
|
protected function getWikiLinkTarget() {
|
|
return str_replace( "'", ''', $this->getPrefixedText() ) .
|
|
( $this->m_fragment !== '' ? "#{$this->m_fragment}" : '' );
|
|
}
|
|
|
|
/**
|
|
* Find the sortkey for this object.
|
|
*
|
|
* @deprecated Use \SMW\Store::getWikiPageSortKey(). Will vanish before SMW 1.7
|
|
*
|
|
* @return string sortkey
|
|
*/
|
|
private function getSortKey() {
|
|
return ApplicationFactory::getInstance()->getStore()->getWikiPageSortKey( $this->m_dataitem );
|
|
}
|
|
|
|
/**
|
|
* @since 2.4
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getDisplayTitle() {
|
|
if ( $this->m_dataitem === null || !$this->hasFeature( SMW_DV_WPV_DTITLE ) ) {
|
|
return '';
|
|
}
|
|
|
|
// Should come from the DataValueServiceFactory
|
|
$displayTitleFinder = ApplicationFactory::getInstance()->singleton( 'DisplayTitleFinder' );
|
|
|
|
return $displayTitleFinder->findDisplayTitle( $this->m_dataitem );
|
|
}
|
|
|
|
}
|