summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/DataValues/ValueFormatters/ReferenceValueFormatter.php
blob: 927f5579df173a4c892af43831625eba6c664613 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
<?php

namespace SMW\DataValues\ValueFormatters;

use RuntimeException;
use SMW\DataValueFactory;
use SMW\DataValues\ExternalIdentifierValue;
use SMW\DataValues\ReferenceValue;
use SMW\DIWikiPage;
use SMW\Message;
use SMWDataValue as DataValue;
use SMWDITime as DITime;
use SMWDIUri as DIUri;
use SMWPropertyValue as PropertyValue;

/**
 * @license GNU GPL v2+
 * @since 2.5
 *
 * @author mwjames
 */
class ReferenceValueFormatter extends DataValueFormatter {

	/**
	 * @since 2.5
	 *
	 * {@inheritDoc}
	 */
	public function isFormatterFor( DataValue $dataValue ) {
		return $dataValue instanceof ReferenceValue;
	}

	/**
	 * @since 2.5
	 *
	 * {@inheritDoc}
	 */
	public function format( $type, $linker = null ) {

		if ( !$this->dataValue instanceof ReferenceValue ) {
			throw new RuntimeException( "The formatter is missing a valid ReferenceValue object" );
		}

		if ( $this->dataValue->getCaption() !== false &&
			( $type === self::WIKI_SHORT || $type === self::HTML_SHORT ) ) {
			return $this->dataValue->getCaption();
		}

		return $this->getOutputText( $type, $linker );
	}

	protected function getOutputText( $type, $linker = null ) {

		if ( !$this->dataValue->isValid() ) {
			return ( ( $type == self::WIKI_SHORT ) || ( $type == self::HTML_SHORT ) ) ? '' : $this->dataValue->getErrorText();
		}

		return $this->createOutput( $type, $linker );
	}

	private function createOutput( $type, $linker ) {

		$results = $this->getListOfFormattedPropertyDataItems(
			$type,
			$linker,
			$this->dataValue->getPropertyDataItems()
		);

		if ( $type == self::VALUE || $linker === null ) {
			return implode( ';', $results );
		}

		$result = array_shift( $results );
		$class = 'smw-reference-otiose';

		// "smw-highlighter smwttinline" signals to invoke the tooltip
		if ( count( $results ) > 0 ) {
			$class = 'smw-reference smw-reference-indicator smw-highlighter smwttinline';
		}

		// Add an extra "title" attribute to support nojs environments by allowing
		// it to display references even without JS, it will be removed when JS is available
		// to show the "normal" tooltip
		$result .= \Html::rawElement(
			'span',
			[
				'class' => $class,
				'data-title'   =>  Message::get( 'smw-ui-tooltip-title-reference', Message::TEXT, Message::USER_LANGUAGE ),
				'data-content' => '<ul><li>' . implode( '</li><li>', $results ) . '</li></ul>',
				'title' => strip_tags( implode( ', ', $results ) )
			]
		);

		return $result;
	}

	private function getListOfFormattedPropertyDataItems( $type, $linker, $propertyDataItems ) {

		$results = [];

		foreach ( $propertyDataItems as $propertyDataItem ) {

			$propertyValues = $this->dataValue->getDataItem()->getSemanticData()->getPropertyValues( $propertyDataItem );
			$dataItem = reset( $propertyValues );

			// By definition the first element in the list is the VALUE other
			// members are referencing to
			$isValue = $results === [];
			$dataValue = null;

			if ( $dataItem !== false ) {
				$dataValue = DataValueFactory::getInstance()->newDataValueByItem( $dataItem, $propertyDataItem );
				$output = $this->findValueOutputFor( $isValue, $type, $dataValue, $linker );
			} else {
				$output = '?';
			}

			// Return a plain value in case no linker object is available
			if ( $dataValue !== null && $linker === null ) {
				return [ $dataValue->getWikiValue() ];
			}

			$dataValue = DataValueFactory::getInstance()->newDataValueByItem(
				$propertyDataItem
			);

			// Tooltip in tooltip isn't expected to work therefore avoid them
			// when generating property labels in a reference output
			$dataValue->setOption( PropertyValue::OPT_NO_HIGHLIGHT, true );

			if ( !$isValue && $type !== self::VALUE ) {
				$output = Message::get(
					[
						'smw-datavalue-reference-outputformat',
						$dataValue->getShortHTMLText( smwfGetLinker() ),
						$output
					],
					Message::TEXT
				);
			}

			$results[] = $output;
		}

		return $results;
	}

	private function findValueOutputFor( $isValue, $type, $dataValue, $linker ) {

		$dataItem = $dataValue->getDataItem();

		// Turn Uri/Page links into a href representation when not used as value
		if ( !$isValue &&
			( $dataItem instanceof DIUri || $dataItem instanceof DIWikiPage ) &&
			$type !== self::VALUE || $dataValue->getTypeID() === ExternalIdentifierValue::TYPE_ID ) {
			return $dataValue->getShortHTMLText( smwfGetLinker() );
		}

		// Dates and times are to be displayed in a localized format
		if ( !$isValue && $dataItem instanceof DITime && $type !== self::VALUE ) {
			$dataValue->setOutputFormat( 'LOCL' );
		}

		switch ( $type ) {
			case self::VALUE:
				return $dataValue->getWikiValue();
			case self::WIKI_SHORT:
				return $dataValue->getShortWikiText( $linker );
			case self::HTML_SHORT:
				return $dataValue->getShortHTMLText( $linker );
			case self::WIKI_LONG:
				return $dataValue->getLongWikiText( $linker );
			case self::HTML_LONG:
				return $dataValue->getLongHTMLText( $linker );
		}
	}

}