Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 120 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
LqtDispatch | |
0.00% |
0 / 120 |
|
0.00% |
0 / 8 |
3422 | |
0.00% |
0 / 1 |
talkpageMain | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
210 | |||
threadPermalinkMain | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
182 | |||
threadSummaryMain | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
isLqtPage | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
132 | |||
getUserLqtOverride | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
56 | |||
tryPage | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
onSkinTemplateNavigation | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
onPageContentLanguage | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | |
3 | use MediaWiki\Context\RequestContext; |
4 | use MediaWiki\MediaWikiServices; |
5 | use MediaWiki\Output\OutputPage; |
6 | use MediaWiki\Request\WebRequest; |
7 | use MediaWiki\Title\Title; |
8 | use MediaWiki\User\User; |
9 | |
10 | class LqtDispatch { |
11 | /** @var (int|null)[] static cache of per-page LiquidThreads activation setting */ |
12 | public static $userLqtOverride = []; |
13 | /** @var LqtView|null */ |
14 | public static $primaryView = null; |
15 | |
16 | /** |
17 | * @param OutputPage &$output |
18 | * @param Article &$article |
19 | * @param Title &$title |
20 | * @param User &$user |
21 | * @param WebRequest &$request |
22 | * @return bool |
23 | */ |
24 | public static function talkpageMain( &$output, &$article, &$title, &$user, &$request ) { |
25 | // We are given a talkpage article and title. Fire up a TalkpageView |
26 | |
27 | if ( $title->getNamespace() == NS_LQT_THREAD + 1 /* talk page */ ) { |
28 | // Threads don't have talk pages; redirect to the thread page. |
29 | $output->redirect( $title->getSubjectPage()->getLocalURL() ); |
30 | return false; |
31 | } |
32 | |
33 | // If we came here from a red-link, redirect to the thread page. |
34 | $redlink = $request->getCheck( 'redlink' ) && |
35 | $request->getText( 'action' ) == 'edit'; |
36 | if ( $redlink ) { |
37 | $output->redirect( $title->getLocalURL() ); |
38 | return false; |
39 | } |
40 | |
41 | $action = $request->getVal( 'action', 'view' ); |
42 | |
43 | // Actions handled by LQT. |
44 | $lqt_actions = [ 'view', 'protect', 'unprotect' ]; |
45 | |
46 | $lqt_action = $request->getVal( 'lqt_method' ); |
47 | if ( $action == 'edit' && $request->getVal( 'section' ) == 'new' ) { |
48 | // Hijack section=new for "new thread". |
49 | $request->setVal( 'lqt_method', 'talkpage_new_thread' ); |
50 | $request->setVal( 'section', '' ); |
51 | |
52 | $viewname = TalkpageView::class; |
53 | } elseif ( !$lqt_action && ( |
54 | ( !in_array( $action, $lqt_actions ) && $action ) || |
55 | $request->getVal( 'diff', null ) !== null || |
56 | $request->getVal( 'oldid', null ) !== null ) |
57 | ) { |
58 | // Pass through wrapper |
59 | $viewname = TalkpageHeaderView::class; |
60 | } elseif ( $action == 'protect' || $action == 'unprotect' ) { |
61 | // Pass through wrapper |
62 | $viewname = ThreadProtectionFormView::class; |
63 | } elseif ( $lqt_action == 'talkpage_history' ) { |
64 | $viewname = TalkpageHistoryView::class; |
65 | } else { |
66 | $viewname = TalkpageView::class; |
67 | } |
68 | |
69 | Thread::$titleCacheById[$article->getPage()->getId()] = $title; |
70 | |
71 | /** @var LqtView $view */ |
72 | $view = new $viewname( $output, $article, $title, $user, $request ); |
73 | self::$primaryView = $view; |
74 | return $view->show(); |
75 | } |
76 | |
77 | /** |
78 | * @param OutputPage &$output |
79 | * @param Article &$article |
80 | * @param Title &$title |
81 | * @param User &$user |
82 | * @param WebRequest &$request |
83 | * @return bool |
84 | */ |
85 | public static function threadPermalinkMain( &$output, &$article, &$title, &$user, &$request ) { |
86 | $action = $request->getVal( 'action' ); |
87 | $lqt_method = $request->getVal( 'lqt_method' ); |
88 | |
89 | if ( $lqt_method == 'thread_history' ) { |
90 | $viewname = ThreadHistoryListingView::class; |
91 | } elseif ( $lqt_method == 'diff' ) { |
92 | // this clause and the next must be in this order. |
93 | $viewname = ThreadDiffView::class; |
94 | } elseif ( $action == 'history' |
95 | || $request->getVal( 'diff', null ) !== null ) { |
96 | $viewname = IndividualThreadHistoryView::class; |
97 | } elseif ( $action == 'protect' || $action == 'unprotect' ) { |
98 | $viewname = ThreadProtectionFormView::class; |
99 | } elseif ( $request->getVal( 'lqt_oldid', null ) !== null ) { |
100 | $viewname = ThreadHistoricalRevisionView::class; |
101 | } elseif ( $action == 'watch' || $action == 'unwatch' ) { |
102 | $viewname = ThreadWatchView::class; |
103 | } elseif ( $action == 'delete' || $action == 'rollback' || $action == 'markpatrolled' ) { |
104 | return true; |
105 | } else { |
106 | $viewname = ThreadPermalinkView::class; |
107 | } |
108 | |
109 | /** @var LqtView $view */ |
110 | $view = new $viewname( $output, $article, $title, $user, $request ); |
111 | self::$primaryView = $view; |
112 | return $view->show(); |
113 | } |
114 | |
115 | public static function threadSummaryMain( &$output, &$article, &$title, &$user, &$request ) { |
116 | $view = new SummaryPageView( $output, $article, $title, $user, $request ); |
117 | self::$primaryView = $view; |
118 | return $view->show(); |
119 | } |
120 | |
121 | /** |
122 | * @param Title|null $title |
123 | * @return bool|null |
124 | */ |
125 | public static function isLqtPage( $title ) { |
126 | if ( !$title ) { |
127 | return false; |
128 | } |
129 | // Ignore it if it's a thread or a summary, makes no sense to have LiquidThreads there. |
130 | if ( $title->getNamespace() == NS_LQT_THREAD || $title->getNamespace() == NS_LQT_SUMMARY ) { |
131 | return false; |
132 | } |
133 | |
134 | global $wgLqtPages, $wgLqtTalkPages, $wgLqtNamespaces; |
135 | $isTalkPage = ( $title->isTalkPage() && $wgLqtTalkPages ) || |
136 | in_array( $title->getPrefixedText(), $wgLqtPages ); |
137 | |
138 | if ( in_array( $title->getNamespace(), $wgLqtNamespaces ) ) { |
139 | $isTalkPage = true; |
140 | } |
141 | |
142 | if ( $title->exists() ) { |
143 | $override = self::getUserLqtOverride( $title ); |
144 | } else { |
145 | $override = null; |
146 | } |
147 | |
148 | global $wgLiquidThreadsAllowUserControl; |
149 | if ( $override !== null && $wgLiquidThreadsAllowUserControl ) { |
150 | $isTalkPage = $override; |
151 | } |
152 | |
153 | $isTalkPage = $isTalkPage && !$title->isRedirect(); |
154 | |
155 | MediaWikiServices::getInstance()->getHookContainer() |
156 | ->run( 'LiquidThreadsIsLqtPage', [ $title, &$isTalkPage ] ); |
157 | |
158 | return $isTalkPage; |
159 | } |
160 | |
161 | /** |
162 | * @param Title $title |
163 | * @return null|int |
164 | */ |
165 | public static function getUserLqtOverride( $title ) { |
166 | if ( !is_object( $title ) ) { |
167 | return null; |
168 | } |
169 | |
170 | global $wgLiquidThreadsAllowUserControl; |
171 | |
172 | if ( !$wgLiquidThreadsAllowUserControl ) { |
173 | return null; |
174 | } |
175 | |
176 | global $wgLiquidThreadsAllowUserControlNamespaces; |
177 | |
178 | $namespaces = $wgLiquidThreadsAllowUserControlNamespaces; |
179 | |
180 | if ( $namespaces !== null && !in_array( $title->getNamespace(), $namespaces ) ) { |
181 | return null; |
182 | } |
183 | |
184 | $articleid = $title->getArticleID(); |
185 | |
186 | // Check instance cache. |
187 | if ( array_key_exists( $articleid, self::$userLqtOverride ) ) { |
188 | return self::$userLqtOverride[$articleid]; |
189 | } |
190 | |
191 | // Load from the database. |
192 | $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase(); |
193 | |
194 | $row = $dbr->newSelectQueryBuilder() |
195 | ->select( 'pp_value' ) |
196 | ->from( 'page_props' ) |
197 | ->where( [ |
198 | 'pp_propname' => 'use-liquid-threads', |
199 | 'pp_page' => $articleid |
200 | ] ) |
201 | ->caller( __METHOD__ ) |
202 | ->fetchRow(); |
203 | |
204 | if ( $row ) { |
205 | $dbVal = $row->pp_value; |
206 | |
207 | self::$userLqtOverride[$articleid] = $dbVal; |
208 | return $dbVal; |
209 | } else { |
210 | // Negative caching. |
211 | self::$userLqtOverride[$articleid] = null; |
212 | return null; |
213 | } |
214 | } |
215 | |
216 | /** |
217 | * If the page we receive is a LiquidThreads page of any kind, process it |
218 | * as needed and return True. If it's a normal, non-liquid page, return false. |
219 | * @param OutputPage $output |
220 | * @param Article $article |
221 | * @param Title $title |
222 | * @param User $user |
223 | * @param WebRequest $request |
224 | * @return bool |
225 | */ |
226 | public static function tryPage( $output, $article, $title, $user, $request ) { |
227 | if ( self::isLqtPage( $title ) ) { |
228 | // LiquidThreads pages, Talk:X etc |
229 | return self::talkpageMain( $output, $article, $title, $user, $request ); |
230 | } elseif ( $title->getNamespace() == NS_LQT_THREAD ) { |
231 | // Thread permalink pages, Thread:X |
232 | return self::threadPermalinkMain( $output, $article, $title, $user, $request ); |
233 | } elseif ( $title->getNamespace() == NS_LQT_SUMMARY ) { |
234 | // Summary pages, Summary:X |
235 | return self::threadSummaryMain( $output, $article, $title, $user, $request ); |
236 | } |
237 | return true; |
238 | } |
239 | |
240 | public static function onSkinTemplateNavigation( $skinTemplate, &$links ) { |
241 | if ( !self::$primaryView ) { |
242 | return true; |
243 | } |
244 | |
245 | self::$primaryView->customizeNavigation( $skinTemplate, $links ); |
246 | |
247 | return true; |
248 | } |
249 | |
250 | /** |
251 | * Most stuff is in the user language. |
252 | * @param Title $title |
253 | * @param Language &$pageLang |
254 | */ |
255 | public static function onPageContentLanguage( $title, &$pageLang ) { |
256 | global $wgRequest; |
257 | $method = $wgRequest->getVal( 'lqt_method' ); |
258 | $oldid = $wgRequest->getVal( 'lqt_oldid' ); |
259 | if ( $title->inNamespace( NS_LQT_THREAD ) ) { |
260 | $pageLang = RequestContext::getMain()->getLanguage(); |
261 | } elseif ( $method == 'diff' ) { |
262 | # the diff contains the wikitext, which is in the content language |
263 | return; |
264 | } elseif ( $method == 'talkpage_history' || $method == 'thread_history' || $oldid != '' ) { |
265 | $pageLang = RequestContext::getMain()->getLanguage(); |
266 | } |
267 | } |
268 | } |