1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace SMW\DataValues\ValueFormatters; |
4
|
|
|
|
5
|
|
|
use SMW\ApplicationFactory; |
6
|
|
|
use SMW\Highlighter; |
7
|
|
|
use SMW\Localizer; |
8
|
|
|
use SMW\Message; |
9
|
|
|
use SMW\DIWikiPage; |
10
|
|
|
use SMWDataValue as DataValue; |
11
|
|
|
use SMWPropertyValue as PropertyValue; |
12
|
|
|
use RuntimeException; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* @license GNU GPL v2+ |
16
|
|
|
* @since 2.5 |
17
|
|
|
* |
18
|
|
|
* @author mwjames |
19
|
|
|
*/ |
20
|
|
|
class PropertyValueFormatter extends DataValueFormatter { |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @since 2.5 |
24
|
|
|
* |
25
|
|
|
* {@inheritDoc} |
26
|
|
|
*/ |
27
|
166 |
|
public function isFormatterFor( DataValue $dataValue ) { |
28
|
166 |
|
return $dataValue instanceof PropertyValue; |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @since 2.5 |
33
|
|
|
* |
34
|
|
|
* {@inheritDoc} |
35
|
|
|
*/ |
36
|
108 |
|
public function format( $type, $linker = null ) { |
37
|
|
|
|
38
|
108 |
|
if ( !$this->dataValue instanceof PropertyValue ) { |
39
|
1 |
|
throw new RuntimeException( "The formatter is missing a valid PropertyValue object" ); |
40
|
|
|
} |
41
|
|
|
|
42
|
107 |
|
if ( !$this->dataValue->isVisible() ) { |
43
|
1 |
|
return ''; |
44
|
|
|
} |
45
|
|
|
|
46
|
106 |
|
if ( $type === self::VALUE ) { |
47
|
88 |
|
return $this->getWikiValue(); |
48
|
|
|
} |
49
|
|
|
|
50
|
76 |
|
if ( $type === PropertyValue::FORMAT_LABEL ) { |
51
|
15 |
|
return $this->getFormattedLabel( $linker ); |
52
|
|
|
} |
53
|
|
|
|
54
|
75 |
|
$wikiPageValue = $this->prepareWikiPageValue( $linker ); |
55
|
75 |
|
$text = ''; |
56
|
|
|
|
57
|
75 |
|
if ( $wikiPageValue === null ) { |
58
|
|
|
return ''; |
59
|
|
|
} |
60
|
|
|
|
61
|
75 |
|
if ( $type === self::WIKI_SHORT ) { |
62
|
53 |
|
$text = $this->doHighlightText( |
63
|
|
|
$wikiPageValue->getShortWikiText( $linker ), |
64
|
|
|
$this->dataValue->getOptionBy( PropertyValue::OPT_HIGHLIGHT_LINKER ) ? $linker : null |
65
|
75 |
|
); |
66
|
14 |
|
} |
67
|
|
|
|
68
|
|
|
if ( $type === self::HTML_SHORT ) { |
69
|
75 |
|
$text = $this->doHighlightText( $wikiPageValue->getShortHTMLText( $linker ), $linker ); |
70
|
15 |
|
} |
71
|
|
|
|
72
|
|
|
if ( $type === self::WIKI_LONG ) { |
73
|
75 |
|
$text = $this->doHighlightText( $wikiPageValue->getLongWikiText( $linker ) ); |
74
|
2 |
|
} |
75
|
|
|
|
76
|
|
|
if ( $type === self::HTML_LONG ) { |
77
|
75 |
|
$text = $this->doHighlightText( $wikiPageValue->getLongHTMLText( $linker ), $linker ); |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
return $text . $this->hintPreferredLabelUse(); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Formatting rule set: |
85
|
|
|
* - preferred goes before translation |
86
|
15 |
|
* - displayTitle goes before translation |
87
|
|
|
* - translation goes before "normal" label |
88
|
15 |
|
*/ |
89
|
15 |
|
private function getFormattedLabel( $linker = null ) { |
90
|
15 |
|
|
91
|
|
|
$property = $this->dataValue->getDataItem(); |
92
|
15 |
|
$output = ''; |
93
|
15 |
|
$displayTitle = ''; |
94
|
|
|
|
95
|
|
|
$preferredLabel = $property->getPreferredLabel( |
96
|
15 |
|
$this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ) |
97
|
|
|
); |
98
|
15 |
|
|
99
|
1 |
|
$label = $preferredLabel; |
100
|
|
|
|
101
|
|
|
if ( $preferredLabel === '' && ( $label = $this->findTranslatedPropertyLabel( $property ) ) === '' ) { |
102
|
15 |
|
$label = $property->getLabel(); |
103
|
14 |
|
} |
104
|
|
|
|
105
|
|
|
if ( $this->dataValue->getWikiPageValue() !== null ) { |
|
|
|
|
106
|
15 |
|
$displayTitle = $this->dataValue->getWikiPageValue()->getDisplayTitle(); |
|
|
|
|
107
|
|
|
} |
108
|
|
|
|
109
|
15 |
|
$canonicalLabel = $property->getCanonicalLabel(); |
110
|
1 |
|
|
111
|
1 |
|
// Display title goes before a translated label (but not preferred) |
112
|
|
|
if ( $displayTitle !== '' && !$property->isUserDefined() ) { |
113
|
|
|
$label = $displayTitle; |
114
|
|
|
$canonicalLabel = $displayTitle; |
115
|
15 |
|
} |
116
|
15 |
|
|
117
|
|
|
// Internal format only used by PropertyValue |
118
|
15 |
|
$format = $this->getOptionBy( PropertyValue::FORMAT_LABEL ); |
119
|
14 |
|
$this->dataValue->setCaption( $label ); |
120
|
|
|
|
121
|
|
|
if ( $format === self::VALUE ) { |
122
|
15 |
|
$output = $this->dataValue->getWikiValue(); |
123
|
|
|
} |
124
|
15 |
|
|
125
|
|
|
if ( $format === self::WIKI_LONG && $linker !== null ) { |
126
|
15 |
|
$output = $this->dataValue->getLongWikiText( $linker ); |
127
|
|
|
} elseif ( $format === self::WIKI_LONG && $preferredLabel === '' && $displayTitle !== '' ) { |
128
|
|
|
$output = $displayTitle; |
129
|
|
|
} elseif ( $format === self::WIKI_LONG ) { |
130
|
|
|
// Avoid Title::getPrefixedText as it transforms the text to have a |
131
|
|
|
// leading capital letter in some configurations |
132
|
15 |
|
$output = Localizer::getInstance()->createTextWithNamespacePrefix( SMW_NS_PROPERTY, $label ); |
133
|
1 |
|
} |
134
|
|
|
|
135
|
|
|
if ( $format === self::HTML_SHORT && $linker !== null ) { |
136
|
|
|
$output = $this->dataValue->getShortHTMLText( $linker ); |
137
|
15 |
|
} |
138
|
3 |
|
|
139
|
|
|
// Output both according to the formatting rule set forth by |
140
|
|
|
if ( $canonicalLabel !== $label ) { |
141
|
15 |
|
$output = Message::get( array( 'smw-property-preferred-title-format', $output, $canonicalLabel ) ); |
142
|
|
|
} |
143
|
|
|
|
144
|
88 |
|
return $output; |
145
|
|
|
} |
146
|
88 |
|
|
147
|
88 |
|
private function getWikiValue() { |
148
|
|
|
|
149
|
88 |
|
$property = $this->dataValue->getDataItem(); |
150
|
5 |
|
$languageCode = $this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ); |
151
|
|
|
|
152
|
|
|
if ( ( $preferredLabel = $property->getPreferredLabel( $languageCode ) ) !== '' ) { |
153
|
84 |
|
return $preferredLabel; |
154
|
2 |
|
} |
155
|
|
|
|
156
|
|
|
if ( $this->dataValue->getWikiPageValue() !== null && $this->dataValue->getWikiPageValue()->getDisplayTitle() !== '' ) { |
|
|
|
|
157
|
83 |
|
return $this->dataValue->getWikiPageValue()->getDisplayTitle(); |
|
|
|
|
158
|
25 |
|
} |
159
|
|
|
|
160
|
|
|
if ( ( $translatedPropertyLabel = $this->findTranslatedPropertyLabel( $property ) ) !== '' ) { |
161
|
69 |
|
return $translatedPropertyLabel; |
162
|
|
|
} |
163
|
|
|
|
164
|
75 |
|
return $this->dataValue->getDataItem()->getLabel(); |
|
|
|
|
165
|
|
|
} |
166
|
75 |
|
|
167
|
|
|
private function prepareWikiPageValue( $linker = null ) { |
|
|
|
|
168
|
75 |
|
|
169
|
|
|
$wikiPageValue = $this->dataValue->getWikiPageValue(); |
|
|
|
|
170
|
|
|
|
171
|
|
|
if ( $wikiPageValue === null ) { |
172
|
75 |
|
return null; |
173
|
75 |
|
} |
174
|
|
|
|
175
|
75 |
|
$property = $this->dataValue->getDataItem(); |
176
|
63 |
|
$caption = $this->dataValue->getCaption(); |
177
|
19 |
|
|
178
|
|
|
if ( $caption !== false && $caption !== '' ) { |
179
|
19 |
|
$wikiPageValue->setCaption( $caption ); |
180
|
4 |
|
} elseif ( ( $preferredLabel = $this->dataValue->getPreferredLabel() ) !== '' ) { |
|
|
|
|
181
|
|
|
$wikiPageValue->setCaption( $preferredLabel ); |
182
|
15 |
|
} elseif ( ( $translatedPropertyLabel = $this->findTranslatedPropertyLabel( $property ) ) !== '' ) { |
183
|
|
|
$wikiPageValue->setCaption( $translatedPropertyLabel ); |
184
|
|
|
} else { |
185
|
75 |
|
$wikiPageValue->setCaption( $property->getLabel() ); |
186
|
|
|
} |
187
|
|
|
|
188
|
74 |
|
return $wikiPageValue; |
189
|
|
|
} |
190
|
74 |
|
|
191
|
|
|
private function doHighlightText( $text, $linker = null ) { |
192
|
74 |
|
|
193
|
67 |
|
$content = ''; |
194
|
|
|
|
195
|
|
|
if ( !$this->canHighlight( $content, $linker ) ) { |
196
|
19 |
|
return $text; |
197
|
19 |
|
} |
198
|
19 |
|
|
199
|
|
|
$highlighter = Highlighter::factory( |
200
|
|
|
Highlighter::TYPE_PROPERTY, |
201
|
19 |
|
$this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ) |
|
|
|
|
202
|
19 |
|
); |
203
|
19 |
|
|
204
|
19 |
|
$highlighter->setContent( array ( |
205
|
|
|
'userDefined' => $this->dataValue->getDataItem()->isUserDefined(), |
|
|
|
|
206
|
|
|
'caption' => $text, |
207
|
19 |
|
'content' => $content !== '' ? $content : Message::get( 'smw_isspecprop' ) |
208
|
|
|
) ); |
209
|
|
|
|
210
|
74 |
|
return $highlighter->getHtml(); |
211
|
|
|
} |
212
|
74 |
|
|
213
|
2 |
|
private function canHighlight( &$propertyDescription, $linker ) { |
214
|
|
|
|
215
|
|
|
if ( $this->dataValue->getOptionBy( PropertyValue::OPT_NO_HIGHLIGHT ) === true ) { |
216
|
74 |
|
return false; |
217
|
|
|
} |
218
|
74 |
|
|
219
|
|
|
$dataItem = $this->dataValue->getDataItem(); |
220
|
74 |
|
|
221
|
|
|
$propertyDescription = ApplicationFactory::getInstance()->getPropertySpecificationLookup()->getPropertyDescriptionBy( |
222
|
|
|
$dataItem, |
|
|
|
|
223
|
|
|
$this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ), |
|
|
|
|
224
|
74 |
|
$linker |
225
|
|
|
); |
226
|
|
|
|
227
|
75 |
|
return !$dataItem->isUserDefined() || $propertyDescription !== ''; |
228
|
|
|
} |
229
|
75 |
|
|
230
|
75 |
|
private function hintPreferredLabelUse() { |
231
|
10 |
|
|
232
|
|
|
if ( !$this->dataValue->isEnabledFeature( SMW_DV_PROV_LHNT ) || |
233
|
|
|
$this->dataValue->getOptionBy( PropertyValue::OPT_NO_PREF_LHNT ) ) { |
|
|
|
|
234
|
65 |
|
return ''; |
235
|
|
|
} |
236
|
65 |
|
|
237
|
65 |
|
$property = $this->dataValue->getDataItem(); |
238
|
|
|
|
239
|
|
|
$preferredLabel = $property->getPreferredLabel( |
240
|
65 |
|
$this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ) |
241
|
60 |
|
); |
242
|
|
|
|
243
|
|
|
if ( $preferredLabel === '' || $this->dataValue->getCaption() !== $preferredLabel ) { |
244
|
8 |
|
return ''; |
245
|
8 |
|
} |
246
|
|
|
|
247
|
8 |
|
$label = $property->getLabel(); |
248
|
8 |
|
$preferredLabelMarker = ''; |
249
|
|
|
|
250
|
|
|
if ( $preferredLabel !== $label ) { |
251
|
8 |
|
$preferredLabelMarker = ' ' . \Html::rawElement( 'span', array( 'title' => $property->getCanonicalLabel() ), '<sup>ᵖ</sup>' ); |
252
|
|
|
} |
253
|
|
|
|
254
|
94 |
|
return $preferredLabelMarker; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
private function findTranslatedPropertyLabel( $property ) { |
258
|
94 |
|
|
259
|
80 |
|
// User-defined properties don't have any translatable label (this is |
260
|
|
|
// what the preferred label is for) |
261
|
|
|
if ( $property->isUserDefined() ) { |
262
|
26 |
|
return ''; |
263
|
26 |
|
} |
264
|
26 |
|
|
265
|
|
|
return ApplicationFactory::getInstance()->getPropertyLabelFinder()->findPropertyLabelByLanguageCode( |
266
|
|
|
$property->getKey(), |
267
|
|
|
$this->dataValue->getOptionBy( PropertyValue::OPT_USER_LANGUAGE ) |
|
|
|
|
268
|
|
|
); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
} |
272
|
|
|
|
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: