Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
6.93% |
23 / 332 |
|
9.30% |
4 / 43 |
CRAP | |
0.00% |
0 / 1 |
UrlGenerator | |
6.93% |
23 / 332 |
|
9.30% |
4 / 43 |
2770.17 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
resolveTitle | |
18.18% |
2 / 11 |
|
0.00% |
0 / 1 |
12.76 | |||
newTopicLink | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
editHeaderLink | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
headerRevisionLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
topicRevisionLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
postRevisionLink | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
summaryRevisionLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
topicLink | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
postLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
postHistoryLink | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
workflowHistoryLink | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
boardHistoryLink | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
undoAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 | |||
undoEditPostAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
undoEditHeaderAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
undoEditSummaryAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
diffLink | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
diffHeaderLink | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
diffPostLink | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
diffSummaryLink | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
workflowLink | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
watchTopicLink | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
unwatchTopicLink | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
boardLink | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
replyAction | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
editTopicSummaryAction | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
lockTopicAction | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
restoreTopicAction | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
restorePostAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
createHeaderAction | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
editHeaderAction | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
editTitleAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
editPostAction | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
hideTopicAction | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
hidePostAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
deleteTopicAction | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
deletePostAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
suppressTopicAction | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
suppressPostAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 | |||
newTopicAction | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
thankAction | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
markRevisionPatrolledAction | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace Flow; |
4 | |
5 | use Flow\Collection\PostCollection; |
6 | use Flow\Data\Mapper\CachingObjectMapper; |
7 | use Flow\Exception\FlowException; |
8 | use Flow\Exception\InvalidInputException; |
9 | use Flow\Model\AbstractRevision; |
10 | use Flow\Model\Anchor; |
11 | use Flow\Model\Header; |
12 | use Flow\Model\PostRevision; |
13 | use Flow\Model\PostSummary; |
14 | use Flow\Model\UUID; |
15 | use MediaWiki\Context\RequestContext; |
16 | use MediaWiki\SpecialPage\SpecialPage; |
17 | use MediaWiki\Title\Title; |
18 | use RecentChange; |
19 | |
20 | /** |
21 | * Provides url generation capabilities for Flow. Ties together an |
22 | * i18n message with a specific Title, query parameters and fragment. |
23 | * |
24 | * URL generation methods mostly accept either a Title or a UUID |
25 | * representing the Workflow. URL generation methods all return |
26 | * Anchor instances.. |
27 | */ |
28 | class UrlGenerator { |
29 | /** |
30 | * @var CachingObjectMapper |
31 | */ |
32 | private $workflowMapper; |
33 | |
34 | public function __construct( CachingObjectMapper $workflowMapper ) { |
35 | $this->workflowMapper = $workflowMapper; |
36 | } |
37 | |
38 | /** |
39 | * @param Title|null $title |
40 | * @param UUID|null $workflowId |
41 | * @return Title |
42 | * @throws FlowException |
43 | */ |
44 | protected function resolveTitle( ?Title $title = null, ?UUID $workflowId = null ) { |
45 | if ( $title !== null ) { |
46 | return $title; |
47 | } |
48 | if ( $workflowId === null ) { |
49 | throw new FlowException( 'No title or workflow given' ); |
50 | } |
51 | |
52 | $alpha = $workflowId->getAlphadecimal(); |
53 | $workflow = $this->workflowMapper->get( [ |
54 | 'workflow_id' => $alpha, |
55 | ] ); |
56 | if ( $workflow === null ) { |
57 | throw new InvalidInputException( 'Unloaded workflow:' . $alpha, 'invalid-workflow' ); |
58 | } |
59 | return $workflow->getArticleTitle(); |
60 | } |
61 | |
62 | /** |
63 | * Link to create new topic on a topiclist. |
64 | * |
65 | * @param Title|null $title |
66 | * @param UUID|null $workflowId |
67 | * @return Anchor |
68 | */ |
69 | public function newTopicLink( ?Title $title = null, ?UUID $workflowId = null ) { |
70 | return new Anchor( |
71 | wfMessage( 'flow-topic-action-new' ), |
72 | $this->resolveTitle( $title, $workflowId ), |
73 | [ 'action' => 'new-topic' ] |
74 | ); |
75 | } |
76 | |
77 | /** |
78 | * Edit the header at the specified workflow. |
79 | * |
80 | * @param Title|null $title |
81 | * @param UUID $workflowId |
82 | * @return Anchor |
83 | */ |
84 | public function editHeaderLink( ?Title $title, UUID $workflowId ) { |
85 | return new Anchor( |
86 | wfMessage( 'flow-edit-header' ), |
87 | $this->resolveTitle( $title, $workflowId ), |
88 | [ 'action' => 'edit-header' ] |
89 | ); |
90 | } |
91 | |
92 | /** |
93 | * View a specific revision of a header workflow. |
94 | * |
95 | * @param Title|null $title |
96 | * @param UUID $workflowId |
97 | * @param UUID $revId |
98 | * @return Anchor |
99 | */ |
100 | public function headerRevisionLink( ?Title $title, UUID $workflowId, UUID $revId ) { |
101 | return new Anchor( |
102 | wfMessage( 'flow-link-header-revision' ), |
103 | $this->resolveTitle( $title, $workflowId ), |
104 | [ |
105 | 'header_revId' => $revId->getAlphadecimal(), |
106 | 'action' => 'view-header' |
107 | ] |
108 | ); |
109 | } |
110 | |
111 | /** |
112 | * View a specific revision of a topic title |
113 | * |
114 | * @param Title|null $title |
115 | * @param UUID $workflowId |
116 | * @param UUID $revId |
117 | * @return Anchor |
118 | */ |
119 | public function topicRevisionLink( ?Title $title, UUID $workflowId, UUID $revId ) { |
120 | return new Anchor( |
121 | wfMessage( 'flow-link-topic-revision' ), |
122 | $this->resolveTitle( $title, $workflowId ), |
123 | [ |
124 | 'topic_revId' => $revId->getAlphadecimal(), |
125 | 'action' => 'single-view' |
126 | ] |
127 | ); |
128 | } |
129 | |
130 | /** |
131 | * View a specific revision of a post within a topic workflow. |
132 | * |
133 | * @param Title|null $title |
134 | * @param UUID $workflowId |
135 | * @param UUID $postId |
136 | * @param UUID $revId |
137 | * @return Anchor |
138 | */ |
139 | public function postRevisionLink( |
140 | ?Title $title, |
141 | UUID $workflowId, |
142 | UUID $postId, |
143 | UUID $revId |
144 | ) { |
145 | return new Anchor( |
146 | wfMessage( 'flow-link-post-revision' ), |
147 | $this->resolveTitle( $title, $workflowId ), |
148 | [ |
149 | 'topic_postId' => $postId->getAlphadecimal(), |
150 | 'topic_revId' => $revId->getAlphadecimal(), |
151 | 'action' => 'single-view' |
152 | ] |
153 | ); |
154 | } |
155 | |
156 | /** |
157 | * View a specific revision of topic summary. |
158 | * |
159 | * @param Title|null $title |
160 | * @param UUID $workflowId |
161 | * @param UUID $revId |
162 | * @return Anchor |
163 | */ |
164 | public function summaryRevisionLink( ?Title $title, UUID $workflowId, UUID $revId ) { |
165 | return new Anchor( |
166 | wfMessage( 'flow-link-summary-revision' ), |
167 | $this->resolveTitle( $title, $workflowId ), |
168 | [ |
169 | 'topicsummary_revId' => $revId->getAlphadecimal(), |
170 | 'action' => 'view-topic-summary' |
171 | ] |
172 | ); |
173 | } |
174 | |
175 | /** |
176 | * View the topic at the specified workflow. |
177 | * |
178 | * @param Title|null $title |
179 | * @param UUID $workflowId |
180 | * @return Anchor |
181 | */ |
182 | public function topicLink( ?Title $title, UUID $workflowId ) { |
183 | return new Anchor( |
184 | wfMessage( 'flow-link-topic' ), |
185 | $this->resolveTitle( $title, $workflowId ) |
186 | ); |
187 | } |
188 | |
189 | /** |
190 | * View a topic scrolled down to the provided post at the |
191 | * specified workflow. |
192 | * |
193 | * @param Title|null $title |
194 | * @param UUID $workflowId |
195 | * @param UUID $postId |
196 | * @return Anchor |
197 | */ |
198 | public function postLink( ?Title $title, UUID $workflowId, UUID $postId ) { |
199 | return new Anchor( |
200 | wfMessage( 'flow-link-post' ), |
201 | $this->resolveTitle( $title, $workflowId ), |
202 | [ |
203 | // If the post is moderated this will flag the backend to still |
204 | // include the content in the html response. |
205 | 'topic_showPostId' => $postId->getAlphadecimal() |
206 | ], |
207 | '#flow-post-' . $postId->getAlphadecimal() |
208 | ); |
209 | } |
210 | |
211 | /** |
212 | * Show the history of a specific post within a topic workflow |
213 | * |
214 | * @param Title|null $title |
215 | * @param UUID $workflowId |
216 | * @param UUID $postId |
217 | * @return Anchor |
218 | */ |
219 | public function postHistoryLink( ?Title $title, UUID $workflowId, UUID $postId ) { |
220 | return new Anchor( |
221 | wfMessage( 'flow-post-action-post-history' ), |
222 | $this->resolveTitle( $title, $workflowId ), |
223 | [ |
224 | 'action' => 'history', |
225 | 'topic_postId' => $postId->getAlphadecimal(), |
226 | ] |
227 | ); |
228 | } |
229 | |
230 | /** |
231 | * Show the history of a workflow. |
232 | * |
233 | * @param Title|null $title |
234 | * @param UUID $workflowId |
235 | * @return Anchor |
236 | */ |
237 | public function workflowHistoryLink( ?Title $title, UUID $workflowId ) { |
238 | return new Anchor( |
239 | wfMessage( 'flow-topic-action-history' ), |
240 | $this->resolveTitle( $title, $workflowId ), |
241 | [ 'action' => 'history' ] |
242 | ); |
243 | } |
244 | |
245 | /** |
246 | * Show the history of a flow board. |
247 | * |
248 | * @param Title $title |
249 | * @return Anchor |
250 | */ |
251 | public function boardHistoryLink( Title $title ) { |
252 | return new Anchor( |
253 | wfMessage( 'hist' ), |
254 | $title, |
255 | [ 'action' => 'history' ] |
256 | ); |
257 | } |
258 | |
259 | /** |
260 | * Generate a link to undo the specified revision. Note that this will only work if |
261 | * that is the most recent content edit against the revision type. |
262 | * |
263 | * @param AbstractRevision $revision The revision to undo. |
264 | * @param Title|null $title The title the revision belongs to |
265 | * @param UUID $workflowId The workflow id the revision belongs to |
266 | * @return Anchor |
267 | * @throws FlowException When the provided revision is not known |
268 | */ |
269 | public function undoAction( AbstractRevision $revision, ?Title $title, UUID $workflowId ) { |
270 | $startId = $revision->getPrevRevisionId(); |
271 | $endId = $revision->getRevisionId(); |
272 | if ( $revision instanceof PostRevision ) { |
273 | return $this->undoEditPostAction( $title, $workflowId, $startId, $endId ); |
274 | } elseif ( $revision instanceof Header ) { |
275 | return $this->undoEditHeaderAction( $title, $workflowId, $startId, $endId ); |
276 | } elseif ( $revision instanceof PostSummary ) { |
277 | return $this->undoEditSummaryAction( $title, $workflowId, $startId, $endId ); |
278 | } else { |
279 | throw new FlowException( 'Unknown revision type: ' . get_class( $revision ) ); |
280 | } |
281 | } |
282 | |
283 | /** |
284 | * @param Title|null $title The title the post belongs to, or null |
285 | * @param UUID $workflowId The workflowId the post belongs to |
286 | * @param UUID $startId The revision to start undo from. |
287 | * @param UUID $endId The revision to stop undoing at |
288 | * @return Anchor |
289 | */ |
290 | public function undoEditPostAction( |
291 | ?Title $title, |
292 | UUID $workflowId, |
293 | UUID $startId, |
294 | UUID $endId |
295 | ) { |
296 | return new Anchor( |
297 | wfMessage( 'flow-undo' ), |
298 | $this->resolveTitle( $title, $workflowId ), |
299 | [ |
300 | 'action' => 'undo-edit-post', |
301 | 'topic_startId' => $startId->getAlphadecimal(), |
302 | 'topic_endId' => $endId->getAlphadecimal(), |
303 | ] |
304 | ); |
305 | } |
306 | |
307 | /** |
308 | * @param Title|null $title The title the header belongs to, or null |
309 | * @param UUID $workflowId The workflowId the header belongs to |
310 | * @param UUID $startId The revision to start undo from. |
311 | * @param UUID $endId The revision to stop undoing at |
312 | * @return Anchor |
313 | */ |
314 | public function undoEditHeaderAction( |
315 | ?Title $title, |
316 | UUID $workflowId, |
317 | UUID $startId, |
318 | UUID $endId |
319 | ) { |
320 | return new Anchor( |
321 | wfMessage( 'flow-undo' ), |
322 | $this->resolveTitle( $title, $workflowId ), |
323 | [ |
324 | 'action' => 'undo-edit-header', |
325 | 'header_startId' => $startId->getAlphadecimal(), |
326 | 'header_endId' => $endId->getAlphadecimal(), |
327 | ] |
328 | ); |
329 | } |
330 | |
331 | /** |
332 | * @param Title|null $title The title the summary belongs to, or null |
333 | * @param UUID $workflowId The workflowId the summary belongs to |
334 | * @param UUID $startId The revision to start undo from. |
335 | * @param UUID $endId The revision to stop undoing at |
336 | * @return Anchor |
337 | */ |
338 | public function undoEditSummaryAction( |
339 | ?Title $title, |
340 | UUID $workflowId, |
341 | UUID $startId, |
342 | UUID $endId |
343 | ) { |
344 | return new Anchor( |
345 | wfMessage( 'flow-undo' ), |
346 | $this->resolveTitle( $title, $workflowId ), |
347 | [ |
348 | 'action' => 'undo-edit-topic-summary', |
349 | 'topicsummary_startId' => $startId->getAlphadecimal(), |
350 | 'topicsummary_endId' => $endId->getAlphadecimal(), |
351 | ] |
352 | ); |
353 | } |
354 | |
355 | /** |
356 | * @param AbstractRevision $revision |
357 | * @param Title|null $title |
358 | * @param UUID $workflowId |
359 | * @param UUID|null $oldRevId |
360 | * @return Anchor |
361 | * @throws FlowException When $revision is not PostRevision, Header or PostSummary |
362 | */ |
363 | public function diffLink( |
364 | AbstractRevision $revision, |
365 | ?Title $title, |
366 | UUID $workflowId, |
367 | ?UUID $oldRevId = null |
368 | ) { |
369 | if ( $revision instanceof PostRevision ) { |
370 | return $this->diffPostLink( $title, $workflowId, $revision->getRevisionId(), $oldRevId ); |
371 | } elseif ( $revision instanceof Header ) { |
372 | return $this->diffHeaderLink( $title, $workflowId, $revision->getRevisionId(), $oldRevId ); |
373 | } elseif ( $revision instanceof PostSummary ) { |
374 | return $this->diffSummaryLink( $title, $workflowId, $revision->getRevisionId(), $oldRevId ); |
375 | } else { |
376 | throw new FlowException( 'Unknown revision type: ' . get_class( $revision ) ); |
377 | } |
378 | } |
379 | |
380 | /** |
381 | * Show the differences between two revisions of a header. |
382 | * |
383 | * When $oldRevId is null shows the differences between $revId and the revision |
384 | * immediately prior. If $oldRevId is provided shows the differences between |
385 | * $oldRevId and $revId. |
386 | * |
387 | * @param Title|null $title |
388 | * @param UUID $workflowId |
389 | * @param UUID $revId |
390 | * @param UUID|null $oldRevId |
391 | * @return Anchor |
392 | */ |
393 | public function diffHeaderLink( |
394 | ?Title $title, |
395 | UUID $workflowId, |
396 | UUID $revId, |
397 | ?UUID $oldRevId = null |
398 | ) { |
399 | return new Anchor( |
400 | wfMessage( 'diff' ), |
401 | $this->resolveTitle( $title, $workflowId ), |
402 | [ |
403 | 'action' => 'compare-header-revisions', |
404 | 'header_newRevision' => $revId->getAlphadecimal(), |
405 | ] + ( $oldRevId === null ? [] : [ |
406 | 'header_oldRevision' => $oldRevId->getAlphadecimal(), |
407 | ] ) |
408 | ); |
409 | } |
410 | |
411 | /** |
412 | * Show the differences between two revisions of a post. |
413 | * |
414 | * When $oldRevId is null shows the differences between $revId and the revision |
415 | * immediately prior. If $oldRevId is provided shows the differences between |
416 | * $oldRevId and $revId. |
417 | * |
418 | * @param Title|null $title |
419 | * @param UUID $workflowId |
420 | * @param UUID $revId |
421 | * @param UUID|null $oldRevId |
422 | * @return Anchor |
423 | */ |
424 | public function diffPostLink( |
425 | ?Title $title, |
426 | UUID $workflowId, |
427 | UUID $revId, |
428 | ?UUID $oldRevId = null |
429 | ) { |
430 | return new Anchor( |
431 | wfMessage( 'diff' ), |
432 | $this->resolveTitle( $title, $workflowId ), |
433 | [ |
434 | 'action' => 'compare-post-revisions', |
435 | 'topic_newRevision' => $revId->getAlphadecimal(), |
436 | ] + ( $oldRevId === null ? [] : [ |
437 | 'topic_oldRevision' => $oldRevId->getAlphadecimal(), |
438 | ] ) |
439 | ); |
440 | } |
441 | |
442 | /** |
443 | * Show the differences between two revisions of a summary. |
444 | * |
445 | * When $oldRevId is null shows the differences between $revId and the revision |
446 | * immediately prior. If $oldRevId is provided shows the differences between |
447 | * $oldRevId and $revId. |
448 | * |
449 | * @param Title|null $title |
450 | * @param UUID $workflowId |
451 | * @param UUID $revId |
452 | * @param UUID|null $oldRevId |
453 | * @return Anchor |
454 | */ |
455 | public function diffSummaryLink( |
456 | ?Title $title, |
457 | UUID $workflowId, |
458 | UUID $revId, |
459 | ?UUID $oldRevId = null |
460 | ) { |
461 | return new Anchor( |
462 | wfMessage( 'diff' ), |
463 | $this->resolveTitle( $title, $workflowId ), |
464 | [ |
465 | 'action' => 'compare-postsummary-revisions', |
466 | 'topicsummary_newRevision' => $revId->getAlphadecimal(), |
467 | ] + ( $oldRevId === null ? [] : [ |
468 | 'topicsummary_oldRevision' => $oldRevId->getAlphadecimal(), |
469 | ] ) |
470 | ); |
471 | } |
472 | |
473 | /** |
474 | * View the specified workflow. |
475 | * |
476 | * @param Title|null $title |
477 | * @param UUID $workflowId |
478 | * @return Anchor |
479 | */ |
480 | public function workflowLink( ?Title $title, UUID $workflowId ) { |
481 | return new Anchor( |
482 | wfMessage( 'flow-workflow' ), |
483 | $this->resolveTitle( $title, $workflowId ) |
484 | ); |
485 | } |
486 | |
487 | /** |
488 | * Watch topic link |
489 | * @todo Replace title with a flow topic namespace topic |
490 | * |
491 | * @param Title|null $title |
492 | * @param UUID $workflowId |
493 | * @return Anchor |
494 | */ |
495 | public function watchTopicLink( ?Title $title, UUID $workflowId ) { |
496 | return new Anchor( |
497 | wfMessage( 'watch' ), |
498 | $this->resolveTitle( $title, $workflowId ), |
499 | [ 'action' => 'watch' ] |
500 | ); |
501 | } |
502 | |
503 | /** |
504 | * Unwatch topic link |
505 | * @todo Replace title with a flow topic namespace topic |
506 | * |
507 | * @param Title|null $title |
508 | * @param UUID $workflowId |
509 | * @return Anchor |
510 | */ |
511 | public function unwatchTopicLink( ?Title $title, UUID $workflowId ) { |
512 | return new Anchor( |
513 | wfMessage( 'unwatch' ), |
514 | $this->resolveTitle( $title, $workflowId ), |
515 | [ 'action' => 'unwatch' ] |
516 | ); |
517 | } |
518 | |
519 | /** |
520 | * View the flow board at the specified title |
521 | * |
522 | * Makes the assumption the title is flow-enabled. |
523 | * |
524 | * @param Title $title |
525 | * @param string|null $sortBy |
526 | * @param bool $saveSortBy |
527 | * @return Anchor |
528 | */ |
529 | public function boardLink( Title $title, $sortBy = null, $saveSortBy = false ) { |
530 | $options = []; |
531 | |
532 | if ( $sortBy !== null ) { |
533 | $options['topiclist_sortby'] = $sortBy; |
534 | if ( $saveSortBy ) { |
535 | $options['topiclist_savesortby'] = '1'; |
536 | } |
537 | } |
538 | |
539 | return new Anchor( |
540 | $title->getPrefixedText(), |
541 | $title, |
542 | $options |
543 | ); |
544 | } |
545 | |
546 | /** |
547 | * Reply to an individual post in a topic workflow. |
548 | * |
549 | * @param Title|null $title |
550 | * @param UUID $workflowId |
551 | * @param UUID $postId |
552 | * @param bool $isTopLevelReply |
553 | * @return Anchor |
554 | */ |
555 | public function replyAction( |
556 | ?Title $title, |
557 | UUID $workflowId, |
558 | UUID $postId, |
559 | $isTopLevelReply |
560 | ) { |
561 | $hash = "#flow-post-{$postId->getAlphadecimal()}"; |
562 | if ( $isTopLevelReply ) { |
563 | $hash .= "-form-content"; |
564 | } |
565 | return new Anchor( |
566 | wfMessage( 'flow-reply-link' ), |
567 | $this->resolveTitle( $title, $workflowId ), |
568 | [ |
569 | 'action' => 'reply', |
570 | 'topic_postId' => $postId->getAlphadecimal(), |
571 | ], |
572 | $hash |
573 | ); |
574 | } |
575 | |
576 | /** |
577 | * Edit the specified topic summary |
578 | * |
579 | * @param Title|null $title |
580 | * @param UUID $workflowId |
581 | * @return Anchor |
582 | */ |
583 | public function editTopicSummaryAction( ?Title $title, UUID $workflowId ) { |
584 | return new Anchor( |
585 | wfMessage( 'flow-topic-action-summarize-topic' ), |
586 | $this->resolveTitle( $title, $workflowId ), |
587 | [ 'action' => 'edit-topic-summary' ] |
588 | ); |
589 | } |
590 | |
591 | /** |
592 | * Lock the specified topic |
593 | * |
594 | * @param Title|null $title |
595 | * @param UUID $workflowId |
596 | * @return Anchor |
597 | */ |
598 | public function lockTopicAction( ?Title $title, UUID $workflowId ) { |
599 | return new Anchor( |
600 | wfMessage( 'flow-topic-action-lock-topic' ), |
601 | $this->resolveTitle( $title, $workflowId ), |
602 | [ |
603 | 'action' => 'lock-topic', |
604 | 'flow_moderationState' => AbstractRevision::MODERATED_LOCKED, |
605 | ] |
606 | ); |
607 | } |
608 | |
609 | /** |
610 | * Restore the specified topic to unmoderated status. |
611 | * |
612 | * @param Title|null $title |
613 | * @param UUID $workflowId |
614 | * @param string $moderationAction |
615 | * @param string $flowAction |
616 | * @return Anchor |
617 | */ |
618 | public function restoreTopicAction( |
619 | ?Title $title, |
620 | UUID $workflowId, |
621 | $moderationAction, |
622 | $flowAction = 'moderate-topic' |
623 | ) { |
624 | return new Anchor( |
625 | wfMessage( 'flow-topic-action-' . $moderationAction . '-topic' ), |
626 | $this->resolveTitle( $title, $workflowId ), |
627 | [ |
628 | 'action' => $flowAction, |
629 | 'flow_moderationState' => $moderationAction, |
630 | ] |
631 | ); |
632 | } |
633 | |
634 | /** |
635 | * Restore the specified post to unmoderated status. |
636 | * |
637 | * @param Title|null $title |
638 | * @param UUID $workflowId |
639 | * @param UUID $postId |
640 | * @param string $moderationAction |
641 | * @param string $flowAction |
642 | * @return Anchor |
643 | */ |
644 | public function restorePostAction( |
645 | ?Title $title, |
646 | UUID $workflowId, |
647 | UUID $postId, |
648 | $moderationAction, |
649 | $flowAction = 'moderate-post' |
650 | ) { |
651 | return new Anchor( |
652 | wfMessage( 'flow-post-action-' . $moderationAction . '-post' ), |
653 | $this->resolveTitle( $title, $workflowId ), |
654 | [ |
655 | 'action' => $flowAction, |
656 | 'topic_moderationState' => $moderationAction, |
657 | 'topic_postId' => $postId->getAlphadecimal(), |
658 | ] |
659 | ); |
660 | } |
661 | |
662 | /** |
663 | * Create a header for the specified page |
664 | * |
665 | * @param Title $title |
666 | * @return Anchor |
667 | */ |
668 | public function createHeaderAction( Title $title ) { |
669 | return new Anchor( |
670 | wfMessage( 'flow-edit-header-link' ), |
671 | $title, |
672 | [ 'action' => 'edit-header' ] |
673 | ); |
674 | } |
675 | |
676 | /** |
677 | * Edit the specified header |
678 | * |
679 | * @param Title|null $title |
680 | * @param UUID $workflowId |
681 | * @param UUID $revId |
682 | * @return Anchor |
683 | */ |
684 | public function editHeaderAction( ?Title $title, UUID $workflowId, UUID $revId ) { |
685 | return new Anchor( |
686 | wfMessage( 'flow-edit-header-link' ), |
687 | $this->resolveTitle( $title, $workflowId ), |
688 | [ 'action' => 'edit-header' ] |
689 | ); |
690 | } |
691 | |
692 | /** |
693 | * Edit the specified topic title |
694 | * |
695 | * @param Title|null $title |
696 | * @param UUID $workflowId |
697 | * @param UUID $postId |
698 | * @param UUID $revId |
699 | * @return Anchor |
700 | */ |
701 | public function editTitleAction( |
702 | ?Title $title, |
703 | UUID $workflowId, |
704 | UUID $postId, |
705 | UUID $revId |
706 | ) { |
707 | return new Anchor( |
708 | wfMessage( 'flow-topic-action-edit-title' ), |
709 | $this->resolveTitle( $title, $workflowId ), |
710 | [ |
711 | 'action' => 'edit-title', |
712 | 'topic_postId' => $postId->getAlphadecimal(), |
713 | 'topic_format' => 'wikitext', |
714 | ] |
715 | ); |
716 | } |
717 | |
718 | /** |
719 | * Edit the specified post within the specified workflow |
720 | * |
721 | * @param Title|null $title |
722 | * @param UUID $workflowId |
723 | * @param UUID $postId |
724 | * @param UUID $revId |
725 | * @return Anchor |
726 | */ |
727 | public function editPostAction( |
728 | ?Title $title, |
729 | UUID $workflowId, |
730 | UUID $postId, |
731 | UUID $revId |
732 | ) { |
733 | return new Anchor( |
734 | wfMessage( 'flow-post-action-edit-post' ), |
735 | $this->resolveTitle( $title, $workflowId ), |
736 | [ |
737 | 'action' => 'edit-post', |
738 | 'topic_postId' => $postId->getAlphadecimal(), |
739 | // @todo not necessary? |
740 | 'topic_revId' => $revId->getAlphadecimal(), |
741 | ], |
742 | '#flow-post-' . $postId->getAlphadecimal() |
743 | |
744 | ); |
745 | } |
746 | |
747 | /** |
748 | * Hide the specified topic |
749 | * |
750 | * @param Title|null $title |
751 | * @param UUID $workflowId |
752 | * @return Anchor |
753 | */ |
754 | public function hideTopicAction( ?Title $title, UUID $workflowId ) { |
755 | return new Anchor( |
756 | wfMessage( 'flow-topic-action-hide-topic' ), |
757 | $this->resolveTitle( $title, $workflowId ), |
758 | [ |
759 | 'action' => 'moderate-topic', |
760 | 'topic_moderationState' => AbstractRevision::MODERATED_HIDDEN, |
761 | ] |
762 | ); |
763 | } |
764 | |
765 | /** |
766 | * Hide the specified post within the specified workflow |
767 | * |
768 | * @param Title|null $title |
769 | * @param UUID $workflowId |
770 | * @param UUID $postId |
771 | * @return Anchor |
772 | */ |
773 | public function hidePostAction( ?Title $title, UUID $workflowId, UUID $postId ) { |
774 | return new Anchor( |
775 | wfMessage( 'flow-post-action-hide-post' ), |
776 | $this->resolveTitle( $title, $workflowId ), |
777 | [ |
778 | 'action' => 'moderate-post', |
779 | 'topic_postId' => $postId->getAlphadecimal(), |
780 | 'topic_moderationState' => AbstractRevision::MODERATED_HIDDEN, |
781 | ] |
782 | ); |
783 | } |
784 | |
785 | /** |
786 | * Delete the specified topic workflow |
787 | * |
788 | * @param Title|null $title |
789 | * @param UUID $workflowId |
790 | * @return Anchor |
791 | */ |
792 | public function deleteTopicAction( ?Title $title, UUID $workflowId ) { |
793 | return new Anchor( |
794 | wfMessage( 'flow-topic-action-delete-topic' ), |
795 | $this->resolveTitle( $title, $workflowId ), |
796 | [ |
797 | 'action' => 'moderate-topic', |
798 | 'topic_moderationState' => AbstractRevision::MODERATED_DELETED, |
799 | ] |
800 | ); |
801 | } |
802 | |
803 | /** |
804 | * Delete the specified post within the specified workflow |
805 | * |
806 | * @param Title|null $title |
807 | * @param UUID $workflowId |
808 | * @param UUID $postId |
809 | * @return Anchor |
810 | */ |
811 | public function deletePostAction( ?Title $title, UUID $workflowId, UUID $postId ) { |
812 | return new Anchor( |
813 | wfMessage( 'flow-post-action-delete-post' ), |
814 | $this->resolveTitle( $title, $workflowId ), |
815 | [ |
816 | 'action' => 'moderate-post', |
817 | 'topic_postId' => $postId->getAlphadecimal(), |
818 | 'topic_moderationState' => AbstractRevision::MODERATED_DELETED, |
819 | ] |
820 | ); |
821 | } |
822 | |
823 | /** |
824 | * Suppress the specified topic workflow |
825 | * |
826 | * @param Title|null $title |
827 | * @param UUID $workflowId |
828 | * @return Anchor |
829 | */ |
830 | public function suppressTopicAction( ?Title $title, UUID $workflowId ) { |
831 | return new Anchor( |
832 | wfMessage( 'flow-topic-action-suppress-topic' ), |
833 | $this->resolveTitle( $title, $workflowId ), |
834 | [ |
835 | 'action' => 'moderate-topic', |
836 | 'topic_moderationState' => AbstractRevision::MODERATED_SUPPRESSED, |
837 | ] |
838 | ); |
839 | } |
840 | |
841 | /** |
842 | * Suppress the specified post within the specified workflow |
843 | * |
844 | * @param Title|null $title |
845 | * @param UUID $workflowId |
846 | * @param UUID $postId |
847 | * @return Anchor |
848 | */ |
849 | public function suppressPostAction( ?Title $title, UUID $workflowId, UUID $postId ) { |
850 | return new Anchor( |
851 | wfMessage( 'flow-post-action-suppress-post' ), |
852 | $this->resolveTitle( $title, $workflowId ), |
853 | [ |
854 | 'action' => 'moderate-post', |
855 | 'topic_postId' => $postId->getAlphadecimal(), |
856 | 'topic_moderationState' => AbstractRevision::MODERATED_SUPPRESSED, |
857 | ] |
858 | ); |
859 | } |
860 | |
861 | /** |
862 | * @param Title|null $title |
863 | * @param UUID|null $workflowId |
864 | * @return Anchor |
865 | */ |
866 | public function newTopicAction( ?Title $title = null, ?UUID $workflowId = null ) { |
867 | return new Anchor( |
868 | wfMessage( 'flow-newtopic-start-placeholder' ), |
869 | // resolveTitle doesn't accept null uuid |
870 | $this->resolveTitle( $title, $workflowId ), |
871 | [ |
872 | 'action' => 'new-topic' |
873 | ] |
874 | ); |
875 | } |
876 | |
877 | public function thankAction( UUID $postId ) { |
878 | $sender = RequestContext::getMain()->getUser(); |
879 | $recipient = $sender; // Default to current user's gender if we can't find the recipient |
880 | $postCollection = PostCollection::newFromId( $postId ); |
881 | $postRevision = $postCollection->getLastRevision(); |
882 | $recipient = $postRevision->getCreatorTuple()->createUser(); |
883 | |
884 | return new Anchor( |
885 | wfMessage( 'flow-thank-link', $sender, $recipient )->text(), |
886 | SpecialPage::getTitleFor( 'Thanks', 'Flow/' . $postId->getAlphadecimal() ), |
887 | [], |
888 | null, |
889 | wfMessage( 'flow-thank-link-title', $sender, $recipient )->text() |
890 | ); |
891 | } |
892 | |
893 | /** |
894 | * Mark a revision as patrolled |
895 | * |
896 | * @param Title|null $title |
897 | * @param UUID $workflowId |
898 | * @param RecentChange $rc |
899 | * @param string $token |
900 | * @return Anchor |
901 | * @throws FlowException |
902 | * @throws InvalidInputException |
903 | */ |
904 | public function markRevisionPatrolledAction( |
905 | ?Title $title, |
906 | UUID $workflowId, |
907 | RecentChange $rc, |
908 | $token |
909 | ) { |
910 | return new Anchor( |
911 | wfMessage( 'flow-mark-revision-patrolled-link-text' )->text(), |
912 | $this->resolveTitle( $title, $workflowId ), |
913 | [ |
914 | 'action' => 'markpatrolled', |
915 | 'rcid' => $rc->getAttribute( 'rc_id' ), |
916 | 'token' => $token, |
917 | ] |
918 | ); |
919 | } |
920 | } |