Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 121 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
ThreadPermalinkView | |
0.00% |
0 / 121 |
|
0.00% |
0 / 8 |
1056 | |
0.00% |
0 / 1 |
customizeNavigation | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
customizeThreadNavigation | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
72 | |||
getCustomTabs | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
30 | |||
noSuchRevision | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
showMissingThreadPage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getSubtitle | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
20 | |||
__construct | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
show | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
110 |
1 | <?php |
2 | |
3 | use MediaWiki\MediaWikiServices; |
4 | use MediaWiki\SpecialPage\SpecialPage; |
5 | use MediaWiki\Title\Title; |
6 | |
7 | class ThreadPermalinkView extends LqtView { |
8 | /** @var Thread */ |
9 | protected $thread; |
10 | |
11 | public function customizeNavigation( $skin, &$links ) { |
12 | self::customizeThreadNavigation( $skin, $links, $this ); |
13 | } |
14 | |
15 | /** |
16 | * @param Skin $skin |
17 | * @param array[] &$links |
18 | * @param ThreadPermalinkView|ThreadProtectionFormView $view |
19 | */ |
20 | public static function customizeThreadNavigation( $skin, &$links, $view ) { |
21 | $tempTitle = Title::makeTitle( NS_LQT_THREAD, 'A' ); |
22 | $talkKey = $tempTitle->getNamespaceKey( '' ) . '_talk'; |
23 | |
24 | if ( !$view->thread ) { |
25 | unset( $links['views']['edit'] ); |
26 | unset( $links['views']['history'] ); |
27 | |
28 | $links['actions'] = []; |
29 | |
30 | unset( $links['namespaces'][$talkKey] ); |
31 | return; |
32 | } |
33 | |
34 | // Insert 'article' and 'discussion' namespace-tabs |
35 | $new_nstabs = self::getCustomTabs( $view ); |
36 | |
37 | $nstabs =& $links['namespaces']; |
38 | |
39 | unset( $nstabs[$talkKey] ); |
40 | $nstabs = $new_nstabs + $nstabs; |
41 | |
42 | // Remove some views. |
43 | $views =& $links['views']; |
44 | unset( $views['viewsource'] ); |
45 | unset( $views['edit'] ); |
46 | |
47 | $subpageTitle = $view->thread->title(); |
48 | // Re-point move, delete and history actions |
49 | $actions =& $links['actions']; |
50 | if ( isset( $actions['move'] ) && $subpageTitle ) { |
51 | $subpage = $subpageTitle->getPrefixedText(); |
52 | $actions['move']['href'] = |
53 | SpecialPage::getTitleFor( 'MoveThread', $subpage )->getLocalURL(); |
54 | } |
55 | |
56 | if ( isset( $actions['delete'] ) && $subpageTitle ) { |
57 | $actions['delete']['href'] = |
58 | $subpageTitle->getLocalURL( 'action=delete' ); |
59 | } |
60 | |
61 | if ( isset( $views['history'] ) ) { |
62 | $views['history']['href'] = |
63 | self::permalinkUrl( $view->thread, 'thread_history' ); |
64 | if ( $view->methodApplies( 'thread_history' ) ) { |
65 | $views['history']['class'] = 'selected'; |
66 | } |
67 | } |
68 | } |
69 | |
70 | /** |
71 | * Pre-generates the tabs to be included, for customizeNavigation to insert in the appropriate |
72 | * place |
73 | * |
74 | * @param ThreadPermalinkView|ThreadProtectionFormView $view |
75 | * @return array[] |
76 | */ |
77 | private static function getCustomTabs( $view ) { |
78 | $tabs = []; |
79 | |
80 | $articleTitle = $view->thread->getTitle()->getSubjectPage(); |
81 | $talkTitle = $view->thread->getTitle()->getTalkPage(); |
82 | |
83 | $articleClasses = []; |
84 | if ( !$articleTitle->exists() ) { |
85 | $articleClasses[] = 'new'; |
86 | } |
87 | if ( $articleTitle->equals( $view->thread->getTitle() ) ) { |
88 | $articleClasses[] = 'selected'; |
89 | } |
90 | |
91 | $talkClasses = []; |
92 | if ( !$talkTitle->exists() ) { |
93 | $talkClasses[] = 'new'; |
94 | } |
95 | |
96 | if ( wfMessage( $articleTitle->getNamespaceKey() )->exists() ) { |
97 | $articleNamespaceText = wfMessage( $articleTitle->getNamespaceKey() )->text(); |
98 | } else { |
99 | $articleNamespaceText = $articleTitle->getNsText(); |
100 | } |
101 | |
102 | $tabs['article'] = |
103 | [ |
104 | 'text' => $articleNamespaceText, |
105 | 'href' => $articleTitle->getLocalURL(), |
106 | 'class' => implode( ' ', $articleClasses ), |
107 | ]; |
108 | |
109 | $tabs['lqt_talk'] = |
110 | [ |
111 | // talkpage certainly exists since this thread is from it. |
112 | 'text' => wfMessage( 'talk' )->text(), |
113 | 'href' => $talkTitle->getLocalURL(), |
114 | 'class' => implode( ' ', $talkClasses ), |
115 | ]; |
116 | |
117 | return $tabs; |
118 | } |
119 | |
120 | public function noSuchRevision() { |
121 | $this->output->addWikiMsg( 'lqt_nosuchrevision' ); |
122 | } |
123 | |
124 | public function showMissingThreadPage() { |
125 | $this->output->setPageTitleMsg( wfMessage( 'lqt_nosuchthread_title' ) ); |
126 | $this->output->addWikiMsg( 'lqt_nosuchthread' ); |
127 | } |
128 | |
129 | /** @return string|null HTML or null */ |
130 | public function getSubtitle() { |
131 | $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer(); |
132 | $fragment = '#' . $this->anchorName( $this->thread ); |
133 | |
134 | $talkpage = $this->thread->getTitle(); |
135 | if ( !$talkpage ) { |
136 | return null; |
137 | } |
138 | $talkpage->setFragment( $fragment ); |
139 | $talkpage_link = $linkRenderer->makeLink( $talkpage ); |
140 | $topmostTitle = $this->thread->topmostThread()->title(); |
141 | if ( $this->thread->hasSuperthread() && $topmostTitle ) { |
142 | $topmostTitle->setFragment( $fragment ); |
143 | |
144 | $linkText = new HtmlArmor( wfMessage( 'lqt_discussion_link' )->parse() ); |
145 | $permalink = $linkRenderer->makeLink( $topmostTitle, $linkText ); |
146 | $message = wfMessage( 'lqt_fragment' ) |
147 | ->rawParams( $permalink, $talkpage_link ) |
148 | ->parse(); |
149 | } else { |
150 | $message = wfMessage( 'lqt_from_talk' )->rawParams( $talkpage_link )->parse(); |
151 | } |
152 | return $message; |
153 | } |
154 | |
155 | public function __construct( &$output, &$article, &$title, &$user, &$request ) { |
156 | parent::__construct( $output, $article, $title, $user, $request ); |
157 | |
158 | $t = Threads::withRoot( $this->article->getPage() ); |
159 | |
160 | $this->thread = $t; |
161 | if ( !$t ) { |
162 | return; |
163 | } |
164 | |
165 | // $this->article gets saved to thread_article, so we want it to point to the |
166 | // subject page associated with the talkpage, always, not the permalink url. |
167 | $this->article = $t->article(); # for creating reply threads. |
168 | } |
169 | |
170 | public function show() { |
171 | if ( !$this->thread ) { |
172 | $this->showMissingThreadPage(); |
173 | return false; |
174 | } |
175 | |
176 | if ( $this->request->getBool( 'lqt_inline' ) ) { |
177 | $this->doInlineEditForm(); |
178 | return false; |
179 | } |
180 | |
181 | // Handle action=edit stuff |
182 | if ( $this->request->getVal( 'action' ) == 'edit' && |
183 | !$this->request->getVal( 'lqt_method', null ) ) { |
184 | // Rewrite to lqt_method = edit |
185 | $this->request->setVal( 'lqt_method', 'edit' ); |
186 | $this->request->setVal( 'lqt_operand', $this->thread->id() ); |
187 | } |
188 | |
189 | $topmostThreadTitle = $this->thread->topmostThread()->title(); |
190 | if ( $topmostThreadTitle ) { |
191 | // Expose feed links. |
192 | global $wgFeedClasses; |
193 | $thread = $topmostThreadTitle->getPrefixedText(); |
194 | $apiParams = [ |
195 | 'action' => 'feedthreads', |
196 | 'type' => 'replies|newthreads', |
197 | 'thread' => $thread |
198 | ]; |
199 | $urlPrefix = wfScript( 'api' ) . '?'; |
200 | foreach ( $wgFeedClasses as $format => $class ) { |
201 | $theseParams = $apiParams + [ 'feedformat' => $format ]; |
202 | $url = $urlPrefix . wfArrayToCgi( $theseParams ); |
203 | $this->output->addFeedLink( $format, $url ); |
204 | } |
205 | } |
206 | |
207 | $subtitle = $this->getSubtitle(); |
208 | if ( $subtitle !== null ) { |
209 | $this->output->setSubtitle( $subtitle ); |
210 | } |
211 | |
212 | if ( $this->methodApplies( 'summarize' ) ) { |
213 | $this->showSummarizeForm( $this->thread ); |
214 | } elseif ( $this->methodApplies( 'split' ) ) { |
215 | // @FIXME Method does not exists |
216 | // @phan-suppress-next-line PhanUndeclaredMethod |
217 | $this->showSplitForm( $this->thread ); |
218 | } |
219 | |
220 | $this->showThread( $this->thread, 1, 1, [ 'maxDepth' => -1, 'maxCount' => -1 ] ); |
221 | |
222 | $services = MediaWikiServices::getInstance(); |
223 | $langConv = $services |
224 | ->getLanguageConverterFactory() |
225 | ->getLanguageConverter( $services->getContentLanguage() ); |
226 | $this->output->setPageTitle( $langConv->convert( $this->thread->subject() ) ); |
227 | return false; |
228 | } |
229 | } |