Index: trunk/extensions/LiquidThreads/migrateDatabase.php |
— | — | @@ -6,26 +6,28 @@ |
7 | 7 | require_once ( getenv( 'MW_INSTALL_PATH' ) !== false |
8 | 8 | ? getenv( 'MW_INSTALL_PATH' ) . "/maintenance/commandLine.inc" |
9 | 9 | : dirname( __FILE__ ) . '/../../maintenance/commandLine.inc' ); |
10 | | - |
| 10 | + |
11 | 11 | $db = wfGetDB( DB_MASTER ); |
12 | 12 | |
13 | 13 | $wgTitle = Title::makeTitleSafe( NS_SPECIAL, 'LiquidThreads' ); |
14 | 14 | |
15 | 15 | // Do database updates |
16 | | -$threadFieldUpdates = array( 'thread_article_namespace' => 'split-thread_article.sql', |
17 | | - 'thread_article_title' => 'split-thread_article.sql', |
18 | | - 'thread_ancestor' => 'normalise-ancestry.sql', |
19 | | - 'thread_parent' => 'normalise-ancestry.sql', |
20 | | - 'thread_modified' => 'split-timestamps.sql', |
21 | | - 'thread_created' => 'split-timestamps.sql', |
22 | | - 'thread_editedness' => 'store-editedness.sql', |
23 | | - 'thread_subject' => 'store_subject-author.sql', |
24 | | - 'thread_author_id' => 'store_subject-author.sql', |
25 | | - 'thread_author_name' => 'store_subject-author.sql', |
26 | | - 'thread_sortkey' => 'new-sortkey.sql', |
27 | | - 'thread_replies' => 'store_reply_count.sql', |
28 | | - 'thread_article_id' => 'store_article_id.sql', |
29 | | - ); |
| 16 | +$threadFieldUpdates = array( |
| 17 | + 'thread_article_namespace' => 'split-thread_article.sql', |
| 18 | + 'thread_article_title' => 'split-thread_article.sql', |
| 19 | + 'thread_ancestor' => 'normalise-ancestry.sql', |
| 20 | + 'thread_parent' => 'normalise-ancestry.sql', |
| 21 | + 'thread_modified' => 'split-timestamps.sql', |
| 22 | + 'thread_created' => 'split-timestamps.sql', |
| 23 | + 'thread_editedness' => 'store-editedness.sql', |
| 24 | + 'thread_subject' => 'store_subject-author.sql', |
| 25 | + 'thread_author_id' => 'store_subject-author.sql', |
| 26 | + 'thread_author_name' => 'store_subject-author.sql', |
| 27 | + 'thread_sortkey' => 'new-sortkey.sql', |
| 28 | + 'thread_replies' => 'store_reply_count.sql', |
| 29 | + 'thread_article_id' => 'store_article_id.sql', |
| 30 | +); |
| 31 | + |
30 | 32 | $threadIndexUpdates = array( 'thread_summary_page' => 'index-summary_page.sql' ); |
31 | 33 | |
32 | 34 | $newTableUpdates = array( 'thread_history' => 'thread_history_table.sql' ); |
— | — | @@ -48,31 +50,32 @@ |
49 | 51 | } |
50 | 52 | } |
51 | 53 | |
52 | | - |
53 | 54 | // Batch lazy updates |
54 | 55 | $upTo = $lastUpTo = 0; |
55 | 56 | |
56 | 57 | do { |
57 | 58 | $lastUpTo = $upTo; |
58 | | - |
| 59 | + |
59 | 60 | $db->begin(); |
60 | | - |
| 61 | + |
61 | 62 | // Read 500 rows |
62 | | - $res = $db->select( 'thread', '*', array( 'thread_id>' . $db->addQuotes( $upTo ) ), |
63 | | - 'lqt-update-script', array( 'LIMIT' => 500, 'FOR UPDATE', |
64 | | - 'ORDER BY' => 'thread_id asc' ) ); |
65 | | - |
| 63 | + $res = $db->select( |
| 64 | + 'thread', '*', array( 'thread_id>' . $db->addQuotes( $upTo ) ), |
| 65 | + 'lqt-update-script', |
| 66 | + array( 'LIMIT' => 500, 'FOR UPDATE', 'ORDER BY' => 'thread_id asc' ) |
| 67 | + ); |
| 68 | + |
66 | 69 | $threads = Threads::loadFromResult( $res, $db ); |
67 | | - |
| 70 | + |
68 | 71 | foreach ( $threads as $thread ) { |
69 | 72 | $thread->doLazyUpdates(); |
70 | 73 | $thread->updateHistory(); |
71 | | - |
| 74 | + |
72 | 75 | if ( $thread->id() > $upTo ) { |
73 | 76 | $upTo = $thread->id(); |
74 | 77 | } |
75 | 78 | } |
76 | | - |
| 79 | + |
77 | 80 | $db->commit(); |
78 | | - |
| 81 | + |
79 | 82 | } while ( $lastUpTo != $upTo ); |
Index: trunk/extensions/LiquidThreads/api/ApiThreadAction.php |
— | — | @@ -1,11 +1,10 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class ApiThreadAction extends ApiBase { |
5 | | - |
6 | 5 | public function getDescription() { |
7 | 6 | return 'Allows actions to be taken on threads and posts in threaded discussions.'; |
8 | 7 | } |
9 | | - |
| 8 | + |
10 | 9 | public function getActions() { |
11 | 10 | return array( |
12 | 11 | 'markread' => 'actionMarkRead', |
— | — | @@ -18,7 +17,7 @@ |
19 | 18 | 'setsortkey' => 'actionSetSortkey', |
20 | 19 | ); |
21 | 20 | } |
22 | | - |
| 21 | + |
23 | 22 | protected function getParamDescription() { |
24 | 23 | return array( |
25 | 24 | 'thread' => 'A list (pipe-separated) of thread IDs or titles to act on', |
— | — | @@ -29,36 +28,35 @@ |
30 | 29 | 'reason' => 'If applicable, the reason/summary for the action', |
31 | 30 | 'newparent' => 'If merging a thread, the ID or title for its new parent', |
32 | 31 | 'text' => 'The text of the post to create', |
33 | | - 'render' => 'If set, on post/reply methods, the top-level thread '. |
| 32 | + 'render' => 'If set, on post/reply methods, the top-level thread ' . |
34 | 33 | 'after the change will be rendered and returned in the result.', |
35 | 34 | 'bump' => 'If set, overrides default behaviour as to whether or not to ', |
36 | | - "increase the thread's sort key. If true, sets it to current ". |
37 | | - "timestamp. If false, does not set it. Default depends on ". |
38 | | - "the action being taken. Presently only works for newthread ". |
| 35 | + "increase the thread's sort key. If true, sets it to current " . |
| 36 | + "timestamp. If false, does not set it. Default depends on " . |
| 37 | + "the action being taken. Presently only works for newthread " . |
39 | 38 | "and reply actions.", |
40 | | - 'sortkey' => "Specifies the timestamp to which to set a thread's ". |
41 | | - "sort key. Must be in the form YYYYMMddhhmmss, ". |
| 39 | + 'sortkey' => "Specifies the timestamp to which to set a thread's " . |
| 40 | + "sort key. Must be in the form YYYYMMddhhmmss, " . |
42 | 41 | "a unix timestamp or 'now'.", |
43 | | - 'signature' => 'Specifies the signature to use for that post. Can be '. |
| 42 | + 'signature' => 'Specifies the signature to use for that post. Can be ' . |
44 | 43 | 'NULL to specify the default signature', |
45 | 44 | ); |
46 | 45 | } |
47 | | - |
| 46 | + |
48 | 47 | public function getExamples() { |
49 | 48 | return array( |
50 | | - |
51 | 49 | ); |
52 | 50 | } |
53 | | - |
| 51 | + |
54 | 52 | public function getAllowedParams() { |
55 | 53 | return array( |
56 | 54 | 'thread' => array( |
57 | | - ApiBase::PARAM_ISMULTI => true, |
58 | | - ), |
| 55 | + ApiBase::PARAM_ISMULTI => true, |
| 56 | + ), |
59 | 57 | 'talkpage' => null, |
60 | 58 | 'threadaction' => array( |
61 | | - ApiBase::PARAM_TYPE => array_keys( $this->getActions() ), |
62 | | - ), |
| 59 | + ApiBase::PARAM_TYPE => array_keys( $this->getActions() ), |
| 60 | + ), |
63 | 61 | 'token' => null, |
64 | 62 | 'subject' => null, |
65 | 63 | 'reason' => null, |
— | — | @@ -70,67 +68,67 @@ |
71 | 69 | 'signature' => null, |
72 | 70 | ); |
73 | 71 | } |
74 | | - |
| 72 | + |
75 | 73 | public function mustBePosted() { return true; } |
76 | 74 | |
77 | 75 | public function isWriteMode() { |
78 | 76 | return true; |
79 | 77 | } |
80 | | - |
| 78 | + |
81 | 79 | public function execute() { |
82 | 80 | $params = $this->extractRequestParams(); |
83 | | - |
| 81 | + |
84 | 82 | global $wgUser; |
85 | | - |
| 83 | + |
86 | 84 | if ( empty( $params['token'] ) || |
87 | 85 | !$wgUser->matchEditToken( $params['token'] ) ) { |
88 | 86 | $this->dieUsage( 'sessionfailure' ); |
89 | 87 | return; |
90 | 88 | } |
91 | | - |
| 89 | + |
92 | 90 | if ( empty( $params['threadaction'] ) ) { |
93 | 91 | $this->dieUsage( 'missing-param', 'action' ); |
94 | 92 | return; |
95 | 93 | } |
96 | | - |
| 94 | + |
97 | 95 | $allowedAllActions = array( 'markread' ); |
98 | 96 | $action = $params['threadaction']; |
99 | | - |
| 97 | + |
100 | 98 | // Pull the threads from the parameters |
101 | 99 | $threads = array(); |
102 | 100 | if ( !empty( $params['thread'] ) ) { |
103 | | - foreach( $params['thread'] as $thread ) { |
| 101 | + foreach ( $params['thread'] as $thread ) { |
104 | 102 | $threadObj = null; |
105 | 103 | if ( is_numeric( $thread ) ) { |
106 | 104 | $threadObj = Threads::withId( $thread ); |
107 | 105 | } elseif ( $thread == 'all' && |
108 | 106 | in_array( $action, $allowedAllActions ) ) { |
109 | | - $threads = array('all'); |
| 107 | + $threads = array( 'all' ); |
110 | 108 | } else { |
111 | 109 | $title = Title::newFromText( $thread ); |
112 | 110 | $article = new Article( $title ); |
113 | 111 | $threadObj = Threads::withRoot( $article ); |
114 | 112 | } |
115 | | - |
| 113 | + |
116 | 114 | if ( $threadObj instanceof Thread ) { |
117 | 115 | $threads[] = $threadObj; |
118 | 116 | } |
119 | 117 | } |
120 | 118 | } |
121 | | - |
| 119 | + |
122 | 120 | // Find the appropriate module |
123 | 121 | $actions = $this->getActions(); |
124 | | - |
| 122 | + |
125 | 123 | $method = $actions[$action]; |
126 | | - |
| 124 | + |
127 | 125 | call_user_func_array( array( $this, $method ), array( $threads, $params ) ); |
128 | 126 | } |
129 | | - |
| 127 | + |
130 | 128 | public function actionMarkRead( $threads, $params ) { |
131 | 129 | global $wgUser; |
132 | | - |
| 130 | + |
133 | 131 | $result = array(); |
134 | | - |
| 132 | + |
135 | 133 | if ( in_array( 'all', $threads ) ) { |
136 | 134 | NewMessages::markAllReadByUser( $wgUser ); |
137 | 135 | $result[] = array( |
— | — | @@ -139,122 +137,119 @@ |
140 | 138 | 'threads' => 'all', |
141 | 139 | ); |
142 | 140 | } else { |
143 | | - foreach( $threads as $t ) { |
| 141 | + foreach ( $threads as $t ) { |
144 | 142 | NewMessages::markThreadAsReadByUser( $t, $wgUser ); |
145 | | - $result[] = |
146 | | - array( |
147 | | - 'result' => 'Success', |
148 | | - 'action' => 'markread', |
149 | | - 'id' => $t->id(), |
150 | | - 'title' => $t->title()->getPrefixedText() |
151 | | - ); |
| 143 | + $result[] = array( |
| 144 | + 'result' => 'Success', |
| 145 | + 'action' => 'markread', |
| 146 | + 'id' => $t->id(), |
| 147 | + 'title' => $t->title()->getPrefixedText() |
| 148 | + ); |
152 | 149 | } |
153 | 150 | } |
154 | | - |
| 151 | + |
155 | 152 | $this->getResult()->setIndexedTagName( $result, 'thread' ); |
156 | 153 | $this->getResult()->addValue( null, 'threadactions', $result ); |
157 | 154 | } |
158 | | - |
| 155 | + |
159 | 156 | public function actionMarkUnread( $threads, $params ) { |
160 | 157 | global $wgUser; |
161 | | - |
| 158 | + |
162 | 159 | $result = array(); |
163 | | - |
164 | | - foreach( $threads as $t ) { |
| 160 | + |
| 161 | + foreach ( $threads as $t ) { |
165 | 162 | NewMessages::markThreadAsUnreadByUser( $t, $wgUser ); |
166 | | - |
167 | | - $result[] = |
168 | | - array( |
169 | | - 'result' => 'Success', |
170 | | - 'action' => 'markunread', |
171 | | - 'id' => $t->id(), |
172 | | - 'title' => $t->title()->getPrefixedText() |
173 | | - ); |
| 163 | + |
| 164 | + $result[] = array( |
| 165 | + 'result' => 'Success', |
| 166 | + 'action' => 'markunread', |
| 167 | + 'id' => $t->id(), |
| 168 | + 'title' => $t->title()->getPrefixedText() |
| 169 | + ); |
174 | 170 | } |
175 | | - |
176 | | - |
| 171 | + |
| 172 | + |
177 | 173 | $this->getResult()->setIndexedTagName( $result, 'thread' ); |
178 | 174 | $this->getResult()->addValue( null, 'threadaction', $result ); |
179 | 175 | } |
180 | | - |
| 176 | + |
181 | 177 | public function actionSplit( $threads, $params ) { |
182 | 178 | global $wgUser; |
183 | | - |
184 | | - if ( count($threads) > 1 ) { |
| 179 | + |
| 180 | + if ( count( $threads ) > 1 ) { |
185 | 181 | $this->dieUsage( 'You may only split one thread at a time', |
186 | 182 | 'too-many-threads' ); |
187 | 183 | return; |
188 | | - } elseif ( count($threads) < 1 ) { |
| 184 | + } elseif ( count( $threads ) < 1 ) { |
189 | 185 | $this->dieUsage( 'You must specify a thread to split', |
190 | 186 | 'no-specified-threads' ); |
191 | 187 | return; |
192 | 188 | } |
193 | | - |
| 189 | + |
194 | 190 | $thread = array_pop( $threads ); |
195 | | - |
| 191 | + |
196 | 192 | if ( $thread->isTopmostThread() ) { |
197 | 193 | $this->dieUsage( 'This thread is already a top-level thread.', |
198 | 194 | 'already-top-level' ); |
199 | 195 | } |
200 | | - |
| 196 | + |
201 | 197 | $title = null; |
202 | 198 | $article = $thread->article(); |
203 | | - if ( empty($params['subject'] ) || |
| 199 | + if ( empty( $params['subject'] ) || |
204 | 200 | ! Thread::validateSubject( $params['subject'], $title, null, $article ) ) { |
205 | | - |
| 201 | + |
206 | 202 | $this->dieUsage( 'No subject, or an invalid subject, was specified', |
207 | 203 | 'no-valid-subject' ); |
208 | 204 | } |
209 | | - |
| 205 | + |
210 | 206 | $subject = $params['subject']; |
211 | | - |
| 207 | + |
212 | 208 | // Pull a reason, if applicable. |
213 | 209 | $reason = ''; |
214 | | - if ( !empty($params['reason']) ) { |
| 210 | + if ( !empty( $params['reason'] ) ) { |
215 | 211 | $reason = $params['reason']; |
216 | 212 | } |
217 | | - |
| 213 | + |
218 | 214 | // Check if they specified a sortkey |
219 | 215 | $sortkey = null; |
220 | | - if ( !empty($params['sortkey']) ) { |
| 216 | + if ( !empty( $params['sortkey'] ) ) { |
221 | 217 | $ts = $params['sortkey']; |
222 | 218 | $ts = wfTimestamp( TS_MW, $ts ); |
223 | | - |
| 219 | + |
224 | 220 | $sortkey = $ts; |
225 | 221 | } |
226 | | - |
| 222 | + |
227 | 223 | // Do the split |
228 | 224 | $thread->split( $subject, $reason, $sortkey ); |
229 | | - |
| 225 | + |
230 | 226 | $result = array(); |
231 | | - $result[] = |
232 | | - array( |
233 | | - 'result' => 'Success', |
234 | | - 'action' => 'split', |
235 | | - 'id' => $thread->id(), |
236 | | - 'title' => $thread->title()->getPrefixedText(), |
237 | | - 'newsubject' => $subject, |
238 | | - ); |
239 | | - |
| 227 | + $result[] = array( |
| 228 | + 'result' => 'Success', |
| 229 | + 'action' => 'split', |
| 230 | + 'id' => $thread->id(), |
| 231 | + 'title' => $thread->title()->getPrefixedText(), |
| 232 | + 'newsubject' => $subject, |
| 233 | + ); |
| 234 | + |
240 | 235 | $this->getResult()->setIndexedTagName( $result, 'thread' ); |
241 | 236 | $this->getResult()->addValue( null, 'threadaction', $result ); |
242 | 237 | } |
243 | | - |
| 238 | + |
244 | 239 | public function actionMerge( $threads, $params ) { |
245 | 240 | global $wgUser; |
246 | | - |
| 241 | + |
247 | 242 | if ( count( $threads ) < 1 ) { |
248 | 243 | $this->dieUsage( 'You must specify a thread to merge', |
249 | 244 | 'no-specified-threads' ); |
250 | 245 | return; |
251 | 246 | } |
252 | | - |
| 247 | + |
253 | 248 | if ( empty( $params['newparent'] ) ) { |
254 | 249 | $this->dieUsage( 'You must specify a new parent thread to merge beneath', |
255 | | - 'no-parent-thread' ); |
| 250 | + 'no-parent-thread' ); |
256 | 251 | return; |
257 | 252 | } |
258 | | - |
| 253 | + |
259 | 254 | $newParent = $params['newparent']; |
260 | 255 | if ( is_numeric( $newParent ) ) { |
261 | 256 | $newParent = Threads::withId( $newParent ); |
— | — | @@ -263,115 +258,114 @@ |
264 | 259 | $article = new Article( $title ); |
265 | 260 | $newParent = Threads::withRoot( $article ); |
266 | 261 | } |
267 | | - |
| 262 | + |
268 | 263 | if ( !$newParent ) { |
269 | | - $this->dieUsage( 'The parent thread you specified was neither the title '. |
| 264 | + $this->dieUsage( 'The parent thread you specified was neither the title ' . |
270 | 265 | 'of a thread, nor a thread ID.', 'invalid-parent-thread' ); |
271 | 266 | return; |
272 | 267 | } |
273 | | - |
| 268 | + |
274 | 269 | // Pull a reason, if applicable. |
275 | 270 | $reason = ''; |
276 | | - if ( !empty($params['reason']) ) { |
| 271 | + if ( !empty( $params['reason'] ) ) { |
277 | 272 | $reason = $params['reason']; |
278 | 273 | } |
279 | | - |
| 274 | + |
280 | 275 | $result = array(); |
281 | | - |
282 | | - foreach( $threads as $thread ) { |
| 276 | + |
| 277 | + foreach ( $threads as $thread ) { |
283 | 278 | $thread->moveToParent( $newParent, $reason ); |
284 | | - $result[] = |
285 | | - array( |
286 | | - 'result' => 'Success', |
287 | | - 'action' => 'merge', |
288 | | - 'id' => $thread->id(), |
289 | | - 'title' => $thread->title()->getPrefixedText(), |
290 | | - 'new-parent-id' => $newParent->id(), |
291 | | - 'new-parent-title' => $newParent->title()->getPrefixedText(), |
292 | | - 'new-ancestor-id' => $newParent->topmostThread()->id(), |
293 | | - 'new-ancestor-title' => $newParent->topmostThread()->title()->getPrefixedText(), |
294 | | - ); |
| 279 | + $result[] = array( |
| 280 | + 'result' => 'Success', |
| 281 | + 'action' => 'merge', |
| 282 | + 'id' => $thread->id(), |
| 283 | + 'title' => $thread->title()->getPrefixedText(), |
| 284 | + 'new-parent-id' => $newParent->id(), |
| 285 | + 'new-parent-title' => $newParent->title()->getPrefixedText(), |
| 286 | + 'new-ancestor-id' => $newParent->topmostThread()->id(), |
| 287 | + 'new-ancestor-title' => $newParent->topmostThread()->title()->getPrefixedText(), |
| 288 | + ); |
295 | 289 | } |
296 | | - |
| 290 | + |
297 | 291 | $this->getResult()->setIndexedTagName( $result, 'thread' ); |
298 | 292 | $this->getResult()->addValue( null, 'threadaction', $result ); |
299 | 293 | } |
300 | | - |
| 294 | + |
301 | 295 | public function actionNewThread( $threads, $params ) { |
302 | 296 | global $wgUser; |
303 | | - |
| 297 | + |
304 | 298 | // Validate talkpage parameters |
305 | 299 | if ( empty( $params['talkpage'] ) ) { |
306 | 300 | $this->dieUsage( 'You must specify a talk-page to post the thread to', |
307 | 301 | 'missing-param' ); |
308 | | - |
| 302 | + |
309 | 303 | return; |
310 | 304 | } |
311 | | - |
| 305 | + |
312 | 306 | $talkpageTitle = Title::newFromText( $params['talkpage'] ); |
313 | | - |
314 | | - if (!$talkpageTitle || !LqtDispatch::isLqtPage( $talkpageTitle ) ) { |
315 | | - $this->dieUsage( 'The talkpage you specified is invalid, or does not '. |
| 307 | + |
| 308 | + if ( !$talkpageTitle || !LqtDispatch::isLqtPage( $talkpageTitle ) ) { |
| 309 | + $this->dieUsage( 'The talkpage you specified is invalid, or does not ' . |
316 | 310 | 'have discussion threading enabled.', 'invalid-talkpage' ); |
317 | 311 | return; |
318 | 312 | } |
319 | 313 | $talkpage = new Article( $talkpageTitle ); |
320 | | - |
| 314 | + |
321 | 315 | // Check if we can post. |
322 | 316 | if ( Thread::canUserPost( $wgUser, $talkpage ) !== true ) { |
323 | | - $this->dieUsage( 'You cannot post to the specified talkpage, '. |
| 317 | + $this->dieUsage( 'You cannot post to the specified talkpage, ' . |
324 | 318 | 'because it is protected from new posts', 'talkpage-protected' ); |
325 | 319 | return; |
326 | 320 | } |
327 | | - |
| 321 | + |
328 | 322 | // Validate subject, generate a title |
329 | 323 | if ( empty( $params['subject'] ) ) { |
330 | 324 | $this->dieUsage( 'You must specify a thread subject', |
331 | 325 | 'missing-param' ); |
332 | 326 | return; |
333 | 327 | } |
334 | | - |
335 | | - $bump = isset($params['bump']) ? $params['bump'] : null; |
336 | | - |
| 328 | + |
| 329 | + $bump = isset( $params['bump'] ) ? $params['bump'] : null; |
| 330 | + |
337 | 331 | $subject = $params['subject']; |
338 | 332 | $title = null; |
339 | 333 | $subjectOk = Thread::validateSubject( $subject, $title, null, $talkpage ); |
340 | | - |
| 334 | + |
341 | 335 | if ( !$subjectOk ) { |
342 | 336 | $this->dieUsage( 'The subject you specified is not valid', |
343 | 337 | 'invalid-subject' ); |
344 | | - |
| 338 | + |
345 | 339 | return; |
346 | 340 | } |
347 | 341 | $article = new Article( $title ); |
348 | | - |
| 342 | + |
349 | 343 | // Check for text |
350 | 344 | if ( empty( $params['text'] ) ) { |
351 | 345 | $this->dieUsage( 'You must include text in your post', 'no-text' ); |
352 | 346 | return; |
353 | 347 | } |
354 | 348 | $text = $params['text']; |
355 | | - |
| 349 | + |
356 | 350 | // Generate or pull summary |
357 | 351 | $summary = wfMsgForContent( 'lqt-newpost-summary', $subject ); |
358 | 352 | if ( !empty( $params['reason'] ) ) { |
359 | 353 | $summary = $params['reason']; |
360 | 354 | } |
361 | | - |
| 355 | + |
362 | 356 | $signature = null; |
363 | 357 | if ( isset( $params['signature'] ) ) { |
364 | 358 | $signature = $params['signature']; |
365 | 359 | } |
366 | | - |
| 360 | + |
367 | 361 | // Inform hooks what we're doing |
368 | 362 | LqtHooks::$editTalkpage = $talkpage; |
369 | 363 | LqtHooks::$editArticle = $article; |
370 | 364 | LqtHooks::$editThread = null; |
371 | 365 | LqtHooks::$editType = 'new'; |
372 | 366 | LqtHooks::$editAppliesTo = null; |
373 | | - |
| 367 | + |
374 | 368 | $token = $params['token']; |
375 | | - |
| 369 | + |
376 | 370 | // All seems in order. Construct an API edit request |
377 | 371 | $requestData = array( |
378 | 372 | 'action' => 'edit', |
— | — | @@ -382,31 +376,31 @@ |
383 | 377 | 'basetimestamp' => wfTimestampNow(), |
384 | 378 | 'format' => 'json', |
385 | 379 | ); |
386 | | - |
| 380 | + |
387 | 381 | $editReq = new FauxRequest( $requestData, true ); |
388 | 382 | $internalApi = new ApiMain( $editReq, true ); |
389 | 383 | $internalApi->execute(); |
390 | | - |
| 384 | + |
391 | 385 | $editResult = $internalApi->getResultData(); |
392 | | - |
| 386 | + |
393 | 387 | if ( $editResult['edit']['result'] != 'Success' ) { |
394 | 388 | $result = array( 'result' => 'EditFailure', 'details' => $editResult ); |
395 | 389 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
396 | 390 | return; |
397 | 391 | } |
398 | | - |
| 392 | + |
399 | 393 | $articleId = $editResult['edit']['pageid']; |
400 | | - |
| 394 | + |
401 | 395 | $article->getTitle()->resetArticleID( $articleId ); |
402 | 396 | $title->resetArticleID( $articleId ); |
403 | | - |
| 397 | + |
404 | 398 | $thread = LqtView::postEditUpdates( 'new', null, $article, $talkpage, |
405 | 399 | $subject, $summary, null, $text, $bump, $signature ); |
406 | 400 | |
407 | 401 | $maxLag = wfGetLB()->getMaxLag(); |
408 | 402 | $maxLag = $maxLag[1]; |
409 | | - |
410 | | - if ($maxLag == -1) { |
| 403 | + |
| 404 | + if ( $maxLag == - 1 ) { |
411 | 405 | $maxLag = 0; |
412 | 406 | } |
413 | 407 | |
— | — | @@ -416,81 +410,81 @@ |
417 | 411 | 'thread-title' => $title->getPrefixedText(), |
418 | 412 | 'max-lag' => $maxLag, |
419 | 413 | ); |
420 | | - |
| 414 | + |
421 | 415 | if ( !empty( $params['render'] ) ) { |
422 | 416 | $result['html'] = self::renderThreadPostAction( $thread ); |
423 | 417 | } |
424 | | - |
| 418 | + |
425 | 419 | $result = array( 'thread' => $result ); |
426 | | - |
| 420 | + |
427 | 421 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
428 | 422 | } |
429 | | - |
| 423 | + |
430 | 424 | public function actionReply( $threads, $params ) { |
431 | 425 | global $wgUser; |
432 | | - |
| 426 | + |
433 | 427 | // Validate thread parameter |
434 | | - if ( count($threads) > 1 ) { |
| 428 | + if ( count( $threads ) > 1 ) { |
435 | 429 | $this->dieUsage( 'You may only reply to one thread at a time', |
436 | 430 | 'too-many-threads' ); |
437 | 431 | return; |
438 | | - } elseif ( count($threads) < 1 ) { |
| 432 | + } elseif ( count( $threads ) < 1 ) { |
439 | 433 | $this->dieUsage( 'You must specify a thread to reply to', |
440 | 434 | 'no-specified-threads' ); |
441 | 435 | return; |
442 | 436 | } |
443 | 437 | $replyTo = array_pop( $threads ); |
444 | | - |
| 438 | + |
445 | 439 | // Check if we can reply to that thread. |
446 | 440 | $perm_result = $replyTo->canUserReply( $wgUser ); |
447 | 441 | if ( $perm_result !== true ) { |
448 | | - $this->dieUsage( "You cannot reply to this thread, because the ". |
449 | | - $perm_result." is protected from replies.", |
450 | | - $perm_result.'-protected' ); |
| 442 | + $this->dieUsage( "You cannot reply to this thread, because the " . |
| 443 | + $perm_result . " is protected from replies.", |
| 444 | + $perm_result . '-protected' ); |
451 | 445 | return; |
452 | 446 | } |
453 | | - |
| 447 | + |
454 | 448 | // Validate text parameter |
455 | 449 | if ( empty( $params['text'] ) ) { |
456 | 450 | $this->dieUsage( 'You must include text in your post', 'no-text' ); |
457 | 451 | return; |
458 | 452 | } |
459 | | - |
| 453 | + |
460 | 454 | $text = $params['text']; |
461 | | - |
462 | | - $bump = isset($params['bump']) ? $params['bump'] : null; |
463 | | - |
| 455 | + |
| 456 | + $bump = isset( $params['bump'] ) ? $params['bump'] : null; |
| 457 | + |
464 | 458 | // Generate/pull summary |
465 | 459 | $summary = wfMsgForContent( 'lqt-reply-summary', $replyTo->subject(), |
466 | 460 | $replyTo->title()->getPrefixedText() ); |
467 | | - |
| 461 | + |
468 | 462 | if ( !empty( $params['reason'] ) ) { |
469 | 463 | $summary = $params['reason']; |
470 | 464 | } |
471 | | - |
| 465 | + |
472 | 466 | $signature = null; |
473 | 467 | if ( isset( $params['signature'] ) ) { |
474 | 468 | $signature = $params['signature']; |
475 | 469 | } |
476 | | - |
| 470 | + |
477 | 471 | // Grab data from parent |
478 | 472 | $talkpage = $replyTo->article(); |
479 | 473 | $subject = $replyTo->subject(); |
480 | | - |
| 474 | + |
481 | 475 | // Generate a reply title. |
482 | 476 | $title = Threads::newReplyTitle( $replyTo, $wgUser ); |
483 | 477 | $article = new Article( $title ); |
484 | | - |
| 478 | + |
485 | 479 | // Inform hooks what we're doing |
486 | 480 | LqtHooks::$editTalkpage = $talkpage; |
487 | 481 | LqtHooks::$editArticle = $article; |
488 | 482 | LqtHooks::$editThread = null; |
489 | 483 | LqtHooks::$editType = 'reply'; |
490 | 484 | LqtHooks::$editAppliesTo = $replyTo; |
491 | | - |
| 485 | + |
492 | 486 | // Pull token in |
493 | 487 | $token = $params['token']; |
494 | | - |
| 488 | + |
495 | 489 | // All seems in order. Construct an API edit request |
496 | 490 | $requestData = array( |
497 | 491 | 'action' => 'edit', |
— | — | @@ -501,33 +495,33 @@ |
502 | 496 | 'basetimestamp' => wfTimestampNow(), |
503 | 497 | 'format' => 'json', |
504 | 498 | ); |
505 | | - |
| 499 | + |
506 | 500 | $editReq = new FauxRequest( $requestData, true ); |
507 | 501 | $internalApi = new ApiMain( $editReq, true ); |
508 | 502 | $internalApi->execute(); |
509 | | - |
| 503 | + |
510 | 504 | $editResult = $internalApi->getResultData(); |
511 | | - |
| 505 | + |
512 | 506 | if ( $editResult['edit']['result'] != 'Success' ) { |
513 | 507 | $result = array( 'result' => 'EditFailure', 'details' => $editResult ); |
514 | 508 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
515 | 509 | return; |
516 | 510 | } |
517 | | - |
| 511 | + |
518 | 512 | $articleId = $editResult['edit']['pageid']; |
519 | 513 | $article->getTitle()->resetArticleID( $articleId ); |
520 | 514 | $title->resetArticleID( $articleId ); |
521 | | - |
| 515 | + |
522 | 516 | $thread = LqtView::postEditUpdates( 'reply', $replyTo, $article, $talkpage, |
523 | 517 | $subject, $summary, null, $text, $bump, $signature ); |
524 | | - |
| 518 | + |
525 | 519 | $maxLag = wfGetLB()->getMaxLag(); |
526 | 520 | $maxLag = $maxLag[1]; |
527 | | - |
528 | | - if ($maxLag == -1) { |
| 521 | + |
| 522 | + if ( $maxLag == - 1 ) { |
529 | 523 | $maxLag = 0; |
530 | 524 | } |
531 | | - |
| 525 | + |
532 | 526 | $result = array( |
533 | 527 | 'action' => 'reply', |
534 | 528 | 'result' => 'Success', |
— | — | @@ -539,19 +533,19 @@ |
540 | 534 | 'ancestor-title' => $replyTo->topmostThread()->title()->getPrefixedText(), |
541 | 535 | 'max-lag' => $maxLag, |
542 | 536 | ); |
543 | | - |
| 537 | + |
544 | 538 | if ( !empty( $params['render'] ) ) { |
545 | 539 | $result['html'] = self::renderThreadPostAction( $thread ); |
546 | 540 | } |
547 | | - |
| 541 | + |
548 | 542 | $result = array( 'thread' => $result ); |
549 | | - |
| 543 | + |
550 | 544 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
551 | 545 | } |
552 | | - |
| 546 | + |
553 | 547 | static function renderThreadPostAction( $thread ) { |
554 | 548 | $thread = $thread->topmostThread(); |
555 | | - |
| 549 | + |
556 | 550 | // Set up OutputPage |
557 | 551 | global $wgOut, $wgUser, $wgRequest; |
558 | 552 | $oldOutputText = $wgOut->getHTML(); |
— | — | @@ -561,58 +555,58 @@ |
562 | 556 | $article = $thread->root(); |
563 | 557 | $title = $article->getTitle(); |
564 | 558 | $view = new LqtView( $wgOut, $article, $title, $wgUser, $wgRequest ); |
565 | | - |
| 559 | + |
566 | 560 | $view->showThread( $thread ); |
567 | 561 | |
568 | 562 | $result = $wgOut->getHTML(); |
569 | 563 | $wgOut->clearHTML(); |
570 | 564 | $wgOut->addHTML( $oldOutputText ); |
571 | | - |
| 565 | + |
572 | 566 | return $result; |
573 | 567 | } |
574 | | - |
| 568 | + |
575 | 569 | public function actionSetSubject( $threads, $params ) { |
576 | 570 | // Validate thread parameter |
577 | | - if ( count($threads) > 1 ) { |
| 571 | + if ( count( $threads ) > 1 ) { |
578 | 572 | $this->dieUsage( 'You may only change the subject of one thread at a time', |
579 | 573 | 'too-many-threads' ); |
580 | 574 | return; |
581 | | - } elseif ( count($threads) < 1 ) { |
| 575 | + } elseif ( count( $threads ) < 1 ) { |
582 | 576 | $this->dieUsage( 'You must specify a thread to change the subject of', |
583 | 577 | 'no-specified-threads' ); |
584 | 578 | return; |
585 | 579 | } |
586 | 580 | $thread = array_pop( $threads ); |
587 | | - |
| 581 | + |
588 | 582 | // Validate subject |
589 | 583 | if ( empty( $params['subject'] ) ) { |
590 | 584 | $this->dieUsage( 'You must specify a thread subject', |
591 | 585 | 'missing-param' ); |
592 | 586 | return; |
593 | 587 | } |
594 | | - |
| 588 | + |
595 | 589 | $talkpage = $thread->article(); |
596 | | - |
| 590 | + |
597 | 591 | $subject = $params['subject']; |
598 | 592 | $title = null; |
599 | 593 | $subjectOk = Thread::validateSubject( $subject, $title, null, $talkpage ); |
600 | | - |
| 594 | + |
601 | 595 | if ( !$subjectOk ) { |
602 | 596 | $this->dieUsage( 'The subject you specified is not valid', |
603 | 597 | 'invalid-subject' ); |
604 | | - |
| 598 | + |
605 | 599 | return; |
606 | 600 | } |
607 | | - |
| 601 | + |
608 | 602 | $reason = null; |
609 | | - |
| 603 | + |
610 | 604 | if ( isset( $params['reason'] ) ) { |
611 | 605 | $reason = $params['reason']; |
612 | 606 | } |
613 | | - |
| 607 | + |
614 | 608 | $thread->setSubject( $subject ); |
615 | 609 | $thread->commitRevision( Threads::CHANGE_EDITED_SUBJECT, $thread, $reason ); |
616 | | - |
| 610 | + |
617 | 611 | $result = array( |
618 | 612 | 'action' => 'setsubject', |
619 | 613 | 'result' => 'success', |
— | — | @@ -620,51 +614,51 @@ |
621 | 615 | 'thread-title' => $thread->title()->getPrefixedText(), |
622 | 616 | 'new-subject' => $subject, |
623 | 617 | ); |
624 | | - |
| 618 | + |
625 | 619 | $result = array( 'thread' => $result ); |
626 | | - |
| 620 | + |
627 | 621 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
628 | 622 | } |
629 | | - |
| 623 | + |
630 | 624 | public function actionSetSortkey( $threads, $params ) { |
631 | 625 | // First check for threads |
632 | | - if ( !count($threads) ) { |
| 626 | + if ( !count( $threads ) ) { |
633 | 627 | $this->dieUsage( 'You must specify a thread to set the sortkey of', |
634 | 628 | 'no-specified-threads' ); |
635 | 629 | return; |
636 | 630 | } |
637 | | - |
| 631 | + |
638 | 632 | // Validate timestamp |
639 | 633 | if ( empty( $params['sortkey'] ) ) { |
640 | | - $this->dieUsage( 'You must specify a valid timestamp for the sortkey'. |
641 | | - 'parameter. It should be in the form YYYYMMddhhmmss, a '. |
| 634 | + $this->dieUsage( 'You must specify a valid timestamp for the sortkey' . |
| 635 | + 'parameter. It should be in the form YYYYMMddhhmmss, a ' . |
642 | 636 | 'unix timestamp or "now".', 'invalid-sortkey' ); |
643 | 637 | return; |
644 | 638 | } |
645 | | - |
| 639 | + |
646 | 640 | $ts = $params['sortkey']; |
647 | | - |
648 | | - if ($ts == 'now') $ts = wfTimestampNow(); |
649 | | - |
| 641 | + |
| 642 | + if ( $ts == 'now' ) $ts = wfTimestampNow(); |
| 643 | + |
650 | 644 | $ts = wfTimestamp( TS_MW, $ts ); |
651 | | - |
| 645 | + |
652 | 646 | if ( !$ts ) { |
653 | | - $this->dieUsage( 'You must specify a valid timestamp for the sortkey'. |
654 | | - 'parameter. It should be in the form YYYYMMddhhmmss, a '. |
| 647 | + $this->dieUsage( 'You must specify a valid timestamp for the sortkey' . |
| 648 | + 'parameter. It should be in the form YYYYMMddhhmmss, a ' . |
655 | 649 | 'unix timestamp or "now".', 'invalid-sortkey' ); |
656 | 650 | return; |
657 | 651 | } |
658 | | - |
| 652 | + |
659 | 653 | $reason = null; |
660 | | - |
| 654 | + |
661 | 655 | if ( isset( $params['reason'] ) ) { |
662 | 656 | $reason = $params['reason']; |
663 | 657 | } |
664 | | - |
665 | | - $thread = array_pop($threads); |
| 658 | + |
| 659 | + $thread = array_pop( $threads ); |
666 | 660 | $thread->setSortkey( $ts ); |
667 | 661 | $thread->commitRevision( Threads::CHANGE_ADJUSTED_SORTKEY, null, $reason ); |
668 | | - |
| 662 | + |
669 | 663 | $result = array( |
670 | 664 | 'action' => 'setsortkey', |
671 | 665 | 'result' => 'success', |
— | — | @@ -672,12 +666,12 @@ |
673 | 667 | 'thread-title' => $thread->title()->getPrefixedText(), |
674 | 668 | 'new-sortkey' => $ts, |
675 | 669 | ); |
676 | | - |
| 670 | + |
677 | 671 | $result = array( 'thread' => $result ); |
678 | | - |
| 672 | + |
679 | 673 | $this->getResult()->addValue( null, $this->getModuleName(), $result ); |
680 | 674 | } |
681 | | - |
| 675 | + |
682 | 676 | public function getVersion() { |
683 | 677 | return __CLASS__ . ': $Id: $'; |
684 | 678 | } |
Index: trunk/extensions/LiquidThreads/api/ApiFeedLQTThreads.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | /* |
5 | 4 | * This program is free software; you can redistribute it and/or modify |
6 | 5 | * it under the terms of the GNU General Public License as published by |
— | — | @@ -28,7 +27,6 @@ |
29 | 28 | * @ingroup API |
30 | 29 | */ |
31 | 30 | class ApiFeedLQTThreads extends ApiBase { |
32 | | - |
33 | 31 | public function __construct( $main, $action ) { |
34 | 32 | parent :: __construct( $main, $action ); |
35 | 33 | } |
— | — | @@ -54,7 +52,7 @@ |
55 | 53 | $feedTitle = self::createFeedTitle( $params ); |
56 | 54 | $feedClass = $wgFeedClasses[$params['feedformat']]; |
57 | 55 | $feedItems = array(); |
58 | | - |
| 56 | + |
59 | 57 | $feedUrl = Title::newMainPage()->getFullURL(); |
60 | 58 | |
61 | 59 | $tables = array( 'thread' ); |
Index: trunk/extensions/LiquidThreads/api/ApiQueryLQTThreads.php |
— | — | @@ -17,27 +17,26 @@ |
18 | 18 | */ |
19 | 19 | |
20 | 20 | class ApiQueryLQTThreads extends ApiQueryBase { |
21 | | - |
22 | 21 | // Property definitions |
23 | 22 | static $propRelations = array( |
24 | | - 'id' => 'thread_id', |
25 | | - 'subject' => 'thread_subject', |
26 | | - 'page' => array( |
27 | | - 'namespace' => 'thread_article_namespace', |
28 | | - 'title' => 'thread_article_title' |
29 | | - ), |
30 | | - 'parent' => 'thread_parent', |
31 | | - 'ancestor' => 'thread_ancestor', |
32 | | - 'created' => 'thread_created', |
33 | | - 'modified' => 'thread_modified', |
34 | | - 'author' => array( |
35 | | - 'id' => 'thread_author_id', |
36 | | - 'name' => 'thread_author_name' |
37 | | - ), |
38 | | - 'summaryid' => 'thread_summary_page', |
39 | | - 'rootid' => 'thread_root', |
40 | | - 'type' => 'thread_type', |
41 | | - ); |
| 23 | + 'id' => 'thread_id', |
| 24 | + 'subject' => 'thread_subject', |
| 25 | + 'page' => array( |
| 26 | + 'namespace' => 'thread_article_namespace', |
| 27 | + 'title' => 'thread_article_title' |
| 28 | + ), |
| 29 | + 'parent' => 'thread_parent', |
| 30 | + 'ancestor' => 'thread_ancestor', |
| 31 | + 'created' => 'thread_created', |
| 32 | + 'modified' => 'thread_modified', |
| 33 | + 'author' => array( |
| 34 | + 'id' => 'thread_author_id', |
| 35 | + 'name' => 'thread_author_name' |
| 36 | + ), |
| 37 | + 'summaryid' => 'thread_summary_page', |
| 38 | + 'rootid' => 'thread_root', |
| 39 | + 'type' => 'thread_type', |
| 40 | + ); |
42 | 41 | |
43 | 42 | public function __construct( $query, $moduleName ) { |
44 | 43 | parent :: __construct( $query, $moduleName, 'th' ); |
— | — | @@ -90,11 +89,11 @@ |
91 | 90 | } |
92 | 91 | |
93 | 92 | $res = $this->select( __METHOD__ ); |
94 | | - |
| 93 | + |
95 | 94 | if ( $params['render'] ) { |
96 | 95 | $threads = Threads::loadFromResult( $res, $this->getDB() ); |
97 | 96 | } |
98 | | - |
| 97 | + |
99 | 98 | $count = 0; |
100 | 99 | foreach ( $res as $row ) |
101 | 100 | { |
Index: trunk/extensions/LiquidThreads/import/import-parsed-discussions.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | require_once ( getenv( 'MW_INSTALL_PATH' ) !== false |
5 | 4 | ? getenv( 'MW_INSTALL_PATH' ) . "/maintenance/commandLine.inc" |
6 | 5 | : dirname( __FILE__ ) . '/../../maintenance/commandLine.inc' ); |
Index: trunk/extensions/LiquidThreads/LqtFunctions.php |
— | — | @@ -44,7 +44,7 @@ |
45 | 45 | 'useliquidthreads', |
46 | 46 | array( 'LqtParserFunctions', 'useLiquidThreads' ) |
47 | 47 | ); |
48 | | - |
| 48 | + |
49 | 49 | $parser->setFunctionHook( |
50 | 50 | 'lqtpagelimit', |
51 | 51 | array( 'LqtParserFunctions', 'lqtPageLimit' ) |
Index: trunk/extensions/LiquidThreads/i18n/Lqt.i18n.php |
— | — | @@ -9,8 +9,6 @@ |
10 | 10 | * @licence GPL2 |
11 | 11 | */ |
12 | 12 | |
13 | | -require_once( dirname( __FILE__ ) . '/LiquidThreads.magic.php' ); |
14 | | - |
15 | 13 | $messages = array(); |
16 | 14 | |
17 | 15 | $messages['en'] = array( |
— | — | @@ -183,7 +181,7 @@ |
184 | 182 | 'lqt-newmessages-from' => 'From $1', |
185 | 183 | 'lqt-hot-topics' => 'Hot topics', |
186 | 184 | 'lqt-add-reply' => 'Add a reply', |
187 | | - |
| 185 | + |
188 | 186 | // Recent changes display |
189 | 187 | 'lqt_rc_new_discussion' => "posted a new thread, \"$1\"", |
190 | 188 | 'lqt_rc_new_reply' => "posted a reply to \"$1\"", |
— | — | @@ -257,12 +255,12 @@ |
258 | 256 | 'lqt-marked-as-read-placeholder' => 'The thread $1 was marked as read.', |
259 | 257 | 'lqt-change-subject' => 'Change subject', |
260 | 258 | 'lqt-save-subject' => 'Save', |
261 | | - 'lqt-save-subject-failed' => 'The following error occurred while attempting to '. |
| 259 | + 'lqt-save-subject-failed' => 'The following error occurred while attempting to ' . |
262 | 260 | 'change the subject of this thread: $1', |
263 | | - 'lqt-ajax-invalid-subject' => 'The subject you specified was invalid, probably '. |
| 261 | + 'lqt-ajax-invalid-subject' => 'The subject you specified was invalid, probably ' . |
264 | 262 | 'because it was too long.', |
265 | 263 | 'lqt-ajax-no-subject' => 'You must specify a subject.', |
266 | | - 'lqt-save-subject-error-unknown' => 'An unknown error occurred when attempting '. |
| 264 | + 'lqt-save-subject-error-unknown' => 'An unknown error occurred when attempting ' . |
267 | 265 | 'to set the subject of this thread. Please try to do this by clicking "edit" on the top post.', |
268 | 266 | 'lqt-cancel-subject-edit' => 'Cancel', |
269 | 267 | 'lqt-drag-activate' => 'Drag to new location', |
— | — | @@ -307,12 +305,12 @@ |
308 | 306 | 'lqt-protected-reply-thread' => 'You cannot post in this thread because it has been protected from new posts.', |
309 | 307 | 'lqt-protected-reply-talkpage' => 'You cannot post in this thread because this discussion page has been protected from replies to its threads.', |
310 | 308 | 'lqt-protected-newthread' => 'You cannot post new threads to this discussion page because it has been protected from new threads.', |
311 | | - |
| 309 | + |
312 | 310 | 'lqt-edit-bump' => 'Bump this thread', |
313 | 311 | 'lqt-edit-bump-tooltip' => 'Move this thread to the top of its discussion page', |
314 | | - |
| 312 | + |
315 | 313 | 'lqt-historicalrevision-error' => 'The revision you have selected is corrupt, and cannot be viewed.', |
316 | | - |
| 314 | + |
317 | 315 | // Reply subpage name |
318 | 316 | 'lqt-reply-subpage' => 'reply', |
319 | 317 | ); |
— | — | @@ -490,7 +488,7 @@ |
491 | 489 | 'lqt-feed-new-thread-intro' => 'Parameters: |
492 | 490 | * $1 is a link to the talk page with the thread |
493 | 491 | * $2 is a link to the user posting in the thread |
494 | | -* $3 -not used- |
| 492 | +* $3 -not used- |
495 | 493 | * $4 is the name of the user posting to the thread, optional, can be used for GENDER', |
496 | 494 | 'lqt-feed-reply-intro' => 'Parameters: |
497 | 495 | * $1 is a link to the talk page with the thread |
— | — | @@ -1533,12 +1531,12 @@ |
1534 | 1532 | 'lqt-enotif-subject-reply' => 'Абмеркаваньне {{GRAMMAR:родны|{{SITENAME}}}} — Адказ: $1', |
1535 | 1533 | 'lqt-enotif-subject-newthread' => 'Абмеркаваньне {{GRAMMAR:родны|{{SITENAME}}}} — Новая галіна: $1', |
1536 | 1534 | 'lqt-enotif-newthread' => "Вітаем $1, |
1537 | | -Гэта паведамленьне з {{GRAMMAR:родны|{{SITENAME}}}} пра новую галіну $5, '$2', |
| 1535 | +Гэта паведамленьне з {{GRAMMAR:родны|{{SITENAME}}}} пра новую галіну $5, '$2', |
1538 | 1536 | створаную $3 $4. |
1539 | 1537 | |
1540 | 1538 | Вы можаце паглядзець яе на <$6>", |
1541 | 1539 | 'lqt-enotif-reply' => "Вітаем $1, |
1542 | | -Гэта паведамленьне з {{GRAMMAR:родны|{{SITENAME}}}} пра новы адказ $5, '$2', |
| 1540 | +Гэта паведамленьне з {{GRAMMAR:родны|{{SITENAME}}}} пра новы адказ $5, '$2', |
1543 | 1541 | створаны $3 $4. |
1544 | 1542 | |
1545 | 1543 | Вы можаце паглядзець яго на <$6>", |
— | — | @@ -1789,7 +1787,7 @@ |
1790 | 1788 | 'lqt-thread-link-url' => 'URL на препратката:', |
1791 | 1789 | 'lqt-thread-link-title' => 'Уикитекст на препратката:', |
1792 | 1790 | 'lqt-thread-link-copy' => 'Копиране в системния буфер', |
1793 | | - 'lqt-sign-not-necessary' => 'Не е нужно да подписвате коментара си с четири вълнички. |
| 1791 | + 'lqt-sign-not-necessary' => 'Не е нужно да подписвате коментара си с четири вълнички. |
1794 | 1792 | Подписът ви ще се покаже автоматично.', |
1795 | 1793 | 'lqt-marked-as-read-placeholder' => 'Тема $1 беше отбелязана като прочетена.', |
1796 | 1794 | 'lqt-change-subject' => 'Смяна на темата', |
— | — | @@ -2086,7 +2084,7 @@ |
2087 | 2085 | 'lqt_delete_show_checkbox' => "Diskouez ar c'haozeadennoù diverket", |
2088 | 2086 | 'lqt_talkpage_autocreate_summary' => "Pajenn gaozeal krouet ent emgefre p'eo bet kaset an neudennad kaozioù kentañ", |
2089 | 2087 | 'lqt_header_warning_big' => "Emaoc'h o kemmañ ur $1", |
2090 | | - 'lqt_header_warning_after_big' => "Evit ar c'hemennoù hag ar rakgerioù eo an talbennoù. |
| 2088 | + 'lqt_header_warning_after_big' => "Evit ar c'hemennoù hag ar rakgerioù eo an talbennoù. |
2091 | 2089 | Marteze e fell deoc'h $2 kentoc'h.", |
2092 | 2090 | 'lqt_header_warning_bold' => 'Talbenn ur bajenn gaozeal', |
2093 | 2091 | 'lqt_header_warning_new_discussion' => "boulc'hañ gant ur gaoz nevez", |
— | — | @@ -2526,7 +2524,7 @@ |
2527 | 2525 | 'lqt_new_thread' => 'Comença una nova discussió', |
2528 | 2526 | 'lqt_invalid_subject' => 'El tema que heu introduït no és vàlid. |
2529 | 2527 | Pot: |
2530 | | -* ser massa llarg, o |
| 2528 | +* ser massa llarg, o |
2531 | 2529 | * entrar en conflicte amb prefixos interwiki o altres espai de noms.', |
2532 | 2530 | 'lqt_empty_subject' => "Heu d'introduir un tema.", |
2533 | 2531 | 'lqt_reply' => 'Respon', |
— | — | @@ -4945,7 +4943,7 @@ |
4946 | 4944 | 'lqt_nosuchthread' => 'Määrittämääsi viestiketjua ei ole.', |
4947 | 4945 | 'lqt_nosuchthread_title' => 'Ketjua ei löydy', |
4948 | 4946 | 'lqt_threadrequired' => 'Sinun tulee antaa ketju URL-osoitteessa.', |
4949 | | - 'lqt_move_movingthread' => 'Siirretään $1. |
| 4947 | + 'lqt_move_movingthread' => 'Siirretään $1. |
4950 | 4948 | Tämä ketju on osa sivua $2.', |
4951 | 4949 | 'lqt_move_torename' => 'Nimetäksesi uudelleen tämän ketjun – $1 ja muuta Aihe-kenttää.', |
4952 | 4950 | 'lqt_move_torename_edit' => 'muokkaa sitä', |
— | — | @@ -4969,7 +4967,7 @@ |
4970 | 4968 | 'lqt_delete_show_checkbox' => 'Näytä poistetut ketjut', |
4971 | 4969 | 'lqt_talkpage_autocreate_summary' => 'Keskustelusivu luotiin automaattisesti kun ensimmäinen ketju lähettiin.', |
4972 | 4970 | 'lqt_header_warning_big' => 'Muokkaat $1.', |
4973 | | - 'lqt_header_warning_after_big' => 'Otsakkeet ovat ilmoituksille. |
| 4971 | + 'lqt_header_warning_after_big' => 'Otsakkeet ovat ilmoituksille. |
4974 | 4972 | Saatat etsiä sivua ”$2” sen sijaan.', |
4975 | 4973 | 'lqt_header_warning_bold' => 'keskustelusivun otsikkoa', |
4976 | 4974 | 'lqt_header_warning_new_discussion' => 'aloita uusi keskustelu', |
— | — | @@ -5056,7 +5054,7 @@ |
5057 | 5055 | 'lqt-enotif-subject-newthread' => '{{SITENAME}} – Uusi viestiketju: $1', |
5058 | 5056 | 'lqt-enotif-newthread' => 'Hei $1, |
5059 | 5057 | |
5060 | | -Tämä on ilmoitus sivustolta {{SITENAME}}, että sivulle $5 on luotu uusi ketju, ”$2”, |
| 5058 | +Tämä on ilmoitus sivustolta {{SITENAME}}, että sivulle $5 on luotu uusi ketju, ”$2”, |
5061 | 5059 | $3 $4. |
5062 | 5060 | |
5063 | 5061 | Näet sen osoitteessa <$6>.', |
— | — | @@ -10439,7 +10437,7 @@ |
10440 | 10438 | 'lqt_protectedfromreply_link' => 'låst', |
10441 | 10439 | 'lqt_subject' => 'Emne:', |
10442 | 10440 | 'lqt_noreason' => 'Ingen grunn gitt.', |
10443 | | - 'lqt_move_placeholder' => 'Denne tråden eksisterer kun for å vise at tråden $1 ble flyttet fra denne siden til en annen diskusjonsside. |
| 10441 | + 'lqt_move_placeholder' => 'Denne tråden eksisterer kun for å vise at tråden $1 ble flyttet fra denne siden til en annen diskusjonsside. |
10444 | 10442 | Denne flyttingen ble foretatt av $2 $3 $4. |
10445 | 10443 | Denne tråden ligger nå på $5', |
10446 | 10444 | 'lqt_thread_deleted_for_sysops' => "Denne tråden har blitt '''slettet''' og er kun synlig for administratorer.", |
— | — | @@ -12460,7 +12458,7 @@ |
12461 | 12459 | 'lqt_protectedfromreply_link' => 'көмүскэммит', |
12462 | 12460 | 'lqt_subject' => 'Аата:', |
12463 | 12461 | 'lqt_noreason' => 'Төрүөтэ ыйыллыбатах.', |
12464 | | - 'lqt_move_placeholder' => 'Бу салаа бүөтэ $1 салаа бу сирэйтэн көһөрүллүбүтүн көрдөрөр. |
| 12462 | + 'lqt_move_placeholder' => 'Бу салаа бүөтэ $1 салаа бу сирэйтэн көһөрүллүбүтүн көрдөрөр. |
12465 | 12463 | Көһөрүүнү $3 $4 сирэйгэ $2 кыттааччы оҥорбут. Онон салаа маннык буолбут $5.', |
12466 | 12464 | 'lqt_thread_deleted_for_sysops' => "Бу салаа '''сотуллубут''', дьаһабылларга эрэ костөр кыахтаах.", |
12467 | 12465 | 'lqt_thread_deleted' => 'Бу салаа сотуллубут.', |
— | — | @@ -12473,7 +12471,7 @@ |
12474 | 12472 | 'lqt_nosuchthread' => 'Ыйбыт салааҥ суох эбит.', |
12475 | 12473 | 'lqt_nosuchthread_title' => 'Маннык салаа суох', |
12476 | 12474 | 'lqt_threadrequired' => 'URL-га салааны ыйыахтааххын.', |
12477 | | - 'lqt_move_movingthread' => '$1 көһөрүү. |
| 12475 | + 'lqt_move_movingthread' => '$1 көһөрүү. |
12478 | 12476 | Бу салаа $2 сорҕото буолар.', |
12479 | 12477 | 'lqt_move_torename' => "Салааны аатын уларытыаххын баҕарар буоллаххына, $1 уонна 'Аата' диэн түннүгү уларыт.", |
12480 | 12478 | 'lqt_move_torename_edit' => 'маны көннөр', |
— | — | @@ -12497,7 +12495,7 @@ |
12498 | 12496 | 'lqt_delete_show_checkbox' => 'Сотуллубут салаалары көрдөр', |
12499 | 12497 | 'lqt_talkpage_autocreate_summary' => 'Саҥа ырытыы сирэйэ бастакы этии оҥоһуллубутун кэннэ апатмаатынан оҥоһулунна.', |
12500 | 12498 | 'lqt_header_warning_big' => 'Маны эрэдээксийэлиигин $1.', |
12501 | | - 'lqt_header_warning_after_big' => 'Ааттар биллэрии уонна киирии быһыытынан туттуллаллар. |
| 12499 | + 'lqt_header_warning_after_big' => 'Ааттар биллэрии уонна киирии быһыытынан туттуллаллар. |
12502 | 12500 | Эн маны оҥоруоххун сөп $2.', |
12503 | 12501 | 'lqt_header_warning_bold' => 'ырытар сирэй аата', |
12504 | 12502 | 'lqt_header_warning_new_discussion' => 'саҥа ырытыыны саҕалааһын', |
— | — | @@ -12582,11 +12580,11 @@ |
12583 | 12581 | 'lqt-enotif-subject-reply' => '{{SITENAME}} ырытыы — Хоруй: $1', |
12584 | 12582 | 'lqt-enotif-subject-newthread' => '{{SITENAME}} ырытыы — Саҥа салаа: $1', |
12585 | 12583 | 'lqt-enotif-newthread' => 'Дорообо, $1. |
12586 | | -Бу $3 $4 {{SITENAME}} саайка баар $5 сирэйгэ «$2» диэн саҥа салаа үөскээбитин туһунан биллэрии. |
| 12584 | +Бу $3 $4 {{SITENAME}} саайка баар $5 сирэйгэ «$2» диэн саҥа салаа үөскээбитин туһунан биллэрии. |
12587 | 12585 | |
12588 | 12586 | Бу аадырыска <$6> көрүөххүн сөп.', |
12589 | 12587 | 'lqt-enotif-reply' => 'Дорообо, $1. |
12590 | | -Бу $3 $4 {{SITENAME}} саайка баар $5 сирэй «$2» салаатыгар саҥа хоруй баар буолбутун туһунан биллэрии. |
| 12588 | +Бу $3 $4 {{SITENAME}} саайка баар $5 сирэй «$2» салаатыгар саҥа хоруй баар буолбутун туһунан биллэрии. |
12591 | 12589 | |
12592 | 12590 | Бу аадырыска <$6> көрүөххүн сөп.', |
12593 | 12591 | 'lqt-quote-intro' => '$2 $3, [[User:$1|$1]] суруйбут:', |
— | — | @@ -13621,7 +13619,7 @@ |
13622 | 13620 | 'lqt_subject' => 'Tema:', |
13623 | 13621 | 'lqt_noreason' => 'Sebäp görkezilmedik.', |
13624 | 13622 | 'lqt_move_placeholder' => 'Bu tred , $1 trediniň bu sahypadan başga bir ýere geçirilendigini görkezýän ýer-saklaýjydyr. |
13625 | | -Tred $4 $3 senesinde $2 tarapyndan geçirilipdir. |
| 13623 | +Tred $4 $3 senesinde $2 tarapyndan geçirilipdir. |
13626 | 13624 | Tred häzirki wagtda $5 adresinde ýerleşýär.', |
13627 | 13625 | 'lqt_thread_deleted_for_sysops' => "Bu tred '''öçürilipdir''' we ony diňe administratorlar görüp bilýär.", |
13628 | 13626 | 'lqt_thread_deleted' => 'Bu tred öçürilipdir.', |
— | — | @@ -13746,7 +13744,7 @@ |
13747 | 13745 | |
13748 | 13746 | Ony <$6> adresinde görüp bilersiňiz.", |
13749 | 13747 | 'lqt-enotif-reply' => "Salam $1, |
13750 | | -Bu {{SITENAME}} saýtynyň uwedomleniýasydyr: $5 sahypasynda $4 $3 senesinde '$2' tredine täze bir jogap döredildi. |
| 13748 | +Bu {{SITENAME}} saýtynyň uwedomleniýasydyr: $5 sahypasynda $4 $3 senesinde '$2' tredine täze bir jogap döredildi. |
13751 | 13749 | |
13752 | 13750 | Ony <$6> adresinde görüp bilersiňiz.", |
13753 | 13751 | 'lqt-quote-intro' => '$2, $3 senesinde [[User:$1|$1]] ýazdy:', |
Index: trunk/extensions/LiquidThreads/compat/generateCompatibilityLocalisation.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | // Utility script to generate an extension messages file for backwards-compatibility. |
5 | 4 | |
6 | 5 | require_once ( getenv( 'MW_INSTALL_PATH' ) !== false |
— | — | @@ -7,15 +6,15 @@ |
8 | 7 | : dirname( __FILE__ ) . '/../../maintenance/commandLine.inc' ); |
9 | 8 | |
10 | 9 | $messages = array( |
11 | | - 'htmlform-reset', |
12 | | - 'htmlform-submit', |
13 | | - 'htmlform-int-invalid', |
14 | | - 'htmlform-int-toolow', |
15 | | - 'htmlform-int-toohigh', |
16 | | - 'htmlform-select-badoption', |
17 | | - 'htmlform-selectorother-other', |
18 | | - 'htmlform-invalid-input', |
19 | | - ); |
| 10 | + 'htmlform-reset', |
| 11 | + 'htmlform-submit', |
| 12 | + 'htmlform-int-invalid', |
| 13 | + 'htmlform-int-toolow', |
| 14 | + 'htmlform-int-toohigh', |
| 15 | + 'htmlform-select-badoption', |
| 16 | + 'htmlform-selectorother-other', |
| 17 | + 'htmlform-invalid-input', |
| 18 | +); |
20 | 19 | |
21 | 20 | $languages = array_keys( Language::getLanguageNames( false ) ); |
22 | 21 | $data = array_fill_keys( $languages, array() ); |
— | — | @@ -35,20 +34,20 @@ |
36 | 35 | |
37 | 36 | foreach ( $languages as $lang ) { |
38 | 37 | $fallback = Language::getFallbackFor( $lang ); |
39 | | - |
| 38 | + |
40 | 39 | print " [$lang from $fallback] "; |
41 | 40 | $lastFallback = $lang; |
42 | | - |
| 41 | + |
43 | 42 | while ( $fallback && !isset( $originalData[$fallback] ) && $fallback != $lastFallback ) { |
44 | 43 | $lastFallback = $fallback; |
45 | 44 | $fallback = Language::getFallbackFor( $lang ); |
46 | 45 | } |
47 | | - |
| 46 | + |
48 | 47 | if ( $fallback && isset( $originalData[$fallback] ) ) { |
49 | 48 | $fallbackData = $originalData[$fallback]; |
50 | | - |
| 49 | + |
51 | 50 | $data[$lang] = array_diff_assoc( $originalData[$lang], $fallbackData ); |
52 | | - |
| 51 | + |
53 | 52 | if ( !count( $data[$lang] ) ) |
54 | 53 | unset( $data[$lang] ); |
55 | 54 | } |
Index: trunk/extensions/LiquidThreads/compat/HTMLForm.php |
— | — | @@ -1,13 +1,13 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class HTMLForm { |
5 | | - |
6 | 4 | static $jsAdded = false; |
7 | 5 | |
8 | 6 | /* The descriptor is an array of arrays. |
9 | 7 | i.e. array( |
10 | | - 'fieldname' => array( 'section' => 'section/subsection', |
11 | | - properties... ), |
| 8 | + 'fieldname' => array( |
| 9 | + 'section' => 'section/subsection', |
| 10 | + properties... |
| 11 | + ), |
12 | 12 | ... |
13 | 13 | ) |
14 | 14 | */ |
— | — | @@ -26,7 +26,7 @@ |
27 | 27 | |
28 | 28 | function __construct( $descriptor, $messagePrefix ) { |
29 | 29 | wfLoadExtensionMessages( 'Lqt-Compat' ); |
30 | | - |
| 30 | + |
31 | 31 | $this->mMessagePrefix = $messagePrefix; |
32 | 32 | |
33 | 33 | // Expand out into a tree. |
— | — | @@ -112,18 +112,21 @@ |
113 | 113 | } |
114 | 114 | |
115 | 115 | /** Return values: |
116 | | - * TRUE == Successful submission |
117 | | - * FALSE == No submission attempted |
118 | | - * Anything else == Error to display. |
119 | | - */ |
| 116 | + * TRUE == Successful submission |
| 117 | + * FALSE == No submission attempted |
| 118 | + * Anything else == Error to display. |
| 119 | + */ |
120 | 120 | function trySubmit() { |
121 | 121 | // Check for validation |
122 | 122 | foreach ( $this->mFlatFields as $fieldname => $field ) { |
123 | 123 | if ( !empty( $field->mParams['nodata'] ) ) continue; |
124 | | - if ( $field->validate( $this->mFieldData[$fieldname], |
125 | | - $this->mFieldData ) !== true ) { |
126 | | - return isset( $this->mValidationErrorMessage ) ? |
127 | | - $this->mValidationErrorMessage : array( 'htmlform-invalid-input' ); |
| 124 | + if ( $field->validate( |
| 125 | + $this->mFieldData[$fieldname], |
| 126 | + $this->mFieldData ) !== true ) |
| 127 | + { |
| 128 | + return isset( $this->mValidationErrorMessage ) |
| 129 | + ? $this->mValidationErrorMessage |
| 130 | + : array( 'htmlform-invalid-input' ); |
128 | 131 | } |
129 | 132 | } |
130 | 133 | |
— | — | @@ -214,7 +217,7 @@ |
215 | 218 | ) |
216 | 219 | ) . "\n"; |
217 | 220 | } |
218 | | - |
| 221 | + |
219 | 222 | return $html; |
220 | 223 | } |
221 | 224 | |
— | — | @@ -228,7 +231,7 @@ |
229 | 232 | } else { |
230 | 233 | $errorstr = $errors; |
231 | 234 | } |
232 | | - |
| 235 | + |
233 | 236 | $errorstr = Xml::tags( 'div', array( 'class' => 'error' ), $errorstr ); |
234 | 237 | |
235 | 238 | global $wgOut; |
— | — | @@ -288,8 +291,8 @@ |
289 | 292 | foreach ( $fields as $key => $value ) { |
290 | 293 | if ( is_object( $value ) ) { |
291 | 294 | $v = empty( $value->mParams['nodata'] ) |
292 | | - ? $this->mFieldData[$key] |
293 | | - : $value->getDefault(); |
| 295 | + ? $this->mFieldData[$key] |
| 296 | + : $value->getDefault(); |
294 | 297 | $tableHtml .= $value->getTableRow( $v ); |
295 | 298 | |
296 | 299 | if ( $value->getLabel() != ' ' ) |
— | — | @@ -456,8 +459,11 @@ |
457 | 460 | $text = wfMsgExt( $msg, 'parseinline' ); |
458 | 461 | |
459 | 462 | if ( !wfEmptyMsg( $msg, $text ) ) { |
460 | | - $row = Xml::tags( 'td', array( 'colspan' => 2, 'class' => 'htmlform-tip' ), |
461 | | - $text ); |
| 463 | + $row = Xml::tags( |
| 464 | + 'td', |
| 465 | + array( 'colspan' => 2, 'class' => 'htmlform-tip' ), |
| 466 | + $text |
| 467 | + ); |
462 | 468 | |
463 | 469 | $row = Xml::tags( 'tr', null, $row ); |
464 | 470 | |
— | — | @@ -507,7 +513,7 @@ |
508 | 514 | if ( isset( $this->mParams['maxlength'] ) ) { |
509 | 515 | $attribs['maxlength'] = $this->mParams['maxlength']; |
510 | 516 | } |
511 | | - |
| 517 | + |
512 | 518 | if ( !empty( $this->mParams['disabled'] ) ) { |
513 | 519 | $attribs['disabled'] = 'disabled'; |
514 | 520 | } |
— | — | @@ -519,7 +525,6 @@ |
520 | 526 | $attribs |
521 | 527 | ); |
522 | 528 | } |
523 | | - |
524 | 529 | } |
525 | 530 | |
526 | 531 | class HTMLIntField extends HTMLTextField { |
— | — | @@ -661,10 +666,12 @@ |
662 | 667 | $tbAttribs['maxlength'] = $this->mParams['maxlength']; |
663 | 668 | } |
664 | 669 | |
665 | | - $textbox = Xml::input( $this->mName . '-other', |
666 | | - $this->getSize(), |
667 | | - $valInSelect ? '' : $value, |
668 | | - $tbAttribs ); |
| 670 | + $textbox = Xml::input( |
| 671 | + $this->mName . '-other', |
| 672 | + $this->getSize(), |
| 673 | + $valInSelect ? '' : $value, |
| 674 | + $tbAttribs |
| 675 | + ); |
669 | 676 | |
670 | 677 | return "$select<br />\n$textbox"; |
671 | 678 | } |
— | — | @@ -722,9 +729,11 @@ |
723 | 730 | $html .= $this->formatOptions( $info, $value ); |
724 | 731 | } else { |
725 | 732 | $thisAttribs = array( 'id' => $this->mID . "-$info", 'value' => $info ); |
726 | | - |
727 | | - $checkbox = Xml::check( $this->mName . '[]', in_array( $info, $value ), |
728 | | - $attribs + $thisAttribs ); |
| 733 | + |
| 734 | + $checkbox = Xml::check( |
| 735 | + $this->mName . '[]', in_array( $info, $value ), |
| 736 | + $attribs + $thisAttribs |
| 737 | + ); |
729 | 738 | $checkbox .= ' ' . Xml::tags( 'label', array( 'for' => $this->mID . "-$info" ), $label ); |
730 | 739 | |
731 | 740 | $html .= $checkbox . '<br />'; |
— | — | @@ -778,7 +787,7 @@ |
779 | 788 | |
780 | 789 | return $html; |
781 | 790 | } |
782 | | - |
| 791 | + |
783 | 792 | function formatOptions( $options, $value ) { |
784 | 793 | $html = ''; |
785 | 794 | |
Index: trunk/extensions/LiquidThreads/compat/LqtCompatArticle.php |
— | — | @@ -3,28 +3,26 @@ |
4 | 4 | |
5 | 5 | global $wgVersion; |
6 | 6 | if ( version_compare( $wgVersion, '1.16', '<' ) ) { |
7 | | - |
8 | 7 | // LiquidThreads compatibility wrapper around the Article object. |
9 | 8 | class Article_LQT_Compat extends Article { |
10 | | - |
11 | 9 | public function getOutputFromWikitext( $text, $cache = true, $parserOptions = false ) { |
12 | 10 | global $wgParser, $wgOut, $wgEnableParserCache, $wgUseFileCache; |
13 | | - |
| 11 | + |
14 | 12 | if ( !$parserOptions ) { |
15 | 13 | $parserOptions = $wgOut->parserOptions(); |
16 | 14 | } |
17 | | - |
| 15 | + |
18 | 16 | $time = - wfTime(); |
19 | 17 | $parserOutput = $wgParser->parse( $text, $this->mTitle, |
20 | 18 | $parserOptions, true, true, $this->getRevIdFetched() ); |
21 | 19 | $time += wfTime(); |
22 | | - |
| 20 | + |
23 | 21 | # Timing hack |
24 | 22 | if ( $time > 3 ) { |
25 | 23 | wfDebugLog( 'slow-parse', sprintf( "%-5.2f %s", $time, |
26 | 24 | $this->mTitle->getPrefixedDBkey() ) ); |
27 | 25 | } |
28 | | - |
| 26 | + |
29 | 27 | if ( $wgEnableParserCache && $cache && $this && $parserOutput->getCacheTime() != - 1 ) { |
30 | 28 | $parserCache = ParserCache::singleton(); |
31 | 29 | $parserCache->save( $parserOutput, $this, $parserOptions ); |
— | — | @@ -37,34 +35,34 @@ |
38 | 36 | } |
39 | 37 | return $parserOutput; |
40 | 38 | } |
41 | | - |
| 39 | + |
42 | 40 | /** Stolen from 1.16-alpha, for compatibility with 1.15 */ |
43 | 41 | /** Lightweight method to get the parser output for a page, checking the parser cache |
44 | 42 | * and so on. Doesn't consider most of the stuff that Article::view is forced to |
45 | 43 | * consider, so it's not appropriate to use there. */ |
46 | 44 | function getParserOutput( $oldid = null ) { |
47 | 45 | global $wgEnableParserCache, $wgUser, $wgOut; |
48 | | - |
| 46 | + |
49 | 47 | // Should the parser cache be used? |
50 | 48 | $useParserCache = $wgEnableParserCache && |
51 | 49 | intval( $wgUser->getOption( 'stubthreshold' ) ) == 0 && |
52 | 50 | $this->exists() && |
53 | 51 | $oldid === null; |
54 | | - |
| 52 | + |
55 | 53 | wfDebug( __METHOD__ . ': using parser cache: ' . ( $useParserCache ? 'yes' : 'no' ) . "\n" ); |
56 | 54 | if ( $wgUser->getOption( 'stubthreshold' ) ) { |
57 | 55 | wfIncrStats( 'pcache_miss_stub' ); |
58 | 56 | } |
59 | | - |
| 57 | + |
60 | 58 | $parserOutput = false; |
61 | 59 | if ( $useParserCache ) { |
62 | 60 | $parserOutput = ParserCache::singleton()->get( $this, $wgOut->parserOptions() ); |
63 | 61 | } |
64 | | - |
| 62 | + |
65 | 63 | if ( $parserOutput === false ) { |
66 | 64 | // Cache miss; parse and output it. |
67 | 65 | $rev = Revision::newFromTitle( $this->getTitle(), $oldid ); |
68 | | - |
| 66 | + |
69 | 67 | return $this->getOutputFromWikitext( $rev->getText(), $useParserCache ); |
70 | 68 | } else { |
71 | 69 | return $parserOutput; |
Index: trunk/extensions/LiquidThreads/LiquidThreads.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) |
5 | 4 | die(); |
6 | 5 | |
— | — | @@ -24,15 +23,15 @@ |
25 | 24 | define( 'LQT_OLDEST_THREADS', 'ot' ); |
26 | 25 | |
27 | 26 | // FIXME: would be neat if it was possible to somehow localise this. |
28 | | -$wgCanonicalNamespaceNames[NS_LQT_THREAD] = 'Thread'; |
29 | | -$wgCanonicalNamespaceNames[NS_LQT_THREAD_TALK] = 'Thread_talk'; |
30 | | -$wgCanonicalNamespaceNames[NS_LQT_SUMMARY] = 'Summary'; |
31 | | -$wgCanonicalNamespaceNames[NS_LQT_SUMMARY_TALK] = 'Summary_talk'; |
| 27 | +$wgCanonicalNamespaceNames[NS_LQT_THREAD] = 'Thread'; |
| 28 | +$wgCanonicalNamespaceNames[NS_LQT_THREAD_TALK] = 'Thread_talk'; |
| 29 | +$wgCanonicalNamespaceNames[NS_LQT_SUMMARY] = 'Summary'; |
| 30 | +$wgCanonicalNamespaceNames[NS_LQT_SUMMARY_TALK] = 'Summary_talk'; |
32 | 31 | |
33 | 32 | // FIXME: would be neat if it was possible to somehow localise this. |
34 | | -$wgExtraNamespaces[NS_LQT_THREAD] = 'Thread'; |
35 | | -$wgExtraNamespaces[NS_LQT_THREAD_TALK] = 'Thread_talk'; |
36 | | -$wgExtraNamespaces[NS_LQT_SUMMARY] = 'Summary'; |
| 33 | +$wgExtraNamespaces[NS_LQT_THREAD] = 'Thread'; |
| 34 | +$wgExtraNamespaces[NS_LQT_THREAD_TALK] = 'Thread_talk'; |
| 35 | +$wgExtraNamespaces[NS_LQT_SUMMARY] = 'Summary'; |
37 | 36 | $wgExtraNamespaces[NS_LQT_SUMMARY_TALK] = 'Summary_talk'; |
38 | 37 | |
39 | 38 | // Localisation |
— | — | @@ -104,7 +103,7 @@ |
105 | 104 | $wgSpecialPages['NewMessages'] = 'SpecialNewMessages'; |
106 | 105 | $wgSpecialPages['SplitThread'] = 'SpecialSplitThread'; |
107 | 106 | $wgSpecialPages['MergeThread'] = 'SpecialMergeThread'; |
108 | | -//$wgSpecialPages['HotTopics'] = 'SpecialHotTopics'; |
| 107 | +// $wgSpecialPages['HotTopics'] = 'SpecialHotTopics'; |
109 | 108 | $wgSpecialPageGroups['NewMessages'] = 'wiki'; |
110 | 109 | |
111 | 110 | // Classes |
— | — | @@ -160,7 +159,7 @@ |
161 | 160 | $wgLogNames['liquidthreads'] = 'lqt-log-name'; |
162 | 161 | $wgLogHeaders['liquidthreads'] = 'lqt-log-header'; |
163 | 162 | |
164 | | -foreach( array( 'move', 'split', 'merge', 'subjectedit', 'resort' ) as $action ) { |
| 163 | +foreach ( array( 'move', 'split', 'merge', 'subjectedit', 'resort' ) as $action ) { |
165 | 164 | $wgLogActionsHandlers["liquidthreads/$action"] = 'LqtLogFormatter::formatLogEntry'; |
166 | 165 | } |
167 | 166 | |
— | — | @@ -204,9 +203,13 @@ |
205 | 204 | /* Thread actions which do *not* cause threads to be "bumped" to the top */ |
206 | 205 | /* Using numbers because the change type constants are defined in Threads.php, don't |
207 | 206 | want to have to parse it on every page view */ |
208 | | -$wgThreadActionsNoBump = array( 3 /* Edited summary */, 10 /* Merged from */, |
209 | | - 12 /* Split from */, 2 /* Edited root */, |
210 | | - 14 /* Adjusted sortkey */ ); |
| 207 | +$wgThreadActionsNoBump = array( |
| 208 | + 3 /* Edited summary */, |
| 209 | + 10 /* Merged from */, |
| 210 | + 12 /* Split from */, |
| 211 | + 2 /* Edited root */, |
| 212 | + 14 /* Adjusted sortkey */ |
| 213 | +); |
211 | 214 | |
212 | 215 | /** Switch this on if you've migrated from a version before around May 2009 */ |
213 | 216 | $wgLiquidThreadsMigrate = false; |
Index: trunk/extensions/LiquidThreads/classes/HotTopics.php |
— | — | @@ -6,117 +6,115 @@ |
7 | 7 | class LqtHotTopicsController { |
8 | 8 | public static function generateHotTopics( $count = 10 ) { |
9 | 9 | $dbr = wfGetDB( DB_SLAVE ); |
10 | | - |
| 10 | + |
11 | 11 | $now = wfTimestamp( TS_UNIX, wfTimestampNow() ); |
12 | | - $dateCutoff = $dbr->addQuotes( $dbr->timestamp( $now - (7*86400) ) ); |
13 | | - |
| 12 | + $dateCutoff = $dbr->addQuotes( $dbr->timestamp( $now - ( 7 * 86400 ) ) ); |
| 13 | + |
14 | 14 | $conds = array(); |
15 | | -// $conds[] ='th_timestamp>'.$dateCutoff; |
16 | | - |
| 15 | + |
17 | 16 | // Grab the ID cutoff |
18 | 17 | $idCutoff = $dbr->selectField( 'thread_history', 'th_id', |
19 | | - array( 'th_timestamp>'.$dateCutoff ), |
| 18 | + array( 'th_timestamp>' . $dateCutoff ), |
20 | 19 | __METHOD__, |
21 | 20 | array( 'ORDER BY' => 'th_id desc', |
22 | 21 | 'OFFSET' => 10000 ) |
23 | 22 | ); |
24 | | - |
| 23 | + |
25 | 24 | if ( $idCutoff ) { |
26 | 25 | $idCutoff = $dbr->addQuotes( $idCutoff ); |
27 | | - $conds[] = 'th_id>'.$idCutoff; |
| 26 | + $conds[] = 'th_id>' . $idCutoff; |
28 | 27 | } |
29 | | - |
| 28 | + |
30 | 29 | $res = $dbr->select( array( 'thread_history' ), |
31 | 30 | array( 'th_id', 'th_thread', 'th_timestamp' ), |
32 | 31 | $conds, |
33 | 32 | __METHOD__, |
34 | 33 | array( 'LIMIT' => 10000 ) |
35 | 34 | ); |
36 | | - |
| 35 | + |
37 | 36 | $threads = array(); |
38 | | - |
39 | | - foreach( $res as $row ) { |
| 37 | + |
| 38 | + foreach ( $res as $row ) { |
40 | 39 | if ( isset( $threads[$row->th_thread] ) ) { |
41 | 40 | $thread =& $threads[$row->th_thread]; |
42 | 41 | $thread['count']++; |
43 | | - |
| 42 | + |
44 | 43 | if ( $thread['firstpost'] > $row->th_timestamp ) { |
45 | 44 | $thread['firstpost'] = $row->th_timestamp; |
46 | 45 | } |
47 | | - |
| 46 | + |
48 | 47 | if ( $thread['lastpost'] < $row->th_timestamp ) { |
49 | 48 | $thread['lastpost'] = $row->th_timestamp; |
50 | 49 | } |
51 | | - unset($thread); |
| 50 | + unset( $thread ); |
52 | 51 | } else { |
53 | 52 | $thread = array(); |
54 | | - |
| 53 | + |
55 | 54 | $thread['id'] = $row->th_thread; |
56 | 55 | $thread['count'] = 1; |
57 | 56 | $thread['firstpost'] = $row->th_timestamp; |
58 | 57 | $thread['lastpost'] = $row->th_timestamp; |
59 | | - |
| 58 | + |
60 | 59 | $threads[$row->th_thread] = $thread; |
61 | 60 | } |
62 | 61 | } |
63 | | - |
64 | | - foreach( $threads as &$thread ) { |
| 62 | + |
| 63 | + foreach ( $threads as &$thread ) { |
65 | 64 | $thread['rate'] = self::getThreadPostRate( $thread ); |
66 | 65 | } |
67 | | - |
| 66 | + |
68 | 67 | // Filter out useless stuff |
69 | 68 | $threads = array_filter( $threads, array( __CLASS__, 'threadFilterCallback' ) ); |
70 | | - |
| 69 | + |
71 | 70 | // Sort |
72 | 71 | usort( $threads, array( __CLASS__, 'threadSortCallback' ) ); |
73 | | - |
| 72 | + |
74 | 73 | $threads = array_slice( $threads, 0, $count, true ); |
75 | | - |
| 74 | + |
76 | 75 | $outputThreads = array(); |
77 | | - |
78 | | - foreach( $threads as $thread ) { |
| 76 | + |
| 77 | + foreach ( $threads as $thread ) { |
79 | 78 | $outputThreads[$thread['id']] = $thread['id']; |
80 | 79 | } |
81 | | - |
| 80 | + |
82 | 81 | return $outputThreads; |
83 | 82 | } |
84 | | - |
| 83 | + |
85 | 84 | public static function getHotThreads( $count = 10 ) { |
86 | 85 | $topics = array_values( self::generateHotTopics( $count ) ); |
87 | | - |
| 86 | + |
88 | 87 | return Threads::where( array( 'thread_id' => $topics ) ); |
89 | 88 | } |
90 | | - |
| 89 | + |
91 | 90 | public static function threadFilterCallback( $entry ) { |
92 | 91 | return $entry['count'] > 3; |
93 | 92 | } |
94 | | - |
| 93 | + |
95 | 94 | public static function threadSortCallback( $a, $b ) { |
96 | | - $rateA = floatval($a['rate']); |
97 | | - $rateB = floatval($b['rate']); |
98 | | - |
| 95 | + $rateA = floatval( $a['rate'] ); |
| 96 | + $rateB = floatval( $b['rate'] ); |
| 97 | + |
99 | 98 | if ( $rateA == $rateB ) { |
100 | 99 | $val = 0; |
101 | 100 | } elseif ( $rateA < $rateB ) { |
102 | 101 | $val = 1; |
103 | 102 | } elseif ( $rateA > $rateB ) { |
104 | | - $val = -1; |
| 103 | + $val = - 1; |
105 | 104 | } |
106 | | - |
| 105 | + |
107 | 106 | return $val; |
108 | 107 | } |
109 | | - |
| 108 | + |
110 | 109 | public static function getThreadPostRate( $entry ) { |
111 | 110 | if ( $entry['count'] < 2 ) { |
112 | 111 | return 0; |
113 | 112 | } |
114 | | - |
| 113 | + |
115 | 114 | $startTime = wfTimestamp( TS_UNIX, $entry['firstpost'] ); |
116 | 115 | $endTime = wfTimestamp( TS_UNIX, wfTimestampNow() ); |
117 | 116 | $duration = $endTime - $startTime; |
118 | | - |
| 117 | + |
119 | 118 | // Get count over duration, multiply out to give posts per day |
120 | | - |
121 | 119 | return ( $entry['count'] / $duration ) * 86400; |
122 | 120 | } |
123 | 121 | } |
Index: trunk/extensions/LiquidThreads/classes/Dispatch.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class LqtDispatch { |
5 | 4 | /** static cache of per-page LiquidThreads activation setting */ |
6 | 5 | static $userLqtOverride = array(); |
— | — | @@ -13,7 +12,7 @@ |
14 | 13 | $output->redirect( $title->getSubjectPage()->getFullUrl() ); |
15 | 14 | return false; |
16 | 15 | } |
17 | | - |
| 16 | + |
18 | 17 | // If we came here from a red-link, redirect to the thread page. |
19 | 18 | $redlink = $request->getCheck( 'redlink' ) && |
20 | 19 | $request->getText( 'action' ) == 'edit'; |
— | — | @@ -22,21 +21,22 @@ |
23 | 22 | return false; |
24 | 23 | } |
25 | 24 | |
26 | | - /* Certain actions apply to the "header", which is stored in the actual talkpage |
27 | | - in the database. Drop everything and behave like a normal page if those |
28 | | - actions come up, to avoid hacking the various history, editing, etc. code. */ |
| 25 | + /** |
| 26 | + * Certain actions apply to the "header", which is stored in the actual talkpage |
| 27 | + * in the database. Drop everything and behave like a normal page if those |
| 28 | + * actions come up, to avoid hacking the various history, editing, etc. code. |
| 29 | + */ |
29 | 30 | $action = $request->getVal( 'action' ); |
30 | 31 | $header_actions = array( 'history', 'edit', 'submit', 'delete' ); |
31 | 32 | global $wgRequest; |
32 | | - |
| 33 | + |
33 | 34 | $lqt_action = $request->getVal( 'lqt_method' ); |
34 | 35 | if ( $action == 'edit' && $request->getVal( 'section' ) == 'new' ) { |
35 | 36 | // Hijack section=new for "new thread". |
36 | 37 | $request->setVal( 'lqt_method', 'talkpage_new_thread' ); |
37 | 38 | $request->setVal( 'section', '' ); |
38 | | - |
| 39 | + |
39 | 40 | $viewname = 'TalkpageView'; |
40 | | - |
41 | 41 | } elseif ( !$lqt_action && ( in_array( $action, $header_actions ) || |
42 | 42 | $request->getVal( 'diff', null ) !== null ) ) { |
43 | 43 | // Pass through wrapper |
— | — | @@ -49,16 +49,15 @@ |
50 | 50 | } else { |
51 | 51 | $viewname = 'TalkpageView'; |
52 | 52 | } |
53 | | - |
| 53 | + |
54 | 54 | Thread::$titleCacheById[$article->getId()] = $title; |
55 | | - |
| 55 | + |
56 | 56 | $view = new $viewname( $output, $article, $title, $user, $request ); |
57 | 57 | self::$primaryView = $view; |
58 | 58 | return $view->show(); |
59 | 59 | } |
60 | 60 | |
61 | 61 | static function threadPermalinkMain( &$output, &$article, &$title, &$user, &$request ) { |
62 | | - |
63 | 62 | $action = $request->getVal( 'action' ); |
64 | 63 | $lqt_method = $request->getVal( 'lqt_method' ); |
65 | 64 | |
— | — | @@ -82,7 +81,7 @@ |
83 | 82 | } else { |
84 | 83 | $viewname = 'ThreadPermalinkView'; |
85 | 84 | } |
86 | | - |
| 85 | + |
87 | 86 | $view = new $viewname( $output, $article, $title, $user, $request ); |
88 | 87 | self::$primaryView = $view; |
89 | 88 | return $view->show(); |
— | — | @@ -94,53 +93,54 @@ |
95 | 94 | self::$primaryView = $view; |
96 | 95 | return $view->show(); |
97 | 96 | } |
98 | | - |
| 97 | + |
99 | 98 | static function isLqtPage( $title ) { |
100 | 99 | // Ignore it if it's a thread or a summary, makes no sense to have LiquidThreads there. |
101 | 100 | if ( $title->getNamespace() == NS_LQT_THREAD || |
102 | 101 | $title->getNamespace() == NS_LQT_SUMMARY ) { |
103 | 102 | return false; |
104 | 103 | } |
105 | | - |
| 104 | + |
106 | 105 | global $wgLqtPages, $wgLqtTalkPages; |
107 | 106 | $isTalkPage = ( $title->isTalkPage() && $wgLqtTalkPages ) || |
108 | 107 | in_array( $title->getPrefixedText(), $wgLqtPages ); |
109 | | - |
| 108 | + |
110 | 109 | if ( $title->exists() ) { |
111 | 110 | $override = self::getUserLqtOverride( $title ); |
112 | 111 | } else { |
113 | 112 | $override = null; |
114 | 113 | } |
115 | | - |
| 114 | + |
116 | 115 | global $wgLiquidThreadsAllowUserControl; |
117 | | - if ( !is_null($override) && $wgLiquidThreadsAllowUserControl ) { |
| 116 | + if ( !is_null( $override ) && $wgLiquidThreadsAllowUserControl ) { |
118 | 117 | $isTalkPage = $override; |
119 | 118 | } |
120 | | - |
| 119 | + |
121 | 120 | $isTalkPage = $isTalkPage && !$title->isRedirect(); |
122 | | - |
| 121 | + |
123 | 122 | return $isTalkPage; |
124 | 123 | } |
125 | | - |
| 124 | + |
126 | 125 | static function getUserLqtOverride( $title ) { |
127 | | - if ( ! is_object($title) ) { |
| 126 | + if ( ! is_object( $title ) ) { |
128 | 127 | return null; |
129 | 128 | } |
130 | | - |
| 129 | + |
131 | 130 | $articleid = $title->getArticleId(); |
132 | | - |
| 131 | + |
133 | 132 | global $wgLiquidThreadsAllowUserControlNamespaces; |
134 | 133 | global $wgLiquidThreadsAllowUserControl; |
135 | | - if (!$wgLiquidThreadsAllowUserControl) { |
| 134 | + |
| 135 | + if ( !$wgLiquidThreadsAllowUserControl ) { |
136 | 136 | return null; |
137 | 137 | } |
138 | | - |
| 138 | + |
139 | 139 | $namespaces = $wgLiquidThreadsAllowUserControlNamespaces; |
140 | | - |
| 140 | + |
141 | 141 | if ( !is_null( $namespaces ) && !in_array( $title->getNamespace(), $namespaces ) ) { |
142 | 142 | return null; |
143 | 143 | } |
144 | | - |
| 144 | + |
145 | 145 | // Check instance cache. |
146 | 146 | if ( array_key_exists( $articleid, self::$userLqtOverride ) ) { |
147 | 147 | $cacheVal = self::$userLqtOverride[$articleid]; |
— | — | @@ -150,15 +150,20 @@ |
151 | 151 | |
152 | 152 | // Load from the database. |
153 | 153 | $dbr = wfGetDB( DB_SLAVE ); |
154 | | - |
155 | | - $row = $dbr->selectRow( 'page_props', 'pp_value', |
156 | | - array( 'pp_propname' => 'use-liquid-threads', |
157 | | - 'pp_page' => $articleid ), __METHOD__ ); |
158 | 154 | |
159 | | - |
| 155 | + $row = $dbr->selectRow( |
| 156 | + 'page_props', |
| 157 | + 'pp_value', |
| 158 | + array( |
| 159 | + 'pp_propname' => 'use-liquid-threads', |
| 160 | + 'pp_page' => $articleid |
| 161 | + ), |
| 162 | + __METHOD__ |
| 163 | + ); |
| 164 | + |
160 | 165 | if ( $row ) { |
161 | 166 | $dbVal = $row->pp_value; |
162 | | - |
| 167 | + |
163 | 168 | self::$userLqtOverride[$articleid] = $dbVal; |
164 | 169 | return $dbVal; |
165 | 170 | } else { |
— | — | @@ -185,20 +190,20 @@ |
186 | 191 | } |
187 | 192 | return true; |
188 | 193 | } |
189 | | - |
| 194 | + |
190 | 195 | static function onSkinTemplateNavigation( $skinTemplate, &$links ) { |
191 | 196 | if ( !self::$primaryView ) return true; |
192 | | - |
| 197 | + |
193 | 198 | self::$primaryView->customizeNavigation( $skinTemplate, $links ); |
194 | | - |
| 199 | + |
195 | 200 | return true; |
196 | 201 | } |
197 | | - |
| 202 | + |
198 | 203 | static function onSkinTemplateTabs( $skinTemplate, &$links ) { |
199 | 204 | if ( !self::$primaryView ) return true; |
200 | | - |
| 205 | + |
201 | 206 | self::$primaryView->customizeTabs( $skinTemplate, $links ); |
202 | | - |
| 207 | + |
203 | 208 | return true; |
204 | 209 | } |
205 | 210 | } |
Index: trunk/extensions/LiquidThreads/classes/Hooks.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class LqtHooks { |
5 | 4 | // Used to inform hooks about edits that are taking place. |
6 | 5 | public static $editType = null; |
— | — | @@ -7,41 +6,41 @@ |
8 | 7 | public static $editAppliesTo = null; |
9 | 8 | public static $editArticle = null; |
10 | 9 | public static $editTalkpage = null; |
11 | | - |
| 10 | + |
12 | 11 | static function customizeOldChangesList( &$changeslist, &$s, $rc ) { |
13 | 12 | if ( $rc->getTitle()->getNamespace() != NS_LQT_THREAD ) |
14 | 13 | return true; |
15 | | - |
| 14 | + |
16 | 15 | $thread = Threads::withRoot( new Article( $rc->getTitle() ) ); |
17 | 16 | if ( !$thread ) return true; |
18 | 17 | |
19 | 18 | LqtView::addJSandCSS(); |
20 | 19 | wfLoadExtensionMessages( 'LiquidThreads' ); |
21 | | - |
| 20 | + |
22 | 21 | global $wgUser, $wgLang; |
23 | 22 | $sk = $wgUser->getSkin(); |
24 | 23 | |
25 | 24 | // Custom display for new posts. |
26 | 25 | if ( $rc->mAttribs['rc_new'] ) { |
27 | 26 | global $wgOut; |
28 | | - |
| 27 | + |
29 | 28 | // Article link, timestamp, user |
30 | 29 | $s = ''; |
31 | 30 | $s .= $sk->link( $thread->article()->getTitle() ); |
32 | 31 | $changeslist->insertTimestamp( $s, $rc ); |
33 | 32 | $changeslist->insertUserRelatedLinks( $s, $rc ); |
34 | | - |
| 33 | + |
35 | 34 | // Action text |
36 | 35 | $msg = $thread->isTopmostThread() |
37 | 36 | ? 'lqt_rc_new_discussion' : 'lqt_rc_new_reply'; |
38 | 37 | $link = LqtView::linkInContext( $thread ); |
39 | | - $s .= ' '. wfMsgExt( $msg, array( 'parseinline', 'replaceafter' ), $link ); |
40 | | - |
| 38 | + $s .= ' ' . wfMsgExt( $msg, array( 'parseinline', 'replaceafter' ), $link ); |
| 39 | + |
41 | 40 | // add the truncated post content |
42 | 41 | $quote = $thread->root()->getContent(); |
43 | 42 | $quote = $wgLang->truncate( $quote, 200 ); |
44 | 43 | $s .= ' ' . $sk->commentBlock( $quote ); |
45 | | - |
| 44 | + |
46 | 45 | $classes = array(); |
47 | 46 | $changeslist->insertTags( $s, $rc, $classes ); |
48 | 47 | $changeslist->insertExtra( $s, $rc, $classes ); |
— | — | @@ -51,11 +50,11 @@ |
52 | 51 | |
53 | 52 | static function setNewtalkHTML( $skintemplate, $tpl ) { |
54 | 53 | global $wgUser, $wgTitle, $wgOut; |
55 | | - |
| 54 | + |
56 | 55 | if ( ! LqtDispatch::isLqtPage( $wgUser->getTalkPage() ) ) { |
57 | 56 | return true; |
58 | 57 | } |
59 | | - |
| 58 | + |
60 | 59 | wfLoadExtensionMessages( 'LiquidThreads' ); |
61 | 60 | $newmsg_t = SpecialPage::getTitleFor( 'NewMessages' ); |
62 | 61 | $watchlist_t = SpecialPage::getTitleFor( 'Watchlist' ); |
— | — | @@ -75,45 +74,45 @@ |
76 | 75 | |
77 | 76 | return true; |
78 | 77 | } |
79 | | - |
| 78 | + |
80 | 79 | static function beforeWatchlist( &$conds, &$tables, &$join_conds, &$fields ) { |
81 | 80 | global $wgOut, $wgUser; |
82 | | - |
| 81 | + |
83 | 82 | $db = wfGetDB( DB_SLAVE ); |
84 | | - |
| 83 | + |
85 | 84 | if ( !in_array( 'page', $tables ) ) { |
86 | 85 | $tables[] = 'page'; |
87 | 86 | // Yes, this is the correct field to join to. Weird naming. |
88 | 87 | $join_conds['page'] = array( 'LEFT JOIN', 'rc_cur_id=page_id' ); |
89 | 88 | } |
90 | 89 | $conds[] = "page_namespace != " . $db->addQuotes( NS_LQT_THREAD ); |
91 | | - |
| 90 | + |
92 | 91 | $talkpage_messages = NewMessages::newUserMessages( $wgUser ); |
93 | 92 | $tn = count( $talkpage_messages ); |
94 | | - |
| 93 | + |
95 | 94 | $watch_messages = NewMessages::watchedThreadsForUser( $wgUser ); |
96 | 95 | $wn = count( $watch_messages ); |
97 | | - |
| 96 | + |
98 | 97 | if ( $tn == 0 && $wn == 0 ) |
99 | 98 | return true; |
100 | | - |
| 99 | + |
101 | 100 | LqtView::addJSandCSS(); |
102 | 101 | wfLoadExtensionMessages( 'LiquidThreads' ); |
103 | 102 | $messages_title = SpecialPage::getTitleFor( 'NewMessages' ); |
104 | 103 | $new_messages = wfMsgExt( 'lqt-new-messages', 'parseinline' ); |
105 | | - |
| 104 | + |
106 | 105 | $sk = $wgUser->getSkin(); |
107 | 106 | $link = $sk->link( $messages_title, $new_messages, |
108 | 107 | array( 'class' => 'lqt_watchlist_messages_notice' ) ); |
109 | 108 | $wgOut->addHTML( $link ); |
110 | | - |
| 109 | + |
111 | 110 | return true; |
112 | 111 | } |
113 | | - |
| 112 | + |
114 | 113 | static function getPreferences( $user, &$preferences ) { |
115 | 114 | global $wgEnableEmail; |
116 | 115 | wfLoadExtensionMessages( 'LiquidThreads' ); |
117 | | - |
| 116 | + |
118 | 117 | if ( $wgEnableEmail ) { |
119 | 118 | $preferences['lqtnotifytalk'] = |
120 | 119 | array( |
— | — | @@ -122,54 +121,55 @@ |
123 | 122 | 'section' => 'personal/email' |
124 | 123 | ); |
125 | 124 | } |
126 | | - |
127 | | - |
128 | | - $preferences['lqt-watch-threads'] = |
129 | | - array( |
130 | | - 'type' => 'toggle', |
131 | | - 'label-message' => 'lqt-preference-watch-threads', |
132 | | - 'section' => 'watchlist/advancedwatchlist', |
133 | | - ); |
134 | | - |
| 125 | + |
| 126 | + $preferences['lqt-watch-threads'] = array( |
| 127 | + 'type' => 'toggle', |
| 128 | + 'label-message' => 'lqt-preference-watch-threads', |
| 129 | + 'section' => 'watchlist/advancedwatchlist', |
| 130 | + ); |
| 131 | + |
135 | 132 | // Display depth and count |
136 | | - $preferences['lqtdisplaydepth'] = |
137 | | - array( |
138 | | - 'type' => 'int', |
139 | | - 'label-message' => 'lqt-preference-display-depth', |
140 | | - 'section' => 'lqt', |
141 | | - ); |
142 | | - |
143 | | - $preferences['lqtdisplaycount'] = |
144 | | - array( |
145 | | - 'type' => 'int', |
146 | | - 'label-message' => 'lqt-preference-display-count', |
147 | | - 'section' => 'lqt', |
148 | | - ); |
149 | | - |
| 133 | + $preferences['lqtdisplaydepth'] = array( |
| 134 | + 'type' => 'int', |
| 135 | + 'label-message' => 'lqt-preference-display-depth', |
| 136 | + 'section' => 'lqt', |
| 137 | + ); |
| 138 | + |
| 139 | + $preferences['lqtdisplaycount'] = array( |
| 140 | + 'type' => 'int', |
| 141 | + 'label-message' => 'lqt-preference-display-count', |
| 142 | + 'section' => 'lqt', |
| 143 | + ); |
| 144 | + |
150 | 145 | return true; |
151 | 146 | } |
152 | | - |
| 147 | + |
153 | 148 | static function updateNewtalkOnEdit( $article ) { |
154 | 149 | $title = $article->getTitle(); |
155 | | - |
| 150 | + |
156 | 151 | if ( LqtDispatch::isLqtPage( $title ) ) { |
157 | 152 | // They're only editing the header, don't update newtalk. |
158 | 153 | return false; |
159 | 154 | } |
160 | | - |
| 155 | + |
161 | 156 | return true; |
162 | 157 | } |
163 | | - |
| 158 | + |
164 | 159 | static function dumpThreadData( $writer, &$out, $row, $title ) { |
165 | | - $editedStati = array( Threads::EDITED_NEVER => 'never', |
166 | | - Threads::EDITED_HAS_REPLY => 'has-reply', |
167 | | - Threads::EDITED_BY_AUTHOR => 'by-author', |
168 | | - Threads::EDITED_BY_OTHERS => 'by-others' ); |
169 | | - $threadTypes = array( Threads::TYPE_NORMAL => 'normal', |
170 | | - Threads::TYPE_MOVED => 'moved', |
171 | | - Threads::TYPE_DELETED => 'deleted' ); |
| 160 | + $editedStati = array( |
| 161 | + Threads::EDITED_NEVER => 'never', |
| 162 | + Threads::EDITED_HAS_REPLY => 'has-reply', |
| 163 | + Threads::EDITED_BY_AUTHOR => 'by-author', |
| 164 | + Threads::EDITED_BY_OTHERS => 'by-others' |
| 165 | + ); |
| 166 | + $threadTypes = array( |
| 167 | + Threads::TYPE_NORMAL => 'normal', |
| 168 | + Threads::TYPE_MOVED => 'moved', |
| 169 | + Threads::TYPE_DELETED => 'deleted' |
| 170 | + ); |
| 171 | + |
172 | 172 | // Is it a thread |
173 | | - if ( !empty($row->thread_id) ) { |
| 173 | + if ( !empty( $row->thread_id ) ) { |
174 | 174 | $thread = Thread::newFromRow( $row ); |
175 | 175 | $threadInfo = "\n"; |
176 | 176 | $attribs = array(); |
— | — | @@ -186,25 +186,25 @@ |
187 | 187 | $attribs['ThreadAuthor'] = $thread->author()->getName(); |
188 | 188 | $attribs['ThreadEditStatus'] = $editedStati[$thread->editedness()]; |
189 | 189 | $attribs['ThreadType'] = $threadTypes[$thread->type()]; |
190 | | - |
| 190 | + |
191 | 191 | foreach ( $attribs as $key => $value ) { |
192 | 192 | $threadInfo .= "\t" . Xml::element( $key, null, $value ) . "\n"; |
193 | 193 | } |
194 | | - |
| 194 | + |
195 | 195 | $out .= Xml::tags( 'DiscussionThreading', null, $threadInfo ) . "\n"; |
196 | 196 | } |
197 | | - |
| 197 | + |
198 | 198 | return true; |
199 | 199 | } |
200 | | - |
| 200 | + |
201 | 201 | static function modifyExportQuery( $db, &$tables, &$cond, &$opts, &$join ) { |
202 | 202 | $tables[] = 'thread'; |
203 | | - |
| 203 | + |
204 | 204 | $join['thread'] = array( 'left join', array( 'thread_root=page_id' ) ); |
205 | | - |
| 205 | + |
206 | 206 | return true; |
207 | 207 | } |
208 | | - |
| 208 | + |
209 | 209 | static function modifyOAIQuery( &$tables, &$fields, &$conds, |
210 | 210 | &$options, &$join_conds ) { |
211 | 211 | |
— | — | @@ -217,21 +217,21 @@ |
218 | 218 | |
219 | 219 | return true; |
220 | 220 | } |
221 | | - |
| 221 | + |
222 | 222 | static function customiseSearchResultTitle( &$title, &$text, $result, $terms, $page ) { |
223 | 223 | if ( $title->getNamespace() != NS_LQT_THREAD ) { |
224 | 224 | return true; |
225 | 225 | } |
226 | | - |
| 226 | + |
227 | 227 | $thread = Threads::withRoot( new Article( $title ) ); |
228 | 228 | $text = $thread->subject(); |
229 | | - |
| 229 | + |
230 | 230 | $title = clone $thread->topmostThread()->title(); |
231 | 231 | $title->setFragment( '#' . $thread->getAnchorName() ); |
232 | | - |
| 232 | + |
233 | 233 | return true; |
234 | 234 | } |
235 | | - |
| 235 | + |
236 | 236 | static function onUserRename( $renameUserSQL ) { |
237 | 237 | // Always use the job queue, talk page edits will take forever |
238 | 238 | $renameUserSQL->tablesJob['thread'] = |
— | — | @@ -240,76 +240,75 @@ |
241 | 241 | array( 'th_user_text', 'th_user', 'th_timestamp' ); |
242 | 242 | return true; |
243 | 243 | } |
244 | | - |
| 244 | + |
245 | 245 | static function editCheckboxes( $editPage, &$checkboxes, &$tabIndex ) { |
246 | 246 | global $wgRequest; |
247 | 247 | $article = $editPage->getArticle(); |
248 | 248 | $title = $article->getTitle(); |
249 | | - |
| 249 | + |
250 | 250 | if ( !$article->exists() && $title->getNamespace() == NS_LQT_THREAD ) { |
251 | 251 | unset( $checkboxes['minor'] ); |
252 | 252 | } |
253 | | - |
| 253 | + |
254 | 254 | if ( $title->getNamespace() == NS_LQT_THREAD && self::$editType != 'new' ) { |
255 | 255 | wfLoadExtensionMessages( 'LiquidThreads' ); |
256 | 256 | $label = wfMsgExt( 'lqt-edit-bump', 'parseinline' ); |
257 | 257 | $tooltip = wfMsgExt( 'lqt-edit-bump-tooltip', 'parsemag' ); |
258 | | - |
| 258 | + |
259 | 259 | $checked = ! $wgRequest->wasPosted() || |
260 | 260 | $wgRequest->getBool( 'wpBumpThread' ); |
261 | | - |
| 261 | + |
262 | 262 | $html = |
263 | 263 | Xml::check( 'wpBumpThread', $checked, array( |
264 | 264 | 'title' => $tooltip, 'id' => 'wpBumpThread' |
265 | 265 | ) ); |
266 | | - |
| 266 | + |
267 | 267 | $html .= Xml::tags( 'label', array( 'for' => 'wpBumpThread', |
268 | 268 | 'title' => $tooltip ), $label ); |
269 | | - |
| 269 | + |
270 | 270 | $checkboxes['bump'] = $html; |
271 | 271 | } |
272 | | - |
| 272 | + |
273 | 273 | return true; |
274 | 274 | } |
275 | | - |
| 275 | + |
276 | 276 | static function customiseSearchProfiles( &$profiles ) { |
277 | 277 | wfLoadExtensionMessages( 'LiquidThreads' ); |
278 | | - |
| 278 | + |
279 | 279 | $namespaces = array( NS_LQT_THREAD, NS_LQT_SUMMARY ); |
280 | | - |
| 280 | + |
281 | 281 | // Add odd namespaces |
282 | 282 | foreach ( SearchEngine::searchableNamespaces() as $ns => $nsName ) { |
283 | 283 | if ( $ns % 2 == 1 ) { |
284 | 284 | $namespaces[] = $ns; |
285 | 285 | } |
286 | 286 | } |
287 | | - |
| 287 | + |
288 | 288 | $insert = array( |
289 | | - 'threads' => |
290 | | - array( |
291 | | - 'message' => 'searchprofile-threads', |
292 | | - 'tooltip' => 'searchprofile-threads-tooltip', |
293 | | - 'namespaces' => $namespaces, |
294 | | - 'namespace-messages' => SearchEngine::namespacesAsText( $namespaces ), |
295 | | - ), |
| 289 | + 'threads' => array( |
| 290 | + 'message' => 'searchprofile-threads', |
| 291 | + 'tooltip' => 'searchprofile-threads-tooltip', |
| 292 | + 'namespaces' => $namespaces, |
| 293 | + 'namespace-messages' => SearchEngine::namespacesAsText( $namespaces ), |
| 294 | + ), |
296 | 295 | ); |
297 | | - |
| 296 | + |
298 | 297 | $profiles = wfArrayInsertAfter( $profiles, $insert, 'help' ); |
299 | | - |
| 298 | + |
300 | 299 | return true; |
301 | 300 | } |
302 | | - |
| 301 | + |
303 | 302 | public static function onLoadExtensionSchemaUpdates() { |
304 | 303 | global $wgExtNewTables, $wgExtNewFields, $wgExtPGNewFields, |
305 | 304 | $wgExtPGAlteredFields, $wgExtNewIndexes, $wgDBtype; |
306 | 305 | |
307 | 306 | $dir = realpath( dirname( __FILE__ ) . '/..' ); |
308 | | - |
| 307 | + |
309 | 308 | // DB updates |
310 | 309 | $wgExtNewTables[] = array( 'thread', "$dir/lqt.sql" ); |
311 | 310 | $wgExtNewTables[] = array( 'user_message_state', "$dir/lqt.sql" ); |
312 | 311 | $wgExtNewTables[] = array( 'thread_history', "$dir/schema-changes/thread_history_table.sql" ); |
313 | | - |
| 312 | + |
314 | 313 | $wgExtNewFields[] = array( "thread", "thread_article_namespace", "$dir/schema-changes/split-thread_article.sql" ); |
315 | 314 | $wgExtNewFields[] = array( "thread", "thread_article_title", "$dir/schema-changes/split-thread_article.sql" ); |
316 | 315 | $wgExtNewFields[] = array( "thread", "thread_ancestor", "$dir/schema-changes/normalise-ancestry.sql" ); |
— | — | @@ -324,51 +323,51 @@ |
325 | 324 | $wgExtNewFields[] = array( 'thread', 'thread_replies', "$dir/schema-changes/store_reply_count.sql" ); |
326 | 325 | $wgExtNewFields[] = array( 'thread', 'thread_article_id', "$dir/schema-changes/store_article_id.sql" ); |
327 | 326 | $wgExtNewFields[] = array( 'thread', 'thread_signature', "$dir/schema-changes/thread_signature.sql" ); |
328 | | - |
| 327 | + |
329 | 328 | $wgExtNewIndexes[] = array( 'thread', 'thread_summary_page', '(thread_summary_page)' ); |
330 | | - |
| 329 | + |
331 | 330 | return true; |
332 | 331 | } |
333 | | - |
| 332 | + |
334 | 333 | static function onArticleMoveComplete( &$form, &$ot, &$nt ) { |
335 | 334 | // Check if it's a talk page. |
336 | 335 | if ( !LqtDispatch::isLqtPage( $ot ) && !LqtDispatch::isLqtPage( $nt ) ) { |
337 | 336 | return true; |
338 | 337 | } |
339 | | - |
| 338 | + |
340 | 339 | // Synchronise the first 500 threads, in reverse order by thread id. If |
341 | 340 | // there are more threads to synchronise, the job queue will take over. |
342 | 341 | Threads::synchroniseArticleData( new Article( $nt ), 500, 'cascade' ); |
343 | | - |
| 342 | + |
344 | 343 | return true; |
345 | 344 | } |
346 | | - |
| 345 | + |
347 | 346 | static function onArticleMove( $ot, $nt, $user, &$err, $reason ) { |
348 | 347 | // Synchronise article data so that moving the article doesn't break any |
349 | 348 | // article association. |
350 | 349 | Threads::synchroniseArticleData( new Article( $ot ) ); |
351 | | - |
| 350 | + |
352 | 351 | return true; |
353 | 352 | } |
354 | | - |
| 353 | + |
355 | 354 | static function userIsBlockedFrom( $user, $title, &$isBlocked, &$allowUserTalk ) { |
356 | 355 | // Limit applicability |
357 | 356 | if ( !( $isBlocked && $allowUserTalk && $title->getNamespace() == NS_LQT_THREAD ) ) { |
358 | 357 | return true; |
359 | 358 | } |
360 | | - |
| 359 | + |
361 | 360 | // Now we're dealing with blocked users with user talk editing allowed editing pages |
362 | 361 | // in the thread namespace. |
363 | 362 | |
364 | 363 | if ( $title->exists() ) { |
365 | 364 | // If the page actually exists, allow the user to edit posts on their own talk page. |
366 | 365 | $thread = Threads::withRoot( new Article( $title ) ); |
367 | | - |
| 366 | + |
368 | 367 | if ( !$thread ) |
369 | 368 | return true; |
370 | | - |
| 369 | + |
371 | 370 | $articleTitle = $thread->article()->getTitle(); |
372 | | - |
| 371 | + |
373 | 372 | if ( $articleTitle->getNamespace() == NS_USER_TALK && |
374 | 373 | $user->getName() == $title->getText() ) { |
375 | 374 | $isBlocked = false; |
— | — | @@ -386,44 +385,43 @@ |
387 | 386 | self::$editAppliesTo->article()->getTitle()->equals( $talkPage ) ); |
388 | 387 | $isOnTalkPage = $isOnTalkPage || |
389 | 388 | ( self::$editArticle->getTitle()->equals( $talkPage ) ); |
390 | | - |
| 389 | + |
391 | 390 | if ( self::$editArticle->getTitle()->equals( $title ) && $isOnTalkPage ) { |
392 | 391 | $isBlocked = false; |
393 | 392 | return true; |
394 | 393 | } |
395 | 394 | } |
396 | | - |
| 395 | + |
397 | 396 | return true; |
398 | 397 | } |
399 | | - |
| 398 | + |
400 | 399 | static function onPersonalUrls( &$personal_urls, &$title ) { |
401 | 400 | global $wgUser, $wgLang; |
402 | | - |
| 401 | + |
403 | 402 | if ( $wgUser->isAnon() ) return true; |
404 | | - |
| 403 | + |
405 | 404 | wfLoadExtensionMessages( 'LiquidThreads' ); |
406 | | - |
| 405 | + |
407 | 406 | $dbr = wfGetDB( DB_SLAVE ); |
408 | | - |
| 407 | + |
409 | 408 | $newMessagesCount = NewMessages::newMessageCount( $wgUser ); |
410 | | - |
| 409 | + |
411 | 410 | // Add new messages link. |
412 | 411 | $url = SpecialPage::getTitleFor( 'NewMessages' )->getLocalURL(); |
413 | 412 | $msg = $newMessagesCount ? 'lqt-newmessages-n' : 'lqt_newmessages'; |
414 | | - $newMessagesLink = |
415 | | - array( |
416 | | - 'href' => $url, |
417 | | - 'text' => wfMsg( $msg, $wgLang->formatNum( $newMessagesCount ) ), |
418 | | - 'active' => $newMessagesCount > 0, |
419 | | - ); |
420 | | - |
| 413 | + $newMessagesLink = array( |
| 414 | + 'href' => $url, |
| 415 | + 'text' => wfMsg( $msg, $wgLang->formatNum( $newMessagesCount ) ), |
| 416 | + 'active' => $newMessagesCount > 0, |
| 417 | + ); |
| 418 | + |
421 | 419 | $insertUrls = array( 'newmessages' => $newMessagesLink ); |
422 | | - |
| 420 | + |
423 | 421 | $personal_urls = wfArrayInsertAfter( $personal_urls, $insertUrls, 'watchlist' ); |
424 | | - |
| 422 | + |
425 | 423 | return true; |
426 | 424 | } |
427 | | - |
| 425 | + |
428 | 426 | static function onArticleSaveComplete( &$article, &$user, $text, $summary, |
429 | 427 | $minoredit, $watchthis, $sectionanchor, &$flags, $revision, |
430 | 428 | &$status, $baseRevId ) { |
— | — | @@ -431,48 +429,56 @@ |
432 | 430 | // Failed |
433 | 431 | return true; |
434 | 432 | } |
435 | | - |
| 433 | + |
436 | 434 | $title = $article->getTitle(); |
437 | 435 | if ( $title->getNamespace() != NS_LQT_THREAD ) { |
438 | 436 | // Not a thread |
439 | 437 | return true; |
440 | 438 | } |
441 | | - |
442 | | - if (!$baseRevId) { |
| 439 | + |
| 440 | + if ( !$baseRevId ) { |
443 | 441 | // New page |
444 | 442 | return true; |
445 | 443 | } |
446 | | - |
| 444 | + |
447 | 445 | $thread = Threads::withRoot( $article ); |
448 | | - |
449 | | - if (!$thread) { |
| 446 | + |
| 447 | + if ( !$thread ) { |
450 | 448 | // No matching thread. |
451 | 449 | return true; |
452 | 450 | } |
453 | | - |
454 | | - LqtView::postEditUpdates( 'editExisting', null, $article, $thread->article(), |
455 | | - $thread->article(), $summary, $thread, $text ); |
456 | | - |
| 451 | + |
| 452 | + LqtView::postEditUpdates( |
| 453 | + 'editExisting', |
| 454 | + null, |
| 455 | + $article, |
| 456 | + $thread->article(), |
| 457 | + $thread->article(), |
| 458 | + $summary, |
| 459 | + $thread, |
| 460 | + $text |
| 461 | + ); |
| 462 | + |
457 | 463 | return true; |
458 | 464 | } |
459 | | - |
| 465 | + |
460 | 466 | static function getProtectionTypes( $title, &$types ) { |
461 | 467 | $isLqtPage = LqtDispatch::isLqtPage( $title ); |
462 | 468 | $isThread = $title->getNamespace() == NS_LQT_THREAD; |
463 | | - |
| 469 | + |
464 | 470 | if ( !$isLqtPage && !$isThread ) { |
465 | 471 | return true; |
466 | 472 | } |
467 | | - |
| 473 | + |
468 | 474 | if ( $isLqtPage ) { |
469 | 475 | $types[] = 'newthread'; |
470 | 476 | $types[] = 'reply'; |
471 | 477 | } |
472 | | - |
| 478 | + |
473 | 479 | if ( $isThread ) { |
474 | 480 | $types[] = 'reply'; |
475 | 481 | } |
476 | | - |
| 482 | + |
477 | 483 | return true; |
478 | 484 | } |
479 | 485 | } |
Index: trunk/extensions/LiquidThreads/classes/LogFormatter.php |
— | — | @@ -18,27 +18,27 @@ |
19 | 19 | } |
20 | 20 | break; |
21 | 21 | default: |
22 | | - $msg = 'lqt-log-action-'.$action; |
| 22 | + $msg = 'lqt-log-action-' . $action; |
23 | 23 | break; |
24 | 24 | } |
25 | | - |
26 | | - $options = array('parseinline'); |
27 | | - |
| 25 | + |
| 26 | + $options = array( 'parseinline' ); |
| 27 | + |
28 | 28 | $forIRC = self::isForIRC(); |
29 | | - |
30 | | - if ($forIRC) { |
| 29 | + |
| 30 | + if ( $forIRC ) { |
31 | 31 | global $wgContLang; |
32 | 32 | $options['language'] = $wgContLang->getCode(); |
33 | 33 | } |
34 | | - |
| 34 | + |
35 | 35 | $replacements = array_merge( array( $title->getPrefixedText() ), $parameters ); |
36 | | - |
| 36 | + |
37 | 37 | $html = wfMsgExt( $msg, $options, $replacements ); |
38 | | - |
39 | | - if ($forIRC) { |
| 38 | + |
| 39 | + if ( $forIRC ) { |
40 | 40 | $html = StringUtils::delimiterReplace( '<', '>', '', $html ); |
41 | 41 | } |
42 | | - |
| 42 | + |
43 | 43 | return $html; |
44 | 44 | } |
45 | 45 | } |
Index: trunk/extensions/LiquidThreads/classes/NewMessagesController.php |
— | — | @@ -2,7 +2,6 @@ |
3 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
4 | 4 | |
5 | 5 | class NewMessages { |
6 | | - |
7 | 6 | static function markThreadAsUnreadByUser( $thread, $user ) { |
8 | 7 | self::writeUserMessageState( $thread, $user, null ); |
9 | 8 | } |
— | — | @@ -13,7 +12,7 @@ |
14 | 13 | } else if ( is_integer( $thread ) ) { |
15 | 14 | $thread_id = $thread; |
16 | 15 | } else { |
17 | | - throw new MWException( __METHOD__." expected Thread or integer but got $thread" ); |
| 16 | + throw new MWException( __METHOD__ . " expected Thread or integer but got $thread" ); |
18 | 17 | } |
19 | 18 | |
20 | 19 | if ( is_object( $user ) ) { |
— | — | @@ -21,33 +20,37 @@ |
22 | 21 | } else if ( is_integer( $user ) ) { |
23 | 22 | $user_id = $user; |
24 | 23 | } else { |
25 | | - throw new MWException( __METHOD__." expected User or integer but got $user" ); |
| 24 | + throw new MWException( __METHOD__ . " expected User or integer but got $user" ); |
26 | 25 | } |
27 | | - |
| 26 | + |
28 | 27 | $dbw = wfGetDB( DB_MASTER ); |
29 | | - |
30 | | - $dbw->delete( 'user_message_state', |
31 | | - array( 'ums_user' => $user_id, 'ums_thread' => $thread_id ), |
32 | | - __METHOD__ ); |
33 | | - |
| 28 | + |
| 29 | + $dbw->delete( |
| 30 | + 'user_message_state', |
| 31 | + array( 'ums_user' => $user_id, 'ums_thread' => $thread_id ), |
| 32 | + __METHOD__ |
| 33 | + ); |
| 34 | + |
34 | 35 | self::recacheMessageCount( $user_id ); |
35 | 36 | } |
36 | | - |
| 37 | + |
37 | 38 | static function markAllReadByUser( $user ) { |
38 | 39 | if ( is_object( $user ) ) { |
39 | 40 | $user_id = $user->getID(); |
40 | 41 | } else if ( is_integer( $user ) ) { |
41 | 42 | $user_id = $user; |
42 | 43 | } else { |
43 | | - throw new MWException( __METHOD__." expected User or integer but got $user" ); |
| 44 | + throw new MWException( __METHOD__ . " expected User or integer but got $user" ); |
44 | 45 | } |
45 | | - |
| 46 | + |
46 | 47 | $dbw = wfGetDB( DB_MASTER ); |
47 | | - |
48 | | - $dbw->delete( 'user_message_state', |
49 | | - array( 'ums_user' => $user_id ), |
50 | | - __METHOD__ ); |
51 | | - |
| 48 | + |
| 49 | + $dbw->delete( |
| 50 | + 'user_message_state', |
| 51 | + array( 'ums_user' => $user_id ), |
| 52 | + __METHOD__ |
| 53 | + ); |
| 54 | + |
52 | 55 | self::recacheMessageCount( $user_id ); |
53 | 56 | } |
54 | 57 | |
— | — | @@ -69,10 +72,12 @@ |
70 | 73 | } |
71 | 74 | |
72 | 75 | $dbw = wfGetDB( DB_MASTER ); |
73 | | - $dbw->replace( 'user_message_state', array( array( 'ums_user', 'ums_thread' ) ), |
74 | | - array( 'ums_user' => $user_id, 'ums_thread' => $thread_id, |
75 | | - 'ums_read_timestamp' => $timestamp ), __METHOD__ ); |
76 | | - |
| 76 | + $dbw->replace( |
| 77 | + 'user_message_state', array( array( 'ums_user', 'ums_thread' ) ), |
| 78 | + array( 'ums_user' => $user_id, 'ums_thread' => $thread_id, |
| 79 | + 'ums_read_timestamp' => $timestamp ), __METHOD__ |
| 80 | + ); |
| 81 | + |
77 | 82 | self::recacheMessageCount( $user_id ); |
78 | 83 | } |
79 | 84 | |
— | — | @@ -82,7 +87,7 @@ |
83 | 88 | */ |
84 | 89 | static function writeMessageStateForUpdatedThread( $t, $type, $changeUser ) { |
85 | 90 | global $wgUser; |
86 | | - |
| 91 | + |
87 | 92 | wfDebugLog( 'LiquidThreads', 'Doing notifications' ); |
88 | 93 | |
89 | 94 | $dbw = wfGetDB( DB_MASTER ); |
— | — | @@ -91,40 +96,51 @@ |
92 | 97 | $root_t = $t->topmostThread()->root()->getTitle(); |
93 | 98 | |
94 | 99 | // Select any applicable watchlist entries for the thread. |
95 | | - $talkpageWhere = array( 'wl_namespace' => $tpTitle->getNamespace(), |
96 | | - 'wl_title' => $tpTitle->getDBkey() ); |
97 | | - $rootWhere = array( 'wl_namespace' => $root_t->getNamespace(), |
98 | | - 'wl_title' => $root_t->getDBkey() ); |
99 | | - |
| 100 | + $talkpageWhere = array( |
| 101 | + 'wl_namespace' => $tpTitle->getNamespace(), |
| 102 | + 'wl_title' => $tpTitle->getDBkey() |
| 103 | + ); |
| 104 | + $rootWhere = array( |
| 105 | + 'wl_namespace' => $root_t->getNamespace(), |
| 106 | + 'wl_title' => $root_t->getDBkey() |
| 107 | + ); |
| 108 | + |
100 | 109 | $talkpageWhere = $dbw->makeList( $talkpageWhere, LIST_AND ); |
101 | 110 | $rootWhere = $dbw->makeList( $rootWhere, LIST_AND ); |
102 | | - |
| 111 | + |
103 | 112 | $where_clause = $dbw->makeList( array( $talkpageWhere, $rootWhere ), LIST_OR ); |
104 | | - |
| 113 | + |
105 | 114 | // <= 1.15 compatibility, it kinda sucks having to do all this up here. |
106 | 115 | $tables = array( 'watchlist', 'user_message_state' ); |
107 | | - $joins = array( 'user_message_state' => |
108 | | - array( 'left join', |
109 | | - array( 'ums_user=wl_user', 'ums_thread' => $t->id() ) ) ); |
| 116 | + $joins = array( |
| 117 | + 'user_message_state' => |
| 118 | + array( |
| 119 | + 'left join', |
| 120 | + array( |
| 121 | + 'ums_user=wl_user', |
| 122 | + 'ums_thread' => $t->id() |
| 123 | + ) |
| 124 | + ) |
| 125 | + ); |
110 | 126 | $fields = array( 'wl_user', 'ums_user', 'ums_read_timestamp' ); |
111 | | - |
| 127 | + |
112 | 128 | $oldPrefCompat = false; |
113 | 129 | global $wgVersion; |
114 | 130 | if ( version_compare( $wgVersion, '1.15.999', '<=' ) ) { |
115 | 131 | $oldPrefCompat = true; |
116 | | - |
| 132 | + |
117 | 133 | $tables[] = 'user'; |
118 | 134 | $joins['user'] = array( 'left join', 'user_id=wl_user' ); |
119 | 135 | $fields[] = 'user_options'; |
120 | 136 | } else { |
121 | 137 | $tables[] = 'user_properties'; |
122 | | - $joins['user_properties'] = |
| 138 | + $joins['user_properties'] = array( |
| 139 | + 'left join', |
123 | 140 | array( |
124 | | - 'left join', |
125 | | - array( 'up_user=wl_user', |
126 | | - 'up_property' => 'lqtnotifytalk', |
127 | | - ) |
128 | | - ); |
| 141 | + 'up_user=wl_user', |
| 142 | + 'up_property' => 'lqtnotifytalk', |
| 143 | + ) |
| 144 | + ); |
129 | 145 | $fields[] = 'up_value'; |
130 | 146 | } |
131 | 147 | |
— | — | @@ -133,7 +149,7 @@ |
134 | 150 | // notification. |
135 | 151 | $dbr = wfGetDB( DB_SLAVE ); |
136 | 152 | $res = $dbr->select( $tables, $fields, $where_clause, __METHOD__, array(), $joins ); |
137 | | - |
| 153 | + |
138 | 154 | $insert_rows = array(); |
139 | 155 | $update_tuples = array(); |
140 | 156 | $notify_users = array(); |
— | — | @@ -141,24 +157,23 @@ |
142 | 158 | // Don't notify yourself |
143 | 159 | if ( $changeUser->getId() == $row->wl_user ) |
144 | 160 | continue; |
145 | | - |
| 161 | + |
146 | 162 | if ( $row->ums_user && !$row->ums_read_timestamp ) { |
147 | 163 | // It's already positive. |
148 | 164 | } else { |
149 | | - $insert_rows[] = |
150 | | - array( |
151 | | - 'ums_user' => $row->wl_user, |
152 | | - 'ums_thread' => $t->id(), |
153 | | - 'ums_read_timestamp' => null, |
154 | | - ); |
| 165 | + $insert_rows[] = array( |
| 166 | + 'ums_user' => $row->wl_user, |
| 167 | + 'ums_thread' => $t->id(), |
| 168 | + 'ums_read_timestamp' => null, |
| 169 | + ); |
155 | 170 | NewMessages::recacheMessageCount( $row->wl_user ); |
156 | 171 | } |
157 | | - |
| 172 | + |
158 | 173 | $wantsTalkNotification = false; |
159 | | - |
| 174 | + |
160 | 175 | if ( $oldPrefCompat ) { |
161 | 176 | $decodedOptions = self::decodeUserOptions( $row->user_options ); |
162 | | - |
| 177 | + |
163 | 178 | $wantsTalkNotification = ( ( !isset( $decodedOptions['lqtnotifytalk'] ) || is_null( $decodedOptions['lqtnotifytalk'] ) ) && |
164 | 179 | User::getDefaultOption( 'lqtnotifytalk' ) ) || $row->up_value; |
165 | 180 | } else { |
— | — | @@ -166,42 +181,47 @@ |
167 | 182 | ( is_null( $row->up_value ) && User::getDefaultOption( 'lqtnotifytalk' ) ) |
168 | 183 | || $row->up_value; |
169 | 184 | } |
170 | | - |
| 185 | + |
171 | 186 | if ( $wantsTalkNotification ) { |
172 | 187 | $notify_users[] = $row->wl_user; |
173 | 188 | } |
174 | 189 | } |
175 | | - |
| 190 | + |
176 | 191 | // Add user talk notification |
177 | 192 | if ( $t->article()->getTitle()->getNamespace() == NS_USER_TALK ) { |
178 | 193 | $name = $t->article()->getTitle()->getText(); |
179 | | - |
| 194 | + |
180 | 195 | $user = User::newFromName( $name ); |
181 | 196 | if ( $user && $user->getName() != $changeUser->getName() ) { |
182 | 197 | $user->setNewtalk( true ); |
183 | | - |
184 | | - $insert_rows[] = array( 'ums_user' => $user->getId(), |
185 | | - 'ums_thread' => $t->id(), |
186 | | - 'ums_read_timestamp' => null ); |
187 | | - |
| 198 | + |
| 199 | + $insert_rows[] = array( |
| 200 | + 'ums_user' => $user->getId(), |
| 201 | + 'ums_thread' => $t->id(), |
| 202 | + 'ums_read_timestamp' => null |
| 203 | + ); |
| 204 | + |
188 | 205 | if ( $user->getOption( 'enotifusertalkpages' ) ) { |
189 | 206 | $notify_users[] = $user->getId(); |
190 | 207 | } |
191 | 208 | } |
192 | 209 | } |
193 | | - |
| 210 | + |
194 | 211 | // Do the actual updates |
195 | 212 | if ( count( $insert_rows ) ) { |
196 | | - $dbw->replace( 'user_message_state', array( array( 'ums_user', 'ums_thread' ) ), |
197 | | - $insert_rows, __METHOD__ ); |
| 213 | + $dbw->replace( |
| 214 | + 'user_message_state', |
| 215 | + array( array( 'ums_user', 'ums_thread' ) ), |
| 216 | + $insert_rows, __METHOD__ |
| 217 | + ); |
198 | 218 | } |
199 | | - |
| 219 | + |
200 | 220 | global $wgLqtEnotif; |
201 | 221 | if ( count( $notify_users ) && $wgLqtEnotif ) { |
202 | 222 | self::notifyUsersByMail( $t, $notify_users, wfTimestampNow(), $type ); |
203 | 223 | } |
204 | 224 | } |
205 | | - |
| 225 | + |
206 | 226 | // Would refactor User::decodeOptions, but the whole point is that this is |
207 | 227 | // compatible with old code :) |
208 | 228 | static function decodeUserOptions( $str ) { |
— | — | @@ -213,10 +233,10 @@ |
214 | 234 | $opts[$m[1]] = $m[2]; |
215 | 235 | } |
216 | 236 | } |
217 | | - |
| 237 | + |
218 | 238 | return $opts; |
219 | 239 | } |
220 | | - |
| 240 | + |
221 | 241 | static function notifyUsersByMail( $t, $watching_users, $timestamp, $type ) { |
222 | 242 | wfLoadExtensionMessages( 'LiquidThreads' ); |
223 | 243 | $messages = array( |
— | — | @@ -227,7 +247,7 @@ |
228 | 248 | Threads::CHANGE_REPLY_CREATED => 'lqt-enotif-subject-reply', |
229 | 249 | Threads::CHANGE_NEW_THREAD => 'lqt-enotif-subject-newthread', |
230 | 250 | ); |
231 | | - |
| 251 | + |
232 | 252 | if ( !isset( $messages[$type] ) || !isset( $subjects[$type] ) ) { |
233 | 253 | wfDebugLog( 'LiquidThreads', "Email notification failed: type $type unrecognised" ); |
234 | 254 | return; |
— | — | @@ -235,7 +255,7 @@ |
236 | 256 | $msgName = $messages[$type]; |
237 | 257 | $subjectMsg = $subjects[$type]; |
238 | 258 | } |
239 | | - |
| 259 | + |
240 | 260 | // Send email notification, fetching all the data in one go |
241 | 261 | |
242 | 262 | global $wgVersion; |
— | — | @@ -249,31 +269,33 @@ |
250 | 270 | } else { |
251 | 271 | $tables[] = 'user_properties as tc_prop'; |
252 | 272 | $fields[] = 'tc_prop.up_value as timecorrection'; |
253 | | - |
254 | | - $join_conds['user_properties as tc_prop'] = |
255 | | - array( 'left join', |
256 | | - array( |
257 | | - 'up_user=user_id', |
258 | | - 'up_property' => 'timecorrection', |
259 | | - ) |
260 | | - ); |
261 | | - |
| 273 | + |
| 274 | + $join_conds['user_properties as tc_prop'] = array( |
| 275 | + 'left join', |
| 276 | + array( |
| 277 | + 'up_user=user_id', |
| 278 | + 'up_property' => 'timecorrection', |
| 279 | + ) |
| 280 | + ); |
| 281 | + |
262 | 282 | $tables[] = 'user_properties as l_prop'; |
263 | 283 | $fields[] = 'l_prop.up_value as language'; |
264 | | - |
265 | | - $join_conds['user_properties as l_prop'] = |
266 | | - array( 'left join', |
267 | | - array( |
268 | | - 'up_user=user_id', |
269 | | - 'up_property' => 'language', |
270 | | - ) |
271 | | - ); |
| 284 | + |
| 285 | + $join_conds['user_properties as l_prop'] = array( |
| 286 | + 'left join', |
| 287 | + array( |
| 288 | + 'up_user=user_id', |
| 289 | + 'up_property' => 'language', |
| 290 | + ) |
| 291 | + ); |
272 | 292 | } |
273 | | - |
274 | | - $res = $dbr->select( $tables, $fields, |
275 | | - array( 'user_id' => $watching_users ), __METHOD__, |
276 | | - array(), $join_conds ); |
277 | | - |
| 293 | + |
| 294 | + $res = $dbr->select( |
| 295 | + $tables, $fields, |
| 296 | + array( 'user_id' => $watching_users ), __METHOD__, |
| 297 | + array(), $join_conds |
| 298 | + ); |
| 299 | + |
278 | 300 | // Set up one-time data. |
279 | 301 | global $wgPasswordSender; |
280 | 302 | $link_title = clone $t->article()->getTitle(); |
— | — | @@ -282,17 +304,12 @@ |
283 | 305 | $talkPage = $t->article()->getTitle()->getPrefixedText(); |
284 | 306 | $from = new MailAddress( $wgPasswordSender, 'WikiAdmin' ); |
285 | 307 | $threadSubject = $t->subject(); |
286 | | - |
| 308 | + |
287 | 309 | // Parse content and strip HTML of post content |
288 | | - // Doesn't work for some reason (transaction issues?) |
289 | | -// $content = $t->root()->getContent(); |
290 | | -// global $wgOut; |
291 | | -// $html = $wgOut->parse( $content ); |
292 | | -// $text = StringUtils::delimiterReplace( '<', '>', '', $html ); |
293 | 310 | |
294 | 311 | while ( $row = $dbr->fetchObject( $res ) ) { |
295 | 312 | $u = User::newFromRow( $row ); |
296 | | - |
| 313 | + |
297 | 314 | if ( $oldPreferenceFormat ) { |
298 | 315 | $langCode = $u->getOption( 'language' ); |
299 | 316 | } elseif ( $row->language ) { |
— | — | @@ -301,9 +318,9 @@ |
302 | 319 | global $wgLanguageCode; |
303 | 320 | $langCode = $wgLanguageCode; |
304 | 321 | } |
305 | | - |
| 322 | + |
306 | 323 | $lang = Language::factory( $langCode ); |
307 | | - |
| 324 | + |
308 | 325 | // Adjust with time correction |
309 | 326 | if ( $oldPreferenceFormat ) { |
310 | 327 | $timeCorrection = $u->getOption( 'timecorrection' ); |
— | — | @@ -311,96 +328,113 @@ |
312 | 329 | $timeCorrection = $row->timecorrection; |
313 | 330 | } |
314 | 331 | $adjustedTimestamp = $lang->userAdjust( $timestamp, $timeCorrection ); |
315 | | - |
| 332 | + |
316 | 333 | $date = $lang->date( $adjustedTimestamp ); |
317 | 334 | $time = $lang->time( $adjustedTimestamp ); |
318 | | - |
| 335 | + |
319 | 336 | $params = array( $u->getName(), $t->subjectWithoutIncrement(), |
320 | 337 | $date, $time, $talkPage, $permalink ); |
321 | | - |
| 338 | + |
322 | 339 | // Get message in user's own language, bug 20645 |
323 | 340 | $msg = wfMsgReal( $msgName, $params, true /* use DB */, $langCode, |
324 | 341 | true /*transform*/ ); |
325 | | - |
| 342 | + |
326 | 343 | $to = new MailAddress( $u ); |
327 | 344 | $subject = wfMsgReal( $subjectMsg, array( $threadSubject ), true /* use DB */, |
328 | 345 | $langCode, true /* transform */ ); |
329 | | - |
| 346 | + |
330 | 347 | UserMailer::send( $to, $from, $subject, $msg ); |
331 | 348 | } |
332 | 349 | } |
333 | 350 | |
334 | 351 | static function newUserMessages( $user ) { |
335 | 352 | $talkPage = new Article( $user->getUserPage()->getTalkPage() ); |
336 | | - |
| 353 | + |
337 | 354 | $dbr = wfGetDB( DB_SLAVE ); |
338 | | - |
| 355 | + |
339 | 356 | $joinConds = array( 'ums_user' => null ); |
340 | | - $joinConds[] = $dbr->makeList( array( 'ums_user' => $user->getId(), |
341 | | - 'ums_thread=thread_id' ), LIST_AND ); |
| 357 | + $joinConds[] = $dbr->makeList( |
| 358 | + array( |
| 359 | + 'ums_user' => $user->getId(), |
| 360 | + 'ums_thread=thread_id' |
| 361 | + ), |
| 362 | + LIST_AND |
| 363 | + ); |
342 | 364 | $joinClause = $dbr->makeList( $joinConds, LIST_OR ); |
343 | | - |
344 | | - $res = $dbr->select( array( 'thread', 'user_message_state' ), '*', |
345 | | - array( 'ums_read_timestamp' => null, |
346 | | - Threads::articleClause( $talkPage ) ), |
347 | | - __METHOD__, array(), |
348 | | - array( |
349 | | - 'user_message_state' => |
350 | | - array( 'RIGHT JOIN', $joinClause ) |
351 | | - ) ); |
352 | | - |
| 365 | + |
| 366 | + $res = $dbr->select( |
| 367 | + array( 'thread', 'user_message_state' ), |
| 368 | + '*', |
| 369 | + array( |
| 370 | + 'ums_read_timestamp' => null, |
| 371 | + Threads::articleClause( $talkPage ) |
| 372 | + ), |
| 373 | + __METHOD__, |
| 374 | + array(), |
| 375 | + array( |
| 376 | + 'user_message_state' => |
| 377 | + array( 'RIGHT JOIN', $joinClause ) |
| 378 | + ) |
| 379 | + ); |
| 380 | + |
353 | 381 | return Threads::loadFromResult( $res, $dbr ); |
354 | 382 | } |
355 | | - |
| 383 | + |
356 | 384 | static function newMessageCount( $user ) { |
357 | 385 | global $wgMemc; |
358 | | - |
| 386 | + |
359 | 387 | $cval = $wgMemc->get( wfMemcKey( 'lqt-new-messages-count', $user->getId() ) ); |
360 | | - |
| 388 | + |
361 | 389 | if ( $cval ) |
362 | 390 | return $cval; |
363 | | - |
| 391 | + |
364 | 392 | $dbr = wfGetDB( DB_SLAVE ); |
365 | | - |
| 393 | + |
366 | 394 | $cond = array( 'ums_user' => $user->getId(), 'ums_read_timestamp' => null ); |
367 | 395 | $options = array( 'LIMIT' => 500 ); |
368 | | - |
| 396 | + |
369 | 397 | $res = $dbr->select( 'user_message_state', '1', $cond, __METHOD__, $options ); |
370 | | - |
| 398 | + |
371 | 399 | $count = $res->numRows(); |
372 | | - |
| 400 | + |
373 | 401 | if ( $count >= 500 ) { |
374 | 402 | $count = $dbr->estimateRowCount( 'user_message_state', '*', $cond, |
375 | 403 | __METHOD__ ); |
376 | 404 | } |
377 | | - |
| 405 | + |
378 | 406 | $wgMemc->set( wfMemcKey( 'lqt-new-messages-count', $user->getId() ), |
379 | 407 | $count, 86400 ); |
380 | | - |
| 408 | + |
381 | 409 | return $count; |
382 | 410 | } |
383 | | - |
| 411 | + |
384 | 412 | static function recacheMessageCount( $uid ) { |
385 | 413 | global $wgMemc; |
386 | | - |
| 414 | + |
387 | 415 | $wgMemc->delete( wfMemcKey( 'lqt-new-messages-count', $uid ) ); |
388 | 416 | } |
389 | 417 | |
390 | 418 | static function watchedThreadsForUser( $user ) { |
391 | 419 | $talkPage = new Article( $user->getUserPage()->getTalkPage() ); |
392 | | - |
| 420 | + |
393 | 421 | $dbr = wfGetDB( DB_SLAVE ); |
394 | | - |
395 | | - $res = $dbr->select( array( 'thread', 'user_message_state' ), '*', |
396 | | - array( 'ums_read_timestamp' => null, |
397 | | - 'ums_user' => $user->getId(), |
398 | | - 'not (' . Threads::articleClause( $talkPage ) . ')', |
399 | | - ), |
400 | | - __METHOD__, array(), |
401 | | - array( 'user_message_state' => |
402 | | - array( 'INNER JOIN', 'ums_thread=thread_id' ), |
403 | | - ) ); |
404 | | - |
| 422 | + |
| 423 | + $res = $dbr->select( |
| 424 | + array( 'thread', 'user_message_state' ), |
| 425 | + '*', |
| 426 | + array( |
| 427 | + 'ums_read_timestamp' => null, |
| 428 | + 'ums_user' => $user->getId(), |
| 429 | + 'not (' . Threads::articleClause( $talkPage ) . ')', |
| 430 | + ), |
| 431 | + __METHOD__, |
| 432 | + array(), |
| 433 | + array( |
| 434 | + 'user_message_state' => |
| 435 | + array( 'INNER JOIN', 'ums_thread=thread_id' ), |
| 436 | + ) |
| 437 | + ); |
| 438 | + |
405 | 439 | return Threads::loadFromResult( $res, $dbr ); |
406 | 440 | } |
407 | 441 | } |
Index: trunk/extensions/LiquidThreads/classes/ParserFunctions.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class LqtParserFunctions { |
5 | 4 | static function useLiquidThreads( &$parser, $param = '1' ) { |
6 | 5 | $offParams = array( 'no', 'off', 'disable' ); |
— | — | @@ -16,7 +15,7 @@ |
17 | 16 | } |
18 | 17 | |
19 | 18 | static function lqtPageLimit( &$parser, $param = null ) { |
20 | | - if ($param && $param > 0) { |
| 19 | + if ( $param && $param > 0 ) { |
21 | 20 | $parser->mOutput->setProperty( 'lqt-page-limit', $param ); |
22 | 21 | } |
23 | 22 | } |
Index: trunk/extensions/LiquidThreads/classes/SynchroniseThreadArticleDataJob.php |
— | — | @@ -1,7 +1,5 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class SynchroniseThreadArticleDataJob extends Job { |
5 | | - |
6 | 4 | public function __construct( $title, $params ) { |
7 | 5 | parent::__construct( 'synchroniseThreadArticleData', $title, $params ); |
8 | 6 | } |
— | — | @@ -15,11 +13,11 @@ |
16 | 14 | $article = new Article( $this->title ); |
17 | 15 | $limit = $this->params['limit']; |
18 | 16 | $cascade = $this->params['cascade']; |
19 | | - |
20 | | - if ( $article ) |
| 17 | + |
| 18 | + if ( $article ) { |
21 | 19 | Threads::synchroniseArticleData( $article, $limit, $cascade ); |
22 | | - |
| 20 | + } |
| 21 | + |
23 | 22 | return true; |
24 | 23 | } |
25 | | - |
26 | 24 | } |
Index: trunk/extensions/LiquidThreads/classes/ThreadRevision.php |
— | — | @@ -4,73 +4,73 @@ |
5 | 5 | class ThreadRevision { |
6 | 6 | static $load = |
7 | 7 | array( |
8 | | - 'th_id' => 'mId', |
9 | | - 'th_thread' => 'mThreadId', |
10 | | - |
11 | | - 'th_timestamp' => 'mTimestamp', |
12 | | - |
13 | | - 'th_user' => 'mUserId', |
14 | | - 'th_user_text' => 'mUserText', |
15 | | - |
16 | | - 'th_change_type' => 'mChangeType', |
17 | | - 'th_change_object' => 'mChangeObjectId', |
18 | | - 'th_change_comment' => 'mChangeComment', |
19 | | - 'th_content' => 'mObjSer', |
| 8 | + 'th_id' => 'mId', |
| 9 | + 'th_thread' => 'mThreadId', |
| 10 | + |
| 11 | + 'th_timestamp' => 'mTimestamp', |
| 12 | + |
| 13 | + 'th_user' => 'mUserId', |
| 14 | + 'th_user_text' => 'mUserText', |
| 15 | + |
| 16 | + 'th_change_type' => 'mChangeType', |
| 17 | + 'th_change_object' => 'mChangeObjectId', |
| 18 | + 'th_change_comment' => 'mChangeComment', |
| 19 | + 'th_content' => 'mObjSer', |
20 | 20 | ); |
21 | | - |
| 21 | + |
22 | 22 | protected $mId, $mThreadId, $mTimestamp, $mUserId, $mUserText, $mChangeType, |
23 | 23 | $mChangeObjectId, $mChangeObject, $mChangeComment, $mObjSer, $mThreadObj; |
24 | | - |
| 24 | + |
25 | 25 | static function loadFromId( $id ) { |
26 | 26 | $dbr = wfGetDB( DB_SLAVE ); |
27 | 27 | $row = $dbr->selectRow( 'thread_history', '*', array( 'th_id' => $id ), __METHOD__ ); |
28 | | - |
29 | | - if (!$row) return null; |
30 | | - |
| 28 | + |
| 29 | + if ( !$row ) return null; |
| 30 | + |
31 | 31 | return self::loadFromRow( $row ); |
32 | 32 | } |
33 | | - |
| 33 | + |
34 | 34 | static function loadFromRow( $row ) { |
35 | | - if (!$row) return null; |
36 | | - |
| 35 | + if ( !$row ) return null; |
| 36 | + |
37 | 37 | $rev = new ThreadRevision; |
38 | | - |
| 38 | + |
39 | 39 | foreach ( self::$load as $col => $field ) { |
40 | 40 | $rev->$field = $row->$col; |
41 | 41 | } |
42 | | - |
| 42 | + |
43 | 43 | $rev->mUser = User::newFromName( $rev->mUserText, /* Don't validate */ false ); |
44 | 44 | $rev->mThreadObj = unserialize( $rev->mObjSer ); |
45 | | - |
| 45 | + |
46 | 46 | return $rev; |
47 | 47 | } |
48 | | - |
| 48 | + |
49 | 49 | static function create( $thread, $change_type, $change_object = null, $comment = '', |
50 | 50 | $user = null, $timestamp = null ) { |
51 | 51 | if ( is_null( $user ) ) { |
52 | 52 | global $wgUser; |
53 | 53 | $user = $wgUser; |
54 | 54 | } |
55 | | - |
| 55 | + |
56 | 56 | if ( is_null( $timestamp ) ) { |
57 | 57 | $timestamp = wfTimestampNow(); |
58 | 58 | } |
59 | | - |
| 59 | + |
60 | 60 | if ( is_null( $comment ) ) { |
61 | 61 | $comment = ''; |
62 | 62 | } |
63 | | - |
| 63 | + |
64 | 64 | $rev = new ThreadRevision; |
65 | | - |
| 65 | + |
66 | 66 | $rev->mThreadId = $thread->topmostThread()->id(); |
67 | 67 | $rev->mTimestamp = $timestamp; |
68 | | - |
| 68 | + |
69 | 69 | $rev->mUser = $user; |
70 | 70 | $rev->mUserId = $user->getId(); |
71 | 71 | $rev->mUserText = $user->getName(); |
72 | | - |
| 72 | + |
73 | 73 | $rev->mChangeType = $change_type; |
74 | | - |
| 74 | + |
75 | 75 | if ( $change_object instanceof Thread ) { |
76 | 76 | $rev->mChangeObjectId = $change_object->id(); |
77 | 77 | $rev->mChangeObject = $change_object; |
— | — | @@ -80,128 +80,128 @@ |
81 | 81 | } else { |
82 | 82 | $rev->mChangeObjectId = $change_object; |
83 | 83 | } |
84 | | - |
| 84 | + |
85 | 85 | $rev->mChangeComment = $comment; |
86 | | - |
| 86 | + |
87 | 87 | $rev->mThreadObj = $thread->topmostThread(); |
88 | 88 | $rev->mObjSer = serialize( $rev->mThreadObj ); |
89 | | - |
| 89 | + |
90 | 90 | $rev->insert(); |
91 | | - |
| 91 | + |
92 | 92 | return $rev; |
93 | 93 | } |
94 | | - |
| 94 | + |
95 | 95 | function insert() { |
96 | 96 | $dbw = wfGetDB( DB_MASTER ); |
97 | | - |
| 97 | + |
98 | 98 | $row = $this->getRow(); |
99 | 99 | $row['th_id'] = $dbw->nextSequenceValue( 'thread_history_th_id' ); |
100 | | - |
| 100 | + |
101 | 101 | $dbw->insert( 'thread_history', $row, __METHOD__ ); |
102 | | - |
| 102 | + |
103 | 103 | $this->mId = $dbw->insertId(); |
104 | 104 | } |
105 | | - |
| 105 | + |
106 | 106 | function save() { |
107 | 107 | $row = $this->getRow(); |
108 | | - |
| 108 | + |
109 | 109 | $dbw = wfGetDB( DB_MASTER ); |
110 | | - |
| 110 | + |
111 | 111 | $dbw->replace( 'thread_history', array( 'th_thread' ), $row, __METHOD__ ); |
112 | 112 | } |
113 | | - |
| 113 | + |
114 | 114 | function getRow() { |
115 | 115 | $row = array(); |
116 | | - |
| 116 | + |
117 | 117 | // First, prep the data for insertion |
118 | 118 | $dbw = wfGetDB( DB_MASTER ); |
119 | 119 | $this->mTimestamp = $dbw->timestamp( $this->mTimestamp ); |
120 | | - |
| 120 | + |
121 | 121 | foreach ( self::$load as $col => $field ) { |
122 | 122 | $row[$col] = $this->$field; |
123 | 123 | } |
124 | | - |
| 124 | + |
125 | 125 | return $row; |
126 | 126 | } |
127 | | - |
| 127 | + |
128 | 128 | function getTimestamp() { |
129 | 129 | return wfTimestamp( TS_MW, $this->mTimestamp ); |
130 | 130 | } |
131 | | - |
| 131 | + |
132 | 132 | function getUser() { |
133 | 133 | if ( $this->mUserId ) { |
134 | 134 | return User::newFromId( $this->mUserId ); |
135 | 135 | } |
136 | | - |
| 136 | + |
137 | 137 | return User::newFromText( $this->mUserText, /* No validation */ false ); |
138 | 138 | } |
139 | | - |
| 139 | + |
140 | 140 | function getChangeType() { |
141 | 141 | return $this->mChangeType; |
142 | 142 | } |
143 | | - |
| 143 | + |
144 | 144 | function getChangeObject() { |
145 | | - if ( is_null($this->mChangeObject) && $this->mChangeObjectId ) { |
| 145 | + if ( is_null( $this->mChangeObject ) && $this->mChangeObjectId ) { |
146 | 146 | $threadObj = $this->getThreadObj(); |
147 | | - |
| 147 | + |
148 | 148 | if ( $threadObj instanceof Thread ) { |
149 | 149 | $objectId = $this->mChangeObjectId; |
150 | 150 | $this->mChangeObject = $threadObj->replyWithId( $objectId ); |
151 | 151 | } |
152 | | - |
| 152 | + |
153 | 153 | if ( !$this->mChangeObject ) { |
154 | 154 | $this->mChangeObject = false; |
155 | 155 | } |
156 | 156 | } |
157 | | - |
| 157 | + |
158 | 158 | return $this->mChangeObject; |
159 | 159 | } |
160 | | - |
| 160 | + |
161 | 161 | function getChangeComment() { |
162 | 162 | return $this->mChangeComment; |
163 | 163 | } |
164 | | - |
| 164 | + |
165 | 165 | function getId() { |
166 | 166 | return $this->mId; |
167 | 167 | } |
168 | | - |
| 168 | + |
169 | 169 | function getThreadObj() { |
170 | | - if ( is_null($this->mThreadObj) && !is_null($this->mObjSer) ) { |
| 170 | + if ( is_null( $this->mThreadObj ) && !is_null( $this->mObjSer ) ) { |
171 | 171 | $this->mThreadObj = unserialize( $this->mObjSer ); |
172 | | - } elseif ( is_null($this->mThreadObj) && is_null($this->mObjSer) ) { |
173 | | - var_dump($this); |
| 172 | + } elseif ( is_null( $this->mThreadObj ) && is_null( $this->mObjSer ) ) { |
| 173 | + var_dump( $this ); |
174 | 174 | throw new MWException( "Missing mObjSer" ); |
175 | 175 | } |
176 | | - |
177 | | - if ( !($this->mThreadObj instanceof Thread) ) { |
| 176 | + |
| 177 | + if ( !( $this->mThreadObj instanceof Thread ) ) { |
178 | 178 | $this->mThreadObj = false; |
179 | 179 | return false; |
180 | 180 | } |
181 | | - |
| 181 | + |
182 | 182 | $this->mThreadObj->threadRevision = $this; |
183 | | - |
| 183 | + |
184 | 184 | return $this->mThreadObj; |
185 | 185 | } |
186 | | - |
| 186 | + |
187 | 187 | function prev() { |
188 | 188 | $dbr = wfGetDB( DB_SLAVE ); |
189 | | - |
190 | | - $cond = 'th_id<' . $dbr->addQuotes( intval($this->getId()) ); |
| 189 | + |
| 190 | + $cond = 'th_id<' . $dbr->addQuotes( intval( $this->getId() ) ); |
191 | 191 | $row = $dbr->selectRow( 'thread_history', '*', |
192 | 192 | array( $cond, 'th_thread' => $this->mThreadId ), |
193 | 193 | __METHOD__ ); |
194 | | - |
| 194 | + |
195 | 195 | return self::loadFromRow( $row ); |
196 | 196 | } |
197 | | - |
| 197 | + |
198 | 198 | function next() { |
199 | 199 | $dbr = wfGetDB( DB_SLAVE ); |
200 | | - |
201 | | - $cond = 'th_id>' . $dbr->addQuotes( intval($this->getId()) ); |
| 200 | + |
| 201 | + $cond = 'th_id>' . $dbr->addQuotes( intval( $this->getId() ) ); |
202 | 202 | $row = $dbr->selectRow( 'thread_history', '*', |
203 | 203 | array( $cond, 'th_thread' => $this->mThreadId ), |
204 | 204 | __METHOD__ ); |
205 | | - |
| 205 | + |
206 | 206 | return self::loadFromRow( $row ); |
207 | 207 | } |
208 | 208 | } |
Index: trunk/extensions/LiquidThreads/classes/DeletionController.php |
— | — | @@ -1,27 +1,26 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class LqtDeletionController { |
5 | 4 | static $pageids_to_revive; |
6 | | - |
| 5 | + |
7 | 6 | static function onArticleDeleteComplete( &$article, &$user, $reason, $id ) { |
8 | 7 | $title = $article->getTitle(); |
9 | | - |
| 8 | + |
10 | 9 | if ( $title->getNamespace() != NS_LQT_THREAD ) { |
11 | 10 | return true; |
12 | 11 | } |
13 | | - |
| 12 | + |
14 | 13 | $threads = Threads::where( array( 'thread_root' => $id ) ); |
15 | | - |
| 14 | + |
16 | 15 | if ( !count( $threads ) ) { |
17 | 16 | wfDebugLog( __METHOD__ . ": no threads with root $id, ignoring...\n" ); |
18 | 17 | return true; |
19 | 18 | } |
20 | | - |
| 19 | + |
21 | 20 | $thread = array_pop( $threads ); |
22 | | - |
| 21 | + |
23 | 22 | // Mark the thread as deleted |
24 | 23 | $thread->delete( $reason ); |
25 | | - |
| 24 | + |
26 | 25 | // Avoid orphaning subthreads, update their parentage. |
27 | 26 | wfLoadExtensionMessages( 'LiquidThreads' ); |
28 | 27 | if ( $thread->replies() && $thread->isTopmostThread() ) { |
— | — | @@ -35,14 +34,14 @@ |
36 | 35 | $reply->save( ); |
37 | 36 | } |
38 | 37 | } |
39 | | - |
| 38 | + |
40 | 39 | // Synchronise the first 500 threads, in reverse order by thread id. If |
41 | 40 | // there are more threads to synchronise, the job queue will take over. |
42 | 41 | Threads::synchroniseArticleData( $article, 500, 'cascade' ); |
43 | | - |
| 42 | + |
44 | 43 | return true; |
45 | 44 | } |
46 | | - |
| 45 | + |
47 | 46 | static function recursivelyDeleteReplies( $thread, $reason ) { |
48 | 47 | foreach ( $thread->replies() as $reply ) { |
49 | 48 | $reply->root()->doDeleteArticle( $reason, false, $reply->root()->getId() ); |
— | — | @@ -50,36 +49,36 @@ |
51 | 50 | self::recursivelyDeleteReplies( $reply, $reason ); |
52 | 51 | } |
53 | 52 | } |
54 | | - |
| 53 | + |
55 | 54 | static function onArticleRevisionUndeleted( &$title, $revision, $page_id ) { |
56 | 55 | if ( $title->getNamespace() == NS_LQT_THREAD ) { |
57 | 56 | self::$pageids_to_revive[$page_id] = $title; |
58 | 57 | } |
59 | | - |
| 58 | + |
60 | 59 | return true; |
61 | 60 | } |
62 | | - |
| 61 | + |
63 | 62 | static function onArticleUndelete( &$udTitle, $created, $comment = '' ) { |
64 | 63 | if ( empty( self::$pageids_to_revive ) ) { |
65 | 64 | return true; |
66 | 65 | } |
67 | | - |
| 66 | + |
68 | 67 | foreach ( self::$pageids_to_revive as $pageid => $title ) { |
69 | 68 | if ( $pageid == 0 ) { |
70 | 69 | continue; |
71 | 70 | } |
72 | | - |
| 71 | + |
73 | 72 | // Try to get comment for old versions where it isn't passed, hacky :( |
74 | 73 | if ( !$comment ) { |
75 | 74 | global $wgRequest; |
76 | 75 | $comment = $wgRequest->getText( 'wpComment' ); |
77 | 76 | } |
78 | | - |
| 77 | + |
79 | 78 | // TX has not been committed yet, so we must select from the master |
80 | 79 | $dbw = wfGetDB( DB_MASTER ); |
81 | 80 | $res = $dbw->select( 'thread', '*', array( 'thread_root' => $pageid ), __METHOD__ ); |
82 | 81 | $threads = Threads::loadFromResult( $res, $dbw ); |
83 | | - |
| 82 | + |
84 | 83 | if ( count( $threads ) ) { |
85 | 84 | $thread = array_pop( $threads ); |
86 | 85 | $thread->setRoot( new Article( $title ) ); |
— | — | @@ -88,35 +87,39 @@ |
89 | 88 | wfDebug( __METHOD__ . ":No thread found with root set to $pageid (??)\n" ); |
90 | 89 | } |
91 | 90 | } |
92 | | - |
| 91 | + |
93 | 92 | // Synchronise the first 500 threads, in reverse order by thread id. If |
94 | 93 | // there are more threads to synchronise, the job queue will take over. |
95 | 94 | Threads::synchroniseArticleData( new Article( $udTitle ), 500, 'cascade' ); |
96 | | - |
| 95 | + |
97 | 96 | return true; |
98 | 97 | } |
99 | | - |
| 98 | + |
100 | 99 | static function onArticleConfirmDelete( $article, $out, &$reason ) { |
101 | | - if ( $article->getTitle()->getNamespace() != NS_LQT_THREAD ) return true; |
102 | | - |
| 100 | + if ( $article->getTitle()->getNamespace() != NS_LQT_THREAD ) { |
| 101 | + return true; |
| 102 | + } |
| 103 | + |
103 | 104 | $thread = Threads::withRoot( $article ); |
104 | | - |
| 105 | + |
105 | 106 | if ( !$thread ) return true; |
106 | | - |
| 107 | + |
107 | 108 | if ( $thread->isTopmostThread() && count( $thread->replies() ) ) { |
108 | 109 | wfLoadExtensionMessages( 'LiquidThreads' ); |
109 | | - $out->wrapWikiMsg( '<strong>$1</strong>', |
110 | | - 'lqt-delete-parent-warning' ); |
| 110 | + $out->wrapWikiMsg( |
| 111 | + '<strong>$1</strong>', |
| 112 | + 'lqt-delete-parent-warning' |
| 113 | + ); |
111 | 114 | } |
112 | | - |
| 115 | + |
113 | 116 | return true; |
114 | 117 | } |
115 | | - |
| 118 | + |
116 | 119 | static function onArticleDelete( $article ) { |
117 | 120 | // Synchronise article data so that moving the article doesn't break any |
118 | 121 | // article association. |
119 | 122 | Threads::synchroniseArticleData( $article ); |
120 | | - |
| 123 | + |
121 | 124 | return true; |
122 | 125 | } |
123 | 126 | } |
Index: trunk/extensions/LiquidThreads/classes/Thread.php |
— | — | @@ -33,36 +33,36 @@ |
34 | 34 | protected $authorId; |
35 | 35 | protected $authorName; |
36 | 36 | protected $signature; |
37 | | - |
| 37 | + |
38 | 38 | protected $allDataLoaded; |
39 | | - |
| 39 | + |
40 | 40 | protected $isHistorical = false; |
41 | | - |
| 41 | + |
42 | 42 | protected $rootRevision; |
43 | 43 | |
44 | 44 | /* Flag about who has edited or replied to this thread. */ |
45 | 45 | protected $editedness; |
46 | 46 | |
47 | 47 | protected $replies; |
48 | | - |
| 48 | + |
49 | 49 | public $dbVersion; // A copy of the thread as it exists in the database. |
50 | | - |
| 50 | + |
51 | 51 | static $titleCacheById = array(); |
52 | 52 | static $replyCacheById = array(); |
53 | 53 | static $articleCacheById = array(); |
54 | | - |
| 54 | + |
55 | 55 | static $VALID_TYPES = array( Threads::TYPE_NORMAL, Threads::TYPE_MOVED, Threads::TYPE_DELETED ); |
56 | 56 | |
57 | 57 | function isHistorical() { |
58 | 58 | return $this->isHistorical; |
59 | 59 | } |
60 | | - |
| 60 | + |
61 | 61 | static function create( $root, $article, $superthread = null, |
62 | | - $type = Threads::TYPE_NORMAL, $subject = '', |
63 | | - $summary = '', $bump = null, $signature = null ) { |
| 62 | + $type = Threads::TYPE_NORMAL, $subject = '', |
| 63 | + $summary = '', $bump = null, $signature = null ) { |
64 | 64 | |
65 | 65 | $dbw = wfGetDB( DB_MASTER ); |
66 | | - |
| 66 | + |
67 | 67 | $thread = new Thread( null ); |
68 | 68 | |
69 | 69 | if ( !in_array( $type, self::$VALID_TYPES ) ) { |
— | — | @@ -80,71 +80,73 @@ |
81 | 81 | $timestamp = wfTimestampNow(); |
82 | 82 | |
83 | 83 | $thread->setAuthor( $wgUser ); |
84 | | - |
85 | | - if ( is_object( $root ) ) |
| 84 | + |
| 85 | + if ( is_object( $root ) ) { |
86 | 86 | $thread->setRoot( $root ); |
87 | | - else |
| 87 | + } else { |
88 | 88 | $thread->setRootId( $root ); |
| 89 | + } |
| 90 | + |
89 | 91 | $thread->setSuperthread( $superthread ); |
90 | 92 | $thread->setArticle( $article ); |
91 | 93 | $thread->setSubject( $subject ); |
92 | 94 | $thread->setType( $type ); |
93 | | - |
94 | | - if ( !is_null($signature) ) { |
| 95 | + |
| 96 | + if ( !is_null( $signature ) ) { |
95 | 97 | $thread->setSignature( $signature ); |
96 | 98 | } |
97 | | - |
| 99 | + |
98 | 100 | $thread->insert(); |
99 | | - |
| 101 | + |
100 | 102 | if ( $superthread ) { |
101 | 103 | $superthread->addReply( $thread ); |
102 | | - |
| 104 | + |
103 | 105 | $superthread->commitRevision( $change_type, $thread, $summary, $bump ); |
104 | 106 | } else { |
105 | 107 | $hthread = ThreadRevision::create( $thread, $change_type ); |
106 | 108 | } |
107 | | - |
| 109 | + |
108 | 110 | // Create talk page |
109 | 111 | Threads::createTalkpageIfNeeded( $article ); |
110 | 112 | |
111 | 113 | // Notifications |
112 | 114 | NewMessages::writeMessageStateForUpdatedThread( $thread, $change_type, $wgUser ); |
113 | | - |
| 115 | + |
114 | 116 | if ( $wgUser->getOption( 'lqt-watch-threads', false ) ) { |
115 | 117 | $thread->topmostThread()->root()->doWatch(); |
116 | 118 | } |
117 | 119 | |
118 | 120 | return $thread; |
119 | 121 | } |
120 | | - |
| 122 | + |
121 | 123 | function insert() { |
122 | 124 | $this->dieIfHistorical(); |
123 | | - |
| 125 | + |
124 | 126 | $dbw = wfGetDB( DB_MASTER ); |
125 | | - |
| 127 | + |
126 | 128 | $row = $this->getRow(); |
127 | 129 | $row['thread_id'] = $dbw->nextSequenceValue( 'thread_thread_id' ); |
128 | | - |
| 130 | + |
129 | 131 | $dbw->insert( 'thread', $row, __METHOD__ ); |
130 | 132 | $this->id = $dbw->insertId(); |
131 | | - |
| 133 | + |
132 | 134 | // Touch the root |
133 | 135 | if ( $this->root() ) { |
134 | 136 | $this->root()->getTitle()->invalidateCache(); |
135 | 137 | } |
136 | | - |
| 138 | + |
137 | 139 | // Touch the talk page, too. |
138 | 140 | $this->article()->getTitle()->invalidateCache(); |
139 | | - |
| 141 | + |
140 | 142 | $this->dbVersion = clone $this; |
141 | 143 | unset( $this->dbVersion->dbVersion ); |
142 | 144 | } |
143 | | - |
| 145 | + |
144 | 146 | function setRoot( $article ) { |
145 | 147 | $this->rootId = $article->getId(); |
146 | 148 | $this->root = $article; |
147 | 149 | } |
148 | | - |
| 150 | + |
149 | 151 | function setRootId( $article ) { |
150 | 152 | $this->rootId = $article; |
151 | 153 | $this->root = null; |
— | — | @@ -154,26 +156,26 @@ |
155 | 157 | $bump = null ) { |
156 | 158 | $this->dieIfHistorical(); |
157 | 159 | global $wgUser; |
158 | | - |
| 160 | + |
159 | 161 | global $wgThreadActionsNoBump; |
160 | | - if ( is_null($bump) ) { |
| 162 | + if ( is_null( $bump ) ) { |
161 | 163 | $bump = !in_array( $change_type, $wgThreadActionsNoBump ); |
162 | 164 | } |
163 | 165 | if ( $bump ) { |
164 | 166 | $this->sortkey = wfTimestamp( TS_MW ); |
165 | 167 | } |
166 | | - |
| 168 | + |
167 | 169 | $original = $this->dbVersion; |
168 | 170 | |
169 | 171 | $this->modified = wfTimestampNow(); |
170 | 172 | $this->updateEditedness( $change_type ); |
171 | 173 | $this->save( __METHOD__ . "/" . wfGetCaller() ); |
172 | | - |
| 174 | + |
173 | 175 | $topmost = $this->topmostThread(); |
174 | 176 | $topmost->modified = wfTimestampNow(); |
175 | 177 | if ( $bump ) $topmost->setSortkey( wfTimestamp( TS_MW ) ); |
176 | 178 | $topmost->save(); |
177 | | - |
| 179 | + |
178 | 180 | ThreadRevision::create( $this, $change_type, $change_object, $reason ); |
179 | 181 | $this->logChange( $change_type, $original, $change_object, $reason ); |
180 | 182 | |
— | — | @@ -181,14 +183,14 @@ |
182 | 184 | NewMessages::writeMessageStateForUpdatedThread( $this, $change_type, $wgUser ); |
183 | 185 | } |
184 | 186 | } |
185 | | - |
| 187 | + |
186 | 188 | function logChange( $change_type, $original, $change_object = null, $reason = '' ) { |
187 | 189 | $log = new LogPage( 'liquidthreads' ); |
188 | | - |
189 | | - if ( is_null($reason) ) { |
| 190 | + |
| 191 | + if ( is_null( $reason ) ) { |
190 | 192 | $reason = ''; |
191 | 193 | } |
192 | | - |
| 194 | + |
193 | 195 | switch( $change_type ) { |
194 | 196 | case Threads::CHANGE_MOVED_TALKPAGE: |
195 | 197 | $log->addEntry( 'move', $this->title(), $reason, |
— | — | @@ -209,8 +211,8 @@ |
210 | 212 | $oldParent = $change_object->dbVersion->isTopmostThread() |
211 | 213 | ? '' |
212 | 214 | : $change_object->dbVersion->superthread()->title(); |
213 | | - |
214 | | - |
| 215 | + |
| 216 | + |
215 | 217 | $log->addEntry( 'merge', $this->title(), $reason, |
216 | 218 | array( $oldParent, $change_object->superthread()->title() ) ); |
217 | 219 | break; |
— | — | @@ -219,16 +221,16 @@ |
220 | 222 | array( $original->sortkey(), $this->sortkey() ) ); |
221 | 223 | } |
222 | 224 | } |
223 | | - |
| 225 | + |
224 | 226 | function updateEditedness( $change_type ) { |
225 | 227 | global $wgUser; |
226 | | - |
| 228 | + |
227 | 229 | if ( $change_type == Threads::CHANGE_REPLY_CREATED |
228 | 230 | && $this->editedness == Threads::EDITED_NEVER ) { |
229 | 231 | $this->editedness = Threads::EDITED_HAS_REPLY; |
230 | 232 | } elseif ( $change_type == Threads::CHANGE_EDITED_ROOT ) { |
231 | 233 | $originalAuthor = $this->author(); |
232 | | - |
| 234 | + |
233 | 235 | if ( ( $wgUser->getId() == 0 && $originalAuthor->getName() != $wgUser->getName() ) |
234 | 236 | || $wgUser->getId() != $originalAuthor->getId() ) { |
235 | 237 | $this->editedness = Threads::EDITED_BY_OTHERS; |
— | — | @@ -237,45 +239,45 @@ |
238 | 240 | } |
239 | 241 | } |
240 | 242 | } |
241 | | - |
| 243 | + |
242 | 244 | /** Unless you know what you're doing, you want commitRevision */ |
243 | 245 | function save( $fname = null ) { |
244 | 246 | $this->dieIfHistorical(); |
245 | 247 | |
246 | 248 | $dbr = wfGetDB( DB_MASTER ); |
247 | | - |
| 249 | + |
248 | 250 | if ( !$fname ) { |
249 | 251 | $fname = __METHOD__ . "/" . wfGetCaller(); |
250 | 252 | } else { |
251 | 253 | $fname = __METHOD__ . "/" . $fname; |
252 | 254 | } |
253 | | - |
| 255 | + |
254 | 256 | $res = $dbr->update( 'thread', |
255 | 257 | /* SET */ $this->getRow(), |
256 | 258 | /* WHERE */ array( 'thread_id' => $this->id, ), |
257 | 259 | $fname ); |
258 | | - |
| 260 | + |
259 | 261 | // Touch the root |
260 | 262 | if ( $this->root() ) { |
261 | 263 | $this->root()->getTitle()->invalidateCache(); |
262 | 264 | } |
263 | | - |
| 265 | + |
264 | 266 | // Touch the talk page, too. |
265 | 267 | $this->article()->getTitle()->invalidateCache(); |
266 | | - |
| 268 | + |
267 | 269 | $this->dbVersion = clone $this; |
268 | 270 | unset( $this->dbVersion->dbVersion ); |
269 | 271 | } |
270 | | - |
| 272 | + |
271 | 273 | function getRow() { |
272 | 274 | $id = $this->id(); |
273 | | - |
| 275 | + |
274 | 276 | $dbw = wfGetDB( DB_MASTER ); |
275 | 277 | |
276 | 278 | if ( !$id ) { |
277 | 279 | $id = $dbw->nextSequenceValue( 'thread_thread_id' ); |
278 | 280 | } |
279 | | - |
| 281 | + |
280 | 282 | // Reflect schema changes here. |
281 | 283 | |
282 | 284 | return array( |
— | — | @@ -299,10 +301,10 @@ |
300 | 302 | 'thread_signature' => $this->signature, |
301 | 303 | ); |
302 | 304 | } |
303 | | - |
| 305 | + |
304 | 306 | function author() { |
305 | 307 | $this->doLazyUpdates(); |
306 | | - |
| 308 | + |
307 | 309 | if ( $this->authorId ) { |
308 | 310 | return User::newFromId( $this->authorId ); |
309 | 311 | } else { |
— | — | @@ -315,30 +317,30 @@ |
316 | 318 | $this->type = Threads::TYPE_DELETED; |
317 | 319 | $this->commitRevision( Threads::CHANGE_DELETED, $this, $reason ); |
318 | 320 | /* Mark thread as read by all users, or we get blank thingies in New Messages. */ |
319 | | - |
| 321 | + |
320 | 322 | $this->dieIfHistorical(); |
321 | | - |
| 323 | + |
322 | 324 | $dbw = wfGetDB( DB_MASTER ); |
323 | | - |
| 325 | + |
324 | 326 | $dbw->delete( 'user_message_state', array( 'ums_thread' => $this->id() ), |
325 | 327 | __METHOD__ ); |
326 | | - |
| 328 | + |
327 | 329 | // Fix reply count. |
328 | 330 | $t = $this->superthread(); |
329 | | - |
330 | | - if ($t) { |
| 331 | + |
| 332 | + if ( $t ) { |
331 | 333 | $t->decrementReplyCount(); |
332 | 334 | $t->save(); |
333 | 335 | } |
334 | 336 | } |
335 | | - |
| 337 | + |
336 | 338 | function undelete( $reason ) { |
337 | 339 | $this->type = Threads::TYPE_NORMAL; |
338 | 340 | $this->commitRevision( Threads::CHANGE_UNDELETED, $this, $reason ); |
339 | | - |
| 341 | + |
340 | 342 | // Fix reply count. |
341 | 343 | $t = $this->superthread(); |
342 | | - if ($t) { |
| 344 | + if ( $t ) { |
343 | 345 | $t->incrementReplyCount( 1 ); |
344 | 346 | $t->save(); |
345 | 347 | } |
— | — | @@ -347,39 +349,41 @@ |
348 | 350 | function moveToPage( $title, $reason, $leave_trace ) { |
349 | 351 | if ( !$this->isTopmostThread() ) |
350 | 352 | throw new MWException( "Attempt to move non-toplevel thread to another page" ); |
351 | | - |
| 353 | + |
352 | 354 | $this->dieIfHistorical(); |
353 | | - |
| 355 | + |
354 | 356 | $dbr = wfGetDB( DB_MASTER ); |
355 | 357 | |
356 | 358 | $oldTitle = $this->article()->getTitle(); |
357 | 359 | $newTitle = $title; |
358 | | - |
| 360 | + |
359 | 361 | $new_articleNamespace = $title->getNamespace(); |
360 | 362 | $new_articleTitle = $title->getDBkey(); |
361 | 363 | $new_articleID = $title->getArticleID(); |
362 | | - |
| 364 | + |
363 | 365 | if ( !$new_articleID ) { |
364 | 366 | $article = new Article( $newTitle ); |
365 | 367 | Threads::createTalkpageIfNeeded( $article ); |
366 | 368 | $new_articleID = $article->getId(); |
367 | 369 | } |
368 | | - |
| 370 | + |
369 | 371 | // Update on *all* subthreads. |
370 | | - $dbr->update( 'thread', |
371 | | - array( |
372 | | - 'thread_article_namespace' => $new_articleNamespace, |
373 | | - 'thread_article_title' => $new_articleTitle, |
374 | | - 'thread_article_id' => $new_articleID, |
375 | | - ), |
376 | | - array( 'thread_ancestor' => $this->id() ), |
377 | | - __METHOD__ ); |
| 372 | + $dbr->update( |
| 373 | + 'thread', |
| 374 | + array( |
| 375 | + 'thread_article_namespace' => $new_articleNamespace, |
| 376 | + 'thread_article_title' => $new_articleTitle, |
| 377 | + 'thread_article_id' => $new_articleID, |
| 378 | + ), |
| 379 | + array( 'thread_ancestor' => $this->id() ), |
| 380 | + __METHOD__ |
| 381 | + ); |
378 | 382 | |
379 | 383 | $this->articleNamespace = $new_articleNamespace; |
380 | 384 | $this->articleTitle = $new_articleTitle; |
381 | 385 | $this->articleId = $new_articleID; |
382 | 386 | $this->article = null; |
383 | | - |
| 387 | + |
384 | 388 | $this->commitRevision( Threads::CHANGE_MOVED_TALKPAGE, null, $reason ); |
385 | 389 | |
386 | 390 | if ( $leave_trace ) { |
— | — | @@ -391,14 +395,14 @@ |
392 | 396 | // there. |
393 | 397 | function leaveTrace( $reason, $oldTitle, $newTitle ) { |
394 | 398 | $this->dieIfHistorical(); |
395 | | - |
| 399 | + |
396 | 400 | $dbw = wfGetDB( DB_MASTER ); |
397 | 401 | |
398 | 402 | // Create redirect text |
399 | 403 | $mwRedir = MagicWord::get( 'redirect' ); |
400 | 404 | $redirectText = $mwRedir->getSynonym( 0 ) . |
401 | 405 | ' [[' . $this->title()->getPrefixedText() . "]]\n"; |
402 | | - |
| 406 | + |
403 | 407 | // Make the article edit. |
404 | 408 | $traceTitle = Threads::newThreadTitle( $this->subject(), new Article_LQT_Compat( $oldTitle ) ); |
405 | 409 | $redirectArticle = new Article_LQT_Compat( $traceTitle ); |
— | — | @@ -407,7 +411,7 @@ |
408 | 412 | // Add the trace thread to the tracking table. |
409 | 413 | $thread = Thread::create( $redirectArticle, new Article_LQT_Compat( $oldTitle ), null, |
410 | 414 | Threads::TYPE_MOVED, $this->subject() ); |
411 | | - |
| 415 | + |
412 | 416 | $thread->setSortkey( $this->sortkey() ); |
413 | 417 | $thread->save(); |
414 | 418 | } |
— | — | @@ -418,52 +422,52 @@ |
419 | 423 | if ( $this->replyCount == - 1 ) { |
420 | 424 | if ( $this->isTopmostThread() ) { |
421 | 425 | $dbr = wfGetDB( DB_SLAVE ); |
422 | | - |
| 426 | + |
423 | 427 | $count = $dbr->selectField( 'thread', 'count(*)', |
424 | 428 | array( 'thread_ancestor' => $this->id() ), __METHOD__ ); |
425 | 429 | } else { |
426 | 430 | $count = self::recursiveGetReplyCount( $this ); |
427 | 431 | } |
428 | | - |
| 432 | + |
429 | 433 | $this->replyCount = $count; |
430 | 434 | $this->save(); |
431 | 435 | } |
432 | | - |
| 436 | + |
433 | 437 | return $this->replyCount; |
434 | 438 | } |
435 | | - |
| 439 | + |
436 | 440 | function incrementReplyCount( $val = 1 ) { |
437 | 441 | $this->replyCount += $val; |
438 | | - |
439 | | - wfDebug( "Incremented reply count for thread ".$this->id()." to ".$this->replyCount."\n" ); |
440 | | - |
| 442 | + |
| 443 | + wfDebug( "Incremented reply count for thread " . $this->id() . " to " . $this->replyCount . "\n" ); |
| 444 | + |
441 | 445 | $thread = $this->superthread(); |
442 | | - |
| 446 | + |
443 | 447 | if ( $thread ) { |
444 | 448 | $thread->incrementReplyCount( $val ); |
445 | | - wfDebug( "Saving Incremented thread ".$thread->id(). |
446 | | - " with reply count ".$thread->replyCount."\n" ); |
| 449 | + wfDebug( "Saving Incremented thread " . $thread->id() . |
| 450 | + " with reply count " . $thread->replyCount . "\n" ); |
447 | 451 | $thread->save(); |
448 | 452 | } |
449 | 453 | } |
450 | | - |
| 454 | + |
451 | 455 | function decrementReplyCount( $val = 1 ) { |
452 | 456 | $this->incrementReplyCount( - $val ); |
453 | 457 | } |
454 | | - |
| 458 | + |
455 | 459 | static function newFromRow( $row ) { |
456 | 460 | $id = $row->thread_id; |
457 | | - |
| 461 | + |
458 | 462 | if ( isset( Threads::$cache_by_id[$id] ) ) { |
459 | 463 | return Threads::$cache_by_id[$id]; |
460 | 464 | } |
461 | | - |
| 465 | + |
462 | 466 | return new Thread( $row ); |
463 | 467 | } |
464 | 468 | |
465 | 469 | protected function __construct( $line, $unused = null ) { |
466 | 470 | /* SCHEMA changes must be reflected here. */ |
467 | | - |
| 471 | + |
468 | 472 | if ( is_null( $line ) ) { // For Thread::create(). |
469 | 473 | $dbr = wfGetDB( DB_SLAVE ); |
470 | 474 | $this->modified = $dbr->timestamp( wfTimestampNow() ); |
— | — | @@ -473,34 +477,34 @@ |
474 | 478 | $this->replyCount = 0; |
475 | 479 | return; |
476 | 480 | } |
477 | | - |
| 481 | + |
478 | 482 | $dataLoads = array( |
479 | | - 'thread_id' => 'id', |
480 | | - 'thread_root' => 'rootId', |
481 | | - 'thread_article_namespace' => 'articleNamespace', |
482 | | - 'thread_article_title' => 'articleTitle', |
483 | | - 'thread_article_id' => 'articleId', |
484 | | - 'thread_summary_page' => 'summaryId', |
485 | | - 'thread_ancestor' => 'ancestorId', |
486 | | - 'thread_parent' => 'parentId', |
487 | | - 'thread_modified' => 'modified', |
488 | | - 'thread_created' => 'created', |
489 | | - 'thread_type' => 'type', |
490 | | - 'thread_editedness' => 'editedness', |
491 | | - 'thread_subject' => 'subject', |
492 | | - 'thread_author_id' => 'authorId', |
493 | | - 'thread_author_name' => 'authorName', |
494 | | - 'thread_sortkey' => 'sortkey', |
495 | | - 'thread_replies' => 'replyCount', |
496 | | - 'thread_signature' => 'signature', |
497 | | - ); |
498 | | - |
| 483 | + 'thread_id' => 'id', |
| 484 | + 'thread_root' => 'rootId', |
| 485 | + 'thread_article_namespace' => 'articleNamespace', |
| 486 | + 'thread_article_title' => 'articleTitle', |
| 487 | + 'thread_article_id' => 'articleId', |
| 488 | + 'thread_summary_page' => 'summaryId', |
| 489 | + 'thread_ancestor' => 'ancestorId', |
| 490 | + 'thread_parent' => 'parentId', |
| 491 | + 'thread_modified' => 'modified', |
| 492 | + 'thread_created' => 'created', |
| 493 | + 'thread_type' => 'type', |
| 494 | + 'thread_editedness' => 'editedness', |
| 495 | + 'thread_subject' => 'subject', |
| 496 | + 'thread_author_id' => 'authorId', |
| 497 | + 'thread_author_name' => 'authorName', |
| 498 | + 'thread_sortkey' => 'sortkey', |
| 499 | + 'thread_replies' => 'replyCount', |
| 500 | + 'thread_signature' => 'signature', |
| 501 | + ); |
| 502 | + |
499 | 503 | foreach ( $dataLoads as $db_field => $member_field ) { |
500 | 504 | if ( isset( $line->$db_field ) ) { |
501 | 505 | $this->$member_field = $line->$db_field; |
502 | 506 | } |
503 | 507 | } |
504 | | - |
| 508 | + |
505 | 509 | if ( isset( $line->page_namespace ) && isset( $line->page_title ) ) { |
506 | 510 | $root_title = Title::makeTitle( $line->page_namespace, $line->page_title ); |
507 | 511 | $this->root = new Article_LQT_Compat( $root_title ); |
— | — | @@ -511,25 +515,25 @@ |
512 | 516 | } else { |
513 | 517 | $root_title = Title::newFromID( $this->rootId ); |
514 | 518 | } |
515 | | - |
| 519 | + |
516 | 520 | if ( $root_title ) { |
517 | 521 | $this->root = new Article_LQT_Compat( $root_title ); |
518 | 522 | } |
519 | 523 | } |
520 | | - |
| 524 | + |
521 | 525 | Threads::$cache_by_id[$line->thread_id] = $this; |
522 | 526 | if ( $line->thread_parent ) { |
523 | 527 | if ( !isset( self::$replyCacheById[$line->thread_parent] ) ) |
524 | 528 | self::$replyCacheById[$line->thread_parent] = array(); |
525 | 529 | self::$replyCacheById[$line->thread_parent][$line->thread_id] = $this; |
526 | 530 | } |
527 | | - |
| 531 | + |
528 | 532 | $this->doLazyUpdates( $line ); |
529 | | - |
| 533 | + |
530 | 534 | $this->dbVersion = clone $this; |
531 | 535 | unset( $this->dbVersion->dbVersion ); |
532 | 536 | } |
533 | | - |
| 537 | + |
534 | 538 | // Load a list of threads in bulk, including all subthreads. |
535 | 539 | static function bulkLoad( $rows ) { |
536 | 540 | // Preload subthreads |
— | — | @@ -538,11 +542,11 @@ |
539 | 543 | $pageIds = array(); |
540 | 544 | $linkBatch = new LinkBatch(); |
541 | 545 | $userIds = array(); |
542 | | - |
| 546 | + |
543 | 547 | if ( !is_array( self::$replyCacheById ) ) { |
544 | 548 | self::$replyCacheById = array(); |
545 | 549 | } |
546 | | - |
| 550 | + |
547 | 551 | // Build a list of threads for which to pull replies, and page IDs to pull data for. |
548 | 552 | // Also, pre-initialise the reply cache. |
549 | 553 | foreach ( $rows as $row ) { |
— | — | @@ -551,18 +555,18 @@ |
552 | 556 | } else { |
553 | 557 | $top_thread_ids[] = $row->thread_id; |
554 | 558 | } |
555 | | - |
| 559 | + |
556 | 560 | // Grab page data while we're here. |
557 | 561 | if ( $row->thread_root ) |
558 | 562 | $pageIds[] = $row->thread_root; |
559 | 563 | if ( $row->thread_summary_page ) |
560 | 564 | $pageIds[] = $row->thread_summary_page; |
561 | | - |
| 565 | + |
562 | 566 | if ( !isset( self::$replyCacheById[$row->thread_id] ) ) { |
563 | 567 | self::$replyCacheById[$row->thread_id] = array(); |
564 | 568 | } |
565 | 569 | } |
566 | | - |
| 570 | + |
567 | 571 | // Pull replies to the threads provided, and as above, pull page IDs to pull data for, |
568 | 572 | // pre-initialise the reply cache, and stash the row object for later use. |
569 | 573 | if ( count( $top_thread_ids ) ) { |
— | — | @@ -571,19 +575,19 @@ |
572 | 576 | array( 'thread_ancestor' => $top_thread_ids, |
573 | 577 | 'thread_type != ' . $dbr->addQuotes( Threads::TYPE_DELETED ) ), |
574 | 578 | __METHOD__ ); |
575 | | - |
| 579 | + |
576 | 580 | while ( $row = $dbr->fetchObject( $res ) ) { |
577 | 581 | // Grab page data while we're here. |
578 | 582 | if ( $row->thread_root ) |
579 | 583 | $pageIds[] = $row->thread_root; |
580 | 584 | if ( $row->thread_summary_page ) |
581 | 585 | $pageIds[] = $row->thread_summary_page; |
582 | | - |
| 586 | + |
583 | 587 | $all_thread_rows[] = $row; |
584 | 588 | } |
585 | 589 | } |
586 | | - |
587 | | - // Preload page data (restrictions, and preload Article object with everything from |
| 590 | + |
| 591 | + // Preload page data (restrictions, and preload Article object with everything from |
588 | 592 | // the page table. Also, precache the title and article objects for pulling later. |
589 | 593 | $articlesById = array(); |
590 | 594 | if ( count( $pageIds ) ) { |
— | — | @@ -595,103 +599,105 @@ |
596 | 600 | while ( $row = $dbr->fetchObject( $res ) ) { |
597 | 601 | $restrictionRows[$row->pr_page][] = $row; |
598 | 602 | } |
599 | | - |
| 603 | + |
600 | 604 | $res = $dbr->select( 'page', '*', array( 'page_id' => $pageIds ), __METHOD__ ); |
601 | | - |
| 605 | + |
602 | 606 | while ( $row = $dbr->fetchObject( $res ) ) { |
603 | 607 | $t = Title::newFromRow( $row ); |
604 | | - |
| 608 | + |
605 | 609 | if ( isset( $restrictionRows[$t->getArticleId()] ) ) { |
606 | 610 | $t->loadRestrictionsFromRows( $restrictionRows[$t->getArticleId()], |
607 | 611 | $row->page_restrictions ); |
608 | 612 | } |
609 | | - |
| 613 | + |
610 | 614 | $article = new Article_LQT_Compat( $t ); |
611 | 615 | $article->loadPageData( $row ); |
612 | | - |
| 616 | + |
613 | 617 | self::$titleCacheById[$t->getArticleId()] = $t; |
614 | 618 | $articlesById[$article->getId()] = $article; |
615 | | - |
| 619 | + |
616 | 620 | if ( count( self::$titleCacheById ) > 10000 ) { |
617 | 621 | self::$titleCacheById = array(); |
618 | 622 | } |
619 | 623 | } |
620 | 624 | } |
621 | | - |
| 625 | + |
622 | 626 | // For every thread we have a row object for, load a Thread object, add the user and |
623 | 627 | // user talk pages to a link batch, cache the relevant user id/name pair, and |
624 | 628 | // populate the reply cache. |
625 | 629 | foreach ( $all_thread_rows as $row ) { |
626 | 630 | $thread = Thread::newFromRow( $row, null ); |
627 | | - |
| 631 | + |
628 | 632 | if ( isset( $articlesById[$thread->rootId] ) ) |
629 | 633 | $thread->root = $articlesById[$thread->rootId]; |
630 | | - |
| 634 | + |
631 | 635 | // User cache data |
632 | 636 | $t = Title::makeTitleSafe( NS_USER, $row->thread_author_name ); |
633 | 637 | $linkBatch->addObj( $t ); |
634 | 638 | $t = Title::makeTitleSafe( NS_USER_TALK, $row->thread_author_name ); |
635 | 639 | $linkBatch->addObj( $t ); |
636 | | - |
| 640 | + |
637 | 641 | User::$idCacheByName[$row->thread_author_name] = $row->thread_author_id; |
638 | 642 | $userIds[$row->thread_author_id] = true; |
639 | 643 | } |
640 | | - |
| 644 | + |
641 | 645 | $userIds = array_keys( $userIds ); |
642 | | - |
| 646 | + |
643 | 647 | // Pull link batch data. |
644 | 648 | $linkBatch->execute(); |
645 | | - |
| 649 | + |
646 | 650 | $threads = array(); |
647 | | - |
| 651 | + |
648 | 652 | // Fill and return an array with the threads that were actually requested. |
649 | 653 | foreach ( $rows as $row ) { |
650 | 654 | $threads[$row->thread_id] = Threads::$cache_by_id[$row->thread_id]; |
651 | 655 | } |
652 | | - |
| 656 | + |
653 | 657 | return $threads; |
654 | 658 | } |
655 | | - |
| 659 | + |
656 | 660 | /** |
657 | 661 | * Return the User object representing the author of the first revision |
658 | 662 | * (or null, if the database is screwed up). |
659 | 663 | */ |
660 | 664 | function loadOriginalAuthorFromRevision( ) { |
661 | 665 | $this->dieIfHistorical(); |
662 | | - |
| 666 | + |
663 | 667 | $dbr = wfGetDB( DB_SLAVE ); |
664 | | - |
| 668 | + |
665 | 669 | $article = $this->root(); |
666 | 670 | |
667 | | - $line = $dbr->selectRow( 'revision', |
668 | | - 'rev_user_text', |
669 | | - array( 'rev_page' => $article->getID() ), |
670 | | - __METHOD__, |
671 | | - array( |
672 | | - 'ORDER BY' => 'rev_timestamp', |
673 | | - 'LIMIT' => '1' |
674 | | - ) ); |
| 671 | + $line = $dbr->selectRow( |
| 672 | + 'revision', |
| 673 | + 'rev_user_text', |
| 674 | + array( 'rev_page' => $article->getID() ), |
| 675 | + __METHOD__, |
| 676 | + array( |
| 677 | + 'ORDER BY' => 'rev_timestamp', |
| 678 | + 'LIMIT' => '1' |
| 679 | + ) |
| 680 | + ); |
675 | 681 | if ( $line ) |
676 | 682 | return User::newFromName( $line->rev_user_text, false ); |
677 | 683 | else |
678 | 684 | return null; |
679 | 685 | } |
680 | | - |
| 686 | + |
681 | 687 | static function recursiveGetReplyCount( $thread, $level = 1 ) { |
682 | | - if ($level > 80) { |
| 688 | + if ( $level > 80 ) { |
683 | 689 | return 1; |
684 | 690 | } |
685 | | - |
| 691 | + |
686 | 692 | $count = 0; |
687 | | - |
688 | | - foreach( $thread->replies() as $reply ) { |
| 693 | + |
| 694 | + foreach ( $thread->replies() as $reply ) { |
689 | 695 | $count++; |
690 | 696 | $count += self::recursiveGetReplyCount( $reply, $level + 1 ); |
691 | 697 | } |
692 | | - |
| 698 | + |
693 | 699 | return $count; |
694 | 700 | } |
695 | | - |
| 701 | + |
696 | 702 | // Lazy updates done whenever a thread is loaded. |
697 | 703 | // Much easier than running a long-running maintenance script. |
698 | 704 | function doLazyUpdates( ) { |
— | — | @@ -703,49 +709,49 @@ |
704 | 710 | static $doingUpdates = false; |
705 | 711 | if ( $doingUpdates ) return; |
706 | 712 | $doingUpdates = true; |
707 | | - |
| 713 | + |
708 | 714 | // Fix missing ancestry information. |
709 | 715 | // (there was a bug where this was not saved properly) |
710 | 716 | if ( $this->parentId && !$this->ancestorId ) { |
711 | 717 | $this->fixMissingAncestor(); |
712 | 718 | } |
713 | | - |
| 719 | + |
714 | 720 | $ancestor = $this->topmostThread(); |
715 | | - |
| 721 | + |
716 | 722 | $set = array(); |
717 | | - |
| 723 | + |
718 | 724 | // Fix missing subject information |
719 | 725 | // (this information only started to be added later) |
720 | 726 | if ( !$this->subject && $this->root() ) { |
721 | 727 | $detectedSubject = $this->root()->getTitle()->getText(); |
722 | 728 | $parts = self::splitIncrementFromSubject( $detectedSubject ); |
723 | | - |
| 729 | + |
724 | 730 | $this->subject = $detectedSubject = $parts[1]; |
725 | | - |
| 731 | + |
726 | 732 | // Update in the DB |
727 | 733 | $set['thread_subject'] = $detectedSubject; |
728 | 734 | } |
729 | | - |
| 735 | + |
730 | 736 | // Fix inconsistent subject information |
731 | 737 | // (in some intermediate versions this was not updated when the subject was changed) |
732 | 738 | if ( $this->subject() != $ancestor->subject() ) { |
733 | 739 | $set['thread_subject'] = $ancestor->subject(); |
734 | | - |
| 740 | + |
735 | 741 | $this->subject = $ancestor->subject(); |
736 | 742 | } |
737 | | - |
| 743 | + |
738 | 744 | // Fix missing authorship information |
739 | 745 | // (this information only started to be added later) |
740 | 746 | if ( !$this->authorName ) { |
741 | 747 | $author = $this->loadOriginalAuthorFromRevision(); |
742 | | - |
| 748 | + |
743 | 749 | $this->authorId = $author->getId(); |
744 | 750 | $this->authorName = $author->getName(); |
745 | | - |
| 751 | + |
746 | 752 | $set['thread_author_name'] = $this->authorName; |
747 | 753 | $set['thread_author_id'] = $this->authorId; |
748 | 754 | } |
749 | | - |
| 755 | + |
750 | 756 | // Check for article being in subject, not talk namespace. |
751 | 757 | // If the page is non-LiquidThreads and it's in subject-space, we'll assume it's meant |
752 | 758 | // to be on the corresponding talk page, but only if the talk-page is a LQT page. |
— | — | @@ -761,31 +767,31 @@ |
762 | 768 | $wgLiquidThreadsMigrate ) { |
763 | 769 | $newTitle = $articleTitle->getTalkPage(); |
764 | 770 | $newArticle = new Article_LQT_Compat( $newTitle ); |
765 | | - |
| 771 | + |
766 | 772 | $set['thread_article_namespace'] = $newTitle->getNamespace(); |
767 | 773 | $set['thread_article_title'] = $newTitle->getDbKey(); |
768 | | - |
| 774 | + |
769 | 775 | $this->articleNamespace = $newTitle->getNamespace(); |
770 | 776 | $this->articleTitle = $newTitle->getDbKey(); |
771 | 777 | $this->articleId = $newTitle->getArticleId(); |
772 | | - |
| 778 | + |
773 | 779 | $this->article = $newArticle; |
774 | 780 | } |
775 | | - |
| 781 | + |
776 | 782 | // Check for article corruption from incomplete thread moves. |
777 | 783 | // (thread moves only updated this on immediate replies, not replies to replies etc) |
778 | 784 | if ( ! $ancestor->article()->getTitle()->equals( $this->article()->getTitle() ) ) { |
779 | 785 | $title = $ancestor->article()->getTitle(); |
780 | 786 | $set['thread_article_namespace'] = $title->getNamespace(); |
781 | 787 | $set['thread_article_title'] = $title->getDbKey(); |
782 | | - |
| 788 | + |
783 | 789 | $this->articleNamespace = $title->getNamespace(); |
784 | 790 | $this->articleTitle = $title->getDbKey(); |
785 | 791 | $this->articleId = $title->getArticleId(); |
786 | | - |
| 792 | + |
787 | 793 | $this->article = $ancestor->article(); |
788 | 794 | } |
789 | | - |
| 795 | + |
790 | 796 | // Check for invalid/missing articleId |
791 | 797 | $articleTitle = null; |
792 | 798 | $dbTitle = Title::makeTitleSafe( $this->articleNamespace, $this->articleTitle ); |
— | — | @@ -796,17 +802,17 @@ |
797 | 803 | } elseif ( $this->articleId ) { |
798 | 804 | $articleTitle = Title::newFromID( $this->articleId ); |
799 | 805 | } |
800 | | - |
| 806 | + |
801 | 807 | // If still unfilled, the article ID referred to is no longer valid. Re-fill it |
802 | 808 | // from the namespace/title pair if an article ID is provided |
803 | 809 | if ( !$articleTitle && ( $this->articleId != 0 || $dbTitle->getArticleId() != 0 ) ) { |
804 | 810 | $articleTitle = $dbTitle; |
805 | 811 | $this->articleId = $articleTitle->getArticleId(); |
806 | 812 | $this->article = new Article_LQT_Compat( $dbTitle ); |
807 | | - |
| 813 | + |
808 | 814 | $set['thread_article_id'] = $this->articleId; |
809 | 815 | wfDebug( "Unfilled or non-existent thread_article_id, refilling to {$this->articleId}\n" ); |
810 | | - |
| 816 | + |
811 | 817 | // There are probably problems on the rest of the article, trigger a small update |
812 | 818 | Threads::synchroniseArticleData( $this->article, 100, 'cascade' ); |
813 | 819 | } elseif ( $articleTitle && !$articleTitle->equals( $dbTitle ) ) { |
— | — | @@ -814,14 +820,14 @@ |
815 | 821 | wfDebug( "Article ID/Title discrepancy, resetting NS/Title to article provided by ID\n" ); |
816 | 822 | $this->articleNamespace = $articleTitle->getNamespace(); |
817 | 823 | $this->articleTitle = $articleTitle->getDBkey(); |
818 | | - |
| 824 | + |
819 | 825 | $set['thread_article_namespace'] = $articleTitle->getNamespace(); |
820 | 826 | $set['thread_article_title'] = $articleTitle->getDBkey(); |
821 | | - |
| 827 | + |
822 | 828 | // There are probably problems on the rest of the article, trigger a small update |
823 | 829 | Threads::synchroniseArticleData( $this->article, 100, 'cascade' ); |
824 | 830 | } |
825 | | - |
| 831 | + |
826 | 832 | // Check for unfilled signature field. This field hasn't existed until |
827 | 833 | // recently. |
828 | 834 | if ( is_null( $this->signature ) ) { |
— | — | @@ -831,100 +837,100 @@ |
832 | 838 | $set['thread_signature'] = $sig; |
833 | 839 | $this->setSignature( $sig ); |
834 | 840 | } |
835 | | - |
| 841 | + |
836 | 842 | if ( count( $set ) ) { |
837 | 843 | $dbw = wfGetDB( DB_MASTER ); |
838 | | - |
| 844 | + |
839 | 845 | $dbw->update( 'thread', $set, array( 'thread_id' => $this->id() ), __METHOD__ ); |
840 | 846 | } |
841 | | - |
| 847 | + |
842 | 848 | // Done |
843 | 849 | $doingUpdates = false; |
844 | 850 | } |
845 | 851 | |
846 | 852 | function addReply( $thread ) { |
847 | 853 | $thread->setSuperThread( $this ); |
848 | | - |
| 854 | + |
849 | 855 | if ( is_array( $this->replies ) ) { |
850 | 856 | $this->replies[$thread->id()] = $thread; |
851 | 857 | } else { |
852 | 858 | $this->replies(); |
853 | 859 | $this->replies[$thread->id()] = $thread; |
854 | 860 | } |
855 | | - |
| 861 | + |
856 | 862 | // Increment reply count. |
857 | 863 | $this->incrementReplyCount( $thread->replyCount() + 1 ); |
858 | 864 | } |
859 | | - |
| 865 | + |
860 | 866 | function removeReply( $thread ) { |
861 | 867 | if ( is_object( $thread ) ) { |
862 | 868 | $thread = $thread->id(); |
863 | 869 | } |
864 | | - |
| 870 | + |
865 | 871 | $this->replies(); |
866 | | - |
| 872 | + |
867 | 873 | unset( $this->replies[$thread] ); |
868 | | - |
| 874 | + |
869 | 875 | // Also, decrement the reply count. |
870 | 876 | $threadObj = Threads::withId( $thread ); |
871 | 877 | $this->decrementReplyCount( 1 + $threadObj->replyCount() ); |
872 | 878 | } |
873 | | - |
| 879 | + |
874 | 880 | function checkReplies( $replies ) { |
875 | 881 | // Fixes a bug where some history pages were not working, before |
876 | 882 | // superthread was properly instance-cached. |
877 | 883 | if ( $this->isHistorical() ) { return; } |
878 | | - foreach( $replies as $reply ) { |
| 884 | + foreach ( $replies as $reply ) { |
879 | 885 | if ( ! $reply->hasSuperthread() ) { |
880 | | - throw new MWException( "Post ".$this->id(). |
881 | | - " has contaminated reply ".$reply->id(). |
882 | | - ". Found no superthread."); |
| 886 | + throw new MWException( "Post " . $this->id() . |
| 887 | + " has contaminated reply " . $reply->id() . |
| 888 | + ". Found no superthread." ); |
883 | 889 | } |
884 | | - |
| 890 | + |
885 | 891 | if ( $reply->superthread()->id() != $this->id() ) { |
886 | | - throw new MWException( "Post ". $this->id() . |
887 | | - " has contaminated reply ".$reply->id(). |
888 | | - ". Expected ".$this->id().", got ". |
| 892 | + throw new MWException( "Post " . $this->id() . |
| 893 | + " has contaminated reply " . $reply->id() . |
| 894 | + ". Expected " . $this->id() . ", got " . |
889 | 895 | $reply->superthread()->id() ); |
890 | 896 | } |
891 | 897 | } |
892 | 898 | } |
893 | | - |
| 899 | + |
894 | 900 | function replies() { |
895 | 901 | if ( !$this->id() ) { |
896 | 902 | return array(); |
897 | 903 | } |
898 | | - |
| 904 | + |
899 | 905 | if ( !is_null( $this->replies ) ) { |
900 | 906 | $this->checkReplies( $this->replies ); |
901 | 907 | return $this->replies; |
902 | 908 | } |
903 | | - |
| 909 | + |
904 | 910 | $this->dieIfHistorical(); |
905 | | - |
| 911 | + |
906 | 912 | // Check cache |
907 | 913 | if ( isset( self::$replyCacheById[$this->id()] ) ) { |
908 | 914 | return $this->replies = self::$replyCacheById[$this->id()]; |
909 | 915 | } |
910 | | - |
| 916 | + |
911 | 917 | $this->replies = array(); |
912 | | - |
| 918 | + |
913 | 919 | $dbr = wfGetDB( DB_SLAVE ); |
914 | | - |
| 920 | + |
915 | 921 | $res = $dbr->select( 'thread', '*', |
916 | 922 | array( 'thread_parent' => $this->id(), |
917 | 923 | 'thread_type != ' . $dbr->addQuotes( Threads::TYPE_DELETED ) ), |
918 | 924 | __METHOD__ ); |
919 | | - |
| 925 | + |
920 | 926 | $rows = array(); |
921 | 927 | while ( $row = $dbr->fetchObject( $res ) ) { |
922 | 928 | $rows[] = $row; |
923 | 929 | } |
924 | | - |
| 930 | + |
925 | 931 | $this->replies = Thread::bulkLoad( $rows ); |
926 | | - |
| 932 | + |
927 | 933 | $this->checkReplies( $this->replies ); |
928 | | - |
| 934 | + |
929 | 935 | return $this->replies; |
930 | 936 | } |
931 | 937 | |
— | — | @@ -934,10 +940,10 @@ |
935 | 941 | $this->ancestorId = 0; |
936 | 942 | return; |
937 | 943 | } |
938 | | - |
| 944 | + |
939 | 945 | $this->parentId = $thread->id(); |
940 | 946 | $this->superthread = $thread; |
941 | | - |
| 947 | + |
942 | 948 | if ( $thread->isTopmostThread() ) { |
943 | 949 | $this->ancestorId = $thread->id(); |
944 | 950 | $this->ancestor = $thread; |
— | — | @@ -970,19 +976,19 @@ |
971 | 977 | return $this->ancestor; |
972 | 978 | } else { |
973 | 979 | $this->dieIfHistorical(); |
974 | | - |
| 980 | + |
975 | 981 | $thread = Threads::withId( $this->ancestorId ); |
976 | 982 | |
977 | 983 | if ( !$thread ) { |
978 | 984 | $thread = $this->fixMissingAncestor(); |
979 | 985 | } |
980 | | - |
| 986 | + |
981 | 987 | $this->ancestor = $thread; |
982 | | - |
| 988 | + |
983 | 989 | return $thread; |
984 | 990 | } |
985 | 991 | } |
986 | | - |
| 992 | + |
987 | 993 | function setAncestor( $newAncestor ) { |
988 | 994 | if ( is_object( $newAncestor ) ) { |
989 | 995 | $this->ancestorId = $newAncestor->id(); |
— | — | @@ -995,19 +1001,19 @@ |
996 | 1002 | // Fix the corruption by repeatedly grabbing the parent until we hit the topmost thread. |
997 | 1003 | function fixMissingAncestor() { |
998 | 1004 | $thread = $this; |
999 | | - |
| 1005 | + |
1000 | 1006 | $this->dieIfHistorical(); |
1001 | | - |
| 1007 | + |
1002 | 1008 | while ( !$thread->isTopmostThread() ) { |
1003 | 1009 | $thread = $thread->superthread(); |
1004 | 1010 | } |
1005 | | - |
| 1011 | + |
1006 | 1012 | $this->ancestorId = $thread->id(); |
1007 | | - |
| 1013 | + |
1008 | 1014 | $dbw = wfGetDB( DB_MASTER ); |
1009 | 1015 | $dbw->update( 'thread', array( 'thread_ancestor' => $thread->id() ), |
1010 | 1016 | array( 'thread_id' => $this->id() ), __METHOD__ ); |
1011 | | - |
| 1017 | + |
1012 | 1018 | return $thread; |
1013 | 1019 | } |
1014 | 1020 | |
— | — | @@ -1022,31 +1028,31 @@ |
1023 | 1029 | $this->articleTitle = $a->getTitle()->getDBkey(); |
1024 | 1030 | $this->touch(); |
1025 | 1031 | } |
1026 | | - |
| 1032 | + |
1027 | 1033 | function touch() { |
1028 | 1034 | // Nothing here yet |
1029 | 1035 | } |
1030 | 1036 | |
1031 | 1037 | function article() { |
1032 | 1038 | if ( $this->article ) return $this->article; |
1033 | | - |
| 1039 | + |
1034 | 1040 | if ( !is_null( $this->articleId ) ) { |
1035 | 1041 | if ( isset( self::$articleCacheById[$this->articleId] ) ) { |
1036 | 1042 | return self::$articleCacheById[$this->articleId]; |
1037 | 1043 | } |
1038 | | - |
| 1044 | + |
1039 | 1045 | if ( isset( self::$titleCacheById[$this->articleId] ) ) { |
1040 | 1046 | $title = self::$titleCacheById[$this->articleId]; |
1041 | 1047 | } else { |
1042 | 1048 | $title = Title::newFromID( $this->articleId ); |
1043 | 1049 | } |
1044 | | - |
| 1050 | + |
1045 | 1051 | if ( $title ) { |
1046 | 1052 | $article = new Article_LQT_Compat( $title ); |
1047 | 1053 | self::$articleCacheById[$this->articleId] = $article; |
1048 | 1054 | } |
1049 | 1055 | } |
1050 | | - |
| 1056 | + |
1051 | 1057 | if ( isset( $article ) && $article->exists() ) { |
1052 | 1058 | $this->article = $article; |
1053 | 1059 | return $article; |
— | — | @@ -1072,15 +1078,15 @@ |
1073 | 1079 | $this->root = self::$articleCacheById[$this->rootId]; |
1074 | 1080 | return $this->root; |
1075 | 1081 | } |
1076 | | - |
| 1082 | + |
1077 | 1083 | if ( isset( self::$titleCacheById[$this->rootId] ) ) { |
1078 | 1084 | $title = self::$titleCacheById[$this->rootId]; |
1079 | 1085 | } else { |
1080 | 1086 | $title = Title::newFromID( $this->rootId ); |
1081 | 1087 | } |
1082 | | - |
| 1088 | + |
1083 | 1089 | if ( !$title ) return null; |
1084 | | - |
| 1090 | + |
1085 | 1091 | $this->root = new Article_LQT_Compat( $title ); |
1086 | 1092 | } |
1087 | 1093 | return $this->root; |
— | — | @@ -1093,20 +1099,20 @@ |
1094 | 1100 | function summary() { |
1095 | 1101 | if ( !$this->summaryId ) |
1096 | 1102 | return null; |
1097 | | - |
| 1103 | + |
1098 | 1104 | if ( !$this->summary ) { |
1099 | 1105 | $title = Title::newFromID( $this->summaryId ); |
1100 | | - |
| 1106 | + |
1101 | 1107 | if ( !$title ) { |
1102 | 1108 | wfDebug( __METHOD__ . ": supposed summary doesn't exist" ); |
1103 | 1109 | $this->summaryId = null; |
1104 | 1110 | return null; |
1105 | 1111 | } |
1106 | | - |
| 1112 | + |
1107 | 1113 | $this->summary = new Article_LQT_Compat( $title ); |
1108 | 1114 | |
1109 | 1115 | } |
1110 | | - |
| 1116 | + |
1111 | 1117 | return $this->summary; |
1112 | 1118 | } |
1113 | 1119 | |
— | — | @@ -1140,15 +1146,15 @@ |
1141 | 1147 | function subject() { |
1142 | 1148 | return $this->subject; |
1143 | 1149 | } |
1144 | | - |
| 1150 | + |
1145 | 1151 | function formattedSubject() { |
1146 | 1152 | return LqtView::formatSubject( $this->subject() ); |
1147 | 1153 | } |
1148 | | - |
| 1154 | + |
1149 | 1155 | function setSubject( $subject ) { |
1150 | 1156 | $this->subject = $subject; |
1151 | | - |
1152 | | - foreach( $this->replies() as $reply ) { |
| 1157 | + |
| 1158 | + foreach ( $this->replies() as $reply ) { |
1153 | 1159 | $reply->setSubject( $subject ); |
1154 | 1160 | } |
1155 | 1161 | } |
— | — | @@ -1183,7 +1189,7 @@ |
1184 | 1190 | function type() { |
1185 | 1191 | return $this->type; |
1186 | 1192 | } |
1187 | | - |
| 1193 | + |
1188 | 1194 | function setType( $t ) { |
1189 | 1195 | $this->type = $t; |
1190 | 1196 | } |
— | — | @@ -1192,7 +1198,7 @@ |
1193 | 1199 | $rev = Revision::newFromId( $this->root()->getLatest() ); |
1194 | 1200 | $rtitle = Title::newFromRedirect( $rev->getRawText() ); |
1195 | 1201 | if ( !$rtitle ) return null; |
1196 | | - |
| 1202 | + |
1197 | 1203 | $this->dieIfHistorical(); |
1198 | 1204 | $rthread = Threads::withRoot( new Article_LQT_Compat( $rtitle ) ); |
1199 | 1205 | return $rthread; |
— | — | @@ -1218,68 +1224,50 @@ |
1219 | 1225 | } |
1220 | 1226 | |
1221 | 1227 | } |
1222 | | - |
| 1228 | + |
1223 | 1229 | function getAnchorName() { |
1224 | | - $wantedId = $this->subject()."_{$this->id()}"; |
| 1230 | + $wantedId = $this->subject() . "_{$this->id()}"; |
1225 | 1231 | return Sanitizer::escapeId( $wantedId ); |
1226 | 1232 | } |
1227 | | - |
| 1233 | + |
1228 | 1234 | function updateHistory() { |
1229 | | -// $dbr = wfGetDB( DB_SLAVE ); |
1230 | | -// |
1231 | | -// $res = $dbr->select( 'historical_thread', '*', |
1232 | | -// array( 'hthread_id' => $this->id() ), |
1233 | | -// __METHOD__, |
1234 | | -// array( 'ORDER BY' => 'hthread_revision ASC' ) ); |
1235 | | -// |
1236 | | -// foreach( $row as $res ) { |
1237 | | -// $historical_thread = HistoricalThread::fromTextRepresentation( $row->hthread_content ); |
1238 | | -// |
1239 | | -// // Insert a revision into the database. |
1240 | | -// $rev = ThreadRevision::create( $historical_thread, |
1241 | | -// $historical_thread->changeType(), |
1242 | | -// $historical_thread->changeObject(), |
1243 | | -// $historical_thread->changeComment(), |
1244 | | -// $historical_thread->changeUser(), |
1245 | | -// $historical_thread->modified() ); |
1246 | | -// } |
1247 | 1235 | } |
1248 | | - |
| 1236 | + |
1249 | 1237 | function setAuthor( $user ) { |
1250 | 1238 | $this->authorId = $user->getId(); |
1251 | 1239 | $this->authorName = $user->getName(); |
1252 | 1240 | } |
1253 | | - |
| 1241 | + |
1254 | 1242 | // Load all lazy-loaded data in prep for (e.g.) serialization. |
1255 | 1243 | function loadAllData() { |
1256 | 1244 | // Make sure superthread and topmost thread are loaded. |
1257 | 1245 | $this->superthread(); |
1258 | 1246 | $this->topmostThread(); |
1259 | | - |
| 1247 | + |
1260 | 1248 | // Make sure replies, and all the data therein, is loaded. |
1261 | 1249 | foreach ( $this->replies() as $reply ) { |
1262 | 1250 | $reply->loadAllData(); |
1263 | 1251 | } |
1264 | 1252 | } |
1265 | | - |
| 1253 | + |
1266 | 1254 | // On serialization, load all data because it will be different in the DB when we wake up. |
1267 | 1255 | function __sleep() { |
1268 | 1256 | $this->loadAllData(); |
1269 | | - |
| 1257 | + |
1270 | 1258 | $fields = array_keys( get_object_vars( $this ) ); |
1271 | | - |
| 1259 | + |
1272 | 1260 | // Filter out article objects, there be dragons (or unserialization problems) |
1273 | 1261 | $fields = array_diff( $fields, array( 'root', 'article', 'summary', 'sleeping', |
1274 | 1262 | 'dbVersion' ) ); |
1275 | | - |
| 1263 | + |
1276 | 1264 | return $fields; |
1277 | 1265 | } |
1278 | | - |
| 1266 | + |
1279 | 1267 | function __wakeup() { |
1280 | 1268 | // Mark as historical. |
1281 | 1269 | $this->isHistorical = true; |
1282 | 1270 | } |
1283 | | - |
| 1271 | + |
1284 | 1272 | // This is a safety valve that makes sure that the DB is NEVER touched by a historical |
1285 | 1273 | // thread (even for reading, because the data will be out of date). |
1286 | 1274 | function dieIfHistorical() { |
— | — | @@ -1287,196 +1275,196 @@ |
1288 | 1276 | throw new MWException( "Attempted write or DB operation on historical thread" ); |
1289 | 1277 | } |
1290 | 1278 | } |
1291 | | - |
| 1279 | + |
1292 | 1280 | function rootRevision() { |
1293 | 1281 | if ( !$this->isHistorical() || !isset( $this->topmostThread()->threadRevision ) ) { |
1294 | 1282 | return null; |
1295 | 1283 | } |
1296 | | - |
| 1284 | + |
1297 | 1285 | $dbr = wfGetDB( DB_SLAVE ); |
1298 | | - |
| 1286 | + |
1299 | 1287 | $revision = $this->topmostThread()->threadRevision; |
1300 | 1288 | $timestamp = $dbr->timestamp( $revision->getTimestamp() ); |
1301 | | - |
| 1289 | + |
1302 | 1290 | $conds = array( |
1303 | | - 'rev_timestamp<=' . $dbr->addQuotes( $timestamp ), |
1304 | | - 'page_namespace' => $this->root()->getTitle()->getNamespace(), |
1305 | | - 'page_title' => $this->root()->getTitle()->getDBKey(), |
1306 | | - ); |
1307 | | - |
| 1291 | + 'rev_timestamp<=' . $dbr->addQuotes( $timestamp ), |
| 1292 | + 'page_namespace' => $this->root()->getTitle()->getNamespace(), |
| 1293 | + 'page_title' => $this->root()->getTitle()->getDBKey(), |
| 1294 | + ); |
| 1295 | + |
1308 | 1296 | $join_conds = array( 'page' => array( 'JOIN', 'rev_page=page_id' ) ); |
1309 | | - |
| 1297 | + |
1310 | 1298 | $row = $dbr->selectRow( array( 'revision', 'page' ), '*', $conds, __METHOD__, |
1311 | 1299 | array( 'ORDER BY' => 'rev_timestamp DESC' ), $join_conds ); |
1312 | | - |
| 1300 | + |
1313 | 1301 | return $row->rev_id; |
1314 | 1302 | } |
1315 | | - |
| 1303 | + |
1316 | 1304 | function sortkey() { |
1317 | 1305 | return $this->sortkey; |
1318 | 1306 | } |
1319 | | - |
| 1307 | + |
1320 | 1308 | function setSortKey( $k = null ) { |
1321 | 1309 | if ( is_null( $k ) ) { |
1322 | 1310 | $dbr = wfGetDB( DB_SLAVE ); |
1323 | 1311 | $k = wfTimestamp( TS_MW ); |
1324 | 1312 | } |
1325 | | - |
| 1313 | + |
1326 | 1314 | $this->sortkey = $k; |
1327 | 1315 | } |
1328 | | - |
| 1316 | + |
1329 | 1317 | function replyWithId( $id ) { |
1330 | 1318 | if ( $this->id() == $id ) { |
1331 | 1319 | return $this; |
1332 | 1320 | } |
1333 | | - |
1334 | | - foreach( $this->replies() as $reply ) { |
1335 | | - if ( $obj = $reply->replyWithId($id) ) { |
| 1321 | + |
| 1322 | + foreach ( $this->replies() as $reply ) { |
| 1323 | + if ( $obj = $reply->replyWithId( $id ) ) { |
1336 | 1324 | return $obj; |
1337 | 1325 | } |
1338 | 1326 | } |
1339 | | - |
| 1327 | + |
1340 | 1328 | return null; |
1341 | 1329 | } |
1342 | | - |
| 1330 | + |
1343 | 1331 | static function createdSortCallback( $a, $b ) { |
1344 | 1332 | $a = $a->created(); |
1345 | 1333 | $b = $b->created(); |
1346 | | - |
| 1334 | + |
1347 | 1335 | if ( $a == $b ) { |
1348 | 1336 | return 0; |
1349 | 1337 | } elseif ( $a > $b ) { |
1350 | 1338 | return 1; |
1351 | 1339 | } else { |
1352 | | - return -1; |
| 1340 | + return - 1; |
1353 | 1341 | } |
1354 | 1342 | } |
1355 | | - |
| 1343 | + |
1356 | 1344 | public function split( $newSubject, $reason = '', $newSortkey = null ) { |
1357 | 1345 | $oldTopThread = $this->topmostThread(); |
1358 | 1346 | $oldParent = $this->superthread(); |
1359 | | - |
| 1347 | + |
1360 | 1348 | $original = $this->dbVersion; |
1361 | | - |
| 1349 | + |
1362 | 1350 | self::recursiveSet( $this, $newSubject, $this, null ); |
1363 | | - |
| 1351 | + |
1364 | 1352 | $oldParent->removeReply( $this ); |
1365 | | - |
| 1353 | + |
1366 | 1354 | $bump = null; |
1367 | | - if ( !is_null($newSortkey) ) { |
| 1355 | + if ( !is_null( $newSortkey ) ) { |
1368 | 1356 | $this->setSortkey( $newSortkey ); |
1369 | 1357 | $bump = false; |
1370 | 1358 | } |
1371 | | - |
| 1359 | + |
1372 | 1360 | // For logging purposes, will be reset by the time this call returns. |
1373 | 1361 | $this->dbVersion = $original; |
1374 | | - |
| 1362 | + |
1375 | 1363 | $this->commitRevision( Threads::CHANGE_SPLIT, null, $reason, $bump ); |
1376 | 1364 | $oldTopThread->commitRevision( Threads::CHANGE_SPLIT_FROM, $this, $reason ); |
1377 | 1365 | } |
1378 | | - |
| 1366 | + |
1379 | 1367 | public function moveToParent( $newParent, $reason = '' ) { |
1380 | 1368 | $newSubject = $newParent->subject(); |
1381 | | - |
| 1369 | + |
1382 | 1370 | $original = $this->dbVersion; |
1383 | | - |
| 1371 | + |
1384 | 1372 | $oldTopThread = $newParent->topmostThread(); |
1385 | 1373 | $oldParent = $this->superthread(); |
1386 | | - |
| 1374 | + |
1387 | 1375 | Thread::recursiveSet( $this, $newSubject, $newParent, $newParent ); |
1388 | 1376 | |
1389 | 1377 | $newParent->addReply( $this ); |
1390 | | - |
| 1378 | + |
1391 | 1379 | if ( $oldParent ) { |
1392 | 1380 | $oldParent->removeReply( $this ); |
1393 | 1381 | } |
1394 | | - |
| 1382 | + |
1395 | 1383 | $this->dbVersion = $original; |
1396 | | - |
| 1384 | + |
1397 | 1385 | $oldTopThread->commitRevision( Threads::CHANGE_MERGED_FROM, $this, $reason ); |
1398 | 1386 | $newParent->commitRevision( Threads::CHANGE_MERGED_TO, $this, $reason ); |
1399 | 1387 | } |
1400 | | - |
| 1388 | + |
1401 | 1389 | static function recursiveSet( $thread, $subject, $ancestor, $superthread = false ) { |
1402 | 1390 | $thread->setSubject( $subject ); |
1403 | 1391 | $thread->setAncestor( $ancestor->id() ); |
1404 | | - |
| 1392 | + |
1405 | 1393 | if ( $superthread !== false ) { |
1406 | 1394 | $thread->setSuperThread( $superthread ); |
1407 | 1395 | } |
1408 | | - |
| 1396 | + |
1409 | 1397 | $thread->save(); |
1410 | | - |
| 1398 | + |
1411 | 1399 | foreach ( $thread->replies() as $subThread ) { |
1412 | 1400 | self::recursiveSet( $subThread, $subject, $ancestor ); |
1413 | 1401 | } |
1414 | 1402 | } |
1415 | | - |
| 1403 | + |
1416 | 1404 | static function validateSubject( $subject, &$title, $replyTo, $article ) { |
1417 | 1405 | $t = null; |
1418 | 1406 | $ok = true; |
1419 | | - |
| 1407 | + |
1420 | 1408 | while ( !$t ) { |
1421 | 1409 | try { |
1422 | 1410 | global $wgUser; |
1423 | | - |
| 1411 | + |
1424 | 1412 | if ( !$replyTo && $subject ) { |
1425 | 1413 | $t = Threads::newThreadTitle( $subject, $article ); |
1426 | 1414 | } elseif ( $replyTo ) { |
1427 | 1415 | $t = Threads::newReplyTitle( $replyTo, $wgUser ); |
1428 | 1416 | } |
1429 | | - |
| 1417 | + |
1430 | 1418 | if ( $t ) |
1431 | 1419 | break; |
1432 | 1420 | } catch ( Exception $e ) { } |
1433 | | - |
| 1421 | + |
1434 | 1422 | $subject = md5( mt_rand() ); // Just a random title |
1435 | 1423 | $ok = false; |
1436 | 1424 | } |
1437 | | - |
| 1425 | + |
1438 | 1426 | $title = $t; |
1439 | | - |
| 1427 | + |
1440 | 1428 | return $ok; |
1441 | 1429 | } |
1442 | | - |
| 1430 | + |
1443 | 1431 | /* N.B. Returns true, or a string with either thread or talkpage, noting which is |
1444 | 1432 | protected */ |
1445 | 1433 | public function canUserReply( $user ) { |
1446 | | - $threadRestrictions = $this->topmostThread()->title()->getRestrictions('reply'); |
1447 | | - $talkpageRestrictions = $this->article()->getTitle()->getRestrictions('reply'); |
1448 | | - |
| 1434 | + $threadRestrictions = $this->topmostThread()->title()->getRestrictions( 'reply' ); |
| 1435 | + $talkpageRestrictions = $this->article()->getTitle()->getRestrictions( 'reply' ); |
| 1436 | + |
1449 | 1437 | $threadRestrictions = array_fill_keys( $threadRestrictions, 'thread' ); |
1450 | 1438 | $talkpageRestrictions = array_fill_keys( $talkpageRestrictions, 'talkpage' ); |
1451 | | - |
| 1439 | + |
1452 | 1440 | $restrictions = array_merge( $threadRestrictions, $talkpageRestrictions ); |
1453 | | - |
1454 | | - foreach( $restrictions as $right => $source ) { |
| 1441 | + |
| 1442 | + foreach ( $restrictions as $right => $source ) { |
1455 | 1443 | if ( $right == 'sysop' ) $right = 'protect'; |
1456 | 1444 | if ( !$user->isAllowed( $right ) ) { |
1457 | 1445 | return $source; |
1458 | 1446 | } |
1459 | 1447 | } |
1460 | | - |
| 1448 | + |
1461 | 1449 | return true; |
1462 | 1450 | } |
1463 | | - |
| 1451 | + |
1464 | 1452 | public static function canUserPost( $user, $talkpage ) { |
1465 | | - $restrictions = $talkpage->getTitle()->getRestrictions('newthread'); |
1466 | | - |
1467 | | - foreach( $restrictions as $right ) { |
| 1453 | + $restrictions = $talkpage->getTitle()->getRestrictions( 'newthread' ); |
| 1454 | + |
| 1455 | + foreach ( $restrictions as $right ) { |
1468 | 1456 | if ( !$user->isAllowed( $right ) ) { |
1469 | 1457 | return false; |
1470 | 1458 | } |
1471 | 1459 | } |
1472 | | - |
| 1460 | + |
1473 | 1461 | return true; |
1474 | 1462 | } |
1475 | | - |
| 1463 | + |
1476 | 1464 | public function signature() { |
1477 | 1465 | return $this->signature; |
1478 | 1466 | } |
1479 | | - |
1480 | | - public function setSignature($sig) { |
| 1467 | + |
| 1468 | + public function setSignature( $sig ) { |
1481 | 1469 | $sig = LqtView::signaturePST( $sig, $this->author() ); |
1482 | 1470 | $this->signature = $sig; |
1483 | 1471 | } |
Index: trunk/extensions/LiquidThreads/classes/ThreadHistoryPager.php |
— | — | @@ -2,14 +2,13 @@ |
3 | 3 | |
4 | 4 | class ThreadHistoryPager extends TablePager { |
5 | 5 | static $change_names; |
6 | | - |
7 | 6 | |
8 | 7 | function __construct( $view, $thread ) { |
9 | 8 | parent::__construct(); |
10 | | - |
| 9 | + |
11 | 10 | $this->thread = $thread; |
12 | 11 | $this->view = $view; |
13 | | - |
| 12 | + |
14 | 13 | self::$change_names = |
15 | 14 | array( |
16 | 15 | Threads::CHANGE_EDITED_ROOT => wfMsgNoTrans( 'lqt_hist_comment_edited' ), |
— | — | @@ -28,19 +27,18 @@ |
29 | 28 | Threads::CHANGE_ADJUSTED_SORTKEY => wfMsgNoTrans( 'lqt_hist_adjusted_sortkey' ), |
30 | 29 | ); |
31 | 30 | } |
32 | | - |
| 31 | + |
33 | 32 | function getQueryInfo() { |
34 | | - $queryInfo = |
35 | | - array( |
36 | | - 'tables' => array( 'thread_history' ), |
37 | | - 'fields' => '*', |
38 | | - 'conds' => array( 'th_thread' => $this->thread->id() ), |
39 | | - 'options' => array( 'order by' => 'th_timestamp desc' ), |
40 | | - ); |
41 | | - |
| 33 | + $queryInfo = array( |
| 34 | + 'tables' => array( 'thread_history' ), |
| 35 | + 'fields' => '*', |
| 36 | + 'conds' => array( 'th_thread' => $this->thread->id() ), |
| 37 | + 'options' => array( 'order by' => 'th_timestamp desc' ), |
| 38 | + ); |
| 39 | + |
42 | 40 | return $queryInfo; |
43 | 41 | } |
44 | | - |
| 42 | + |
45 | 43 | function getFieldMessages() { |
46 | 44 | $headers = array( |
47 | 45 | 'th_timestamp' => 'lqt-history-time', |
— | — | @@ -48,24 +46,24 @@ |
49 | 47 | 'th_change_type' => 'lqt-history-action', |
50 | 48 | 'th_change_comment' => 'lqt-history-comment', |
51 | 49 | ); |
52 | | - |
| 50 | + |
53 | 51 | return $headers; |
54 | 52 | } |
55 | | - |
| 53 | + |
56 | 54 | function getFieldNames() { |
57 | 55 | static $headers = null; |
58 | 56 | |
59 | 57 | if ( !empty( $headers ) ) { |
60 | 58 | return $headers; |
61 | 59 | } |
62 | | - |
| 60 | + |
63 | 61 | $headers = $this->getFieldMessages(); |
64 | 62 | |
65 | 63 | $headers = array_map( 'wfMsg', $headers ); |
66 | 64 | |
67 | 65 | return $headers; |
68 | 66 | } |
69 | | - |
| 67 | + |
70 | 68 | function formatValue( $name, $value ) { |
71 | 69 | global $wgOut, $wgLang, $wgTitle; |
72 | 70 | |
— | — | @@ -83,11 +81,18 @@ |
84 | 82 | switch( $name ) { |
85 | 83 | case 'th_timestamp': |
86 | 84 | $formatted = $wgLang->timeanddate( $value ); |
87 | | - return $sk->link( $wgTitle, $formatted, array(), |
88 | | - array( 'lqt_oldid' => $row->th_id ) ); |
| 85 | + return $sk->link( |
| 86 | + $wgTitle, |
| 87 | + $formatted, |
| 88 | + array(), |
| 89 | + array( 'lqt_oldid' => $row->th_id ) |
| 90 | + ); |
89 | 91 | case 'th_user_text': |
90 | | - return $sk->userLink( $row->th_user, $row->th_user_text ) . ' ' . |
91 | | - $sk->userToolLinks( $row->th_user, $row->th_user_text ); |
| 92 | + return $sk->userLink( |
| 93 | + $row->th_user, |
| 94 | + $row->th_user_text |
| 95 | + ) . |
| 96 | + ' ' . $sk->userToolLinks( $row->th_user, $row->th_user_text ); |
92 | 97 | case 'th_change_type': |
93 | 98 | return $this->getActionDescription( $value ); |
94 | 99 | case 'th_change_comment': |
— | — | @@ -97,29 +102,29 @@ |
98 | 103 | break; |
99 | 104 | } |
100 | 105 | } |
101 | | - |
| 106 | + |
102 | 107 | function getActionDescription( $type ) { |
103 | 108 | global $wgOut; |
104 | | - |
| 109 | + |
105 | 110 | $args = array(); |
106 | 111 | $revision = ThreadRevision::loadFromRow( $this->mCurrentRow ); |
107 | 112 | $changeObject = $revision->getChangeObject(); |
108 | | - |
| 113 | + |
109 | 114 | if ( $revision && $revision->prev() ) { |
110 | 115 | $lastChangeObject = $revision->prev()->getChangeObject(); |
111 | 116 | } |
112 | | - |
| 117 | + |
113 | 118 | if ( $changeObject && $changeObject->title() ) { |
114 | 119 | $args[] = $changeObject->title()->getPrefixedText(); |
115 | 120 | } else { |
116 | 121 | $args[] = ''; |
117 | 122 | } |
118 | | - |
| 123 | + |
119 | 124 | $msg = self::$change_names[$type]; |
120 | | - |
| 125 | + |
121 | 126 | switch( $type ) { |
122 | 127 | case Threads::CHANGE_EDITED_SUBJECT: |
123 | | - if ($changeObject && $lastChangeObject) { |
| 128 | + if ( $changeObject && $lastChangeObject ) { |
124 | 129 | $args[] = $lastChangeObject->subject(); |
125 | 130 | $args[] = $changeObject->subject(); |
126 | 131 | } else { |
— | — | @@ -129,7 +134,7 @@ |
130 | 135 | case Threads::CHANGE_EDITED_ROOT: |
131 | 136 | case Threads::CHANGE_ROOT_BLANKED: |
132 | 137 | $view = $this->view; |
133 | | - |
| 138 | + |
134 | 139 | if ( $changeObject && $changeObject->title() ) { |
135 | 140 | $diffLink = $view->diffPermalinkURL( $changeObject, $revision ); |
136 | 141 | $args[] = $diffLink; |
— | — | @@ -138,15 +143,15 @@ |
139 | 144 | } |
140 | 145 | break; |
141 | 146 | } |
142 | | - |
| 147 | + |
143 | 148 | $content = wfMsgReplaceArgs( $msg, $args ); |
144 | 149 | return $wgOut->parseInline( $content ); |
145 | 150 | } |
146 | | - |
| 151 | + |
147 | 152 | function getIndexField() { |
148 | 153 | return 'th_timestamp'; |
149 | 154 | } |
150 | | - |
| 155 | + |
151 | 156 | function getDefaultSort() { |
152 | 157 | return 'th_timestamp'; |
153 | 158 | } |
— | — | @@ -155,6 +160,6 @@ |
156 | 161 | $sortable_fields = array( 'th_timestamp', 'th_user_text', 'th_change_type' ); |
157 | 162 | return in_array( $name, $sortable_fields ); |
158 | 163 | } |
159 | | - |
| 164 | + |
160 | 165 | function getDefaultDirections() { return true; /* descending */ } |
161 | 166 | } |
Index: trunk/extensions/LiquidThreads/classes/HistoricalThread.php |
— | — | @@ -2,7 +2,6 @@ |
3 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
4 | 4 | |
5 | 5 | class HistoricalThread extends Thread { |
6 | | - |
7 | 6 | /* Information about what changed in this revision. */ |
8 | 7 | protected $changeType; |
9 | 8 | protected $changeObject; |
— | — | @@ -46,7 +45,10 @@ |
47 | 46 | $line = $dbr->selectRow( |
48 | 47 | 'historical_thread', |
49 | 48 | 'hthread_contents', |
50 | | - array( 'hthread_id' => $id, 'hthread_revision' => $rev ), |
| 49 | + array( |
| 50 | + 'hthread_id' => $id, |
| 51 | + 'hthread_revision' => $rev |
| 52 | + ), |
51 | 53 | __METHOD__ ); |
52 | 54 | if ( $line ) |
53 | 55 | return HistoricalThread::fromTextRepresentation( $line->hthread_contents ); |
— | — | @@ -57,12 +59,12 @@ |
58 | 60 | function isHistorical() { |
59 | 61 | return true; |
60 | 62 | } |
61 | | - |
62 | 63 | |
| 64 | + |
63 | 65 | function changeType() { |
64 | 66 | return $this->changeType; |
65 | 67 | } |
66 | | - |
| 68 | + |
67 | 69 | function changeObject() { |
68 | 70 | return $this->replyWithId( $this->changeObject ); |
69 | 71 | } |
— | — | @@ -95,7 +97,7 @@ |
96 | 98 | function changeComment() { |
97 | 99 | return $this->changeComment; |
98 | 100 | } |
99 | | - |
| 101 | + |
100 | 102 | function setChangeUser( $user ) { |
101 | 103 | $this->changeUser = $user->getId(); |
102 | 104 | $this->changeUserText = $user->getName(); |
Index: trunk/extensions/LiquidThreads/classes/Threads.php |
— | — | @@ -3,7 +3,6 @@ |
4 | 4 | |
5 | 5 | /** Module of factory methods. */ |
6 | 6 | class Threads { |
7 | | - |
8 | 7 | const TYPE_NORMAL = 0; |
9 | 8 | const TYPE_MOVED = 1; |
10 | 9 | const TYPE_DELETED = 2; |
— | — | @@ -24,7 +23,7 @@ |
25 | 24 | const CHANGE_SPLIT_FROM = 12; |
26 | 25 | const CHANGE_ROOT_BLANKED = 13; |
27 | 26 | const CHANGE_ADJUSTED_SORTKEY = 14; |
28 | | - |
| 27 | + |
29 | 28 | static $VALID_CHANGE_TYPES = array( |
30 | 29 | self::CHANGE_EDITED_SUMMARY, |
31 | 30 | self::CHANGE_EDITED_ROOT, |
— | — | @@ -61,39 +60,41 @@ |
62 | 61 | if ( ! $talkpage->exists() ) { |
63 | 62 | try { |
64 | 63 | wfLoadExtensionMessages( 'LiquidThreads' ); |
65 | | - $talkpage->doEdit( "", |
| 64 | + $talkpage->doEdit( |
| 65 | + "", |
66 | 66 | wfMsgForContent( 'lqt_talkpage_autocreate_summary' ), |
67 | | - EDIT_NEW | EDIT_SUPPRESS_RC ); |
| 67 | + EDIT_NEW | EDIT_SUPPRESS_RC |
| 68 | + ); |
68 | 69 | } catch ( DBQueryError $e ) { |
69 | 70 | // The article already existed by now. No need to do anything. |
70 | 71 | wfDebug( __METHOD__ . ": Article already exists." ); |
71 | 72 | } |
72 | 73 | } |
73 | 74 | } |
74 | | - |
| 75 | + |
75 | 76 | static function loadFromResult( $res, $db, $bulkLoad = false ) { |
76 | 77 | $rows = array(); |
77 | 78 | $threads = array(); |
78 | | - |
| 79 | + |
79 | 80 | while ( $row = $db->fetchObject( $res ) ) { |
80 | 81 | $rows[] = $row; |
81 | | - |
82 | | - if (!$bulkLoad) { |
| 82 | + |
| 83 | + if ( !$bulkLoad ) { |
83 | 84 | $threads[$row->thread_id] = Thread::newFromRow( $row ); |
84 | 85 | } |
85 | 86 | } |
86 | | - |
87 | | - if (!$bulkLoad) { |
| 87 | + |
| 88 | + if ( !$bulkLoad ) { |
88 | 89 | return $threads; |
89 | 90 | } |
90 | | - |
| 91 | + |
91 | 92 | return Thread::bulkLoad( $rows ); |
92 | 93 | } |
93 | 94 | |
94 | 95 | static function where( $where, $options = array(), $bulkLoad = true ) { |
95 | 96 | global $wgDBprefix; |
96 | 97 | $dbr = wfGetDB( DB_SLAVE ); |
97 | | - |
| 98 | + |
98 | 99 | $res = $dbr->select( 'thread', '*', $where, __METHOD__, $options ); |
99 | 100 | $threads = Threads::loadFromResult( $res, $dbr, $bulkLoad ); |
100 | 101 | |
— | — | @@ -113,8 +114,14 @@ |
114 | 115 | } |
115 | 116 | |
116 | 117 | private static function assertSingularity( $threads, $attribute, $value ) { |
117 | | - if ( count( $threads ) == 0 ) { return null; } |
118 | | - if ( count( $threads ) == 1 ) { return array_pop( $threads ); } |
| 118 | + if ( count( $threads ) == 0 ) { |
| 119 | + return null; |
| 120 | + } |
| 121 | + |
| 122 | + if ( count( $threads ) == 1 ) { |
| 123 | + return array_pop( $threads ); |
| 124 | + } |
| 125 | + |
119 | 126 | if ( count( $threads ) > 1 ) { |
120 | 127 | Threads::databaseError( "More than one thread with $attribute = $value." ); |
121 | 128 | return null; |
— | — | @@ -126,14 +133,14 @@ |
127 | 134 | // No articles outside the thread namespace have threads associated with them; |
128 | 135 | return null; |
129 | 136 | } |
130 | | - |
| 137 | + |
131 | 138 | if ( array_key_exists( $post->getID(), self::$cache_by_root ) ) { |
132 | 139 | return self::$cache_by_root[$post->getID()]; |
133 | 140 | } |
134 | | - |
| 141 | + |
135 | 142 | $ts = Threads::where( array( 'thread_root' => $post->getID() ), array(), |
136 | 143 | $bulkLoad ); |
137 | | - |
| 144 | + |
138 | 145 | return self::assertSingularity( $ts, 'thread_root', $post->getID() ); |
139 | 146 | } |
140 | 147 | |
— | — | @@ -141,65 +148,65 @@ |
142 | 149 | if ( array_key_exists( $id, self::$cache_by_id ) ) { |
143 | 150 | return self::$cache_by_id[$id]; |
144 | 151 | } |
145 | | - |
| 152 | + |
146 | 153 | $ts = Threads::where( array( 'thread_id' => $id ), array(), $bulkLoad ); |
147 | | - |
| 154 | + |
148 | 155 | return self::assertSingularity( $ts, 'thread_id', $id ); |
149 | 156 | } |
150 | 157 | |
151 | 158 | static function withSummary( $article, $bulkLoad = true ) { |
152 | 159 | $ts = Threads::where( array( 'thread_summary_page' => $article->getId() ), |
153 | | - array(), $bulkLoad); |
| 160 | + array(), $bulkLoad ); |
154 | 161 | return self::assertSingularity( $ts, 'thread_summary_page', $article->getId() ); |
155 | 162 | } |
156 | 163 | |
157 | 164 | static function articleClause( $article ) { |
158 | 165 | $dbr = wfGetDB( DB_SLAVE ); |
159 | | - |
| 166 | + |
160 | 167 | $titleCond = array( 'thread_article_title' => $article->getTitle()->getDBKey(), |
161 | 168 | 'thread_article_namespace' => $article->getTitle()->getNamespace() ); |
162 | 169 | $titleCond = $dbr->makeList( $titleCond, LIST_AND ); |
163 | | - |
| 170 | + |
164 | 171 | $conds = array( $titleCond ); |
165 | | - |
| 172 | + |
166 | 173 | if ( $article->getId() ) { |
167 | 174 | $idCond = array( 'thread_article_id' => $article->getId() ); |
168 | 175 | $conds[] = $dbr->makeList( $idCond, LIST_AND ); |
169 | 176 | } |
170 | | - |
| 177 | + |
171 | 178 | return $dbr->makeList( $conds, LIST_OR ); |
172 | 179 | } |
173 | 180 | |
174 | 181 | static function topLevelClause() { |
175 | 182 | $dbr = wfGetDB( DB_SLAVE ); |
176 | | - |
| 183 | + |
177 | 184 | $arr = array( 'thread_ancestor=thread_id', 'thread_parent' => null ); |
178 | | - |
| 185 | + |
179 | 186 | return $dbr->makeList( $arr, LIST_OR ); |
180 | 187 | } |
181 | | - |
| 188 | + |
182 | 189 | static function newThreadTitle( $subject, $article ) { |
183 | 190 | wfLoadExtensionMessages( 'LiquidThreads' ); |
184 | | - |
| 191 | + |
185 | 192 | $base = $article->getTitle()->getPrefixedText() . "/$subject"; |
186 | | - |
| 193 | + |
187 | 194 | return self::incrementedTitle( $base, NS_LQT_THREAD ); |
188 | 195 | } |
189 | | - |
| 196 | + |
190 | 197 | static function newSummaryTitle( $t ) { |
191 | 198 | return self::incrementedTitle( $t->title()->getText(), NS_LQT_SUMMARY ); |
192 | 199 | } |
193 | | - |
| 200 | + |
194 | 201 | static function newReplyTitle( $thread, $user ) { |
195 | 202 | wfLoadExtensionMessages( 'LiquidThreads' ); |
196 | 203 | $topThread = $thread->topmostThread(); |
197 | | - |
| 204 | + |
198 | 205 | $base = $topThread->title()->getText() . '/' |
199 | | - . wfMsgForContent('lqt-reply-subpage'); |
200 | | - |
| 206 | + . wfMsgForContent( 'lqt-reply-subpage' ); |
| 207 | + |
201 | 208 | return self::incrementedTitle( $base, NS_LQT_THREAD ); |
202 | 209 | } |
203 | | - |
| 210 | + |
204 | 211 | // This will attempt to replace invalid characters and sequences in a title with |
205 | 212 | // a safe replacement (_, currently). Before doing this, it will parse any wikitext |
206 | 213 | // and strip the HTML, before converting HTML entities back into their corresponding |
— | — | @@ -207,9 +214,9 @@ |
208 | 215 | public static function makeTitleValid( $text ) { |
209 | 216 | $text = self::stripWikitext( $text ); |
210 | 217 | $text = html_entity_decode( $text, ENT_QUOTES, 'UTF-8' ); |
211 | | - |
| 218 | + |
212 | 219 | static $rxTc; |
213 | | - |
| 220 | + |
214 | 221 | if ( is_callable( array( 'Title', 'getTitleInvalidRegex' ) ) ) { |
215 | 222 | $rxTc = Title::getTitleInvalidRegex(); |
216 | 223 | } elseif ( !$rxTc ) { // Back-compat |
— | — | @@ -225,47 +232,47 @@ |
226 | 233 | '|&#x[0-9A-Fa-f]+;' . |
227 | 234 | '/S'; |
228 | 235 | } |
229 | | - |
| 236 | + |
230 | 237 | $text = preg_replace( $rxTc, '_', $text ); |
231 | | - |
| 238 | + |
232 | 239 | return $text; |
233 | 240 | } |
234 | | - |
| 241 | + |
235 | 242 | // This will strip wikitext of its formatting. |
236 | 243 | public static function stripWikitext( $text ) { |
237 | 244 | global $wgOut; |
238 | 245 | $text = $wgOut->parseInline( $text ); |
239 | | - |
| 246 | + |
240 | 247 | $text = StringUtils::delimiterReplace( '<', '>', '', $text ); |
241 | | - |
| 248 | + |
242 | 249 | return $text; |
243 | 250 | } |
244 | | - |
| 251 | + |
245 | 252 | public static function stripHTML( $text ) { |
246 | 253 | return StringUtils::delimiterReplace( '<', '>', '', $text ); |
247 | 254 | } |
248 | | - |
| 255 | + |
249 | 256 | /** Keep trying titles starting with $basename until one is unoccupied. */ |
250 | 257 | public static function incrementedTitle( $basename, $namespace ) { |
251 | 258 | $i = 2; |
252 | | - |
| 259 | + |
253 | 260 | // Try to make the title valid. |
254 | 261 | $basename = Threads::makeTitleValid( $basename ); |
255 | | - |
| 262 | + |
256 | 263 | $t = Title::makeTitleSafe( $namespace, $basename ); |
257 | 264 | while ( !$t || $t->exists() || |
258 | 265 | in_array( $t->getPrefixedDBkey(), self::$occupied_titles ) ) { |
259 | | - |
| 266 | + |
260 | 267 | if ( !$t ) { |
261 | 268 | throw new MWException( "Error in creating title for basename $basename" ); |
262 | 269 | } |
263 | | - |
| 270 | + |
264 | 271 | $t = Title::makeTitleSafe( $namespace, $basename . ' (' . $i . ')' ); |
265 | 272 | $i++; |
266 | 273 | } |
267 | 274 | return $t; |
268 | 275 | } |
269 | | - |
| 276 | + |
270 | 277 | // Called just before any function that might cause a loss of article association. |
271 | 278 | // by breaking either a NS-title reference (by moving the article), or a page-id |
272 | 279 | // reference (by deleting the article). |
— | — | @@ -281,50 +288,50 @@ |
282 | 289 | static function synchroniseArticleData( $article, $limit = false, $queueMore = false ) { |
283 | 290 | $dbr = wfGetDB( DB_SLAVE ); |
284 | 291 | $dbw = wfGetDB( DB_MASTER ); |
285 | | - |
| 292 | + |
286 | 293 | $title = $article->getTitle(); |
287 | 294 | $id = $article->getId(); |
288 | | - |
| 295 | + |
289 | 296 | $titleCond = array( 'thread_article_namespace' => $title->getNamespace(), |
290 | 297 | 'thread_article_title' => $title->getDBkey() ); |
291 | 298 | $titleCondText = $dbr->makeList( $titleCond, LIST_AND ); |
292 | | - |
| 299 | + |
293 | 300 | $idCond = array( 'thread_article_id' => $id ); |
294 | 301 | $idCondText = $dbr->makeList( $idCond, LIST_AND ); |
295 | | - |
| 302 | + |
296 | 303 | $fixTitleCond = array( $idCondText, "NOT ($titleCondText)" ); |
297 | 304 | $fixIdCond = array( $titleCondText, "NOT ($idCondText)" ); |
298 | | - |
| 305 | + |
299 | 306 | // Try to hit the most recent threads first. |
300 | 307 | $options = array( 'LIMIT' => 500, 'ORDER BY' => 'thread_id DESC' ); |
301 | | - |
| 308 | + |
302 | 309 | // Batch in 500s |
303 | 310 | if ( $limit ) $options['LIMIT'] = min( $limit, 500 ); |
304 | | - |
| 311 | + |
305 | 312 | $rowsAffected = 0; |
306 | 313 | $roundRowsAffected = 1; |
307 | 314 | while ( ( !$limit || $rowsAffected < $limit ) && $roundRowsAffected > 0 ) { |
308 | 315 | $roundRowsAffected = 0; |
309 | | - |
| 316 | + |
310 | 317 | // Fix wrong title. |
311 | 318 | $res = $dbw->update( 'thread', $titleCond, $fixTitleCond, |
312 | 319 | __METHOD__, $options ); |
313 | 320 | $roundRowsAffected += $dbw->affectedRows(); |
314 | | - |
| 321 | + |
315 | 322 | // Fix wrong ID |
316 | 323 | $res = $dbw->update( 'thread', $idCond, $fixIdCond, __METHOD__, $options ); |
317 | 324 | $roundRowsAffected += $dbw->affectedRows(); |
318 | | - |
| 325 | + |
319 | 326 | $rowsAffected += $roundRowsAffected; |
320 | 327 | } |
321 | | - |
| 328 | + |
322 | 329 | if ( $limit && ( $rowsAffected >= $limit ) && $queueMore ) { |
323 | 330 | $jobParams = array( 'limit' => $limit, 'cascade' => true ); |
324 | 331 | $job = new SynchroniseThreadArticleDataJob( $article->getTitle(), |
325 | 332 | $jobParams ); |
326 | 333 | $job->insert(); |
327 | 334 | } |
328 | | - |
| 335 | + |
329 | 336 | return $limit ? ( $rowsAffected < $limit ) : true; |
330 | 337 | } |
331 | 338 | } |
Index: trunk/extensions/LiquidThreads/classes/View.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | /** |
5 | 4 | * @package MediaWiki |
6 | 5 | * @subpackage LiquidThreads |
— | — | @@ -19,7 +18,7 @@ |
20 | 19 | public $title; |
21 | 20 | public $request; |
22 | 21 | |
23 | | - protected $headerLevel = 2; /* h1, h2, h3, etc. */ |
| 22 | + protected $headerLevel = 2; /* h1, h2, h3, etc. */ |
24 | 23 | protected $lastUnindentedSuperthread; |
25 | 24 | |
26 | 25 | public $threadNestingLevel = 0; |
— | — | @@ -48,8 +47,8 @@ |
49 | 48 | } |
50 | 49 | |
51 | 50 | /************************* |
52 | | - * (1) linking to liquidthreads pages and |
53 | | - * (2) figuring out what page you're on and what you need to do. |
| 51 | + * (1) linking to liquidthreads pages and |
| 52 | + * (2) figuring out what page you're on and what you need to do. |
54 | 53 | *************************/ |
55 | 54 | |
56 | 55 | function methodAppliesToThread( $method, $thread ) { |
— | — | @@ -126,15 +125,15 @@ |
127 | 126 | |
128 | 127 | $query['lqt_mustshow'] = $thread->id(); |
129 | 128 | |
130 | | - $title->setFragment( '#'.$thread->getAnchorName() ); |
| 129 | + $title->setFragment( '#' . $thread->getAnchorName() ); |
131 | 130 | |
132 | 131 | return array( $title, $query ); |
133 | 132 | } |
134 | 133 | |
135 | 134 | static function linkInContext( $thread, $contextType = 'page', $text = null ) { |
136 | 135 | list( $title, $query ) = self::linkInContextData( $thread, $contextType ); |
137 | | - |
138 | | - if ( is_null($text) ) { |
| 136 | + |
| 137 | + if ( is_null( $text ) ) { |
139 | 138 | $text = Threads::stripHTML( $thread->formattedSubject() ); |
140 | 139 | } |
141 | 140 | |
— | — | @@ -157,9 +156,11 @@ |
158 | 157 | $prev_rev = $curr_rev->getPrevious(); |
159 | 158 | $oldid = $prev_rev ? $prev_rev->getId() : ""; |
160 | 159 | |
161 | | - $query = array( 'lqt_method' => 'diff', |
162 | | - 'diff' => $curr_rev_id, |
163 | | - 'oldid' => $oldid ); |
| 160 | + $query = array( |
| 161 | + 'lqt_method' => 'diff', |
| 162 | + 'diff' => $curr_rev_id, |
| 163 | + 'oldid' => $oldid |
| 164 | + ); |
164 | 165 | |
165 | 166 | return $query; |
166 | 167 | } |
— | — | @@ -178,9 +179,11 @@ |
179 | 180 | $includeFragment = true, $attribs = array(), |
180 | 181 | $options = array(), $perpetuateOffset = true ) |
181 | 182 | { |
182 | | - list( $title, $query ) = self::talkpageLinkData( $title, $method, $operand, |
183 | | - $includeFragment, |
184 | | - $perpetuateOffset ); |
| 183 | + list( $title, $query ) = self::talkpageLinkData( |
| 184 | + $title, $method, $operand, |
| 185 | + $includeFragment, |
| 186 | + $perpetuateOffset |
| 187 | + ); |
185 | 188 | |
186 | 189 | global $wgUser; |
187 | 190 | $sk = $wgUser->getSkin(); |
— | — | @@ -189,8 +192,8 @@ |
190 | 193 | } |
191 | 194 | |
192 | 195 | static function talkpageLinkData( $title, $method = null, $operand = null, |
193 | | - $includeFragment = true, |
194 | | - $perpetuateOffset = true ) { |
| 196 | + $includeFragment = true, $perpetuateOffset = true ) |
| 197 | + { |
195 | 198 | global $wgRequest; |
196 | 199 | $query = array(); |
197 | 200 | |
— | — | @@ -231,10 +234,13 @@ |
232 | 235 | return array( $title, $query ); |
233 | 236 | } |
234 | 237 | |
235 | | - /* If you want $perpetuateOffset to perpetuate from a specific request, pass that instead |
236 | | - of true */ |
| 238 | + /** |
| 239 | + * If you want $perpetuateOffset to perpetuate from a specific request, |
| 240 | + * pass that instead of true |
| 241 | + */ |
237 | 242 | static function talkpageUrl( $title, $method = null, $operand = null, |
238 | | - $includeFragment = true, $perpetuateOffset = true ) { |
| 243 | + $includeFragment = true, $perpetuateOffset = true ) |
| 244 | + { |
239 | 245 | global $wgUser; |
240 | 246 | $sk = $wgUser->getSkin(); |
241 | 247 | |
— | — | @@ -247,10 +253,10 @@ |
248 | 254 | |
249 | 255 | |
250 | 256 | /** |
251 | | - * Return a URL for the current page, including Title and query vars, |
| 257 | + * Return a URL for the current page, including Title and query vars, |
252 | 258 | * with the given replacements made. |
253 | | - * @param $repls array( 'name'=>new_value, ... ) |
254 | | - */ |
| 259 | + * @param $repls array( 'name'=>new_value, ... ) |
| 260 | + */ |
255 | 261 | function queryReplaceLink( $repls ) { |
256 | 262 | $query = $this->getReplacedQuery( $repls ); |
257 | 263 | |
— | — | @@ -268,10 +274,10 @@ |
269 | 275 | } |
270 | 276 | |
271 | 277 | /************************************************************* |
272 | | - * Editing methods (here be dragons) * |
273 | | - * Forget dragons: This section distorts the rest of the code * |
274 | | - * like a star bending spacetime around itself. * |
275 | | - *************************************************************/ |
| 278 | + * Editing methods (here be dragons) * |
| 279 | + * Forget dragons: This section distorts the rest of the code * |
| 280 | + * like a star bending spacetime around itself. * |
| 281 | + *************************************************************/ |
276 | 282 | |
277 | 283 | /** |
278 | 284 | * Return an HTML form element whose value is gotten from the request. |
— | — | @@ -331,13 +337,13 @@ |
332 | 338 | } |
333 | 339 | |
334 | 340 | private function showEditingFormInGeneral( $thread, $edit_type, $edit_applies_to ) { |
335 | | - /* |
336 | | - EditPage needs an Article. If there isn't a real one, as for new posts, |
337 | | - replies, and new summaries, we need to generate a title. Auto-generated |
338 | | - titles are based on the subject line. If the subject line is blank, we |
339 | | - can temporarily use a random scratch title. It's fine if the title changes |
340 | | - throughout the edit cycle, since the article doesn't exist yet anyways. |
341 | | - */ |
| 341 | + /** |
| 342 | + * EditPage needs an Article. If there isn't a real one, as for new posts, |
| 343 | + * replies, and new summaries, we need to generate a title. Auto-generated |
| 344 | + * titles are based on the subject line. If the subject line is blank, we |
| 345 | + * can temporarily use a random scratch title. It's fine if the title changes |
| 346 | + * throughout the edit cycle, since the article doesn't exist yet anyways. |
| 347 | + */ |
342 | 348 | |
343 | 349 | // Check permissions |
344 | 350 | if ( $edit_type == 'new' ) { |
— | — | @@ -441,8 +447,11 @@ |
442 | 448 | |
443 | 449 | $reply_subject = $edit_applies_to->subject(); |
444 | 450 | $reply_title = $edit_applies_to->title()->getPrefixedText(); |
445 | | - $summary = wfMsgForContent( 'lqt-reply-summary', |
446 | | - $reply_subject, $reply_title ); |
| 451 | + $summary = wfMsgForContent( |
| 452 | + 'lqt-reply-summary', |
| 453 | + $reply_subject, |
| 454 | + $reply_title |
| 455 | + ); |
447 | 456 | $wgRequest->setVal( 'wpSummary', $summary ); |
448 | 457 | } |
449 | 458 | |
— | — | @@ -463,7 +472,7 @@ |
464 | 473 | |
465 | 474 | $signatureText = $this->request->getVal( 'wpLqtSignature', null ); |
466 | 475 | |
467 | | - if ( is_null($signatureText) ) { |
| 476 | + if ( is_null( $signatureText ) ) { |
468 | 477 | if ( !$thread && $edit_type != 'summarize' ) { |
469 | 478 | $signatureText = LqtView::getUserSignature( $this->user ); |
470 | 479 | } else { |
— | — | @@ -474,12 +483,18 @@ |
475 | 484 | $signatureHTML = LqtView::parseSignature( $signatureText ); |
476 | 485 | |
477 | 486 | // Signature edit box |
478 | | - $signaturePreview = Xml::tags( 'span', |
479 | | - array( 'class' => 'lqt-signature-preview', |
480 | | - 'style' => 'display: none;' ), |
481 | | - $signatureHTML ); |
482 | | - $signatureEditBox = Xml::input( 'wpLqtSignature', 45, $signatureText, |
483 | | - array( 'class' => 'lqt-signature-edit' ) ); |
| 487 | + $signaturePreview = Xml::tags( |
| 488 | + 'span', |
| 489 | + array( |
| 490 | + 'class' => 'lqt-signature-preview', |
| 491 | + 'style' => 'display: none;' |
| 492 | + ), |
| 493 | + $signatureHTML |
| 494 | + ); |
| 495 | + $signatureEditBox = Xml::input( |
| 496 | + 'wpLqtSignature', 45, $signatureText, |
| 497 | + array( 'class' => 'lqt-signature-edit' ) |
| 498 | + ); |
484 | 499 | |
485 | 500 | $signatureEditor = $signaturePreview . $signatureEditBox; |
486 | 501 | |
— | — | @@ -564,13 +579,13 @@ |
565 | 580 | } |
566 | 581 | |
567 | 582 | static function postEditUpdates( $edit_type, $edit_applies_to, $edit_page, $article, |
568 | | - $subject, $edit_summary, $thread, $new_text, |
569 | | - $bump = null, $signature = null ) { |
| 583 | + $subject, $edit_summary, $thread, $new_text, $bump = null, $signature = null ) |
| 584 | + { |
570 | 585 | // Update metadata - create and update thread and thread revision objects as |
571 | 586 | // appropriate. |
572 | 587 | |
573 | 588 | $noSignature = false; |
574 | | - if ( is_null($signature) ) { |
| 589 | + if ( is_null( $signature ) ) { |
575 | 590 | global $wgUser; |
576 | 591 | $signature = LqtView::getUserSignature( $wgUser ); |
577 | 592 | $noSignature = true; |
— | — | @@ -579,17 +594,21 @@ |
580 | 595 | if ( $edit_type == 'reply' ) { |
581 | 596 | $subject = $edit_applies_to->subject(); |
582 | 597 | |
583 | | - $thread = Thread::create( $edit_page, $article, $edit_applies_to, |
584 | | - Threads::TYPE_NORMAL, $subject, |
585 | | - $edit_summary, $bump, $signature ); |
| 598 | + $thread = Thread::create( |
| 599 | + $edit_page, $article, $edit_applies_to, |
| 600 | + Threads::TYPE_NORMAL, $subject, |
| 601 | + $edit_summary, $bump, $signature |
| 602 | + ); |
586 | 603 | |
587 | 604 | global $wgUser; |
588 | 605 | NewMessages::markThreadAsReadByUser( $edit_applies_to, $wgUser ); |
589 | 606 | } elseif ( $edit_type == 'summarize' ) { |
590 | 607 | $edit_applies_to->setSummary( $edit_page ); |
591 | | - $edit_applies_to->commitRevision( Threads::CHANGE_EDITED_SUMMARY, |
592 | | - $edit_applies_to, $edit_summary, |
593 | | - $bump); |
| 608 | + $edit_applies_to->commitRevision( |
| 609 | + Threads::CHANGE_EDITED_SUMMARY, |
| 610 | + $edit_applies_to, $edit_summary, |
| 611 | + $bump |
| 612 | + ); |
594 | 613 | } elseif ( $edit_type == 'editExisting' ) { |
595 | 614 | // Use a separate type if the content is blanked. |
596 | 615 | $type = strlen( trim( $new_text ) ) |
— | — | @@ -603,9 +622,11 @@ |
604 | 623 | // Add the history entry. |
605 | 624 | $thread->commitRevision( $type, $thread, $edit_summary, $bump ); |
606 | 625 | } else { |
607 | | - $thread = Thread::create( $edit_page, $article, null, |
608 | | - Threads::TYPE_NORMAL, $subject, |
609 | | - $edit_summary, null, $signature ); |
| 626 | + $thread = Thread::create( |
| 627 | + $edit_page, $article, null, |
| 628 | + Threads::TYPE_NORMAL, $subject, |
| 629 | + $edit_summary, null, $signature |
| 630 | + ); |
610 | 631 | } |
611 | 632 | |
612 | 633 | return $thread; |
— | — | @@ -640,7 +661,6 @@ |
641 | 662 | } |
642 | 663 | |
643 | 664 | # Variables beginning with 'o' for old article 'n' for new article |
644 | | - |
645 | 665 | $ot = $old_title; |
646 | 666 | $nt = $this->incrementedTitle( $new_subject, $old_title->getNamespace() ); |
647 | 667 | |
— | — | @@ -686,9 +706,11 @@ |
687 | 707 | } |
688 | 708 | |
689 | 709 | $history_url = self::permalinkUrlWithQuery( $thread, array( 'action' => 'history' ) ); |
690 | | - $commands['history'] = array( 'label' => wfMsgExt( 'history_short', 'parseinline' ), |
691 | | - 'href' => $history_url, |
692 | | - 'enabled' => true ); |
| 710 | + $commands['history'] = array( 'label' => wfMsgExt( |
| 711 | + 'history_short', 'parseinline' ), |
| 712 | + 'href' => $history_url, |
| 713 | + 'enabled' => true |
| 714 | + ); |
693 | 715 | |
694 | 716 | if ( $thread->isHistorical() ) { |
695 | 717 | return array(); |
— | — | @@ -696,25 +718,36 @@ |
697 | 719 | $user_can_edit = $thread->root()->getTitle()->quickUserCan( 'edit' ); |
698 | 720 | $editMsg = $user_can_edit ? 'edit' : 'viewsource'; |
699 | 721 | |
700 | | - $commands['edit'] = array( 'label' => wfMsgExt( $editMsg, 'parseinline' ), |
701 | | - 'href' => $this->talkpageUrl( $this->title, 'edit', $thread, |
702 | | - true /* include fragment */ , $this->request ), |
703 | | - 'enabled' => true ); |
| 722 | + $commands['edit'] = array( |
| 723 | + 'label' => wfMsgExt( $editMsg, 'parseinline' ), |
| 724 | + 'href' => $this->talkpageUrl( |
| 725 | + $this->title, |
| 726 | + 'edit', $thread, |
| 727 | + true, /* include fragment */ |
| 728 | + $this->request |
| 729 | + ), |
| 730 | + 'enabled' => true |
| 731 | + ); |
704 | 732 | |
705 | 733 | if ( $this->user->isAllowed( 'delete' ) ) { |
706 | 734 | $delete_url = $thread->title()->getFullURL( 'action=delete' ); |
707 | 735 | $deleteMsg = $thread->type() == Threads::TYPE_DELETED ? 'lqt_undelete' : 'delete'; |
708 | 736 | |
709 | | - $commands['delete'] = array( 'label' => wfMsgExt( $deleteMsg, 'parseinline' ), |
710 | | - 'href' => $delete_url, |
711 | | - 'enabled' => true ); |
| 737 | + $commands['delete'] = array( |
| 738 | + 'label' => wfMsgExt( $deleteMsg, 'parseinline' ), |
| 739 | + 'href' => $delete_url, |
| 740 | + 'enabled' => true |
| 741 | + ); |
712 | 742 | } |
713 | 743 | |
714 | 744 | if ( !$thread->isTopmostThread() && $this->user->isAllowed( 'lqt-split' ) ) { |
715 | 745 | $splitUrl = SpecialPage::getTitleFor( 'SplitThread', |
716 | 746 | $thread->title()->getPrefixedText() )->getFullURL(); |
717 | | - $commands['split'] = array( 'label' => wfMsgExt( 'lqt-thread-split', 'parseinline' ), |
718 | | - 'href' => $splitUrl, 'enabled' => true ); |
| 747 | + $commands['split'] = array( |
| 748 | + 'label' => wfMsgExt( 'lqt-thread-split', 'parseinline' ), |
| 749 | + 'href' => $splitUrl, |
| 750 | + 'enabled' => true |
| 751 | + ); |
719 | 752 | } |
720 | 753 | |
721 | 754 | if ( $this->user->isAllowed( 'lqt-merge' ) ) { |
— | — | @@ -726,8 +759,11 @@ |
727 | 760 | $mergeUrl = $this->title->getFullURL( wfArrayToCGI( $mergeParams ) ); |
728 | 761 | $label = wfMsgExt( 'lqt-thread-merge', 'parseinline' ); |
729 | 762 | |
730 | | - $commands['merge'] = array( 'label' => $label, |
731 | | - 'href' => $mergeUrl, 'enabled' => true ); |
| 763 | + $commands['merge'] = array( |
| 764 | + 'label' => $label, |
| 765 | + 'href' => $mergeUrl, |
| 766 | + 'enabled' => true |
| 767 | + ); |
732 | 768 | } |
733 | 769 | |
734 | 770 | return $commands; |
— | — | @@ -761,8 +797,11 @@ |
762 | 798 | $mergeUrl = $mergeTitle->getFullURL( 'dest=' . $thread->id() ); |
763 | 799 | $label = wfMsgExt( 'lqt-thread-merge-to', 'parseinline' ); |
764 | 800 | |
765 | | - $commands['merge-to'] = array( 'label' => $label, 'href' => $mergeUrl, |
766 | | - 'enabled' => true, 'tooltip' => $label ); |
| 801 | + $commands['merge-to'] = array( |
| 802 | + 'label' => $label, 'href' => $mergeUrl, |
| 803 | + 'enabled' => true, |
| 804 | + 'tooltip' => $label |
| 805 | + ); |
767 | 806 | } |
768 | 807 | |
769 | 808 | $commands['link'] = array( |
— | — | @@ -773,16 +812,6 @@ |
774 | 813 | 'showlabel' => true, |
775 | 814 | 'tooltip' => wfMsgExt( 'lqt_permalink', 'parseinline' ) |
776 | 815 | ); |
777 | | - /* |
778 | | - if ( $thread->root()->getTitle()->quickUserCan( 'edit' ) ) { |
779 | | - $commands['edit'] = array( |
780 | | - 'label' => wfMsgExt( 'edit', 'parseinline' ), |
781 | | - 'href' => $this->talkpageUrl( $this->title, 'edit', $thread, |
782 | | - true, $this->request ), |
783 | | - 'enabled' => true, 'icon' => 'edit.png', |
784 | | - 'tooltip' => wfMsgExt( 'edit', 'parseinline' ) ); |
785 | | - } |
786 | | - */ |
787 | 816 | |
788 | 817 | return $commands; |
789 | 818 | } |
— | — | @@ -791,16 +820,20 @@ |
792 | 821 | wfLoadExtensionMessages( 'LiquidThreads' ); |
793 | 822 | $commands = array(); |
794 | 823 | |
795 | | - $commands['history'] = array( 'label' => wfMsg( 'history_short' ), |
796 | | - 'href' => self::permalinkUrl( $thread, 'thread_history' ), |
797 | | - 'enabled' => true ); |
| 824 | + $commands['history'] = array( |
| 825 | + 'label' => wfMsg( 'history_short' ), |
| 826 | + 'href' => self::permalinkUrl( $thread, 'thread_history' ), |
| 827 | + 'enabled' => true |
| 828 | + ); |
798 | 829 | |
799 | 830 | if ( $this->user->isAllowed( 'move' ) ) { |
800 | 831 | $move_href = SpecialPage::getTitleFor( 'MoveThread' )->getFullURL() |
801 | 832 | . '/' . $thread->title()->getPrefixedURL(); |
802 | | - $commands['move'] = array( 'label' => wfMsg( 'lqt-movethread' ), |
803 | | - 'href' => $move_href, |
804 | | - 'enabled' => true ); |
| 833 | + $commands['move'] = array( |
| 834 | + 'label' => wfMsg( 'lqt-movethread' ), |
| 835 | + 'href' => $move_href, |
| 836 | + 'enabled' => true |
| 837 | + ); |
805 | 838 | } |
806 | 839 | |
807 | 840 | if ( $this->user->isAllowed( 'protect' ) ) { |
— | — | @@ -813,19 +846,25 @@ |
814 | 847 | $label = wfMsg( 'unprotect' ); |
815 | 848 | } |
816 | 849 | |
817 | | - $commands['protect'] = array( 'label' => $label, |
818 | | - 'href' => $protect_href, |
819 | | - 'enabled' => true, ); |
| 850 | + $commands['protect'] = array( |
| 851 | + 'label' => $label, |
| 852 | + 'href' => $protect_href, |
| 853 | + 'enabled' => true |
| 854 | + ); |
820 | 855 | } |
821 | 856 | |
822 | 857 | if ( !$this->user->isAnon() && !$thread->title()->userIsWatching() ) { |
823 | | - $commands['watch'] = array( 'label' => wfMsg( 'watch' ), |
824 | | - 'href' => self::permalinkUrlWithQuery( $thread, 'action=watch' ), |
825 | | - 'enabled' => true ); |
| 858 | + $commands['watch'] = array( |
| 859 | + 'label' => wfMsg( 'watch' ), |
| 860 | + 'href' => self::permalinkUrlWithQuery( $thread, 'action=watch' ), |
| 861 | + 'enabled' => true |
| 862 | + ); |
826 | 863 | } else if ( !$this->user->isAnon() ) { |
827 | | - $commands['unwatch'] = array( 'label' => wfMsg( 'unwatch' ), |
828 | | - 'href' => self::permalinkUrlWithQuery( $thread, 'action=unwatch' ), |
829 | | - 'enabled' => true ); |
| 864 | + $commands['unwatch'] = array( |
| 865 | + 'label' => wfMsg( 'unwatch' ), |
| 866 | + 'href' => self::permalinkUrlWithQuery( $thread, 'action=unwatch' ), |
| 867 | + 'enabled' => true |
| 868 | + ); |
830 | 869 | } |
831 | 870 | |
832 | 871 | $summarizeUrl = self::permalinkUrl( $thread, 'summarize', $thread->id() ); |
— | — | @@ -926,11 +965,11 @@ |
927 | 966 | } |
928 | 967 | |
929 | 968 | $parserOutput = $post->getParserOutput( $oldid ); |
930 | | - |
| 969 | + |
931 | 970 | // Remove title, so that it stays set correctly. |
932 | 971 | $parserOutput->setTitleText( '' ); |
933 | | - |
934 | | - |
| 972 | + |
| 973 | + |
935 | 974 | $wgOut->addParserOutputNoText( $parserOutput ); |
936 | 975 | |
937 | 976 | return $parserOutput->getText(); |
— | — | @@ -964,7 +1003,7 @@ |
965 | 1004 | 'lqt-command-icon', 'style' => 'display: none;' ), |
966 | 1005 | $triggerText ); |
967 | 1006 | |
968 | | - if ( count($commands) ) { |
| 1007 | + if ( count( $commands ) ) { |
969 | 1008 | $headerParts[] = Xml::tags( 'li', |
970 | 1009 | array( 'class' => 'lqt-thread-toolbar-menu' ), |
971 | 1010 | $dropDownTrigger ); |
— | — | @@ -986,9 +1025,11 @@ |
987 | 1026 | foreach ( $commands as $key => $command ) { |
988 | 1027 | $thisCommand = $this->contentForCommand( $command ); |
989 | 1028 | |
990 | | - $thisCommand = Xml::tags( 'li', |
991 | | - array( 'class' => 'lqt-command lqt-command-' . $key ), |
992 | | - $thisCommand ); |
| 1029 | + $thisCommand = Xml::tags( |
| 1030 | + 'li', |
| 1031 | + array( 'class' => 'lqt-command lqt-command-' . $key ), |
| 1032 | + $thisCommand |
| 1033 | + ); |
993 | 1034 | |
994 | 1035 | $result[] = $thisCommand; |
995 | 1036 | } |
— | — | @@ -1121,7 +1162,7 @@ |
1122 | 1163 | $editedNotice ); |
1123 | 1164 | } |
1124 | 1165 | |
1125 | | - if ( ! count($infoElements) ) { |
| 1166 | + if ( ! count( $infoElements ) ) { |
1126 | 1167 | return ''; |
1127 | 1168 | } |
1128 | 1169 | |
— | — | @@ -1185,13 +1226,13 @@ |
1186 | 1227 | |
1187 | 1228 | $article = new Article( $thread->title() ); |
1188 | 1229 | $target = Title::newFromRedirect( $article->getContent() ); |
1189 | | - |
1190 | | - if (!$target) { |
1191 | | - throw new MWException( "Thread ".$thread->id().' purports to be moved, '. |
1192 | | - 'but no redirect found in text of '. |
1193 | | - $thread->title()->getPrefixedText().'. Dying.' ); |
| 1230 | + |
| 1231 | + if ( !$target ) { |
| 1232 | + throw new MWException( "Thread " . $thread->id() . ' purports to be moved, ' . |
| 1233 | + 'but no redirect found in text of ' . |
| 1234 | + $thread->title()->getPrefixedText() . '. Dying.' ); |
1194 | 1235 | } |
1195 | | - |
| 1236 | + |
1196 | 1237 | $t_thread = Threads::withRoot( new Article( $target ) ); |
1197 | 1238 | |
1198 | 1239 | // Grab data about the new post. |
— | — | @@ -1206,7 +1247,7 @@ |
1207 | 1248 | $sig, |
1208 | 1249 | $wgLang->date( $thread->modified() ), |
1209 | 1250 | $wgLang->time( $thread->modified() ), |
1210 | | - $sk->link($newTalkpage) |
| 1251 | + $sk->link( $newTalkpage ) |
1211 | 1252 | ); |
1212 | 1253 | |
1213 | 1254 | $this->output->addHTML( $html ); |
— | — | @@ -1280,7 +1321,7 @@ |
1281 | 1322 | $walk_thread = Threads::withId( $walk_thread ); |
1282 | 1323 | } |
1283 | 1324 | |
1284 | | - if (!is_object( $walk_thread ) ) { |
| 1325 | + if ( !is_object( $walk_thread ) ) { |
1285 | 1326 | continue; |
1286 | 1327 | } |
1287 | 1328 | |
— | — | @@ -1327,11 +1368,11 @@ |
1328 | 1369 | static function threadContainsRepliesWithContent( $thread ) { |
1329 | 1370 | $replies = $thread->replies(); |
1330 | 1371 | |
1331 | | - foreach( $replies as $reply ) { |
| 1372 | + foreach ( $replies as $reply ) { |
1332 | 1373 | $content = ''; |
1333 | 1374 | if ( $reply->root() ) $content = $reply->root()->getContent(); |
1334 | 1375 | |
1335 | | - if ( trim($content) != '' ) { |
| 1376 | + if ( trim( $content ) != '' ) { |
1336 | 1377 | return true; |
1337 | 1378 | } |
1338 | 1379 | |
— | — | @@ -1376,7 +1417,7 @@ |
1377 | 1418 | // We've shown too many threads. |
1378 | 1419 | $link = $this->getShowMore( $thread, $st, $i ); |
1379 | 1420 | |
1380 | | - $this->output->addHTML( $div.$link ); |
| 1421 | + $this->output->addHTML( $div . $link ); |
1381 | 1422 | $showThreads = false; |
1382 | 1423 | continue; |
1383 | 1424 | } |
— | — | @@ -1385,7 +1426,7 @@ |
1386 | 1427 | if ( $showCount == 1 ) { |
1387 | 1428 | // There's a post sep before each reply group to |
1388 | 1429 | // separate from the parent thread. |
1389 | | - $this->output->addHTML( $sep.$div ); |
| 1430 | + $this->output->addHTML( $sep . $div ); |
1390 | 1431 | } |
1391 | 1432 | |
1392 | 1433 | $this->showThread( $st, $i, $subthreadCount, $cascadeOptions ); |
— | — | @@ -1446,7 +1487,7 @@ |
1447 | 1488 | if ( $thread->root() ) $content = $thread->root()->getContent(); |
1448 | 1489 | |
1449 | 1490 | if ( |
1450 | | - trim($content) == '' && |
| 1491 | + trim( $content ) == '' && |
1451 | 1492 | $thread->type() != Threads::TYPE_MOVED && |
1452 | 1493 | ! self::threadContainsRepliesWithContent( $thread ) && |
1453 | 1494 | ! array_key_exists( $thread->id(), $mustShowThreads ) |
— | — | @@ -1555,7 +1596,7 @@ |
1556 | 1597 | $cascadeOptions = $options; |
1557 | 1598 | unset( $cascadeOptions['startAt'] ); |
1558 | 1599 | |
1559 | | - if ( ($hasSubthreads && $showThreads) ) { |
| 1600 | + if ( ( $hasSubthreads && $showThreads ) ) { |
1560 | 1601 | $this->showThreadReplies( $thread, $startAt, $maxCount, $showThreads, |
1561 | 1602 | $cascadeOptions ); |
1562 | 1603 | } elseif ( $hasSubthreads && !$showThreads ) { |
— | — | @@ -1573,7 +1614,7 @@ |
1574 | 1615 | Xml::tags( 'div', array( 'class' => 'lqt-post-sep' ), ' ' ) ); |
1575 | 1616 | |
1576 | 1617 | if ( $replyTo ) { |
1577 | | - $class = 'lqt-thread-replies lqt-thread-replies-'. |
| 1618 | + $class = 'lqt-thread-replies lqt-thread-replies-' . |
1578 | 1619 | $this->threadNestingLevel; |
1579 | 1620 | $html = Xml::openElement( 'div', array( 'class' => $class ) ); |
1580 | 1621 | $html .= Xml::openElement( 'div', |
— | — | @@ -1598,7 +1639,7 @@ |
1599 | 1640 | } |
1600 | 1641 | |
1601 | 1642 | if ( $this->threadNestingLevel == 1 ) { |
1602 | | - if ( !($hasSubthreads && $showThreads) ) { |
| 1643 | + if ( !( $hasSubthreads && $showThreads ) ) { |
1603 | 1644 | $this->showReplyBox( $thread ); |
1604 | 1645 | $finishDiv = ''; |
1605 | 1646 | $finishDiv .= Xml::tags( 'div', array( 'class' => 'lqt-replies-finish' ), |
— | — | @@ -1742,7 +1783,7 @@ |
1743 | 1784 | global $wgParser, $wgOut, $wgTitle; |
1744 | 1785 | |
1745 | 1786 | static $parseCache = array(); |
1746 | | - $sigKey = md5($sig); |
| 1787 | + $sigKey = md5( $sig ); |
1747 | 1788 | |
1748 | 1789 | if ( isset( $parseCache[$sigKey] ) ) { |
1749 | 1790 | return $parseCache[$sigKey]; |
— | — | @@ -1790,7 +1831,7 @@ |
1791 | 1832 | function show() { |
1792 | 1833 | return true; // No-op |
1793 | 1834 | } |
1794 | | - |
| 1835 | + |
1795 | 1836 | // Copy-and-modify of Linker::formatComment |
1796 | 1837 | static function formatSubject( $s ) { |
1797 | 1838 | wfProfileIn( __METHOD__ ); |
Index: trunk/extensions/LiquidThreads/pages/ThreadDiffView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class ThreadDiffView extends LqtView { |
— | — | @@ -10,15 +9,15 @@ |
11 | 10 | |
12 | 11 | $content_actions['history']['class'] = 'selected'; |
13 | 12 | } |
14 | | - |
| 13 | + |
15 | 14 | function customizeNavigation( $skin, &$links ) { |
16 | 15 | $remove = array( 'views/edit', 'views/viewsource' ); |
17 | 16 | |
18 | | - foreach( $remove as $rem ) { |
19 | | - list($section, $item) = explode( '/', $rem, 2 ); |
| 17 | + foreach ( $remove as $rem ) { |
| 18 | + list( $section, $item ) = explode( '/', $rem, 2 ); |
20 | 19 | unset( $links[$section][$item] ); |
21 | 20 | } |
22 | | - |
| 21 | + |
23 | 22 | $links['views']['history']['class'] = 'selected'; |
24 | 23 | } |
25 | 24 | } |
Index: trunk/extensions/LiquidThreads/pages/TalkpageHeaderView.php |
— | — | @@ -1,8 +1,7 @@ |
2 | 2 | <?php |
| 3 | +if ( !defined( 'MEDIAWIKI' ) ) die; |
3 | 4 | |
4 | | -if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 5 | // Pass-through wrapper with an extra note at the top |
6 | | - |
7 | 6 | class TalkpageHeaderView extends LqtView { |
8 | 7 | function customizeTabs( $skintemplate, &$content_actions ) { |
9 | 8 | unset( $content_actions['edit'] ); |
— | — | @@ -18,16 +17,20 @@ |
19 | 18 | 'href' => '', |
20 | 19 | ); |
21 | 20 | } |
22 | | - |
| 21 | + |
23 | 22 | function customizeNavigation( $skin, &$links ) { |
24 | | - $remove = array( 'actions/edit', 'actions/addsection', 'views/history', |
25 | | - 'actions/watch', 'actions/move' ); |
26 | | - |
27 | | - foreach( $remove as $rem ) { |
28 | | - list($section, $item) = explode( '/', $rem, 2 ); |
| 23 | + $remove = array( |
| 24 | + 'actions/edit', |
| 25 | + 'actions/addsection', |
| 26 | + 'views/history', |
| 27 | + 'actions/watch','actions/move' |
| 28 | + ); |
| 29 | + |
| 30 | + foreach ( $remove as $rem ) { |
| 31 | + list( $section, $item ) = explode( '/', $rem, 2 ); |
29 | 32 | unset( $links[$section][$item] ); |
30 | 33 | } |
31 | | - |
| 34 | + |
32 | 35 | $links['views']['header'] = array( |
33 | 36 | 'class' => 'selected', |
34 | 37 | 'text' => wfMsg( 'lqt-talkpage-history-tab' ), |
— | — | @@ -40,30 +43,44 @@ |
41 | 44 | |
42 | 45 | if ( $wgRequest->getVal( 'action' ) === 'edit' ) { |
43 | 46 | wfLoadExtensionMessages( 'LiquidThreads' ); |
44 | | - |
| 47 | + |
45 | 48 | $html = ''; |
46 | | - |
47 | | - $warn_bold = Xml::tags( 'strong', null, |
48 | | - wfMsgExt( 'lqt_header_warning_bold', 'parseinline' ) ); |
49 | | - |
50 | | - $warn_link = |
51 | | - $this->talkpageLink( $wgTitle, wfMsgExt( 'lqt_header_warning_new_discussion', |
52 | | - 'parseinline' ), 'talkpage_new_thread' ); |
53 | | - |
54 | | - $html .= wfMsgExt( 'lqt_header_warning_before_big', |
55 | | - array( 'parseinline', 'replaceafter' ), |
56 | | - array( $warn_bold, $warn_link ) ); |
57 | | - $html .= Xml::tags( 'big', null, |
58 | | - wfMsgExt( 'lqt_header_warning_big', |
59 | | - array( 'parseinline', 'replaceafter' ), |
60 | | - array( $warn_bold, $warn_link ) ) ); |
| 49 | + |
| 50 | + $warn_bold = Xml::tags( |
| 51 | + 'strong', |
| 52 | + null, |
| 53 | + wfMsgExt( 'lqt_header_warning_bold', 'parseinline' ) |
| 54 | + ); |
| 55 | + |
| 56 | + $warn_link = $this->talkpageLink( |
| 57 | + $wgTitle, |
| 58 | + wfMsgExt( 'lqt_header_warning_new_discussion', 'parseinline' ), |
| 59 | + 'talkpage_new_thread' |
| 60 | + ); |
| 61 | + |
| 62 | + $html .= wfMsgExt( |
| 63 | + 'lqt_header_warning_before_big', |
| 64 | + array( 'parseinline', 'replaceafter' ), |
| 65 | + array( $warn_bold, $warn_link ) |
| 66 | + ); |
| 67 | + $html .= Xml::tags( |
| 68 | + 'big', |
| 69 | + null, |
| 70 | + wfMsgExt( |
| 71 | + 'lqt_header_warning_big', |
| 72 | + array( 'parseinline', 'replaceafter' ), |
| 73 | + array( $warn_bold, $warn_link ) |
| 74 | + ) |
| 75 | + ); |
61 | 76 | $html .= wfMsg( 'word-separator' ); |
62 | | - $html .= wfMsgExt( 'lqt_header_warning_after_big', |
63 | | - array( 'parseinline', 'replaceafter' ), |
64 | | - array( $warn_bold, $warn_link ) ); |
65 | | - |
| 77 | + $html .= wfMsgExt( |
| 78 | + 'lqt_header_warning_after_big', |
| 79 | + array( 'parseinline', 'replaceafter' ), |
| 80 | + array( $warn_bold, $warn_link ) |
| 81 | + ); |
| 82 | + |
66 | 83 | $html = Xml::tags( 'p', array( 'class' => 'lqt_header_warning' ), $html ); |
67 | | - |
| 84 | + |
68 | 85 | $wgOut->addHTML( $html ); |
69 | 86 | } |
70 | 87 | |
Index: trunk/extensions/LiquidThreads/pages/ThreadProtectionFormView.php |
— | — | @@ -1,35 +1,34 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | // Pass-through wrapper |
7 | 6 | class ThreadProtectionFormView extends LqtView { |
8 | 7 | function customizeTabs( $skintemplate, &$content_actions ) { |
9 | 8 | ThreadPermalinkView::customizeThreadTabs( $skintemplate, $content_actions, $this ); |
10 | | - |
| 9 | + |
11 | 10 | if ( array_key_exists( 'protect', $content_actions ) ) |
12 | 11 | $content_actions['protect']['class'] = 'selected'; |
13 | 12 | else if ( array_key_exists( 'unprotect', $content_actions ) ) |
14 | 13 | $content_actions['unprotect']['class'] = 'selected'; |
15 | 14 | } |
16 | | - |
| 15 | + |
17 | 16 | function customizeNavigation( $skintemplate, &$links ) { |
18 | 17 | ThreadPermalinkView::customizeThreadNavigation( $skintemplate, $links, $this ); |
19 | | - |
| 18 | + |
20 | 19 | if ( isset( $links['actions']['protect'] ) ) { |
21 | 20 | $links['actions']['protect']['class'] = 'selected'; |
22 | 21 | } |
23 | | - |
| 22 | + |
24 | 23 | if ( isset( $links['actions']['unprotect'] ) ) { |
25 | 24 | $links['actions']['unprotect']['class'] = 'selected'; |
26 | 25 | } |
27 | 26 | } |
28 | | - |
| 27 | + |
29 | 28 | function __construct( &$output, &$article, &$title, &$user, &$request ) { |
30 | 29 | parent::__construct( $output, $article, $title, $user, $request ); |
31 | 30 | |
32 | 31 | $t = Threads::withRoot( $this->article ); |
33 | | - |
| 32 | + |
34 | 33 | $this->thread = $t; |
35 | 34 | if ( !$t ) { |
36 | 35 | return; |
Index: trunk/extensions/LiquidThreads/pages/IndividualThreadHistoryView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class IndividualThreadHistoryView extends ThreadPermalinkView { |
— | — | @@ -10,7 +9,7 @@ |
11 | 10 | parent::customizeTabs( $skintemplate, $content_actions ); |
12 | 11 | return true; |
13 | 12 | } |
14 | | - |
| 13 | + |
15 | 14 | function customizeNavigation( $skin, &$links ) { |
16 | 15 | $links['views']['history']['class'] = 'selected'; |
17 | 16 | parent::customizeNavigation( $skin, $links ); |
— | — | @@ -22,12 +21,16 @@ |
23 | 22 | function customizeSubtitle() { |
24 | 23 | wfLoadExtensionMessages( 'LiquidThreads' ); |
25 | 24 | $msg = wfMsgExt( 'lqt_hist_view_whole_thread', 'parseinline' ); |
26 | | - $threadhist = $this->permalink( $this->thread->topmostThread(), |
27 | | - $msg, |
28 | | - 'thread_history' ); |
29 | | - $this->output->setSubtitle( parent::getSubtitle() . '<br />' . |
30 | | - $this->output->getSubtitle() . |
31 | | - "<br />$threadhist" ); |
| 25 | + $threadhist = $this->permalink( |
| 26 | + $this->thread->topmostThread(), |
| 27 | + $msg, |
| 28 | + 'thread_history' |
| 29 | + ); |
| 30 | + $this->output->setSubtitle( |
| 31 | + parent::getSubtitle() . '<br />' . |
| 32 | + $this->output->getSubtitle() . |
| 33 | + "<br />$threadhist" |
| 34 | + ); |
32 | 35 | return true; |
33 | 36 | } |
34 | 37 | |
— | — | @@ -40,7 +43,7 @@ |
41 | 44 | |
42 | 45 | function show() { |
43 | 46 | global $wgHooks; |
44 | | - |
| 47 | + |
45 | 48 | if ( !$this->thread ) { |
46 | 49 | $this->showMissingThreadPage(); |
47 | 50 | return false; |
Index: trunk/extensions/LiquidThreads/pages/SpecialMoveThread.php |
— | — | @@ -1,9 +1,7 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class SpecialMoveThread extends ThreadActionPage { |
7 | | - |
8 | 6 | /** |
9 | 7 | * @see SpecialPage::getDescription |
10 | 8 | */ |
— | — | @@ -11,61 +9,71 @@ |
12 | 10 | wfLoadExtensionMessages( 'LiquidThreads' ); |
13 | 11 | return wfMsg( 'lqt_movethread' ); |
14 | 12 | } |
15 | | - |
| 13 | + |
16 | 14 | function getFormFields() { |
17 | | - return |
18 | | - array( |
19 | | - 'dest-title' => |
20 | | - array( |
21 | | - 'label-message' => 'lqt_move_destinationtitle', |
22 | | - 'type' => 'text', |
23 | | - 'validation-callback' => array( $this, 'validateTarget' ), |
24 | | - ), |
25 | | - 'reason' => |
26 | | - array( |
27 | | - 'label-message' => 'movereason', |
28 | | - 'type' => 'text', |
29 | | - ), |
30 | | - ); |
| 15 | + return array( |
| 16 | + 'dest-title' => array( |
| 17 | + 'label-message' => 'lqt_move_destinationtitle', |
| 18 | + 'type' => 'text', |
| 19 | + 'validation-callback' => array( $this, 'validateTarget' ), |
| 20 | + ), |
| 21 | + 'reason' => array( |
| 22 | + 'label-message' => 'movereason', |
| 23 | + 'type' => 'text', |
| 24 | + ) |
| 25 | + ); |
31 | 26 | } |
32 | | - |
| 27 | + |
33 | 28 | function getPageName() { return 'MoveThread'; } |
34 | | - |
| 29 | + |
35 | 30 | function getSubmitText() { |
36 | 31 | wfLoadExtensionMessages( 'LiquidThreads' ); |
37 | 32 | return wfMsg( 'lqt_move_move' ); |
38 | 33 | } |
39 | | - |
| 34 | + |
40 | 35 | function buildForm() { |
41 | 36 | $form = parent::buildForm(); |
42 | | - |
| 37 | + |
43 | 38 | // Generate introduction |
44 | 39 | $intro = ''; |
45 | | - |
| 40 | + |
46 | 41 | global $wgUser; |
47 | 42 | $sk = $wgUser->getSkin(); |
48 | 43 | $page = $article_name = $this->mThread->article()->getTitle()->getPrefixedText(); |
49 | | - |
| 44 | + |
50 | 45 | $edit_text = wfMsgExt( 'lqt_move_torename_edit', 'parseinline' ); |
51 | | - $edit_link = $sk->link( $this->mThread->title(), $edit_text, array(), |
52 | | - array( 'lqt_method' => 'edit', 'lqt_operand' => $this->mThread->id() ) ); |
53 | | - |
54 | | - $intro .= wfMsgExt( 'lqt_move_movingthread', 'parse', |
55 | | - array( '[[' . $this->mTarget . ']]', '[[' . $page . ']]' ) ); |
56 | | - $intro .= wfMsgExt( 'lqt_move_torename', array( 'parse', 'replaceafter' ), |
57 | | - array( $edit_link ) ); |
58 | | - |
| 46 | + $edit_link = $sk->link( |
| 47 | + $this->mThread->title(), |
| 48 | + $edit_text, |
| 49 | + array(), |
| 50 | + array( |
| 51 | + 'lqt_method' => 'edit', |
| 52 | + 'lqt_operand' => $this->mThread->id() |
| 53 | + ) |
| 54 | + ); |
| 55 | + |
| 56 | + $intro .= wfMsgExt( |
| 57 | + 'lqt_move_movingthread', |
| 58 | + 'parse', |
| 59 | + array( '[[' . $this->mTarget . ']]', '[[' . $page . ']]' ) |
| 60 | + ); |
| 61 | + $intro .= wfMsgExt( |
| 62 | + 'lqt_move_torename', |
| 63 | + array( 'parse', 'replaceafter' ), |
| 64 | + array( $edit_link ) |
| 65 | + ); |
| 66 | + |
59 | 67 | $form->setIntro( $intro ); |
60 | | - |
| 68 | + |
61 | 69 | return $form; |
62 | 70 | } |
63 | | - |
| 71 | + |
64 | 72 | function checkUserRights( $oldTitle, $newTitle ) { |
65 | 73 | global $wgUser, $wgOut; |
66 | | - |
| 74 | + |
67 | 75 | $oldErrors = $oldTitle->getUserPermissionsErrors( 'move', $wgUser ); |
68 | 76 | $newErrors = $newTitle->getUserPermissionsErrors( 'move', $wgUser ); |
69 | | - |
| 77 | + |
70 | 78 | // Custom merge/unique function because we don't have the second parameter to |
71 | 79 | // array_unique on Wikimedia. |
72 | 80 | $mergedErrors = array(); |
— | — | @@ -76,54 +84,53 @@ |
77 | 85 | $mergedErrors[] = $value; |
78 | 86 | } |
79 | 87 | } |
80 | | - |
| 88 | + |
81 | 89 | if ( count( $mergedErrors ) > 0 ) { |
82 | | - return $wgOut->parse( |
83 | | - $wgOut->formatPermissionsErrorMessage( $mergedErrors, 'move' ) |
84 | | - ); |
| 90 | + return $wgOut->parse( |
| 91 | + $wgOut->formatPermissionsErrorMessage( $mergedErrors, 'move' ) |
| 92 | + ); |
85 | 93 | } |
86 | 94 | |
87 | 95 | return true; |
88 | 96 | } |
89 | | - |
| 97 | + |
90 | 98 | function trySubmit( $data ) { |
91 | 99 | // Load data |
92 | 100 | $tmp = $data['dest-title']; |
93 | 101 | $newtitle = Title::newFromText( $tmp ); |
94 | 102 | $reason = $data['reason']; |
95 | | - |
| 103 | + |
96 | 104 | $rightsResult = $this->checkUserRights( $this->mThread->title(), $newtitle ); |
97 | | - |
| 105 | + |
98 | 106 | if ( $rightsResult !== true ) |
99 | 107 | return $rightsResult; |
100 | 108 | |
101 | 109 | // TODO no status code from this method. |
102 | 110 | $this->mThread->moveToPage( $newtitle, $reason, true ); |
103 | | - |
| 111 | + |
104 | 112 | global $wgOut, $wgUser; |
105 | 113 | $sk = $wgUser->getSkin(); |
106 | 114 | $wgOut->addHTML( wfMsgExt( 'lqt_move_success', array( 'parse', 'replaceafter' ), |
107 | 115 | array( $sk->link( $newtitle ) ) ) ); |
108 | | - |
| 116 | + |
109 | 117 | return true; |
110 | 118 | } |
111 | | - |
| 119 | + |
112 | 120 | function validateTarget( $target ) { |
113 | 121 | if ( !$target ) { |
114 | 122 | return wfMsgExt( 'lqt_move_nodestination', 'parseinline' ); |
115 | 123 | } |
116 | | - |
| 124 | + |
117 | 125 | $title = Title::newFromText( $target ); |
118 | | - |
| 126 | + |
119 | 127 | if ( !$title || !LqtDispatch::isLqtPage( $title ) ) { |
120 | 128 | return wfMsgExt( 'lqt_move_thread_bad_destination', 'parseinline' ); |
121 | 129 | } |
122 | | - |
| 130 | + |
123 | 131 | if ( $title->equals( $this->mThread->article()->getTitle() ) ) { |
124 | 132 | return wfMsgExt( 'lqt_move_samedestination', 'parseinline' ); |
125 | 133 | } |
126 | | - |
| 134 | + |
127 | 135 | return true; |
128 | 136 | } |
129 | | - |
130 | 137 | } |
Index: trunk/extensions/LiquidThreads/pages/ThreadActionPage.php |
— | — | @@ -1,45 +1,44 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | abstract class ThreadActionPage extends UnlistedSpecialPage { |
5 | 4 | protected $user, $output, $request, $title, $mThread; |
6 | 5 | |
7 | 6 | function __construct() { |
8 | 7 | parent::__construct( $this->getPageName(), $this->getRightRequirement() ); |
9 | 8 | $this->includable( false ); |
10 | | - |
| 9 | + |
11 | 10 | global $wgOut, $wgUser, $wgRequest; |
12 | 11 | $this->output = $wgOut; |
13 | 12 | $this->user = $wgUser; |
14 | 13 | $this->request = $wgRequest; |
15 | 14 | } |
16 | | - |
| 15 | + |
17 | 16 | abstract function getPageName(); |
18 | | - |
| 17 | + |
19 | 18 | abstract function getFormFields(); |
20 | | - |
| 19 | + |
21 | 20 | protected function getRightRequirement() { return ''; } |
22 | 21 | |
23 | 22 | function execute( $par ) { |
24 | 23 | wfLoadExtensionMessages( 'LiquidThreads' ); |
25 | | - |
| 24 | + |
26 | 25 | global $wgOut, $wgUser; |
27 | | - |
| 26 | + |
28 | 27 | if ( !$this->userCanExecute( $wgUser ) ) { |
29 | 28 | $this->displayRestrictionError(); |
30 | 29 | return; |
31 | 30 | } |
32 | | - |
| 31 | + |
33 | 32 | // Page title |
34 | 33 | $wgOut->setPageTitle( $this->getDescription() ); |
35 | | - |
| 34 | + |
36 | 35 | if ( !$this->checkParameters( $par ) ) { |
37 | 36 | return; |
38 | 37 | } |
39 | | - |
| 38 | + |
40 | 39 | $form = $this->buildForm(); |
41 | 40 | $form->show(); |
42 | 41 | } |
43 | | - |
| 42 | + |
44 | 43 | // Loads stuff like the thread and so on |
45 | 44 | function checkParameters( $par ) { |
46 | 45 | // Handle parameter |
— | — | @@ -49,32 +48,31 @@ |
50 | 49 | $this->output->addHTML( wfMsg( 'lqt_threadrequired' ) ); |
51 | 50 | return false; |
52 | 51 | } |
53 | | - |
| 52 | + |
54 | 53 | $thread = Threads::withRoot( new Article( Title::newFromURL( $par ) ) ); |
55 | 54 | if ( !$thread ) { |
56 | 55 | $this->output->addHTML( wfMsg( 'lqt_nosuchthread' ) ); |
57 | 56 | return false; |
58 | 57 | } |
59 | | - |
| 58 | + |
60 | 59 | $this->mThread = $thread; |
61 | | - |
| 60 | + |
62 | 61 | return true; |
63 | 62 | } |
64 | | - |
| 63 | + |
65 | 64 | abstract function getSubmitText(); |
66 | | - |
| 65 | + |
67 | 66 | function buildForm() { |
68 | 67 | $form = new HTMLForm( $this->getFormFields(), 'lqt-' . $this->getPageName() ); |
69 | | - |
| 68 | + |
70 | 69 | $par = $this->mThread->title()->getPrefixedText(); |
71 | | - |
| 70 | + |
72 | 71 | $form->setSubmitText( $this->getSubmitText() ); |
73 | 72 | $form->setTitle( SpecialPage::getTitleFor( $this->getPageName(), $par ) ); |
74 | 73 | $form->setSubmitCallback( array( $this, 'trySubmit' ) ); |
75 | | - |
| 74 | + |
76 | 75 | return $form; |
77 | 76 | } |
78 | | - |
79 | | - abstract function trySubmit( $data ); |
80 | 77 | |
| 78 | + abstract function trySubmit( $data ); |
81 | 79 | } |
Index: trunk/extensions/LiquidThreads/pages/ThreadHistoricalRevisionView.php |
— | — | @@ -1,9 +1,7 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class ThreadHistoricalRevisionView extends ThreadPermalinkView { |
7 | | - |
8 | 6 | public $mDisplayRevision = null; |
9 | 7 | |
10 | 8 | /* TOOD: customize tabs so that History is highlighted. */ |
— | — | @@ -12,16 +10,16 @@ |
13 | 11 | $changedObject = $this->mDisplayRevision->getChangeObject(); |
14 | 12 | $is_changed_thread = $changedObject && |
15 | 13 | ( $changedObject->id() == $thread->id() ); |
16 | | - |
| 14 | + |
17 | 15 | $class = parent::postDivClass( $thread ); |
18 | | - |
| 16 | + |
19 | 17 | if ( $is_changed_thread ) { |
20 | 18 | return "$class lqt_post_changed_by_history"; |
21 | 19 | } else { |
22 | 20 | return $class; |
23 | 21 | } |
24 | 22 | } |
25 | | - |
| 23 | + |
26 | 24 | function getMessageForChangeType( $ct ) { |
27 | 25 | static $messages = array( |
28 | 26 | Threads::CHANGE_NEW_THREAD => 'lqt_change_new_thread', |
— | — | @@ -38,11 +36,11 @@ |
39 | 37 | Threads::CHANGE_ROOT_BLANKED => 'lqt_change_root_blanked', |
40 | 38 | Threads::CHANGE_EDITED_ROOT => 'lqt_change_edited_root', |
41 | 39 | ); |
42 | | - |
| 40 | + |
43 | 41 | if ( isset( $messages[$ct] ) ) { |
44 | 42 | return $messages[$ct]; |
45 | 43 | } |
46 | | - |
| 44 | + |
47 | 45 | return ''; |
48 | 46 | } |
49 | 47 | |
— | — | @@ -50,54 +48,55 @@ |
51 | 49 | global $wgLang; |
52 | 50 | wfLoadExtensionMessages( 'LiquidThreads' ); |
53 | 51 | |
54 | | - $html = ''; |
55 | | - $html .= wfMsgExt( 'lqt_revision_as_of', 'parseinline', |
| 52 | + $html = wfMsgExt( |
| 53 | + 'lqt_revision_as_of', |
| 54 | + 'parseinline', |
56 | 55 | array( |
57 | 56 | $wgLang->timeanddate( $this->mDisplayRevision->getTimestamp() ), |
58 | 57 | $wgLang->date( $this->mDisplayRevision->getTimestamp() ), |
59 | 58 | $wgLang->time( $this->mDisplayRevision->getTimestamp() ) |
60 | 59 | ) |
61 | 60 | ); |
62 | | - |
| 61 | + |
63 | 62 | $html .= '<br />'; |
64 | | - |
65 | 63 | $html .= $this->getChangeDescription(); |
66 | | - |
| 64 | + |
67 | 65 | $html = Xml::tags( 'div', array( 'class' => 'lqt_history_info' ), $html ); |
68 | | - |
| 66 | + |
69 | 67 | $this->output->addHTML( $html ); |
70 | 68 | } |
71 | | - |
| 69 | + |
72 | 70 | function getChangeDescription( ) { |
73 | 71 | $args = array(); |
74 | | - |
| 72 | + |
75 | 73 | $revision = $this->mDisplayRevision; |
76 | 74 | $change_type = $revision->getChangeType(); |
77 | | - |
| 75 | + |
78 | 76 | $post = $revision->getChangeObject(); |
79 | 77 | $args[] = LqtView::linkInContextURL( $post ); |
80 | | - |
| 78 | + |
81 | 79 | $msg = $this->getMessageForChangeType( $change_type ); |
82 | | - |
| 80 | + |
83 | 81 | switch( $change_type ) { |
84 | 82 | case Threads::CHANGE_EDITED_SUBJECT: |
85 | 83 | $args[] = $revision->prev()->getChangeObject()->subject(); |
86 | 84 | $args[] = $revision->getChangeObject()->subject(); |
87 | 85 | break; |
88 | 86 | } |
89 | | - |
| 87 | + |
90 | 88 | $html = wfMsgExt( $msg, 'parseinline', $args ); |
91 | | - |
| 89 | + |
92 | 90 | if ( $change_type == Threads::CHANGE_ROOT_BLANKED || |
93 | 91 | $change_type == Threads::CHANGE_EDITED_ROOT ) { |
94 | | - $diff_link = $this->diffPermalink( $post, |
95 | | - wfMsgExt( 'diff', 'parseinline' ), |
96 | | - $this->mDisplayRevision ); |
97 | | - |
| 92 | + $diff_link = $this->diffPermalink( |
| 93 | + $post, |
| 94 | + wfMsgExt( 'diff', 'parseinline' ), |
| 95 | + $this->mDisplayRevision |
| 96 | + ); |
| 97 | + |
98 | 98 | $html .= " [$diff_link]"; |
| 99 | + } |
99 | 100 | |
100 | | - } |
101 | | - |
102 | 101 | return $html; |
103 | 102 | } |
104 | 103 | |
— | — | @@ -106,31 +105,38 @@ |
107 | 106 | $this->showMissingThreadPage(); |
108 | 107 | return false; |
109 | 108 | } |
110 | | - |
| 109 | + |
111 | 110 | $oldid = $this->request->getInt( 'lqt_oldid' ); |
112 | 111 | $this->mDisplayRevision = ThreadRevision::loadFromId( $oldid ); |
113 | 112 | |
114 | 113 | $this->thread = $this->mDisplayRevision->getThreadObj(); |
115 | | - |
116 | | - if (!$this->mDisplayRevision) { |
| 114 | + |
| 115 | + if ( !$this->mDisplayRevision ) { |
117 | 116 | $this->showMissingThreadPage(); |
118 | 117 | return false; |
119 | 118 | } elseif ( !$this->thread ) { |
120 | 119 | $this->output->addWikiMsg( 'lqt-historicalrevision-error' ); |
121 | 120 | return false; |
122 | 121 | } |
123 | | - |
| 122 | + |
124 | 123 | $this->showHistoryInfo(); |
125 | 124 | |
126 | 125 | self::addJSandCSS(); |
127 | 126 | $this->output->setSubtitle( $this->getSubtitle() ); |
128 | | - |
| 127 | + |
129 | 128 | $changedObject = $this->mDisplayRevision->getChangeObject(); |
130 | 129 | |
131 | | - $this->showThread( $this->thread, 1, 1, |
132 | | - array( 'maxDepth' => - 1, 'maxCount' => - 1, |
133 | | - 'mustShowThreads' => array( $changedObject->id() ) ) ); |
134 | | - |
| 130 | + $this->showThread( |
| 131 | + $this->thread, |
| 132 | + 1, |
| 133 | + 1, |
| 134 | + array( |
| 135 | + 'maxDepth' => - 1, |
| 136 | + 'maxCount' => - 1, |
| 137 | + 'mustShowThreads' => array( $changedObject->id() ) |
| 138 | + ) |
| 139 | + ); |
| 140 | + |
135 | 141 | $this->output->setPageTitle( $this->thread->subject() ); |
136 | 142 | return false; |
137 | 143 | } |
Index: trunk/extensions/LiquidThreads/pages/TalkpageHistoryView.php |
— | — | @@ -1,44 +1,43 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class TalkpageHistoryView extends TalkpageView { |
7 | 6 | function show() { |
8 | 7 | global $wgUser; |
9 | | - |
| 8 | + |
10 | 9 | self::addJSandCSS(); |
11 | 10 | wfLoadExtensionMessages( 'LiquidThreads' ); |
12 | | - |
| 11 | + |
13 | 12 | $sk = $wgUser->getSkin(); |
14 | | - |
| 13 | + |
15 | 14 | $talkpageTitle = $this->article->getTitle(); |
16 | 15 | $talkpageLink = $sk->link( $talkpageTitle ); |
17 | 16 | |
18 | 17 | $this->output->setPageTitle( wfMsg( 'lqt-talkpage-history-title' ) ); |
19 | | - $this->output->setSubtitle( |
20 | | - wfMsgExt( 'lqt-talkpage-history-subtitle', |
21 | | - array( 'replaceafter', 'parseinline' ), |
22 | | - $talkpageLink ) |
23 | | - ); |
24 | | - |
| 18 | + $this->output->setSubtitle( wfMsgExt( |
| 19 | + 'lqt-talkpage-history-subtitle', |
| 20 | + array( 'replaceafter', 'parseinline' ), |
| 21 | + $talkpageLink |
| 22 | + ) ); |
| 23 | + |
25 | 24 | $pager = new TalkpageHistoryPager( $this, $this->article ); |
26 | | - |
| 25 | + |
27 | 26 | $html = $pager->getNavigationBar() . |
28 | | - $pager->getBody() . |
29 | | - $pager->getNavigationBar(); |
30 | | - |
| 27 | + $pager->getBody() . |
| 28 | + $pager->getNavigationBar(); |
| 29 | + |
31 | 30 | $this->output->addHTML( $html ); |
32 | | - |
| 31 | + |
33 | 32 | return false; |
34 | 33 | } |
35 | | - |
| 34 | + |
36 | 35 | function customizeTabs( $skin, &$links ) { |
37 | 36 | TalkpageView::customizeTalkpageTabs( $skin, $links, $this ); |
38 | | - |
| 37 | + |
39 | 38 | $tabid = $this->article->getTitle()->getNamespaceKey(); |
40 | 39 | $links['history']['class'] = 'selected'; |
41 | 40 | } |
42 | | - |
| 41 | + |
43 | 42 | function customizeNavigation( $skin, &$links ) { |
44 | 43 | TalkpageView::customizeTalkpageNavigation( $skin, $links, $this ); |
45 | 44 | $links['views']['history']['class'] = 'selected'; |
— | — | @@ -49,10 +48,10 @@ |
50 | 49 | class TalkpageHistoryPager extends ThreadHistoryPager { |
51 | 50 | function __construct( $view, $talkpage ) { |
52 | 51 | $this->talkpage = $talkpage; |
53 | | - |
| 52 | + |
54 | 53 | parent::__construct( $view, null ); |
55 | 54 | } |
56 | | - |
| 55 | + |
57 | 56 | function getFieldMessages() { |
58 | 57 | $headers = array( |
59 | 58 | 'th_timestamp' => 'lqt-history-time', |
— | — | @@ -61,26 +60,25 @@ |
62 | 61 | 'th_change_type' => 'lqt-history-action', |
63 | 62 | 'th_change_comment' => 'lqt-history-comment', |
64 | 63 | ); |
65 | | - |
| 64 | + |
66 | 65 | return $headers; |
67 | 66 | } |
68 | | - |
| 67 | + |
69 | 68 | function getQueryInfo() { |
70 | | - $queryInfo = |
71 | | - array( |
72 | | - 'tables' => array( 'thread_history', 'thread', 'page' ), |
73 | | - 'fields' => '*', |
74 | | - 'conds' => array( Threads::articleClause( $this->talkpage ) ), |
75 | | - 'options' => array( 'order by' => 'th_timestamp desc' ), |
76 | | - 'join_conds' => array( |
77 | | - 'thread' => array( 'LEFT JOIN', 'thread_id=th_thread' ), |
78 | | - 'page' => array( 'LEFT JOIN', 'thread_root=page_id' ), |
79 | | - ), |
80 | | - ); |
81 | | - |
| 69 | + $queryInfo = array( |
| 70 | + 'tables' => array( 'thread_history', 'thread', 'page' ), |
| 71 | + 'fields' => '*', |
| 72 | + 'conds' => array( Threads::articleClause( $this->talkpage ) ), |
| 73 | + 'options' => array( 'order by' => 'th_timestamp desc' ), |
| 74 | + 'join_conds' => array( |
| 75 | + 'thread' => array( 'LEFT JOIN', 'thread_id=th_thread' ), |
| 76 | + 'page' => array( 'LEFT JOIN', 'thread_root=page_id' ), |
| 77 | + ), |
| 78 | + ); |
| 79 | + |
82 | 80 | return $queryInfo; |
83 | 81 | } |
84 | | - |
| 82 | + |
85 | 83 | function formatValue( $name, $value ) { |
86 | 84 | global $wgOut, $wgLang, $wgTitle; |
87 | 85 | |
— | — | @@ -92,23 +90,36 @@ |
93 | 91 | } |
94 | 92 | |
95 | 93 | $row = $this->mCurrentRow; |
96 | | - |
| 94 | + |
97 | 95 | switch( $name ) { |
98 | 96 | case 'thread_subject': |
99 | | - $title = Title::makeTitleSafe( $row->page_namespace, |
100 | | - $row->page_title ); |
101 | | - |
102 | | - $link = $sk->link( $title, $value, array(), array(), |
103 | | - array( 'known' ) ); |
104 | | - |
| 97 | + $title = Title::makeTitleSafe( |
| 98 | + $row->page_namespace, |
| 99 | + $row->page_title |
| 100 | + ); |
| 101 | + |
| 102 | + $link = $sk->link( |
| 103 | + $title, |
| 104 | + $value, |
| 105 | + array(), |
| 106 | + array(), |
| 107 | + array( 'known' ) |
| 108 | + ); |
| 109 | + |
105 | 110 | return $link; |
106 | 111 | case 'th_timestamp': |
107 | 112 | $formatted = $wgLang->timeanddate( $value ); |
108 | | - $title = Title::makeTitleSafe( $row->page_namespace, |
109 | | - $row->page_title ); |
110 | | - |
111 | | - return $sk->link( $title, $formatted, array(), |
112 | | - array( 'lqt_oldid' => $row->th_id ) ); |
| 113 | + $title = Title::makeTitleSafe( |
| 114 | + $row->page_namespace, |
| 115 | + $row->page_title |
| 116 | + ); |
| 117 | + |
| 118 | + return $sk->link( |
| 119 | + $title, |
| 120 | + $formatted, |
| 121 | + array(), |
| 122 | + array( 'lqt_oldid' => $row->th_id ) |
| 123 | + ); |
113 | 124 | default: |
114 | 125 | return parent::formatValue( $name, $value ); |
115 | 126 | } |
Index: trunk/extensions/LiquidThreads/pages/ThreadPermalinkView.php |
— | — | @@ -1,42 +1,41 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class ThreadPermalinkView extends LqtView { |
7 | 6 | protected $thread; |
8 | | - |
| 7 | + |
9 | 8 | function customizeTabs( $skin, &$links ) { |
10 | 9 | self::customizeThreadTabs( $skin, $links, $this ); |
11 | 10 | } |
12 | | - |
| 11 | + |
13 | 12 | function customizeNavigation( $skin, &$links ) { |
14 | 13 | self::customizeThreadNavigation( $skin, $links, $this ); |
15 | 14 | } |
16 | 15 | |
17 | 16 | static function customizeThreadTabs( $skintemplate, &$content_actions, $view ) { |
18 | 17 | wfLoadExtensionMessages( 'LiquidThreads' ); |
19 | | - |
| 18 | + |
20 | 19 | if ( !$view->thread ) { |
21 | 20 | return true; |
22 | 21 | } |
23 | | - |
| 22 | + |
24 | 23 | // Insert 'article' and 'discussion' tabs before the thread tab. |
25 | | - |
| 24 | + |
26 | 25 | $tabs = self::getCustomTabs( $view ); |
27 | 26 | $content_actions = $tabs + $content_actions; |
28 | 27 | |
29 | 28 | unset( $content_actions['edit'] ); |
30 | 29 | unset( $content_actions['viewsource'] ); |
31 | 30 | unset( $content_actions['talk'] ); |
32 | | - |
| 31 | + |
33 | 32 | $subpage = $view->thread->title()->getPrefixedText(); |
34 | | - |
| 33 | + |
35 | 34 | // Repoint move/delete/history tabs |
36 | 35 | if ( array_key_exists( 'move', $content_actions ) && $view->thread ) { |
37 | 36 | $content_actions['move']['href'] = |
38 | 37 | SpecialPage::getTitleFor( 'MoveThread', $subpage )->getFullURL(); |
39 | 38 | } |
40 | | - |
| 39 | + |
41 | 40 | if ( array_key_exists( 'delete', $content_actions ) && $view->thread ) { |
42 | 41 | $content_actions['delete']['href'] = |
43 | 42 | $view->thread->title()->getFullURL( 'action=delete' ); |
— | — | @@ -51,40 +50,40 @@ |
52 | 51 | |
53 | 52 | return true; |
54 | 53 | } |
55 | | - |
| 54 | + |
56 | 55 | static function customizeThreadNavigation( $skin, &$links, $view ) { |
57 | 56 | if ( !$view->thread ) { |
58 | 57 | return true; |
59 | 58 | } |
60 | | - |
| 59 | + |
61 | 60 | // Insert 'article' and 'discussion' namespace-tabs |
62 | 61 | $new_nstabs = self::getCustomTabs( $view ); |
63 | | - |
| 62 | + |
64 | 63 | $nstabs =& $links['namespaces']; |
65 | 64 | |
66 | | - $talkKey = $view->thread->title()->getNamespaceKey('').'_talk'; |
| 65 | + $talkKey = $view->thread->title()->getNamespaceKey( '' ) . '_talk'; |
67 | 66 | unset( $nstabs[$talkKey] ); |
68 | 67 | $nstabs = $new_nstabs + $nstabs; |
69 | | - |
| 68 | + |
70 | 69 | // Remove some views. |
71 | 70 | $views =& $links['views']; |
72 | 71 | unset( $views['viewsource'] ); |
73 | 72 | unset( $views['edit'] ); |
74 | | - |
| 73 | + |
75 | 74 | // Re-point move, delete and history actions |
76 | 75 | $subpage = $view->thread->title()->getPrefixedText(); |
77 | 76 | $actions =& $links['actions']; |
78 | | - if ( isset($actions['move']) ) { |
| 77 | + if ( isset( $actions['move'] ) ) { |
79 | 78 | $actions['move']['href'] = |
80 | 79 | SpecialPage::getTitleFor( 'MoveThread', $subpage )->getFullURL(); |
81 | 80 | } |
82 | | - |
83 | | - if ( isset($actions['delete']) ) { |
| 81 | + |
| 82 | + if ( isset( $actions['delete'] ) ) { |
84 | 83 | $actions['delete']['href'] = |
85 | 84 | $view->thread->title()->getFullURL( 'action=delete' ); |
86 | 85 | } |
87 | | - |
88 | | - if ( isset($views['history']) ) { |
| 86 | + |
| 87 | + if ( isset( $views['history'] ) ) { |
89 | 88 | $views['history']['href'] = |
90 | 89 | self::permalinkUrl( $view->thread, 'thread_history' ); |
91 | 90 | if ( $view->methodApplies( 'thread_history' ) ) { |
— | — | @@ -92,30 +91,30 @@ |
93 | 92 | } |
94 | 93 | } |
95 | 94 | } |
96 | | - |
| 95 | + |
97 | 96 | // Pre-generates the tabs to be included, for customizeTabs and customizeNavigation |
98 | 97 | // to insert in the appropriate place |
99 | 98 | static function getCustomTabs( $view ) { |
100 | 99 | $tabs = array(); |
101 | | - |
| 100 | + |
102 | 101 | $articleTitle = $view->thread->article()->getTitle()->getSubjectPage(); |
103 | 102 | $talkTitle = $view->thread->article()->getTitle()->getTalkPage(); |
104 | | - |
| 103 | + |
105 | 104 | $articleClasses = array(); |
106 | 105 | if ( !$articleTitle->exists() ) $articleClasses[] = 'new'; |
107 | 106 | if ( $articleTitle->equals( $view->thread->article()->getTitle() ) ) |
108 | 107 | $articleClasses[] = 'selected'; |
109 | | - |
| 108 | + |
110 | 109 | $talkClasses = array(); |
111 | 110 | if ( !$talkTitle->exists() ) $talkClasses[] = 'new'; |
112 | | - |
| 111 | + |
113 | 112 | $tabs['article'] = |
114 | 113 | array( |
115 | 114 | 'text' => wfMsg( $articleTitle->getNamespaceKey() ), |
116 | 115 | 'href' => $articleTitle->getFullURL(), |
117 | 116 | 'class' => implode( ' ', $articleClasses ), |
118 | 117 | ); |
119 | | - |
| 118 | + |
120 | 119 | $tabs['lqt_talk'] = |
121 | 120 | array( |
122 | 121 | // talkpage certainly exists since this thread is from it. |
— | — | @@ -123,7 +122,7 @@ |
124 | 123 | 'href' => $talkTitle->getFullURL(), |
125 | 124 | 'class' => implode( ' ', $talkClasses ), |
126 | 125 | ); |
127 | | - |
| 126 | + |
128 | 127 | return $tabs; |
129 | 128 | } |
130 | 129 | |
— | — | @@ -144,33 +143,39 @@ |
145 | 144 | |
146 | 145 | function getSubtitle() { |
147 | 146 | wfLoadExtensionMessages( 'LiquidThreads' ); |
148 | | - |
| 147 | + |
149 | 148 | $sk = $this->user->getSkin(); |
150 | 149 | $fragment = '#' . $this->anchorName( $this->thread ); |
151 | | - |
| 150 | + |
152 | 151 | if ( $this->thread->isHistorical() ) { |
153 | 152 | // TODO: Point to the relevant part of the archive. |
154 | 153 | $query = ''; |
155 | 154 | } else { |
156 | 155 | $query = ''; |
157 | 156 | } |
158 | | - |
| 157 | + |
159 | 158 | $talkpage = $this->thread->article()->getTitle(); |
160 | 159 | $talkpage->setFragment( $fragment ); |
161 | 160 | $talkpage_link = $sk->link( $talkpage ); |
162 | | - |
| 161 | + |
163 | 162 | if ( $this->thread->hasSuperthread() ) { |
164 | 163 | $topmostTitle = $this->thread->topmostThread()->title(); |
165 | 164 | $topmostTitle->setFragment( $fragment ); |
166 | | - |
| 165 | + |
167 | 166 | $linkText = wfMsgExt( 'lqt_discussion_link', 'parseinline' ); |
168 | 167 | $permalink = $sk->link( $topmostTitle, $linkText ); |
169 | | - |
170 | | - return wfMsgExt( 'lqt_fragment', array( 'parseinline', 'replaceafter' ), |
171 | | - array( $permalink, $talkpage_link ) ); |
| 168 | + |
| 169 | + return wfMsgExt( |
| 170 | + 'lqt_fragment', |
| 171 | + array( 'parseinline', 'replaceafter' ), |
| 172 | + array( $permalink, $talkpage_link ) |
| 173 | + ); |
172 | 174 | } else { |
173 | | - return wfMsgExt( 'lqt_from_talk', array( 'parseinline', 'replaceafter' ), |
174 | | - array( $talkpage_link ) ); |
| 175 | + return wfMsgExt( |
| 176 | + 'lqt_from_talk', |
| 177 | + array( 'parseinline', 'replaceafter' ), |
| 178 | + array( $talkpage_link ) |
| 179 | + ); |
175 | 180 | } |
176 | 181 | } |
177 | 182 | |
— | — | @@ -178,7 +183,7 @@ |
179 | 184 | parent::__construct( $output, $article, $title, $user, $request ); |
180 | 185 | |
181 | 186 | $t = Threads::withRoot( $this->article ); |
182 | | - |
| 187 | + |
183 | 188 | $this->thread = $t; |
184 | 189 | if ( !$t ) { |
185 | 190 | return; |
— | — | @@ -194,24 +199,27 @@ |
195 | 200 | $this->showMissingThreadPage(); |
196 | 201 | return false; |
197 | 202 | } |
198 | | - |
| 203 | + |
199 | 204 | if ( $this->request->getBool( 'lqt_inline' ) ) { |
200 | 205 | $this->doInlineEditForm(); |
201 | 206 | return false; |
202 | 207 | } |
203 | | - |
| 208 | + |
204 | 209 | // Handle action=edit stuff |
205 | 210 | if ( $this->request->getVal( 'action' ) == 'edit' ) { |
206 | 211 | // Rewrite to lqt_method = edit |
207 | 212 | $this->request->setVal( 'lqt_method', 'edit' ); |
208 | 213 | $this->request->setVal( 'lqt_operand', $this->thread->id() ); |
209 | 214 | } |
210 | | - |
| 215 | + |
211 | 216 | // Expose feed links. |
212 | 217 | global $wgFeedClasses, $wgScriptPath, $wgServer; |
213 | 218 | $thread = $this->thread->topmostThread()->title()->getPrefixedText(); |
214 | | - $apiParams = array( 'action' => 'feedthreads', 'type' => 'replies|newthreads', |
215 | | - 'thread' => $thread ); |
| 219 | + $apiParams = array( |
| 220 | + 'action' => 'feedthreads', |
| 221 | + 'type' => 'replies|newthreads', |
| 222 | + 'thread' => $thread |
| 223 | + ); |
216 | 224 | $urlPrefix = wfScript( 'api' ) . '?'; |
217 | 225 | foreach ( $wgFeedClasses as $format => $class ) { |
218 | 226 | $theseParams = $apiParams + array( 'feedformat' => $format ); |
— | — | @@ -228,7 +236,7 @@ |
229 | 237 | $this->showSplitForm( $this->thread ); |
230 | 238 | |
231 | 239 | $this->showThread( $this->thread, 1, 1, array( 'maxDepth' => - 1, 'maxCount' => - 1 ) ); |
232 | | - |
| 240 | + |
233 | 241 | $this->output->setPageTitle( $this->thread->subject() ); |
234 | 242 | return false; |
235 | 243 | } |
Index: trunk/extensions/LiquidThreads/pages/NewUserMessagesView.php |
— | — | @@ -1,9 +1,7 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class NewUserMessagesView extends LqtView { |
7 | | - |
8 | 6 | protected $threads; |
9 | 7 | protected $tops; |
10 | 8 | protected $targets; |
— | — | @@ -13,11 +11,16 @@ |
14 | 12 | $html = ''; |
15 | 13 | $html .= Xml::hidden( 'lqt_method', 'mark_as_read' ); |
16 | 14 | $html .= Xml::hidden( 'lqt_operand', $ids_s ); |
17 | | - $html .= Xml::submitButton( $label, |
18 | | - array( 'name' => 'lqt_read_button', |
19 | | - 'title' => $title, 'class' => 'lqt-read-button' ) ); |
| 15 | + $html .= Xml::submitButton( |
| 16 | + $label, |
| 17 | + array( |
| 18 | + 'name' => 'lqt_read_button', |
| 19 | + 'title' => $title, |
| 20 | + 'class' => 'lqt-read-button' |
| 21 | + ) |
| 22 | + ); |
20 | 23 | $html = Xml::tags( 'form', array( 'method' => 'post', 'class' => $class ), $html ); |
21 | | - |
| 24 | + |
22 | 25 | return $html; |
23 | 26 | } |
24 | 27 | |
— | — | @@ -25,16 +28,16 @@ |
26 | 29 | wfLoadExtensionMessages( 'LiquidThreads' ); |
27 | 30 | $ids = array_map( create_function( '$t', 'return $t->id();' ), $threads ); // ew |
28 | 31 | return $this->htmlForReadButton( |
29 | | - wfMsg( 'lqt-read-all' ), |
30 | | - wfMsg( 'lqt-read-all-tooltip' ), |
31 | | - "lqt_newmessages_read_all_button", |
32 | | - $ids |
33 | | - ); |
| 32 | + wfMsg( 'lqt-read-all' ), |
| 33 | + wfMsg( 'lqt-read-all-tooltip' ), |
| 34 | + "lqt_newmessages_read_all_button", |
| 35 | + $ids |
| 36 | + ); |
34 | 37 | } |
35 | 38 | |
36 | 39 | function getUndoButton( $ids ) { |
37 | 40 | wfLoadExtensionMessages( 'LiquidThreads' ); |
38 | | - |
| 41 | + |
39 | 42 | if ( count( $ids ) == 1 ) { |
40 | 43 | $t = Threads::withId( $ids[0] ); |
41 | 44 | if ( !$t ) |
— | — | @@ -45,49 +48,56 @@ |
46 | 49 | $msg = wfMsgExt( 'lqt-count-marked-read', 'parseinline', array( $count ) ); |
47 | 50 | } |
48 | 51 | $operand = implode( ',', $ids ); |
49 | | - |
| 52 | + |
50 | 53 | $html = ''; |
51 | 54 | $html .= $msg; |
52 | 55 | $html .= Xml::hidden( 'lqt_method', 'mark_as_unread' ); |
53 | 56 | $html .= Xml::hidden( 'lqt_operand', $operand ); |
54 | | - $html .= Xml::submitButton( wfMsg( 'lqt-email-undo' ), array( 'name' => 'lqt_read_button', |
55 | | - 'title' => wfMsg( 'lqt-email-info-undo' ) ) ); |
56 | | - |
57 | | - $html = Xml::tags( 'form', |
58 | | - array( 'method' => 'post', 'class' => 'lqt_undo_mark_as_read' ), |
59 | | - $html ); |
60 | | - |
| 57 | + $html .= Xml::submitButton( |
| 58 | + wfMsg( 'lqt-email-undo' ), |
| 59 | + array( |
| 60 | + 'name' => 'lqt_read_button', |
| 61 | + 'title' => wfMsg( 'lqt-email-info-undo' ) |
| 62 | + ) |
| 63 | + ); |
| 64 | + |
| 65 | + $html = Xml::tags( |
| 66 | + 'form', |
| 67 | + array( 'method' => 'post', 'class' => 'lqt_undo_mark_as_read' ), |
| 68 | + $html |
| 69 | + ); |
| 70 | + |
61 | 71 | return $html; |
62 | 72 | } |
63 | 73 | |
64 | 74 | function postDivClass( $thread ) { |
65 | 75 | $origClass = parent::postDivClass( $thread ); |
66 | | - |
| 76 | + |
67 | 77 | $topid = $thread->topmostThread()->id(); |
68 | | - |
| 78 | + |
69 | 79 | if ( isset( $this->targets[$topid] ) && is_array( $this->targets[$topid] ) && |
70 | 80 | in_array( $thread->id(), $this->targets[$topid] ) ) |
71 | 81 | return "$origClass lqt_post_new_message"; |
72 | | - |
| 82 | + |
73 | 83 | return $origClass; |
74 | 84 | } |
75 | 85 | |
76 | 86 | function showOnce() { |
77 | 87 | self::addJSandCSS(); |
78 | | - |
| 88 | + |
79 | 89 | static $scriptDone = false; |
80 | | - |
| 90 | + |
81 | 91 | if ( !$scriptDone ) { |
82 | 92 | global $wgOut, $wgScriptPath, $wgLiquidThreadsExtensionName; |
83 | 93 | $prefix = "{$wgScriptPath}/extensions/{$wgLiquidThreadsExtensionName}"; |
84 | 94 | $wgOut->addScriptFile( "$prefix/newmessages.js" ); |
85 | 95 | } |
86 | | - |
| 96 | + |
87 | 97 | $this->user->setNewtalk( false ); |
88 | 98 | |
89 | 99 | if ( $this->methodApplies( 'mark_as_unread' ) ) { |
90 | 100 | $ids = explode( ',', $this->request->getVal( 'lqt_operand', '' ) ); |
91 | | - |
| 101 | + |
92 | 102 | if ( $ids !== false ) { |
93 | 103 | foreach ( $ids as $id ) { |
94 | 104 | $tmp_thread = Threads::withId( $id ); if ( $tmp_thread ) |
— | — | @@ -124,7 +134,7 @@ |
125 | 135 | $this->tops = array(); |
126 | 136 | foreach ( $this->threads as $t ) { |
127 | 137 | $top = $t->topmostThread(); |
128 | | - |
| 138 | + |
129 | 139 | // It seems that in some cases $top is zero. |
130 | 140 | if ( !$top ) |
131 | 141 | throw new MWException( "{$t->id()} seems to have no topmost thread" ); |
— | — | @@ -135,7 +145,7 @@ |
136 | 146 | $this->targets[$top->id()] = array(); |
137 | 147 | $this->targets[$top->id()][] = $t->id(); |
138 | 148 | } |
139 | | - |
| 149 | + |
140 | 150 | $this->output->addHTML( '<table class="lqt-new-messages"><tbody>' ); |
141 | 151 | |
142 | 152 | foreach ( $this->tops as $t ) { |
— | — | @@ -145,42 +155,49 @@ |
146 | 156 | |
147 | 157 | $this->showWrappedThread( $t ); |
148 | 158 | } |
149 | | - |
| 159 | + |
150 | 160 | $this->output->addHTML( '</tbody></table>' ); |
151 | | - |
| 161 | + |
152 | 162 | return false; |
153 | 163 | } |
154 | | - |
| 164 | + |
155 | 165 | function showWrappedThread( $t ) { |
156 | 166 | wfLoadExtensionMessages( 'LiquidThreads' ); |
157 | | - |
| 167 | + |
158 | 168 | $read_button = $this->htmlForReadButton( |
159 | 169 | wfMsg( 'lqt-read-message' ), |
160 | 170 | wfMsg( 'lqt-read-message-tooltip' ), |
161 | 171 | 'lqt_newmessages_read_button', |
162 | 172 | $this->targets[$t->id()] ); |
163 | | - |
| 173 | + |
164 | 174 | // Left-hand column read button and context link to the full thread. |
165 | 175 | global $wgUser; |
166 | 176 | $topmostThread = $t->topmostThread(); |
167 | 177 | $sk = $wgUser->getSkin(); |
168 | 178 | $title = clone $topmostThread->article()->getTitle(); |
169 | 179 | $title->setFragment( '#' . $t->getAnchorName() ); |
170 | | - |
| 180 | + |
171 | 181 | // Make sure it points to the right page. The Pager seems to use the DB |
172 | 182 | // representation of a timestamp for its offset field, odd. |
173 | 183 | $dbr = wfGetDB( DB_SLAVE ); |
174 | 184 | $offset = wfTimestamp( TS_UNIX, $topmostThread->modified() ) + 1; |
175 | 185 | $offset = $dbr->timestamp( $offset ); |
176 | | - |
177 | | - $contextLink = $sk->link( $title, |
178 | | - wfMsgExt( 'lqt-newmessages-context', 'parseinline' ), array(), |
179 | | - array( 'offset' => $offset ), array( 'known' ) ); |
180 | | - |
| 186 | + |
| 187 | + $contextLink = $sk->link( |
| 188 | + $title, |
| 189 | + wfMsgExt( 'lqt-newmessages-context', 'parseinline' ), |
| 190 | + array(), |
| 191 | + array( 'offset' => $offset ), |
| 192 | + array( 'known' ) |
| 193 | + ); |
| 194 | + |
181 | 195 | $talkpageLink = $sk->link( $topmostThread->article()->getTitle() ); |
182 | | - $talkpageInfo = wfMsgExt( 'lqt-newmessages-from', |
183 | | - array( 'parse', 'replaceafter' ), $talkpageLink ); |
184 | | - |
| 196 | + $talkpageInfo = wfMsgExt( |
| 197 | + 'lqt-newmessages-from', |
| 198 | + array( 'parse', 'replaceafter' ), |
| 199 | + $talkpageLink |
| 200 | + ); |
| 201 | + |
185 | 202 | $leftColumn = Xml::tags( 'p', null, $read_button ) . |
186 | 203 | Xml::tags( 'p', null, $contextLink ) . |
187 | 204 | $talkpageInfo; |
— | — | @@ -192,7 +209,7 @@ |
193 | 210 | $mustShowThreads = $this->targets[$t->id()]; |
194 | 211 | |
195 | 212 | $this->showThread( $t, 1, 1, array( 'mustShowThreads' => $mustShowThreads ) ); |
196 | | - |
| 213 | + |
197 | 214 | $this->output->addHTML( "</td></tr>" ); |
198 | 215 | } |
199 | 216 | |
Index: trunk/extensions/LiquidThreads/pages/SpecialHotTopics.php |
— | — | @@ -1,31 +1,30 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | class SpecialHotTopics extends SpecialPage { |
5 | 4 | function __construct() { |
6 | 5 | parent::__construct( 'HotTopics' ); |
7 | 6 | } |
8 | | - |
| 7 | + |
9 | 8 | function execute( $par ) { |
10 | 9 | global $wgOut; |
11 | | - |
| 10 | + |
12 | 11 | wfLoadExtensionMessages( 'LiquidThreads' ); |
13 | | - |
| 12 | + |
14 | 13 | $this->setHeaders(); |
15 | | - |
| 14 | + |
16 | 15 | $wgOut->setPageTitle( wfMsg( 'lqt-hot-topics' ) ); |
17 | 16 | $view = LqtView::getView(); |
18 | | - |
| 17 | + |
19 | 18 | LqtView::addJsAndCss(); |
20 | | - |
| 19 | + |
21 | 20 | // Get hot topics |
22 | 21 | $topics = LqtHotTopicsController::getHotThreads(); |
23 | | - |
24 | | - foreach( $topics as $thread ) { |
| 22 | + |
| 23 | + foreach ( $topics as $thread ) { |
25 | 24 | $view->showThread( $thread ); |
26 | 25 | } |
27 | 26 | } |
28 | | - |
29 | | - function getPageName() { |
| 27 | + |
| 28 | + function getPageName() { |
30 | 29 | return wfMsg( 'lqt-hot-topics' ); |
31 | 30 | } |
32 | 31 | } |
Index: trunk/extensions/LiquidThreads/pages/ThreadHistoryListingView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class ThreadHistoryListingView extends ThreadPermalinkView { |
— | — | @@ -10,36 +9,37 @@ |
11 | 10 | } |
12 | 11 | self::addJSandCSS(); |
13 | 12 | wfLoadExtensionMessages( 'LiquidThreads' ); |
14 | | - |
| 13 | + |
15 | 14 | $this->thread->updateHistory(); |
16 | 15 | |
17 | 16 | $this->output->setPageTitle( wfMsg( 'lqt-history-title' ) ); |
18 | | - $this->output->setSubtitle( $this->getSubtitle() . '<br />' . |
19 | | - wfMsg( 'lqt_hist_listing_subtitle' ) ); |
| 17 | + $this->output->setSubtitle( |
| 18 | + $this->getSubtitle() . '<br />' . |
| 19 | + wfMsg( 'lqt_hist_listing_subtitle' ) |
| 20 | + ); |
20 | 21 | $this->showThreadHeading( $this->thread ); |
21 | | - |
| 22 | + |
22 | 23 | $pager = new ThreadHistoryPager( $this, $this->thread ); |
23 | | - |
| 24 | + |
24 | 25 | $html = $pager->getNavigationBar() . |
25 | 26 | $pager->getBody() . |
26 | 27 | $pager->getNavigationBar(); |
27 | | - |
| 28 | + |
28 | 29 | $this->output->addHTML( $html ); |
29 | | - |
| 30 | + |
30 | 31 | $this->showThread( $this->thread ); |
31 | | - |
| 32 | + |
32 | 33 | return false; |
33 | 34 | } |
34 | | - |
| 35 | + |
35 | 36 | function customizeTabs( $skin, &$links ) { |
36 | 37 | parent::customizeTabs( $skin, $links ); |
37 | 38 | $links['history']['class'] = 'selected'; |
38 | 39 | } |
39 | | - |
40 | | - function customizeNavigation( $skin, &$links ) { |
| 40 | + |
| 41 | + function customizeNavigation( $skin, &$links ) { |
41 | 42 | parent::customizeNavigation( $skin, $links ); |
42 | 43 | $links['views']['history']['class'] = 'selected'; |
43 | 44 | $links['views']['view']['class'] = ''; |
44 | 45 | } |
45 | 46 | } |
46 | | - |
Index: trunk/extensions/LiquidThreads/pages/SpecialNewMessages.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class SpecialNewMessages extends SpecialPage { |
— | — | @@ -26,16 +25,16 @@ |
27 | 26 | $this->request = $wgRequest; |
28 | 27 | |
29 | 28 | $this->setHeaders(); |
30 | | - |
| 29 | + |
31 | 30 | $article = new Article( $this->getTitle() ); |
32 | 31 | $title = $this->getTitle(); |
33 | | - |
| 32 | + |
34 | 33 | // Clear newtalk |
35 | 34 | $this->user->setNewtalk( false ); |
36 | 35 | |
37 | 36 | $view = new NewUserMessagesView( $this->output, $article, |
38 | 37 | $title, $this->user, $this->request ); |
39 | | - |
| 38 | + |
40 | 39 | if ( $this->request->getBool( 'lqt_inline' ) ) { |
41 | 40 | $view->doInlineEditForm(); |
42 | 41 | return; |
— | — | @@ -50,21 +49,27 @@ |
51 | 50 | $wgOut->addWikitext( wfMsg( 'lqt-no-new-messages' ) ); |
52 | 51 | return; |
53 | 52 | } |
54 | | - |
| 53 | + |
55 | 54 | $html = ''; |
56 | | - |
| 55 | + |
57 | 56 | $html .= $view->getReadAllButton( $both_sets ); |
58 | 57 | |
59 | 58 | $view->setHeaderLevel( 3 ); |
60 | 59 | |
61 | | - $html .= Xml::tags( 'h2', array( 'class' => 'lqt_newmessages_section' ), |
62 | | - wfMsgExt( 'lqt-messages-sent', 'parseinline' ) ); |
| 60 | + $html .= Xml::tags( |
| 61 | + 'h2', |
| 62 | + array( 'class' => 'lqt_newmessages_section' ), |
| 63 | + wfMsgExt( 'lqt-messages-sent', 'parseinline' ) |
| 64 | + ); |
63 | 65 | $wgOut->addHTML( $html ); |
64 | 66 | $view->setThreads( $first_set ); |
65 | 67 | $view->show(); |
66 | 68 | |
67 | | - $wgOut->addHTML( Xml::tags( 'h2', array( 'class' => 'lqt_newmessages_section' ), |
68 | | - wfMsgExt( 'lqt-other-messages', 'parseinline' ) ) ); |
| 69 | + $wgOut->addHTML( Xml::tags( |
| 70 | + 'h2', |
| 71 | + array( 'class' => 'lqt_newmessages_section' ), |
| 72 | + wfMsgExt( 'lqt-other-messages', 'parseinline' ) |
| 73 | + ) ); |
69 | 74 | $view->setThreads( $second_set ); |
70 | 75 | $view->show(); |
71 | 76 | } |
Index: trunk/extensions/LiquidThreads/pages/TalkpageView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class TalkpageView extends LqtView { |
— | — | @@ -17,33 +16,33 @@ |
18 | 17 | $content_actions['history']['href'] = $history_url; |
19 | 18 | } |
20 | 19 | } |
21 | | - |
| 20 | + |
22 | 21 | static function customizeTalkpageNavigation( $skin, &$links, $view ) { |
23 | 22 | $remove = array( 'views/edit', 'views/viewsource', 'actions/delete' ); |
24 | | - |
25 | | - foreach( $remove as $rem ) { |
26 | | - list($section, $item) = explode( '/', $rem, 2 ); |
| 23 | + |
| 24 | + foreach ( $remove as $rem ) { |
| 25 | + list( $section, $item ) = explode( '/', $rem, 2 ); |
27 | 26 | unset( $links[$section][$item] ); |
28 | 27 | } |
29 | | - |
| 28 | + |
30 | 29 | if ( isset( $links['views']['history'] ) ) { |
31 | 30 | $title = $view->article->getTitle(); |
32 | 31 | $history_url = $title->getFullURL( 'lqt_method=talkpage_history' ); |
33 | 32 | $links['views']['history']['href'] = $history_url; |
34 | 33 | } |
35 | 34 | } |
36 | | - |
| 35 | + |
37 | 36 | function customizeTabs( $skintemplate, &$links ) { |
38 | 37 | self::customizeTalkpageTabs( $skintemplate, $links, $this ); |
39 | 38 | } |
40 | | - |
| 39 | + |
41 | 40 | function customizeNavigation( $skintemplate, &$links ) { |
42 | 41 | self::customizeTalkpageNavigation( $skintemplate, $links, $this ); |
43 | 42 | } |
44 | 43 | |
45 | 44 | function showHeader() { |
46 | 45 | /* Show the contents of the actual talkpage article if it exists. */ |
47 | | - |
| 46 | + |
48 | 47 | global $wgUser; |
49 | 48 | $sk = $wgUser->getSkin(); |
50 | 49 | |
— | — | @@ -56,23 +55,32 @@ |
57 | 56 | // when the first thread was posted to make the links blue. |
58 | 57 | if ( $article->exists() ) { |
59 | 58 | $html = ''; |
60 | | - |
| 59 | + |
61 | 60 | $article->view(); |
62 | | - |
| 61 | + |
63 | 62 | $actionLinks = array(); |
64 | | - $actionLinks[] = $sk->link( $this->title, |
65 | | - wfMsgExt( 'edit', 'parseinline' ) . "↑", |
66 | | - array(), array( 'action' => 'edit' ) ); |
67 | | - $actionLinks[] = $sk->link( $this->title, |
68 | | - wfMsgExt( 'history_short', 'parseinline' ) . "↑", |
69 | | - array(), array( 'action' => 'history' ) ); |
70 | | - |
| 63 | + $actionLinks[] = $sk->link( |
| 64 | + $this->title, |
| 65 | + wfMsgExt( 'edit', 'parseinline' ) . "↑", |
| 66 | + array(), |
| 67 | + array( 'action' => 'edit' ) |
| 68 | + ); |
| 69 | + $actionLinks[] = $sk->link( |
| 70 | + $this->title, |
| 71 | + wfMsgExt( 'history_short', 'parseinline' ) . "↑", |
| 72 | + array(), |
| 73 | + array( 'action' => 'history' ) |
| 74 | + ); |
| 75 | + |
71 | 76 | if ( $wgUser->isAllowed( 'delete' ) ) { |
72 | | - $actionLinks[] = $sk->link( $this->title, |
73 | | - wfMsgExt( 'delete', 'parseinline' ) . '↑', |
74 | | - array(), array( 'action' => 'delete' ) ); |
| 77 | + $actionLinks[] = $sk->link( |
| 78 | + $this->title, |
| 79 | + wfMsgExt( 'delete', 'parseinline' ) . '↑', |
| 80 | + array(), |
| 81 | + array( 'action' => 'delete' ) |
| 82 | + ); |
75 | 83 | } |
76 | | - |
| 84 | + |
77 | 85 | $actions = ''; |
78 | 86 | foreach ( $actionLinks as $link ) { |
79 | 87 | $actions .= Xml::tags( 'li', null, "[$link]" ) . "\n"; |
— | — | @@ -81,30 +89,34 @@ |
82 | 90 | $html .= $actions; |
83 | 91 | |
84 | 92 | $html = Xml::tags( 'div', array( 'class' => 'lqt_header_content' ), $html ); |
85 | | - |
| 93 | + |
86 | 94 | $this->output->addHTML( $html ); |
87 | 95 | } else { |
88 | | - |
89 | | - $editLink = $sk->link( $this->title, wfMsgExt( 'lqt_add_header', 'parseinline' ), |
90 | | - array(), array( 'action' => 'edit' ) ); |
91 | | - |
| 96 | + |
| 97 | + $editLink = $sk->link( |
| 98 | + $this->title, |
| 99 | + wfMsgExt( 'lqt_add_header', 'parseinline' ), |
| 100 | + array(), |
| 101 | + array( 'action' => 'edit' ) |
| 102 | + ); |
| 103 | + |
92 | 104 | $html = Xml::tags( 'p', array( 'class' => 'lqt_header_notice' ), "[$editLink]" ); |
93 | | - |
| 105 | + |
94 | 106 | $this->output->addHTML( $html ); |
95 | 107 | } |
96 | 108 | } |
97 | | - |
| 109 | + |
98 | 110 | function getTOC( $threads ) { |
99 | 111 | global $wgLang; |
100 | | - |
| 112 | + |
101 | 113 | wfLoadExtensionMessages( 'LiquidThreads' ); |
102 | 114 | |
103 | 115 | $sk = $this->user->getSkin(); |
104 | | - |
| 116 | + |
105 | 117 | $html = ''; |
106 | | - |
| 118 | + |
107 | 119 | $h2_header = Xml::tags( 'h2', null, wfMsgExt( 'lqt_contents_title', 'parseinline' ) ); |
108 | | - |
| 120 | + |
109 | 121 | // Header row |
110 | 122 | $headerRow = ''; |
111 | 123 | $headers = array( 'lqt_toc_thread_title', |
— | — | @@ -114,7 +126,7 @@ |
115 | 127 | } |
116 | 128 | $headerRow = Xml::tags( 'tr', null, $headerRow ); |
117 | 129 | $headerRow = Xml::tags( 'thead', null, $headerRow ); |
118 | | - |
| 130 | + |
119 | 131 | // Table body |
120 | 132 | $rows = array(); |
121 | 133 | foreach ( $threads as $thread ) { |
— | — | @@ -122,42 +134,42 @@ |
123 | 135 | !LqtView::threadContainsRepliesWithContent( $thread ) ) { |
124 | 136 | continue; |
125 | 137 | } |
126 | | - |
| 138 | + |
127 | 139 | $row = ''; |
128 | 140 | $anchor = '#' . $this->anchorName( $thread ); |
129 | 141 | $subject = Xml::tags( 'a', array( 'href' => $anchor ), |
130 | 142 | Threads::stripHTML( $thread->formattedSubject() ) ); |
131 | 143 | $row .= Xml::tags( 'td', null, $subject ); |
132 | | - |
| 144 | + |
133 | 145 | $row .= Xml::element( 'td', null, $thread->replyCount() ); |
134 | | - |
| 146 | + |
135 | 147 | $timestamp = $wgLang->timeanddate( $thread->modified(), true ); |
136 | 148 | $row .= Xml::element( 'td', null, $timestamp ); |
137 | | - |
| 149 | + |
138 | 150 | $row = Xml::tags( 'tr', null, $row ); |
139 | 151 | $rows[] = $row; |
140 | 152 | } |
141 | | - |
| 153 | + |
142 | 154 | $html .= $headerRow . "\n" . Xml::tags( 'tbody', null, implode( "\n", $rows ) ); |
143 | 155 | $html = $h2_header . Xml::tags( 'table', array( 'class' => 'lqt_toc' ), $html ); |
144 | | - |
| 156 | + |
145 | 157 | return $html; |
146 | 158 | } |
147 | | - |
| 159 | + |
148 | 160 | function getList( $kind, $class, $id, $contents ) { |
149 | 161 | $html = ''; |
150 | 162 | foreach ( $contents as $li ) { |
151 | 163 | $html .= Xml::tags( 'li', null, $li ); |
152 | 164 | } |
153 | 165 | $html = Xml::tags( $kind, array( 'class' => $class, 'id' => $id ), $html ); |
154 | | - |
| 166 | + |
155 | 167 | return $html; |
156 | 168 | } |
157 | 169 | |
158 | 170 | function getArchiveWidget( ) { |
159 | 171 | wfLoadExtensionMessages( 'LiquidThreads' ); |
160 | 172 | $url = $this->talkpageUrl( $this->title, 'talkpage_archive' ); |
161 | | - |
| 173 | + |
162 | 174 | $html = ''; |
163 | 175 | $html = Xml::tags( 'div', array( 'class' => 'lqt_archive_teaser' ), $html ); |
164 | 176 | return $html; |
— | — | @@ -169,32 +181,44 @@ |
170 | 182 | if ( $article->exists() ) { |
171 | 183 | $form_action_url = $this->talkpageUrl( $this->title, 'talkpage_sort_order' ); |
172 | 184 | $go = wfMsg( 'go' ); |
173 | | - |
| 185 | + |
174 | 186 | $html = ''; |
175 | | - |
| 187 | + |
176 | 188 | $html .= Xml::label( wfMsg( 'lqt_sorting_order' ), 'lqt_sort_select' ) . ' '; |
177 | 189 | |
178 | 190 | $sortOrderSelect = |
179 | 191 | new XmlSelect( 'lqt_order', 'lqt_sort_select', $this->getSortType() ); |
180 | | - |
| 192 | + |
181 | 193 | $sortOrderSelect->setAttribute( 'class', 'lqt_sort_select' ); |
182 | | - $sortOrderSelect->addOption( wfMsg( 'lqt_sort_newest_changes' ), |
183 | | - LQT_NEWEST_CHANGES ); |
184 | | - $sortOrderSelect->addOption( wfMsg( 'lqt_sort_newest_threads' ), |
185 | | - LQT_NEWEST_THREADS ); |
186 | | - $sortOrderSelect->addOption( wfMsg( 'lqt_sort_oldest_threads' ), |
187 | | - LQT_OLDEST_THREADS ); |
| 194 | + $sortOrderSelect->addOption( |
| 195 | + wfMsg( 'lqt_sort_newest_changes' ), |
| 196 | + LQT_NEWEST_CHANGES |
| 197 | + ); |
| 198 | + $sortOrderSelect->addOption( |
| 199 | + wfMsg( 'lqt_sort_newest_threads' ), |
| 200 | + LQT_NEWEST_THREADS |
| 201 | + ); |
| 202 | + $sortOrderSelect->addOption( |
| 203 | + wfMsg( 'lqt_sort_oldest_threads' ), |
| 204 | + LQT_OLDEST_THREADS |
| 205 | + ); |
188 | 206 | $html .= $sortOrderSelect->getHTML(); |
189 | | - |
| 207 | + |
190 | 208 | $html .= Xml::submitButton( wfMsg( 'go' ), array( 'class' => 'lqt_go_sort' ) ); |
191 | 209 | $html .= Xml::hidden( 'title', $this->title->getPrefixedText() ); |
192 | | - |
193 | | - |
194 | | - $html = Xml::tags( 'form', array( 'action' => $form_action_url, |
195 | | - 'method' => 'get', |
196 | | - 'name' => 'lqt_sort' ), $html ); |
| 210 | + |
| 211 | + |
| 212 | + $html = Xml::tags( |
| 213 | + 'form', |
| 214 | + array( |
| 215 | + 'action' => $form_action_url, |
| 216 | + 'method' => 'get', |
| 217 | + 'name' => 'lqt_sort' |
| 218 | + ), |
| 219 | + $html |
| 220 | + ); |
197 | 221 | $html = Xml::tags( 'div', array( 'class' => 'lqt_view_options' ), $html ); |
198 | | - |
| 222 | + |
199 | 223 | return $html; |
200 | 224 | } |
201 | 225 | } |
— | — | @@ -204,7 +228,7 @@ |
205 | 229 | |
206 | 230 | $this->output->setPageTitle( $this->title->getPrefixedText() ); |
207 | 231 | self::addJSandCSS(); |
208 | | - |
| 232 | + |
209 | 233 | // Expose feed links. |
210 | 234 | global $wgFeedClasses, $wgScriptPath, $wgServer; |
211 | 235 | $apiParams = array( 'action' => 'feedthreads', 'type' => 'replies|newthreads', |
— | — | @@ -215,58 +239,65 @@ |
216 | 240 | $url = $urlPrefix . wfArrayToCGI( $theseParams ); |
217 | 241 | $this->output->addFeedLink( $format, $url ); |
218 | 242 | } |
219 | | - |
| 243 | + |
220 | 244 | $sk = $this->user->getSkin(); |
221 | | - |
| 245 | + |
222 | 246 | $article = new Article( $this->title ); |
223 | | - |
| 247 | + |
224 | 248 | if ( $this->request->getBool( 'lqt_inline' ) ) { |
225 | 249 | $this->doInlineEditForm(); |
226 | 250 | return false; |
227 | 251 | } |
228 | | - |
| 252 | + |
229 | 253 | // Search! |
230 | 254 | if ( $this->request->getCheck( 'lqt_search' ) ) { |
231 | 255 | $q = $this->request->getText( 'lqt_search' ); |
232 | 256 | $q .= ' ondiscussionpage:' . $article->getTitle()->getPrefixedText(); |
233 | | - |
234 | | - $params = array( 'search' => $q, |
235 | | - 'fulltext' => 1, |
236 | | - 'ns' . NS_LQT_THREAD => 1, |
237 | | - ); |
238 | | - |
| 257 | + |
| 258 | + $params = array( |
| 259 | + 'search' => $q, |
| 260 | + 'fulltext' => 1, |
| 261 | + 'ns' . NS_LQT_THREAD => 1, |
| 262 | + ); |
| 263 | + |
239 | 264 | $t = SpecialPage::getTitleFor( 'Search' ); |
240 | 265 | $url = $t->getLocalURL( wfArrayToCGI( $params ) ); |
241 | | - |
| 266 | + |
242 | 267 | $this->output->redirect( $url ); |
243 | | - |
244 | 268 | } |
245 | 269 | |
246 | 270 | $this->showHeader(); |
247 | | - |
| 271 | + |
248 | 272 | $html = ''; |
249 | | - |
| 273 | + |
250 | 274 | // Set up a per-page header for new threads, search box, and sorting stuff. |
251 | 275 | |
252 | 276 | $talkpageHeader = ''; |
253 | | - |
| 277 | + |
254 | 278 | if ( Thread::canUserPost( $this->user, $this->article ) ) { |
255 | 279 | $newThreadText = wfMsgExt( 'lqt_new_thread', 'parseinline' ); |
256 | | - $newThreadLink = $sk->link( $this->title, $newThreadText, |
257 | | - array( ), |
258 | | - array( 'lqt_method' => 'talkpage_new_thread' ), |
259 | | - array( 'known' ) ); |
260 | | - |
261 | | - $talkpageHeader .= Xml::tags( 'strong', |
262 | | - array( 'class' => 'lqt_start_discussion' ), |
263 | | - $newThreadLink ); |
| 280 | + $newThreadLink = $sk->link( |
| 281 | + $this->title, $newThreadText, |
| 282 | + array( ), |
| 283 | + array( 'lqt_method' => 'talkpage_new_thread' ), |
| 284 | + array( 'known' ) |
| 285 | + ); |
| 286 | + |
| 287 | + $talkpageHeader .= Xml::tags( |
| 288 | + 'strong', |
| 289 | + array( 'class' => 'lqt_start_discussion' ), |
| 290 | + $newThreadLink |
| 291 | + ); |
264 | 292 | } |
265 | | - |
| 293 | + |
266 | 294 | $talkpageHeader .= $this->getSearchBox(); |
267 | 295 | $talkpageHeader .= $this->showTalkpageViewOptions( $article ); |
268 | | - $talkpageHeader = Xml::tags( 'div', array( 'class' => 'lqt-talkpage-header' ), |
269 | | - $talkpageHeader ); |
270 | | - |
| 296 | + $talkpageHeader = Xml::tags( |
| 297 | + 'div', |
| 298 | + array( 'class' => 'lqt-talkpage-header' ), |
| 299 | + $talkpageHeader |
| 300 | + ); |
| 301 | + |
271 | 302 | $this->output->addHTML( $talkpageHeader ); |
272 | 303 | |
273 | 304 | global $wgRequest; |
— | — | @@ -279,9 +310,9 @@ |
280 | 311 | $this->output->addHTML( Xml::tags( 'div', |
281 | 312 | array( 'class' => 'lqt-new-thread lqt-edit-form' ), '' ) ); |
282 | 313 | } |
283 | | - |
| 314 | + |
284 | 315 | $pager = $this->getPager(); |
285 | | - |
| 316 | + |
286 | 317 | $threads = $this->getPageThreads( $pager ); |
287 | 318 | |
288 | 319 | if ( count( $threads ) > 0 ) { |
— | — | @@ -290,52 +321,57 @@ |
291 | 322 | $html .= Xml::tags( 'div', array( 'class' => 'lqt-no-threads' ), |
292 | 323 | wfMsgExt( 'lqt-no-threads', 'parseinline' ) ); |
293 | 324 | } |
294 | | - |
| 325 | + |
295 | 326 | $html .= $pager->getNavigationBar(); |
296 | | - |
| 327 | + |
297 | 328 | $this->output->addHTML( $html ); |
298 | 329 | |
299 | 330 | foreach ( $threads as $t ) { |
300 | 331 | $this->showThread( $t ); |
301 | 332 | } |
302 | | - |
| 333 | + |
303 | 334 | $this->output->addHTML( $pager->getNavigationBar() ); |
304 | | - |
| 335 | + |
305 | 336 | return false; |
306 | 337 | } |
307 | | - |
| 338 | + |
308 | 339 | function getSearchBox() { |
309 | 340 | $html = ''; |
310 | | - $html .= Xml::inputLabel( wfMsg( 'lqt-search-label' ), 'lqt_search', 'lqt-search-box', |
311 | | - 45 ); |
312 | | - |
| 341 | + $html .= Xml::inputLabel( |
| 342 | + wfMsg( 'lqt-search-label' ), |
| 343 | + 'lqt_search', |
| 344 | + 'lqt-search-box', |
| 345 | + 45 |
| 346 | + ); |
| 347 | + |
313 | 348 | $html .= ' ' . Xml::submitButton( wfMsg( 'lqt-search-button' ) ); |
314 | 349 | $html .= Xml::hidden( 'title', $this->title->getPrefixedText() ); |
315 | | - $html = Xml::tags( 'form', |
316 | | - array( 'action' => $this->title->getLocalURL(), |
317 | | - 'method' => 'get' ), |
318 | | - $html ); |
319 | | - |
320 | | -# $html = Xml::fieldset( wfMsg('lqt-search-legend' ), $html, |
321 | | -# array( 'class' => 'lqt-talkpage-search' ) ); |
| 350 | + $html = Xml::tags( |
| 351 | + 'form', |
| 352 | + array( |
| 353 | + 'action' => $this->title->getLocalURL(), |
| 354 | + 'method' => 'get' |
| 355 | + ), |
| 356 | + $html |
| 357 | + ); |
322 | 358 | |
323 | 359 | $html = Xml::tags( 'div', array( 'class' => 'lqt-talkpage-search' ), $html ); |
324 | | - |
| 360 | + |
325 | 361 | return $html; |
326 | 362 | } |
327 | | - |
| 363 | + |
328 | 364 | function getPager() { |
329 | | - |
| 365 | + |
330 | 366 | $sortType = $this->getSortType(); |
331 | 367 | return new LqtDiscussionPager( $this->article, $sortType ); |
332 | 368 | } |
333 | | - |
| 369 | + |
334 | 370 | function getPageThreads( $pager ) { |
335 | 371 | $rows = $pager->getRows(); |
336 | | - |
| 372 | + |
337 | 373 | return Thread::bulkLoad( $rows ); |
338 | 374 | } |
339 | | - |
| 375 | + |
340 | 376 | function getSortType() { |
341 | 377 | // Determine sort order |
342 | 378 | if ( $this->request->getCheck( 'lqt_order' ) ) { |
— | — | @@ -350,69 +386,66 @@ |
351 | 387 | return LQT_OLDEST_THREADS; |
352 | 388 | } |
353 | 389 | } |
354 | | - |
| 390 | + |
355 | 391 | // Default |
356 | 392 | return LQT_NEWEST_CHANGES; |
357 | 393 | } |
358 | 394 | } |
359 | 395 | |
360 | 396 | class LqtDiscussionPager extends IndexPager { |
361 | | - |
362 | 397 | function __construct( $article, $orderType ) { |
363 | 398 | $this->article = $article; |
364 | 399 | $this->orderType = $orderType; |
365 | | - |
| 400 | + |
366 | 401 | parent::__construct(); |
367 | | - |
| 402 | + |
368 | 403 | $this->mLimit = $this->getPageLimit(); |
369 | 404 | } |
370 | | - |
| 405 | + |
371 | 406 | function getPageLimit() { |
372 | 407 | $article = $this->article; |
373 | | - |
| 408 | + |
374 | 409 | global $wgRequest; |
375 | 410 | $requestedLimit = $wgRequest->getVal( 'limit', null ); |
376 | 411 | if ( $requestedLimit ) { |
377 | 412 | return $requestedLimit; |
378 | 413 | } |
379 | | - |
| 414 | + |
380 | 415 | if ( $article->exists() ) { |
381 | 416 | $pout = $article->getParserOutput(); |
382 | | - $setLimit = $pout->getProperty('lqt-page-limit'); |
383 | | - if ($setLimit) return $setLimit; |
| 417 | + $setLimit = $pout->getProperty( 'lqt-page-limit' ); |
| 418 | + if ( $setLimit ) return $setLimit; |
384 | 419 | } |
385 | | - |
| 420 | + |
386 | 421 | global $wgLiquidThreadsDefaultPageLimit; |
387 | 422 | return $wgLiquidThreadsDefaultPageLimit; |
388 | 423 | } |
389 | | - |
| 424 | + |
390 | 425 | function getQueryInfo() { |
391 | | - $queryInfo = |
392 | | - array( |
393 | | - 'tables' => array( 'thread' ), |
394 | | - 'fields' => '*', |
395 | | - 'conds' => |
396 | | - array( |
397 | | - Threads::articleClause( $this->article ), |
398 | | - Threads::topLevelClause(), |
399 | | - 'thread_type != ' . $this->mDb->addQuotes( Threads::TYPE_DELETED ), |
400 | | - ), |
401 | | - ); |
402 | | - |
| 426 | + $queryInfo = array( |
| 427 | + 'tables' => array( 'thread' ), |
| 428 | + 'fields' => '*', |
| 429 | + 'conds' => array( |
| 430 | + Threads::articleClause( $this->article ), |
| 431 | + Threads::topLevelClause(), |
| 432 | + 'thread_type != ' . $this->mDb->addQuotes( Threads::TYPE_DELETED ), |
| 433 | + ), |
| 434 | + ); |
| 435 | + |
403 | 436 | return $queryInfo; |
404 | 437 | } |
405 | | - |
| 438 | + |
406 | 439 | // Adapted from getBody(). |
407 | 440 | function getRows() { |
408 | 441 | if ( !$this->mQueryDone ) { |
409 | 442 | $this->doQuery(); |
410 | 443 | } |
411 | | - |
| 444 | + |
412 | 445 | # Don't use any extra rows returned by the query |
413 | 446 | $numRows = min( $this->mResult->numRows(), $this->mLimit ); |
414 | 447 | |
415 | 448 | $rows = array(); |
416 | | - |
| 449 | + |
417 | 450 | if ( $numRows ) { |
418 | 451 | if ( $this->mIsBackwards ) { |
419 | 452 | for ( $i = $numRows - 1; $i >= 0; $i-- ) { |
— | — | @@ -428,14 +461,14 @@ |
429 | 462 | } |
430 | 463 | } |
431 | 464 | } |
432 | | - |
| 465 | + |
433 | 466 | return $rows; |
434 | 467 | } |
435 | | - |
| 468 | + |
436 | 469 | function formatRow( $row ) { |
437 | 470 | // No-op, we get the list of rows from getRows() |
438 | 471 | } |
439 | | - |
| 472 | + |
440 | 473 | function getIndexField() { |
441 | 474 | switch( $this->orderType ) { |
442 | 475 | case LQT_NEWEST_CHANGES: |
— | — | @@ -447,7 +480,7 @@ |
448 | 481 | throw new MWException( "Unknown sort order " . $this->orderType ); |
449 | 482 | } |
450 | 483 | } |
451 | | - |
| 484 | + |
452 | 485 | function getDefaultDirections() { |
453 | 486 | switch( $this->orderType ) { |
454 | 487 | case LQT_NEWEST_CHANGES: |
— | — | @@ -459,7 +492,7 @@ |
460 | 493 | throw new MWException( "Unknown sort order " . $this->orderType ); |
461 | 494 | } |
462 | 495 | } |
463 | | - |
| 496 | + |
464 | 497 | /** |
465 | 498 | * A navigation bar with images |
466 | 499 | * Stolen from TablePager because it's pretty. |
— | — | @@ -509,7 +542,7 @@ |
510 | 543 | $s .= "</tr></table>\n"; |
511 | 544 | return $s; |
512 | 545 | } |
513 | | - |
| 546 | + |
514 | 547 | function getNavClass() { |
515 | 548 | return 'TalkpagePager_nav'; |
516 | 549 | } |
Index: trunk/extensions/LiquidThreads/pages/SpecialSplitThread.php |
— | — | @@ -1,29 +1,24 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | // TODO access control |
5 | 4 | class SpecialSplitThread extends ThreadActionPage { |
6 | | - |
7 | 5 | function getFormFields() { |
8 | 6 | $splitForm = array( |
9 | | - 'src' => |
10 | | - array( |
11 | | - 'type' => 'info', |
12 | | - 'label-message' => 'lqt-thread-split-thread', |
13 | | - 'default' => LqtView::permalink( $this->mThread ), |
14 | | - 'raw' => 1, |
15 | | - ), |
16 | | - 'subject' => |
17 | | - array( |
18 | | - 'type' => 'text', |
19 | | - 'label-message' => 'lqt-thread-split-subject', |
20 | | - ), |
21 | | - 'reason' => |
22 | | - array( |
23 | | - 'label-message' => 'movereason', |
24 | | - 'type' => 'text', |
25 | | - ), |
| 7 | + 'src' => array( |
| 8 | + 'type' => 'info', |
| 9 | + 'label-message' => 'lqt-thread-split-thread', |
| 10 | + 'default' => LqtView::permalink( $this->mThread ), |
| 11 | + 'raw' => 1, |
| 12 | + ), |
| 13 | + 'subject' => array( |
| 14 | + 'type' => 'text', |
| 15 | + 'label-message' => 'lqt-thread-split-subject', |
| 16 | + ), |
| 17 | + 'reason' => array( |
| 18 | + 'label-message' => 'movereason', |
| 19 | + 'type' => 'text', |
| 20 | + ), |
26 | 21 | ); |
27 | | - |
| 22 | + |
28 | 23 | return $splitForm; |
29 | 24 | } |
30 | 25 | |
— | — | @@ -34,46 +29,46 @@ |
35 | 30 | wfLoadExtensionMessages( 'LiquidThreads' ); |
36 | 31 | return wfMsg( 'lqt_split_thread' ); |
37 | 32 | } |
38 | | - |
| 33 | + |
39 | 34 | protected function getRightRequirement() { return 'lqt-split'; } |
40 | | - |
| 35 | + |
41 | 36 | function trySubmit( $data ) { |
42 | 37 | // Load data |
43 | 38 | $newSubject = $data['subject']; |
44 | 39 | $reason = $data['reason']; |
45 | | - |
| 40 | + |
46 | 41 | $this->mThread->split( $newSubject, $reason ); |
47 | | - |
| 42 | + |
48 | 43 | $link = LqtView::linkInContext( $this->mThread ); |
49 | | - |
| 44 | + |
50 | 45 | global $wgOut; |
51 | 46 | $wgOut->addHTML( wfMsgExt( 'lqt-split-success', array( 'parseinline', 'replaceafter' ), |
52 | 47 | $link ) ); |
53 | | - |
| 48 | + |
54 | 49 | return true; |
55 | 50 | } |
56 | | - |
| 51 | + |
57 | 52 | function validateSubject( $target ) { |
58 | 53 | if ( !$target ) { |
59 | 54 | return wfMsgExt( 'lqt_split_nosubject', 'parseinline' ); |
60 | 55 | } |
61 | | - |
| 56 | + |
62 | 57 | $title = null; |
63 | 58 | $article = $this->mThread->article(); |
64 | | - |
| 59 | + |
65 | 60 | $ok = Thread::validateSubject( $target, $title, null, $article ); |
66 | | - |
| 61 | + |
67 | 62 | if ( !$ok ) { |
68 | 63 | return wfMsgExt( 'lqt_split_badsubject', 'parseinline' ); |
69 | 64 | } |
70 | | - |
| 65 | + |
71 | 66 | return true; |
72 | 67 | } |
73 | | - |
| 68 | + |
74 | 69 | function getPageName() { |
75 | 70 | return 'SplitThread'; |
76 | 71 | } |
77 | | - |
| 72 | + |
78 | 73 | function getSubmitText() { |
79 | 74 | wfLoadExtensionMessages( 'LiquidThreads' ); |
80 | 75 | return wfMsg( 'lqt-split-submit' ); |
Index: trunk/extensions/LiquidThreads/pages/SummaryPageView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class SummaryPageView extends LqtView { |
— | — | @@ -8,12 +7,16 @@ |
9 | 8 | $thread = Threads::withSummary( $this->article ); |
10 | 9 | if ( $thread && $thread->root() ) { |
11 | 10 | global $wgUser; |
12 | | - |
| 11 | + |
13 | 12 | $t = $thread->root()->getTitle(); |
14 | 13 | $link = $wgUser->getSkin()->link( $t ); |
15 | 14 | $this->output->setSubtitle( |
16 | | - wfMsgExt( 'lqt_summary_subtitle', array( 'parseinline', 'replaceafter' ), |
17 | | - $link ) ); |
| 15 | + wfMsgExt( |
| 16 | + 'lqt_summary_subtitle', |
| 17 | + array( 'parseinline', 'replaceafter' ), |
| 18 | + $link |
| 19 | + ) |
| 20 | + ); |
18 | 21 | } |
19 | 22 | return true; |
20 | 23 | } |
Index: trunk/extensions/LiquidThreads/pages/SpecialMergeThread.php |
— | — | @@ -2,73 +2,68 @@ |
3 | 3 | |
4 | 4 | // TODO access control |
5 | 5 | class SpecialMergeThread extends ThreadActionPage { |
6 | | - |
7 | 6 | function getFormFields() { |
8 | 7 | $splitForm = array( |
9 | | - 'src' => |
10 | | - array( |
11 | | - 'type' => 'info', |
12 | | - 'label-message' => 'lqt-thread-merge-source', |
13 | | - 'default' => $this->formatThreadField( 'src', $this->mThread->id() ), |
14 | | - 'raw' => 1, |
15 | | - ), |
16 | | - 'dest' => |
17 | | - array( |
18 | | - 'type' => 'info', |
19 | | - 'label-message' => 'lqt-thread-merge-dest', |
20 | | - 'default' => |
21 | | - $this->formatThreadField( 'dest', $this->request->getVal( 'dest' ) ), |
22 | | - 'raw' => 1, |
23 | | - ), |
24 | | - 'reason' => |
25 | | - array( |
26 | | - 'label-message' => 'movereason', |
27 | | - 'type' => 'text', |
28 | | - ), |
| 8 | + 'src' => array( |
| 9 | + 'type' => 'info', |
| 10 | + 'label-message' => 'lqt-thread-merge-source', |
| 11 | + 'default' => $this->formatThreadField( 'src', $this->mThread->id() ), |
| 12 | + 'raw' => 1 |
| 13 | + ), |
| 14 | + 'dest' => array( |
| 15 | + 'type' => 'info', |
| 16 | + 'label-message' => 'lqt-thread-merge-dest', |
| 17 | + 'default' => $this->formatThreadField( 'dest', $this->request->getVal( 'dest' ) ), |
| 18 | + 'raw' => 1 |
| 19 | + ), |
| 20 | + 'reason' => array( |
| 21 | + 'label-message' => 'movereason', |
| 22 | + 'type' => 'text' |
| 23 | + ) |
29 | 24 | ); |
30 | | - |
| 25 | + |
31 | 26 | return $splitForm; |
32 | 27 | } |
33 | | - |
| 28 | + |
34 | 29 | protected function getRightRequirement() { return 'lqt-merge'; } |
35 | | - |
| 30 | + |
36 | 31 | public function checkParameters( $par ) { |
37 | 32 | global $wgOut; |
38 | 33 | if ( !parent::checkParameters( $par ) ) { |
39 | 34 | return false; |
40 | 35 | } |
41 | | - |
| 36 | + |
42 | 37 | $dest = $this->request->getVal( 'dest' ); |
43 | | - |
| 38 | + |
44 | 39 | if ( !$dest ) { |
45 | 40 | $wgOut->addWikiMsg( 'lqt_threadrequired' ); |
46 | 41 | return false; |
47 | 42 | } |
48 | | - |
| 43 | + |
49 | 44 | $thread = Threads::withId( $dest ); |
50 | | - |
| 45 | + |
51 | 46 | if ( !$thread ) { |
52 | 47 | $wgOut->addWikiMsg( 'lqt_nosuchthread' ); |
53 | 48 | return false; |
54 | 49 | } |
55 | | - |
| 50 | + |
56 | 51 | $this->mDestThread = $thread; |
57 | | - |
| 52 | + |
58 | 53 | return true; |
59 | 54 | } |
60 | 55 | |
61 | 56 | function formatThreadField( $field, $threadid ) { |
62 | | - |
| 57 | + |
63 | 58 | if ( !is_object( $threadid ) ) { |
64 | 59 | $t = Threads::withId( $threadid ); |
65 | 60 | } else { |
66 | 61 | $t = $threadid; |
67 | 62 | $threadid = $t->id(); |
68 | 63 | } |
69 | | - |
| 64 | + |
70 | 65 | $out = Xml::hidden( $field, $threadid ); |
71 | 66 | $out .= LqtView::permalink( $t ); |
72 | | - |
| 67 | + |
73 | 68 | return $out; |
74 | 69 | } |
75 | 70 | |
— | — | @@ -79,29 +74,29 @@ |
80 | 75 | wfLoadExtensionMessages( 'LiquidThreads' ); |
81 | 76 | return wfMsg( 'lqt_merge_thread' ); |
82 | 77 | } |
83 | | - |
| 78 | + |
84 | 79 | function trySubmit( $data ) { |
85 | 80 | // Load data |
86 | 81 | $srcThread = $this->mThread; |
87 | 82 | $dstThread = $this->mDestThread; |
88 | 83 | $reason = $data['reason']; |
89 | | - |
| 84 | + |
90 | 85 | $srcThread->moveToParent( $dstThread, $reason ); |
91 | | - |
| 86 | + |
92 | 87 | $srcLink = LqtView::linkInContext( $srcThread ); |
93 | 88 | $dstLink = LqtView::linkInContext( $dstThread ); |
94 | | - |
| 89 | + |
95 | 90 | global $wgOut; |
96 | 91 | $wgOut->addHTML( wfMsgExt( 'lqt-merge-success', array( 'parseinline', 'replaceafter' ), |
97 | 92 | $srcLink, $dstLink ) ); |
98 | | - |
| 93 | + |
99 | 94 | return true; |
100 | 95 | } |
101 | | - |
| 96 | + |
102 | 97 | function getPageName() { |
103 | 98 | return 'MergeThread'; |
104 | 99 | } |
105 | | - |
| 100 | + |
106 | 101 | function getSubmitText() { |
107 | 102 | wfLoadExtensionMessages( 'LiquidThreads' ); |
108 | 103 | return wfMsg( 'lqt-merge-submit' ); |
Index: trunk/extensions/LiquidThreads/pages/ThreadWatchView.php |
— | — | @@ -1,5 +1,4 @@ |
2 | 2 | <?php |
3 | | - |
4 | 3 | if ( !defined( 'MEDIAWIKI' ) ) die; |
5 | 4 | |
6 | 5 | class ThreadWatchView extends ThreadPermalinkView { |