1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
use SMW\ApplicationFactory; |
4
|
|
|
use SMW\DIProperty; |
5
|
|
|
use SMW\Localizer; |
6
|
|
|
use SMW\Message; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* @ingroup SMWDataValues |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* This datavalue implements special processing suitable for defining |
14
|
|
|
* wikipages as values of properties. |
15
|
|
|
* |
16
|
|
|
* The class can support general wiki pages, or pages of a fixed |
17
|
|
|
* namespace, Whether a namespace is fixed is decided based on the |
18
|
|
|
* type ID when the object is constructed. |
19
|
|
|
* |
20
|
|
|
* The short display simulates the behavior of the MediaWiki "pipe trick" |
21
|
|
|
* but always includes fragments. This can be overwritten by setting a |
22
|
|
|
* caption, which is also done by default when generating a value from user |
23
|
|
|
* input. The long display always includes all relevant information. Only if a |
24
|
|
|
* fixed namespace is used for the datatype, the namespace prefix is omitted. |
25
|
|
|
* This behavior has changed in SMW 1.7: up to this time, short displays have |
26
|
|
|
* always inlcuded the namespace and long displays used the pipe trick, leading |
27
|
|
|
* to a paradoxical confusion of "long" and "short". |
28
|
|
|
* |
29
|
|
|
* @author Nikolas Iwan |
30
|
|
|
* @author Markus Krötzsch |
31
|
|
|
* @ingroup SMWDataValues |
32
|
|
|
*/ |
33
|
|
|
class SMWWikiPageValue extends SMWDataValue { |
|
|
|
|
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Fragment text for user-specified title. Not stored, but kept for |
37
|
|
|
* printout on page. |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
protected $m_fragment = ''; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Full titletext with prefixes, including interwiki prefix. |
44
|
|
|
* Set to empty string if not computed yet. |
45
|
|
|
* @var string |
46
|
|
|
*/ |
47
|
|
|
protected $m_prefixedtext = ''; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* Cache for the related MW page ID. |
51
|
|
|
* Set to -1 if not computed yet. |
52
|
|
|
* @var integer |
53
|
|
|
*/ |
54
|
|
|
protected $m_id = -1; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* Cache for the related MW title object. |
58
|
|
|
* Set to null if not computed yet. |
59
|
|
|
* @var Title |
60
|
|
|
*/ |
61
|
|
|
protected $m_title = null; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* If this has a value other than NS_MAIN, the datavalue will only |
65
|
|
|
* accept pages in this namespace. This field is initialized when |
66
|
|
|
* creating the object (based on the type id or base on the preference |
67
|
|
|
* of some subclass); it is not usually changed afterwards. |
68
|
|
|
* @var integer |
69
|
|
|
*/ |
70
|
|
|
protected $m_fixNamespace = NS_MAIN; |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @var array |
74
|
|
|
*/ |
75
|
|
|
protected $linkAttributes = array(); |
76
|
|
|
|
77
|
238 |
|
/** |
78
|
238 |
|
* @var array |
79
|
|
|
*/ |
80
|
238 |
|
protected $queryParameters = array(); |
81
|
|
|
|
82
|
|
|
public function __construct( $typeid ) { |
83
|
238 |
|
parent::__construct( $typeid ); |
84
|
5 |
|
switch ( $typeid ) { |
85
|
5 |
|
case '__typ': |
86
|
237 |
|
$this->m_fixNamespace = SMW_NS_TYPE; |
87
|
40 |
|
break; |
88
|
40 |
|
case '_wpp' : case '__sup': |
|
|
|
|
89
|
232 |
|
$this->m_fixNamespace = SMW_NS_PROPERTY; |
90
|
|
|
break; |
91
|
|
|
case '_wpc' : case '__suc': case '__sin': |
|
|
|
|
92
|
|
|
$this->m_fixNamespace = NS_CATEGORY; |
93
|
232 |
|
break; |
94
|
|
|
case '_wpf' : case '__spf': |
|
|
|
|
95
|
238 |
|
$this->m_fixNamespace = SF_NS_FORM; |
96
|
|
|
break; |
97
|
167 |
|
default: // case '_wpg': |
98
|
167 |
|
$this->m_fixNamespace = NS_MAIN; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
|
102
|
167 |
|
protected function parseUserValue( $value ) { |
103
|
|
|
global $wgContLang; |
|
|
|
|
104
|
|
|
|
105
|
|
|
// support inputs like " [[Test]] "; |
106
|
167 |
|
// note that this only works in pages if $smwgLinksInValues is set to true |
107
|
15 |
|
$value = ltrim( rtrim( $value, ' ]' ), ' [' ); |
108
|
|
|
|
109
|
|
|
// #1066, Manipulate the output only for when the value has no caption |
110
|
167 |
|
// assigned and only if a single :Foo is being present, ::Foo is not permitted |
111
|
167 |
|
if ( $this->m_caption === false && isset( $value[2] ) && $value[0] === ':' && $value[1] !== ':' ) { |
112
|
|
|
$value = substr( $value, 1 ); |
113
|
|
|
} |
114
|
167 |
|
|
115
|
1 |
|
if ( $this->m_caption === false ) { |
116
|
|
|
$this->m_caption = $value; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
if ( $value === '' ) { |
120
|
|
|
return $this->addErrorMsg( array( 'smw-datavalue-wikipage-empty' ), Message::ESCAPED ); |
121
|
|
|
} |
122
|
|
|
|
123
|
167 |
|
// #1701 If the DV is part of a Description and an approximate search |
124
|
17 |
|
// (e.g. ~foo* / ~Foo*) then use the value as-is and avoid being |
125
|
1 |
|
// transformed by the Title object |
126
|
|
|
// If the vaue contains a valid NS then use the Title to create a correct |
127
|
16 |
|
// instance to distinguish [[~Foo*]] from [[Help:~Foo*]] |
128
|
|
|
if ( $this->getOption( self::OPT_QUERY_COMP_CONTEXT ) ) { |
|
|
|
|
129
|
|
|
if ( ( $title = Title::newFromText( $value ) ) !== null && $title->getNamespace() !== NS_MAIN ) { |
130
|
|
|
return $this->m_dataitem = SMWDIWikiPage::newFromTitle( $title ); |
131
|
167 |
|
} else { |
132
|
|
|
return $this->m_dataitem = new SMWDIWikiPage( $value, NS_MAIN ); |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
if ( $value[0] == '#' ) { |
137
|
|
|
if ( is_null( $this->m_contextPage ) ) { |
138
|
|
|
$this->addErrorMsg( array( 'smw-datavalue-wikipage-missing-fragment-context', $value ) ); |
139
|
|
|
return; |
140
|
|
|
} else { |
141
|
167 |
|
$this->m_title = Title::makeTitle( $this->m_contextPage->getNamespace(), |
142
|
|
|
$this->m_contextPage->getDBkey(), substr( $value, 1 ), |
143
|
|
|
$this->m_contextPage->getInterwiki() ); |
144
|
|
|
} |
145
|
167 |
|
} else { |
146
|
4 |
|
$this->m_title = Title::newFromText( $value, $this->m_fixNamespace ); |
147
|
167 |
|
} |
148
|
167 |
|
|
149
|
|
|
/// TODO: Escape the text so users can see punctuation problems (bug 11666). |
150
|
|
|
if ( is_null( $this->m_title ) ) { |
151
|
167 |
|
$this->addErrorMsg( array( 'smw-datavalue-wikipage-invalid-title', $value ) ); |
152
|
167 |
|
} elseif ( ( $this->m_fixNamespace != NS_MAIN ) && |
153
|
167 |
|
( $this->m_fixNamespace != $this->m_title->getNamespace() ) ) { |
154
|
167 |
|
$this->addErrorMsg( array( 'smw_wrong_namespace', $wgContLang->getNsText( $this->m_fixNamespace ) ) ); |
155
|
|
|
} else { |
156
|
167 |
|
$this->m_fragment = str_replace( ' ', '_', $this->m_title->getFragment() ); |
157
|
|
|
$this->m_prefixedtext = ''; |
158
|
|
|
$this->m_id = -1; // unset id |
159
|
|
|
$this->m_dataitem = SMWDIWikiPage::newFromTitle( $this->m_title, $this->m_typeid ); |
|
|
|
|
160
|
|
|
} |
161
|
|
|
} |
162
|
|
|
|
163
|
184 |
|
/** |
164
|
|
|
* @see SMWDataValue::loadDataItem() |
165
|
184 |
|
* @param $dataitem SMWDataItem |
166
|
|
|
* @return boolean |
167
|
|
|
*/ |
168
|
|
|
protected function loadDataItem( SMWDataItem $dataItem ) { |
169
|
|
|
|
170
|
184 |
|
if ( $dataItem->getDIType() == SMWDataItem::TYPE_CONTAINER ) { |
171
|
|
|
// might throw an exception, we just pass it through |
172
|
|
|
$dataItem = $dataItem->getSemanticData()->getSubject(); |
173
|
|
|
} |
174
|
184 |
|
|
175
|
184 |
|
if ( $dataItem->getDIType() !== SMWDataItem::TYPE_WIKIPAGE ) { |
176
|
184 |
|
return false; |
177
|
184 |
|
} |
178
|
184 |
|
|
179
|
184 |
|
$this->m_dataitem = $dataItem; |
180
|
184 |
|
$this->m_id = -1; |
181
|
|
|
$this->m_title = null; |
182
|
184 |
|
$this->m_fragment = $dataItem->getSubobjectName(); |
183
|
184 |
|
$this->m_prefixedtext = ''; |
184
|
|
|
$this->m_caption = false; // this class can handle this |
|
|
|
|
185
|
|
|
$this->linkAttributes = array(); |
186
|
|
|
|
187
|
|
|
if ( ( $this->m_fixNamespace != NS_MAIN ) && |
188
|
|
|
( $this->m_fixNamespace != $dataItem->getNamespace() ) ) { |
189
|
|
|
$this->addErrorMsg( |
190
|
|
|
array( |
191
|
|
|
'smw_wrong_namespace', |
192
|
184 |
|
Localizer::getInstance()->getNamespaceTextById( $this->m_fixNamespace ) |
193
|
|
|
) |
194
|
|
|
); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return true; |
198
|
|
|
} |
199
|
|
|
|
200
|
129 |
|
/** |
201
|
129 |
|
* @since 2.4 |
202
|
129 |
|
* |
203
|
|
|
* @param array $linkAttributes |
204
|
|
|
*/ |
205
|
|
|
public function setLinkAttributes( array $linkAttributes ) { |
206
|
|
|
$this->linkAttributes = $linkAttributes; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* @since 2.5 |
211
|
|
|
* |
212
|
|
|
* @param array $queryParameters |
213
|
|
|
*/ |
214
|
|
|
public function setQueryParameters( array $queryParameters ) { |
215
|
|
|
$this->queryParameters = $queryParameters; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* Display the value on a wiki page. This is used to display the value |
220
|
|
|
* in the place where it was annotated on a wiki page. The desired |
221
|
|
|
* behavior is that the display in this case looks as if no property |
222
|
|
|
* annotation had been given, i.e. an annotation [[property::page|foo]] |
223
|
|
|
* should display like [[page|foo]] in MediaWiki. But this should lead |
224
|
|
|
* to a link, not to a category assignment. This means that: |
225
|
|
|
* |
226
|
|
|
* (1) If Image: is used (instead of Media:) then let MediaWiki embed |
227
|
|
|
* the image. |
228
|
133 |
|
* |
229
|
|
|
* (2) If Category: is used, treat it as a page and link to it (do not |
230
|
133 |
|
* categorize the page) |
231
|
128 |
|
* |
232
|
133 |
|
* (3) Preserve everything given after "|" for display (caption, image |
233
|
37 |
|
* parameters, ...) |
234
|
|
|
* |
235
|
|
|
* (4) Use the (default) caption for display. When the value comes from |
236
|
128 |
|
* user input, this includes the full value that one would also see in |
237
|
5 |
|
* MediaWiki. |
238
|
5 |
|
* |
239
|
5 |
|
* @param $linked mixed generate links if not null or false |
240
|
|
|
* @return string |
241
|
125 |
|
*/ |
242
|
125 |
|
public function getShortWikiText( $linked = null ) { |
243
|
|
|
|
244
|
|
|
if ( is_null( $linked ) || $linked === false || |
245
|
128 |
|
$this->m_outformat == '-' || !$this->isValid() || |
246
|
50 |
|
$this->m_caption === '' ) { |
247
|
|
|
return $this->m_caption !== false ? $this->m_caption : $this->getWikiValue(); |
248
|
121 |
|
} |
249
|
|
|
|
250
|
|
|
if ( $this->m_dataitem->getNamespace() == NS_FILE && $this->m_dataitem->getInterwiki() === '' ) { |
|
|
|
|
251
|
128 |
|
$linkEscape = ''; |
252
|
11 |
|
$options = $this->m_outformat === false ? 'frameless|border|text-top|' : str_replace( ';', '|', \Sanitizer::removeHTMLtags( $this->m_outformat ) ); |
253
|
|
|
$defaultCaption = '|' . $this->getShortCaptionText() . '|' . $options; |
254
|
|
|
} else { |
255
|
128 |
|
$linkEscape = ':'; |
256
|
11 |
|
$defaultCaption = '|' . $this->getShortCaptionText(); |
257
|
11 |
|
} |
258
|
11 |
|
|
259
|
|
|
if ( $this->m_caption === false ) { |
260
|
|
|
$link = '[[' . $linkEscape . $this->getWikiLinkTarget() . $defaultCaption . ']]'; |
261
|
|
|
} else { |
262
|
|
|
$link = '[[' . $linkEscape . $this->getWikiLinkTarget() . '|' . $this->m_caption . ']]'; |
263
|
128 |
|
} |
264
|
|
|
|
265
|
|
|
if ( $this->m_fragment !== '' ) { |
266
|
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity'; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
if ( $this->linkAttributes !== array() ) { |
270
|
|
|
$link = \Html::rawElement( |
271
|
|
|
'span', |
272
|
|
|
$this->linkAttributes, |
273
|
14 |
|
$link |
274
|
|
|
); |
275
|
14 |
|
} |
276
|
|
|
|
277
|
|
|
return $link; |
278
|
|
|
} |
279
|
|
|
|
280
|
14 |
|
/** |
281
|
14 |
|
* Display the value as in getShortWikiText() but create HTML. |
282
|
14 |
|
* The only difference is that images are not embedded. |
283
|
|
|
* |
284
|
|
|
* @param Linker $linker mixed the Linker object to use or null if no linking is desired |
285
|
14 |
|
* @return string |
286
|
14 |
|
*/ |
287
|
|
|
public function getShortHTMLText( $linker = null ) { |
288
|
2 |
|
|
289
|
2 |
|
if ( $this->m_fragment !== '' ) { |
290
|
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity'; |
291
|
|
|
} |
292
|
14 |
|
|
293
|
14 |
|
// init the Title object, may reveal hitherto unnoticed errors: |
294
|
|
|
if ( !is_null( $linker ) && $linker !== false && |
295
|
14 |
|
$this->m_caption !== '' && $this->m_outformat != '-' ) { |
296
|
|
|
$this->getTitle(); |
297
|
|
|
} |
298
|
|
|
|
299
|
14 |
|
if ( is_null( $linker ) || $linker === false || !$this->isValid() || |
300
|
14 |
|
$this->m_outformat == '-' || $this->m_caption === '' ) { |
301
|
|
|
|
302
|
14 |
|
$caption = $this->m_caption === false ? $this->getWikiValue() : $this->m_caption; |
303
|
|
|
return \Sanitizer::removeHTMLtags( $caption ); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
$caption = $this->m_caption === false ? $this->getShortCaptionText() : $this->m_caption; |
307
|
|
|
$caption = \Sanitizer::removeHTMLtags( $caption ); |
308
|
|
|
|
309
|
|
|
if ( $this->getNamespace() == NS_MEDIA ) { // this extra case *is* needed |
310
|
|
|
return $linker->makeMediaLinkObj( $this->getTitle(), $caption ); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
return $linker->link( |
314
|
23 |
|
$this->getTitle(), |
315
|
23 |
|
$caption, |
316
|
|
|
$this->linkAttributes, |
317
|
|
|
$this->queryParameters |
318
|
|
|
); |
319
|
23 |
|
} |
320
|
9 |
|
|
321
|
17 |
|
/** |
322
|
|
|
* Display the "long" value on a wiki page. This behaves largely like |
323
|
|
|
* getShortWikiText() but does not use the caption. Instead, it always |
324
|
|
|
* takes the long display form (wiki value). |
325
|
|
|
* |
326
|
|
|
* @param $linked mixed if true the result will be linked |
327
|
|
|
* @return string |
328
|
|
|
*/ |
329
|
|
|
public function getLongWikiText( $linked = null ) { |
330
|
17 |
|
if ( !$this->isValid() ) { |
331
|
|
|
return $this->getErrorText(); |
332
|
17 |
|
} |
333
|
|
|
|
334
|
|
|
if ( is_null( $linked ) || $linked === false || $this->m_outformat == '-' ) { |
335
|
|
|
return $this->getWikiValue(); |
336
|
17 |
|
} elseif ( $this->m_dataitem->getNamespace() == NS_FILE && $this->m_dataitem->getInterwiki() === '' ) { |
|
|
|
|
337
|
|
|
// Embed images and other files |
338
|
|
|
// Note that the embedded file links to the image, hence needs no additional link text. |
339
|
|
|
// There should not be a linebreak after an impage, just like there is no linebreak after |
340
|
|
|
// other values (whether formatted or not). |
341
|
|
|
return '[[' . $this->getWikiLinkTarget() . '|' . |
342
|
|
|
$this->getLongCaptionText() . '|frameless|border|text-top]]'; |
343
|
|
|
} |
344
|
17 |
|
|
345
|
|
|
$link = '[[:' . $this->getWikiLinkTarget() . '|' . $this->getLongCaptionText() . ']]'; |
346
|
|
|
|
347
|
|
|
if ( $this->m_fragment !== '' ) { |
348
|
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity'; |
349
|
|
|
} |
350
|
|
|
|
351
|
|
|
if ( $this->linkAttributes !== array() ) { |
352
|
|
|
$link = \Html::rawElement( |
353
|
|
|
'span', |
354
|
6 |
|
$this->linkAttributes, |
355
|
|
|
$link |
356
|
6 |
|
); |
357
|
1 |
|
} |
358
|
|
|
|
359
|
|
|
return $link; |
360
|
|
|
} |
361
|
6 |
|
|
362
|
6 |
|
/** |
363
|
|
|
* Display the "long" value in HTML. This behaves largely like |
364
|
|
|
* getLongWikiText() but does not embed images. |
365
|
6 |
|
* |
366
|
|
|
* @param $linker mixed if a Linker is given, the result will be linked |
367
|
|
|
* @return string |
368
|
|
|
*/ |
369
|
6 |
|
public function getLongHTMLText( $linker = null ) { |
370
|
|
|
|
371
|
6 |
|
if ( $this->m_fragment !== '' ) { |
372
|
|
|
$this->linkAttributes['class'] = 'smw-subobject-entity'; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
// init the Title object, may reveal hitherto unnoticed errors: |
376
|
|
|
if ( !is_null( $linker ) && ( $this->m_outformat != '-' ) ) { |
377
|
6 |
|
$this->getTitle(); |
378
|
6 |
|
} |
379
|
6 |
|
|
380
|
6 |
|
if ( !$this->isValid() ) { |
381
|
|
|
return $this->getErrorText(); |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
if ( $linker === null|| $linker === false || $this->m_outformat == '-' ) { |
385
|
|
|
return \Sanitizer::removeHTMLtags( $this->getWikiValue() ); |
386
|
|
|
} elseif ( $this->getNamespace() == NS_MEDIA ) { // this extra case is really needed |
387
|
|
|
return $linker->makeMediaLinkObj( $this->getTitle(), |
388
|
|
|
\Sanitizer::removeHTMLtags( $this->getLongCaptionText() ) ); |
389
|
|
|
} |
390
|
|
|
|
391
|
|
|
// all others use default linking, no embedding of images here |
392
|
|
|
return $linker->link( |
393
|
|
|
$this->getTitle(), |
394
|
111 |
|
\Sanitizer::removeHTMLtags( $this->getLongCaptionText() ), |
395
|
111 |
|
$this->linkAttributes, |
396
|
111 |
|
$this->queryParameters |
397
|
|
|
); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Return a string that could be used in an in-page property assignment |
402
|
|
|
* for setting this value. This does not include initial ":" for |
403
|
|
|
* escaping things like Category: links since the property value does |
404
|
|
|
* not include such escapes either. Fragment information is included. |
405
|
|
|
* Namespaces are omitted if a fixed namespace is used, since they are |
406
|
|
|
* not needed in this case when making a property assignment. |
407
|
|
|
* |
408
|
|
|
* @return string |
409
|
|
|
*/ |
410
|
1 |
|
public function getWikiValue() { |
411
|
1 |
|
return ( $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText() : $this->getText() ) . |
412
|
1 |
|
( $this->m_fragment !== '' ? "#{$this->m_fragment}" : '' ); |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
public function getHash() { |
416
|
|
|
return $this->isValid() ? $this->getPrefixedText() : implode( "\t", $this->getErrors() ); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
/** |
420
|
|
|
* Create links to mapping services based on a wiki-editable message. |
421
|
|
|
* The parameters available to the message are: |
422
|
|
|
* $1: urlencoded article name (no namespace) |
423
|
|
|
* |
424
|
|
|
* @return array |
425
|
|
|
*/ |
426
|
|
|
protected function getServiceLinkParams() { |
427
|
|
|
if ( $this->isValid() ) { |
428
|
|
|
return array( rawurlencode( str_replace( '_', ' ', $this->m_dataitem->getDBkey() ) ) ); |
|
|
|
|
429
|
|
|
} else { |
430
|
14 |
|
return array(); |
|
|
|
|
431
|
14 |
|
} |
432
|
14 |
|
} |
433
|
|
|
|
434
|
14 |
|
///// special interface for wiki page values |
435
|
|
|
|
436
|
|
|
/** |
437
|
|
|
* Return according Title object or null if no valid value was set. |
438
|
|
|
* null can be returned even if this object returns true for isValid(), |
439
|
|
|
* since the latter function does not check whether MediaWiki can really |
440
|
|
|
* make a Title out of the given data. |
441
|
|
|
* However, isValid() will return false *after* this function failed in |
442
|
|
|
* trying to create a title. |
443
|
|
|
* |
444
|
14 |
|
* @return Title |
445
|
|
|
*/ |
446
|
|
|
public function getTitle() { |
447
|
|
|
if ( ( $this->isValid() ) && is_null( $this->m_title ) ) { |
448
|
|
|
$this->m_title = $this->m_dataitem->getTitle(); |
|
|
|
|
449
|
|
|
|
450
|
|
|
if ( is_null( $this->m_title ) ) { // should not normally happen, but anyway ... |
451
|
|
|
$this->addErrorMsg( |
452
|
|
|
array( |
453
|
|
|
'smw_notitle', |
454
|
|
|
Localizer::getInstance()->getNamespaceTextById( $this->m_dataitem->getNamespace() ) . ':' . $this->m_dataitem->getDBkey() |
|
|
|
|
455
|
|
|
) |
456
|
|
|
); |
457
|
|
|
} |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return $this->m_title; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* Get MediaWiki's ID for this value or 0 if not available. |
465
|
14 |
|
* |
466
|
14 |
|
* @return integer |
467
|
|
|
*/ |
468
|
|
|
public function getArticleID() { |
469
|
|
|
if ( $this->m_id === false ) { |
470
|
|
|
$this->m_id = !is_null( $this->getTitle() ) ? $this->m_title->getArticleID() : 0; |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
return $this->m_id; |
474
|
|
|
} |
475
|
|
|
|
476
|
|
|
/** |
477
|
|
|
* Get namespace constant for this value. |
478
|
|
|
* |
479
|
|
|
* @return integer |
480
|
|
|
*/ |
481
|
|
|
public function getNamespace() { |
482
|
|
|
return $this->m_dataitem->getNamespace(); |
|
|
|
|
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
/** |
486
|
170 |
|
* Get DBKey for this value. Subclasses that allow for values that do not |
487
|
170 |
|
* correspond to wiki pages may choose a DB key that is not a legal title |
488
|
|
|
* DB key but rather another suitable internal ID. Thus it is not suitable |
489
|
|
|
* to use this method in places where only MediaWiki Title keys are allowed. |
490
|
|
|
* |
491
|
|
|
* @return string |
492
|
|
|
*/ |
493
|
|
|
public function getDBkey() { |
494
|
|
|
return $this->m_dataitem->getDBkey(); |
|
|
|
|
495
|
|
|
} |
496
|
167 |
|
|
497
|
|
|
/** |
498
|
167 |
|
* Get text label for this value, just like Title::getText(). |
499
|
15 |
|
* |
500
|
|
|
* @return string |
501
|
|
|
*/ |
502
|
167 |
|
public function getText() { |
503
|
|
|
return str_replace( '_', ' ', $this->m_dataitem->getDBkey() ); |
|
|
|
|
504
|
167 |
|
} |
505
|
167 |
|
|
506
|
167 |
|
/** |
507
|
167 |
|
* Get the prefixed text for this value, including a localized namespace |
508
|
167 |
|
* prefix. |
509
|
|
|
* |
510
|
|
|
* @return string |
511
|
167 |
|
*/ |
512
|
|
|
public function getPrefixedText() { |
513
|
|
|
|
514
|
|
|
if ( $this->m_prefixedtext !== '' ) { |
515
|
|
|
return $this->m_prefixedtext; |
516
|
|
|
} |
517
|
|
|
|
518
|
|
|
$this->m_prefixedtext = 'NO_VALID_VALUE'; |
519
|
|
|
|
520
|
|
|
if ( $this->isValid() ) { |
521
|
|
|
$nstext = Localizer::getInstance()->getNamespaceTextById( $this->m_dataitem->getNamespace() ); |
|
|
|
|
522
|
|
|
$this->m_prefixedtext = |
523
|
|
|
( $this->m_dataitem->getInterwiki() !== '' ? $this->m_dataitem->getInterwiki() . ':' : '' ) . |
|
|
|
|
524
|
|
|
( $nstext !== '' ? "$nstext:" : '' ) . $this->getText(); |
525
|
|
|
} |
526
|
|
|
|
527
|
|
|
return $this->m_prefixedtext; |
528
|
|
|
} |
529
|
|
|
|
530
|
1 |
|
/** |
531
|
|
|
* Get interwiki prefix or empty string. |
532
|
1 |
|
* |
533
|
|
|
* @return string |
534
|
|
|
*/ |
535
|
|
|
public function getInterwiki() { |
536
|
1 |
|
return $this->m_dataitem->getInterwiki(); |
|
|
|
|
537
|
|
|
} |
538
|
1 |
|
|
539
|
1 |
|
/** |
540
|
|
|
* DataValue::getPreferredCaption |
541
|
|
|
* |
542
|
1 |
|
* @since 2.4 |
543
|
|
|
* |
544
|
|
|
* @return string |
545
|
|
|
*/ |
546
|
|
|
public function getPreferredCaption() { |
547
|
|
|
|
548
|
|
|
if ( ( $preferredCaption = parent::getPreferredCaption() ) !== '' && $preferredCaption !== false ) { |
549
|
|
|
return $preferredCaption; |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
$preferredCaption = $this->getDisplayTitle(); |
553
|
|
|
|
554
|
|
|
if ( $preferredCaption === '' ) { |
555
|
129 |
|
$preferredCaption = $this->getText(); |
556
|
129 |
|
} |
557
|
1 |
|
|
558
|
|
|
return $preferredCaption; |
559
|
129 |
|
} |
560
|
|
|
|
561
|
|
|
/** |
562
|
129 |
|
* Get a short caption used to label this value. In particular, this |
563
|
121 |
|
* omits namespace and interwiki prefixes (similar to the MediaWiki |
564
|
|
|
* "pipe trick"). Fragments are included unless they start with an |
565
|
|
|
* underscore (used for generated fragment names that are not helpful |
566
|
51 |
|
* for users and that might change easily). |
567
|
|
|
* |
568
|
51 |
|
* @since 1.7 |
569
|
51 |
|
* @return string |
570
|
|
|
*/ |
571
|
|
|
protected function getShortCaptionText() { |
572
|
51 |
|
if ( $this->m_fragment !== '' && $this->m_fragment[0] != '_' ) { |
573
|
|
|
$fragmentText = '#' . $this->m_fragment; |
574
|
|
|
} else { |
575
|
|
|
$fragmentText = ''; |
576
|
|
|
} |
577
|
|
|
|
578
|
|
|
if ( $this->m_caption && $this->m_caption !== '' ) { |
579
|
|
|
return $this->m_caption; |
580
|
|
|
} |
581
|
|
|
|
582
|
|
|
$displayTitle = $this->getDisplayTitle(); |
583
|
|
|
|
584
|
|
|
if ( $displayTitle === '' ) { |
585
|
23 |
|
$displayTitle = $this->getText(); |
586
|
23 |
|
} |
587
|
1 |
|
|
588
|
|
|
return $displayTitle . $fragmentText; |
589
|
23 |
|
} |
590
|
|
|
|
591
|
|
|
/** |
592
|
23 |
|
* Get a long caption used to label this value. In particular, this |
593
|
13 |
|
* includes namespace and interwiki prefixes, while fragments are only |
594
|
|
|
* included if they do not start with an underscore (used for generated |
595
|
|
|
* fragment names that are not helpful for users and that might change |
596
|
10 |
|
* easily). |
597
|
|
|
* |
598
|
10 |
|
* @since 1.7 |
599
|
10 |
|
* @return string |
600
|
|
|
*/ |
601
|
|
|
protected function getLongCaptionText() { |
602
|
10 |
|
if ( $this->m_fragment !== '' && $this->m_fragment[0] != '_' ) { |
603
|
|
|
$fragmentText = '#' . $this->m_fragment; |
604
|
|
|
} else { |
605
|
|
|
$fragmentText = ''; |
606
|
|
|
} |
607
|
|
|
|
608
|
|
|
if ( $this->m_caption && $this->m_caption !== '' ) { |
609
|
|
|
return $this->m_caption; |
610
|
|
|
} |
611
|
|
|
|
612
|
|
|
$displayTitle = $this->getDisplayTitle(); |
613
|
133 |
|
|
614
|
133 |
|
if ( $displayTitle === '' ) { |
615
|
133 |
|
$displayTitle = $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText() : $this->getText(); |
616
|
|
|
} |
617
|
|
|
|
618
|
|
|
return $displayTitle . $fragmentText; |
619
|
|
|
} |
620
|
|
|
|
621
|
|
|
/** |
622
|
|
|
* Compute a text that can be used in wiki text to link to this |
623
|
|
|
* datavalue. Processing includes some escaping and adding the |
624
|
|
|
* fragment. |
625
|
|
|
* |
626
|
|
|
* @since 1.7 |
627
|
|
|
* @return string |
628
|
|
|
*/ |
629
|
|
|
protected function getWikiLinkTarget() { |
630
|
|
|
return str_replace( "'", ''', $this->getPrefixedText() ) . |
631
|
|
|
( $this->m_fragment !== '' ? "#{$this->m_fragment}" : '' ); |
632
|
|
|
} |
633
|
|
|
|
634
|
109 |
|
/** |
635
|
|
|
* Find the sortkey for this object. |
636
|
109 |
|
* |
637
|
5 |
|
* @deprecated Use SMWStore::getWikiPageSortKey(). Will vanish before SMW 1.7 |
638
|
|
|
* |
639
|
|
|
* @return string sortkey |
640
|
105 |
|
*/ |
641
|
|
|
public function getSortKey() { |
642
|
|
|
return ApplicationFactory::getInstance()->getStore()->getWikiPageSortKey( $this->m_dataitem ); |
|
|
|
|
643
|
|
|
} |
644
|
|
|
|
645
|
|
|
/** |
646
|
|
|
* @since 2.4 |
647
|
|
|
* |
648
|
|
|
* @return string |
649
|
|
|
*/ |
650
|
|
|
public function getDisplayTitle() { |
651
|
|
|
|
652
|
|
|
if ( $this->m_dataitem === null || !$this->isEnabledFeature( SMW_DV_WPV_DTITLE ) ) { |
653
|
|
|
return ''; |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
return $this->findDisplayTitleFor( $this->m_dataitem ); |
657
|
|
|
} |
658
|
|
|
|
659
|
|
|
/** |
660
|
|
|
* Static function for creating a new wikipage object from |
661
|
|
|
* data as it is typically stored internally. In particular, |
662
|
|
|
* the title string is supposed to be in DB key form. |
663
|
|
|
* |
664
|
|
|
* @note The resulting wikipage object might be invalid if |
665
|
|
|
* the provided title is not allowed. An object is returned |
666
|
|
|
* in any case. |
667
|
|
|
* |
668
|
|
|
* @deprecated This method will vanish before SMW 1.7. If you really need this, simply copy its code. |
669
|
|
|
* |
670
|
|
|
* @return SMWWikiPageValue |
671
|
|
|
*/ |
672
|
|
|
static public function makePage( $dbkey, $namespace, $ignoredParameter = '', $interwiki = '' ) { |
|
|
|
|
673
|
|
|
$diWikiPage = new SMWDIWikiPage( $dbkey, $namespace, $interwiki ); |
674
|
|
|
$dvWikiPage = new SMWWikiPageValue( '_wpg' ); |
675
|
|
|
$dvWikiPage->setDataItem( $diWikiPage ); |
676
|
|
|
return $dvWikiPage; |
677
|
|
|
} |
678
|
|
|
|
679
|
105 |
|
/** |
680
|
|
|
* Static function for creating a new wikipage object from a |
681
|
105 |
|
* MediaWiki Title object. |
682
|
|
|
* |
683
|
105 |
|
* @deprecated This method will vanish before SMW 1.7. If you really need this, simply copy its code. |
684
|
|
|
* |
685
|
105 |
|
* @return SMWWikiPageValue |
686
|
|
|
*/ |
687
|
|
|
static public function makePageFromTitle( Title $title ) { |
|
|
|
|
688
|
105 |
|
$dvWikiPage = new SMWWikiPageValue( '_wpg' ); |
689
|
5 |
|
$diWikiPage = SMWDIWikiPage::newFromTitle( $title ); |
690
|
104 |
|
$dvWikiPage->setDataItem( $diWikiPage ); |
691
|
|
|
$dvWikiPage->m_title = $title; // optional, just for efficiency |
692
|
12 |
|
return $dvWikiPage; |
693
|
|
|
} |
694
|
|
|
|
695
|
105 |
|
private function findDisplayTitleFor( $subject ) { |
696
|
|
|
|
697
|
|
|
$displayTitle = ''; |
698
|
|
|
|
699
|
|
|
$dataItems = ApplicationFactory::getInstance()->getCachedPropertyValuesPrefetcher()->getPropertyValues( |
700
|
|
|
$subject, |
701
|
|
|
new DIProperty( '_DTITLE' ) |
702
|
|
|
); |
703
|
|
|
|
704
|
|
|
if ( $dataItems !== null && $dataItems !== array() ) { |
705
|
|
|
$displayTitle = end( $dataItems )->getString(); |
706
|
|
|
} elseif ( $subject->getSubobjectName() !== '' ) { |
707
|
|
|
// Check whether the base subject has a DISPLAYTITLE |
708
|
|
|
return $this->findDisplayTitleFor( $subject->asBase() ); |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
return $displayTitle; |
712
|
|
|
} |
713
|
|
|
|
714
|
|
|
} |
715
|
|
|
|
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.