r86009 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r86008‎ | r86009 | r86010 >
Date:23:36, 13 April 2011
Author:happy-melon
Status:ok
Tags:
Comment:
Revert r86001: Brion says it's too scary :D will recommit in pieces
Modified paths:
  • /trunk/extensions/LiquidThreads/LiquidThreads.php (modified) (history)
  • /trunk/extensions/LiquidThreads/classes/DeletionController.php (modified) (history)
  • /trunk/extensions/LiquidThreads/classes/Thread.php (modified) (history)
  • /trunk/extensions/MetavidWiki/includes/articlepages/MV_DataPage.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/LiquidThreads/LiquidThreads.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/LiquidThreads/classes/DeletionController.php (modified) (history)
  • /trunk/extensions/MultilingualLiquidThreads/LiquidThreads/classes/Thread.php (modified) (history)
  • /trunk/extensions/PureWikiDeletion/PureWikiDeletion.hooks.php (modified) (history)
  • /trunk/extensions/PureWikiDeletion/PureWikiDeletion.php (modified) (history)
  • /trunk/extensions/ReplaceText/ReplaceTextJob.php (modified) (history)
  • /trunk/phase3/docs/hooks.txt (modified) (history)
  • /trunk/phase3/includes/Action.php (deleted) (history)
  • /trunk/phase3/includes/Article.php (modified) (history)
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/Credits.php (added) (history)
  • /trunk/phase3/includes/DefaultSettings.php (modified) (history)
  • /trunk/phase3/includes/EditPage.php (modified) (history)
  • /trunk/phase3/includes/FileDeleteForm.php (modified) (history)
  • /trunk/phase3/includes/ProtectionForm.php (modified) (history)
  • /trunk/phase3/includes/Setup.php (modified) (history)
  • /trunk/phase3/includes/Wiki.php (modified) (history)
  • /trunk/phase3/includes/actions (deleted) (history)
  • /trunk/phase3/includes/api/ApiBase.php (modified) (history)
  • /trunk/phase3/includes/api/ApiDelete.php (modified) (history)
  • /trunk/phase3/includes/api/ApiWatch.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialMovepage.php (modified) (history)
  • /trunk/phase3/languages/messages/MessagesEn.php (modified) (history)

Diff [purge]

Index: trunk/phase3/docs/hooks.txt
@@ -264,17 +264,6 @@
265265 $user: the User object about to be created (read-only, incomplete)
266266 $message: out parameter: error message to display on abort
267267
268 -'ActionBeforeFormDisplay': Modify the form shown for an action (added 1.18)
269 -$action: String
270 -$form: HTMLForm
271 -$page: Article
272 -
273 -'ActionModifyFormFields': Modify the descriptor array which will be used to create an
274 -action form
275 -$action: String
276 -$fields: Array
277 -$page: Article
278 -
279268 'AddNewAccount': after a user account is created
280269 $user: the User object that was created. (Parameter added in 1.7)
281270 $byEmail: true when account was created "by email" (added in 1.12)
@@ -395,6 +384,12 @@
396385 $article: the article (object) being loaded from the database
397386 $content: the content (string) of the article
398387
 388+'ArticleConfirmDelete': before writing the confirmation form for article
 389+ deletion
 390+$article: the article (object) being deleted
 391+$output: the OutputPage object ($wgOut)
 392+&$reason: the reason (string) the article is being deleted
 393+
399394 'ArticleContentOnDiff': before showing the article content below a diff.
400395 Use this to change the content in this area or how it is loaded.
401396 $diffEngine: the DifferenceEngine
Index: trunk/phase3/includes/Action.php
@@ -1,440 +0,0 @@
2 -<?php
3 -/**
4 - * Actions are things which can be done to pages (edit, delete, rollback, etc). They
5 - * are distinct from Special Pages because an action must apply to exactly one page.
6 - *
7 - * To add an action in an extension, create a subclass of Action, and add the key to
8 - * $wgActions. There is also the deprecated UnknownAction hook
9 - *
10 - *
11 - * This program is free software; you can redistribute it and/or modify
12 - * it under the terms of the GNU General Public License as published by
13 - * the Free Software Foundation; either version 2 of the License, or
14 - * (at your option) any later version.
15 - *
16 - * This program is distributed in the hope that it will be useful,
17 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 - * GNU General Public License for more details.
20 - *
21 - * You should have received a copy of the GNU General Public License
22 - * along with this program; if not, write to the Free Software
23 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 - *
25 - * @file
26 - */
27 -abstract class Action {
28 -
29 - // Page on which we're performing the action
30 - // @var Article
31 - protected $page;
32 -
33 - // RequestContext if specified; otherwise we'll use the Context from the Page
34 - // @var RequestContext
35 - protected $context;
36 -
37 - // The fields used to create the HTMLForm
38 - // @var Array
39 - protected $fields;
40 -
41 - /**
42 - * Get the Action subclass which should be used to handle this action, false if
43 - * the action is disabled, or null if it's not recognised
44 - * @param $action String
45 - * @return bool|null|string
46 - */
47 - private final static function getClass( $action ){
48 - global $wgActions;
49 - $action = strtolower( $action );
50 -
51 - if( !isset( $wgActions[$action] ) ){
52 - return null;
53 - }
54 -
55 - if( $wgActions[$action] === false ){
56 - return false;
57 - }
58 -
59 - elseif( $wgActions[$action] === true ){
60 - return ucfirst( $action ) . 'Action';
61 - }
62 -
63 - else {
64 - return $wgActions[$action];
65 - }
66 - }
67 -
68 - /**
69 - * Get an appropriate Action subclass for the given action
70 - * @param $action String
71 - * @param $page Article
72 - * @return Action|false|null false if the action is disabled, null
73 - * if it is not recognised
74 - */
75 - public final static function factory( $action, Article $page ){
76 - $class = self::getClass( $action );
77 - if( $class ){
78 - $obj = new $class( $page );
79 - return $obj;
80 - }
81 - return null;
82 - }
83 -
84 - /**
85 - * Check if a given action is recognised, even if it's disabled
86 - *
87 - * @param $name String: name of an action
88 - * @return Bool
89 - */
90 - public final static function exists( $name ) {
91 - return self::getClass( $name ) !== null;
92 - }
93 -
94 - /**
95 - * Get the RequestContext in use here
96 - * @return RequestContext
97 - */
98 - protected final function getContext(){
99 - if( $this->context instanceof RequestContext ){
100 - return $this->context;
101 - }
102 - return $this->page->getContext();
103 - }
104 -
105 - /**
106 - * Get the WebRequest being used for this instance
107 - *
108 - * @return WebRequest
109 - */
110 - protected final function getRequest() {
111 - return $this->getContext()->request;
112 - }
113 -
114 - /**
115 - * Get the OutputPage being used for this instance
116 - *
117 - * @return OutputPage
118 - */
119 - protected final function getOutput() {
120 - return $this->getContext()->output;
121 - }
122 -
123 - /**
124 - * Shortcut to get the skin being used for this instance
125 - *
126 - * @return User
127 - */
128 - protected final function getUser() {
129 - return $this->getContext()->user;
130 - }
131 -
132 - /**
133 - * Shortcut to get the skin being used for this instance
134 - *
135 - * @return Skin
136 - */
137 - protected final function getSkin() {
138 - return $this->getContext()->skin;
139 - }
140 -
141 - /**
142 - * Shortcut to get the Title object from the page
143 - * @return Title
144 - */
145 - protected final function getTitle(){
146 - return $this->page->getTitle();
147 - }
148 -
149 - /**
150 - * Protected constructor: use Action::factory( $action, $page ) to actually build
151 - * these things in the real world
152 - * @param Article $page
153 - */
154 - protected function __construct( Article $page ){
155 - $this->page = $page;
156 - }
157 -
158 - /**
159 - * Return the name of the action this object responds to
160 - * @return String lowercase
161 - */
162 - public abstract function getName();
163 -
164 - /**
165 - * Get the permission required to perform this action. Often, but not always,
166 - * the same as the action name
167 - */
168 - public abstract function getRestriction();
169 -
170 - /**
171 - * Checks if the given user (identified by an object) can perform this action. Can be
172 - * overridden by sub-classes with more complicated permissions schemes. Failures here
173 - * must throw subclasses of ErrorPageError
174 - *
175 - * @param $user User: the user to check, or null to use the context user
176 - * @throws ErrorPageError
177 - */
178 - protected function checkCanExecute( User $user ) {
179 - if( $this->requiresWrite() && wfReadOnly() ){
180 - throw new ReadOnlyError();
181 - }
182 -
183 - if( $this->getRestriction() !== null && !$user->isAllowed( $this->getRestriction() ) ){
184 - throw new PermissionsError( $this->getRestriction() );
185 - }
186 -
187 - if( $this->requiresUnblock() && $user->isBlocked() ){
188 - $block = $user->mBlock;
189 - throw new UserBlockedError( $block );
190 - }
191 - }
192 -
193 - /**
194 - * Whether this action requires the wiki not to be locked
195 - * @return Bool
196 - */
197 - public function requiresWrite(){
198 - return true;
199 - }
200 -
201 - /**
202 - * Whether this action can still be executed by a blocked user
203 - * @return Bool
204 - */
205 - public function requiresUnblock(){
206 - return true;
207 - }
208 -
209 - /**
210 - * Set output headers for noindexing etc. This function will not be called through
211 - * the execute() entry point, so only put UI-related stuff in here.
212 - */
213 - protected function setHeaders() {
214 - $out = $this->getOutput();
215 - $out->setRobotPolicy( "noindex,nofollow" );
216 - $out->setPageTitle( $this->getTitle()->getPrefixedText() );
217 - $this->getOutput()->setSubtitle( $this->getDescription() );
218 - $out->setArticleRelated( true );
219 - }
220 -
221 - /**
222 - * Returns the name that goes in the \<h1\> page title
223 - *
224 - * Derived classes can override this, but usually it is easier to keep the
225 - * default behaviour. Messages can be added at run-time, see
226 - * MessageCache.php.
227 - *
228 - * @return String
229 - */
230 - protected function getDescription() {
231 - return wfMsg( strtolower( $this->getName() ) );
232 - }
233 -
234 - /**
235 - * The basic pattern for actions is to display some sort of HTMLForm UI, maybe with
236 - * some stuff underneath (history etc); to do some processing on submission of that
237 - * form (delete, protect, etc) and to do something exciting on 'success', be that
238 - * display something new or redirect to somewhere. Some actions have more exotic
239 - * behaviour, but that's what subclassing is for :D
240 - */
241 - public function show(){
242 - $this->setHeaders();
243 -
244 - // This will throw exceptions if there's a problem
245 - $this->checkCanExecute( $this->getUser() );
246 -
247 - $form = $this->getForm();
248 - if( $form instanceof HTMLForm ){
249 - if( $form->show() ){
250 - $this->onSuccess();
251 - }
252 - } else {
253 - // You're using the wrong type of Action
254 - throw new MWException( "Action::getFormFields() must produce a form. Use GetAction if you don't want one." );
255 - }
256 - }
257 -
258 - /**
259 - * Execute the action in a silent fashion: do not display anything or release any errors.
260 - * @param $data Array values that would normally be in the POST request
261 - * @param $captureErrors Bool whether to catch exceptions and just return false
262 - * @return Bool whether execution was successful
263 - */
264 - public function execute( array $data = null, $captureErrors = true ){
265 - try {
266 - // Set a new context so output doesn't leak.
267 - $this->context = clone $this->page->getContext();
268 -
269 - // This will throw exceptions if there's a problem
270 - $this->checkCanExecute( $this->getUser() );
271 -
272 - $form = $this->getForm();
273 - if( $form instanceof HTMLForm ){
274 - // Great, so there's a form. Ignore it and go straight to the submission callback
275 - $fields = array();
276 - foreach( $this->fields as $key => $params ){
277 - if( isset( $data[$key] ) ){
278 - $fields[$key] = $data[$key];
279 - } elseif( isset( $params['default'] ) ) {
280 - $fields[$key] = $params['default'];
281 - } else {
282 - $fields[$key] = null;
283 - }
284 - }
285 - $status = $this->onSubmit( $fields );
286 - if( $status === true ){
287 - // This might do permanent stuff
288 - $this->onSuccess();
289 - return true;
290 - } else {
291 - return false;
292 - }
293 - } else {
294 - // You're using the wrong type of Action
295 - throw new MWException( "Action::getFormFields() must produce a form. Use GetAction if you don't want one." );
296 - }
297 - }
298 - catch ( ErrorPageError $e ){
299 - if( $captureErrors ){
300 - return false;
301 - } else {
302 - throw $e;
303 - }
304 - }
305 - }
306 -
307 - /**
308 - * Get an HTMLForm descriptor array, or false if you don't want a form
309 - * @return Array
310 - */
311 - protected abstract function getFormFields();
312 -
313 - /**
314 - * Add pre- or post-text to the form
315 - * @return String
316 - */
317 - protected function preText(){ return ''; }
318 - protected function postText(){ return ''; }
319 -
320 - /**
321 - * Play with the HTMLForm if you need to more substantially
322 - * @param &$form HTMLForm
323 - */
324 - protected function alterForm( HTMLForm &$form ){}
325 -
326 - /**
327 - * Get the HTMLForm to control behaviour
328 - * @return HTMLForm|null
329 - */
330 - protected function getForm(){
331 - $this->fields = $this->getFormFields();
332 -
333 - // Give hooks a chance to alter the form, adding extra fields or text etc
334 - wfRunHooks( 'ActionModifyFormFields', array( $this->getName(), &$this->fields, $this->page ) );
335 -
336 - if( $this->fields === false ){
337 - return null;
338 - }
339 -
340 - $form = new HTMLForm( $this->fields, $this->getContext() );
341 - $form->setSubmitCallback( array( $this, 'onSubmit' ) );
342 - $form->addHiddenField( 'action', $this->getName() );
343 -
344 - $form->addPreText( $this->preText() );
345 - $form->addPostText( $this->postText() );
346 - $this->alterForm( $form );
347 -
348 - // Give hooks a chance to alter the form, adding extra fields or text etc
349 - wfRunHooks( 'ActionBeforeFormDisplay', array( $this->getName(), &$form, $this->page ) );
350 -
351 - return $form;
352 - }
353 -
354 - /**
355 - * Process the form on POST submission. If you return false from getFormFields(),
356 - * this will obviously never be reached. If you don't want to do anything with the
357 - * form, just return false here
358 - * @param $data Array
359 - * @return Bool|Array true for success, false for didn't-try, array of errors on failure
360 - */
361 - public abstract function onSubmit( $data );
362 -
363 - /**
364 - * Do something exciting on successful processing of the form. This might be to show
365 - * a confirmation message (watch, rollback, etc) or to redirect somewhere else (edit,
366 - * protect, etc).
367 - */
368 - public abstract function onSuccess();
369 -
370 -}
371 -
372 -/**
373 - * Actions generally fall into two groups: the show-a-form-then-do-something-with-the-input
374 - * format (protect, delete, move, etc), and the just-do-something format (watch, rollback,
375 - * patrol, etc).
376 - */
377 -abstract class FormlessAction extends Action {
378 -
379 - /**
380 - * Show something on GET request. This is displayed as the postText() of the HTMLForm
381 - * if there is one; you can always use alterForm() to add pre text if you need it. If
382 - * you call addPostText() from alterForm() as well as overriding this function, you
383 - * might get strange ordering.
384 - * @return String|null will be added to the HTMLForm if present, or just added to the
385 - * output if not. Return null to not add anything
386 - */
387 - public abstract function onView();
388 -
389 - /**
390 - * We don't want an HTMLForm
391 - */
392 - protected function getFormFields(){
393 - return false;
394 - }
395 -
396 - public function onSubmit( $data ){
397 - return false;
398 - }
399 -
400 - public function onSuccess(){
401 - return false;
402 - }
403 -
404 - public function show(){
405 - $this->setHeaders();
406 -
407 - // This will throw exceptions if there's a problem
408 - $this->checkCanExecute( $this->getUser() );
409 - $this->getOutput()->addHTML( $this->onView() );
410 - }
411 -
412 - /**
413 - * Execute the action silently, not giving any output. Since these actions don't have
414 - * forms, they probably won't have any data, but some (eg rollback) may do
415 - * @param $data Array values that would normally be in the GET request
416 - * @param $captureErrors Bool whether to catch exceptions and just return false
417 - * @return Bool whether execution was successful
418 - */
419 - public function execute( array $data = null, $captureErrors = true){
420 - try {
421 - // Set a new context so output doesn't leak.
422 - $this->context = clone $this->page->getContext();
423 - if( is_array( $data ) ){
424 - $this->context->setRequest( new FauxRequest( $data, false ) );
425 - }
426 -
427 - // This will throw exceptions if there's a problem
428 - $this->checkCanExecute( $this->getUser() );
429 -
430 - $this->onView();
431 - return true;
432 - }
433 - catch ( ErrorPageError $e ){
434 - if( $captureErrors ){
435 - return false;
436 - } else {
437 - throw $e;
438 - }
439 - }
440 - }
441 -}
\ No newline at end of file
Index: trunk/phase3/includes/ProtectionForm.php
@@ -317,9 +317,9 @@
318318 }
319319
320320 if( $wgRequest->getCheck( 'mwProtectWatch' ) && $wgUser->isLoggedIn() ) {
321 - Action::factory( 'watch', $this->mArticle )->execute();
 321+ $this->mArticle->doWatch();
322322 } elseif( $this->mTitle->userIsWatching() ) {
323 - Action::factory( 'unwatch', $this->mArticle )->execute();
 323+ $this->mArticle->doUnwatch();
324324 }
325325 return $ok;
326326 }
Index: trunk/phase3/includes/Article.php
@@ -2345,10 +2345,27 @@
23462346
23472347 /**
23482348 * User-interface handler for the "watch" action
2349 - * @deprecated since 1.18
23502349 */
23512350 public function watch() {
2352 - Action::factory( 'watch', $this )->show();
 2351+ global $wgOut;
 2352+
 2353+ if ( $wgOut->getUser()->isAnon() ) {
 2354+ $wgOut->showErrorPage( 'watchnologin', 'watchnologintext' );
 2355+ return;
 2356+ }
 2357+
 2358+ if ( wfReadOnly() ) {
 2359+ $wgOut->readOnlyPage();
 2360+ return;
 2361+ }
 2362+
 2363+ if ( $this->doWatch() ) {
 2364+ $wgOut->setPagetitle( wfMsg( 'addedwatch' ) );
 2365+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 2366+ $wgOut->addWikiMsg( 'addedwatchtext', $this->mTitle->getPrefixedText() );
 2367+ }
 2368+
 2369+ $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() );
23532370 }
23542371
23552372 /**
@@ -2357,27 +2374,64 @@
23582375 * This is safe to be called multiple times
23592376 *
23602377 * @return bool true on successful watch operation
2361 - * @deprecated since 1.18
23622378 */
23632379 public function doWatch() {
2364 - return Action::factory( 'watch', $this )->execute();
 2380+ global $wgUser;
 2381+
 2382+ if ( $wgUser->isAnon() ) {
 2383+ return false;
 2384+ }
 2385+
 2386+ if ( wfRunHooks( 'WatchArticle', array( &$wgUser, &$this ) ) ) {
 2387+ $wgUser->addWatch( $this->mTitle );
 2388+ return wfRunHooks( 'WatchArticleComplete', array( &$wgUser, &$this ) );
 2389+ }
 2390+
 2391+ return false;
23652392 }
23662393
23672394 /**
23682395 * User interface handler for the "unwatch" action.
2369 - * @deprecated since 1.18
23702396 */
23712397 public function unwatch() {
2372 - Action::factory( 'unwatch', $this )->show();
 2398+ global $wgOut;
 2399+
 2400+ if ( $wgOut->getUser()->isAnon() ) {
 2401+ $wgOut->showErrorPage( 'watchnologin', 'watchnologintext' );
 2402+ return;
 2403+ }
 2404+
 2405+ if ( wfReadOnly() ) {
 2406+ $wgOut->readOnlyPage();
 2407+ return;
 2408+ }
 2409+
 2410+ if ( $this->doUnwatch() ) {
 2411+ $wgOut->setPagetitle( wfMsg( 'removedwatch' ) );
 2412+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 2413+ $wgOut->addWikiMsg( 'removedwatchtext', $this->mTitle->getPrefixedText() );
 2414+ }
 2415+
 2416+ $wgOut->returnToMain( true, $this->mTitle->getPrefixedText() );
23732417 }
23742418
23752419 /**
23762420 * Stop watching a page
23772421 * @return bool true on successful unwatch
2378 - * @deprecated since 1.18
23792422 */
23802423 public function doUnwatch() {
2381 - return Action::factory( 'unwatch', $this )->execute();
 2424+ global $wgUser;
 2425+
 2426+ if ( $wgUser->isAnon() ) {
 2427+ return false;
 2428+ }
 2429+
 2430+ if ( wfRunHooks( 'UnwatchArticle', array( &$wgUser, &$this ) ) ) {
 2431+ $wgUser->removeWatch( $this->mTitle );
 2432+ return wfRunHooks( 'UnwatchArticleComplete', array( &$wgUser, &$this ) );
 2433+ }
 2434+
 2435+ return false;
23822436 }
23832437
23842438 /**
@@ -2609,28 +2663,229 @@
26102664 * @param &$hasHistory Boolean: whether the page has a history
26112665 * @return mixed String containing deletion reason or empty string, or boolean false
26122666 * if no revision occurred
2613 - * @deprecated since 1.18
26142667 */
26152668 public function generateReason( &$hasHistory ) {
2616 - return DeleteAction::getAutoReason( $this );
 2669+ global $wgContLang;
 2670+
 2671+ $dbw = wfGetDB( DB_MASTER );
 2672+ // Get the last revision
 2673+ $rev = Revision::newFromTitle( $this->mTitle );
 2674+
 2675+ if ( is_null( $rev ) ) {
 2676+ return false;
 2677+ }
 2678+
 2679+ // Get the article's contents
 2680+ $contents = $rev->getText();
 2681+ $blank = false;
 2682+
 2683+ // If the page is blank, use the text from the previous revision,
 2684+ // which can only be blank if there's a move/import/protect dummy revision involved
 2685+ if ( $contents == '' ) {
 2686+ $prev = $rev->getPrevious();
 2687+
 2688+ if ( $prev ) {
 2689+ $contents = $prev->getText();
 2690+ $blank = true;
 2691+ }
 2692+ }
 2693+
 2694+ // Find out if there was only one contributor
 2695+ // Only scan the last 20 revisions
 2696+ $res = $dbw->select( 'revision', 'rev_user_text',
 2697+ array( 'rev_page' => $this->getID(), $dbw->bitAnd( 'rev_deleted', Revision::DELETED_USER ) . ' = 0' ),
 2698+ __METHOD__,
 2699+ array( 'LIMIT' => 20 )
 2700+ );
 2701+
 2702+ if ( $res === false ) {
 2703+ // This page has no revisions, which is very weird
 2704+ return false;
 2705+ }
 2706+
 2707+ $hasHistory = ( $res->numRows() > 1 );
 2708+ $row = $dbw->fetchObject( $res );
 2709+
 2710+ if ( $row ) { // $row is false if the only contributor is hidden
 2711+ $onlyAuthor = $row->rev_user_text;
 2712+ // Try to find a second contributor
 2713+ foreach ( $res as $row ) {
 2714+ if ( $row->rev_user_text != $onlyAuthor ) { // Bug 22999
 2715+ $onlyAuthor = false;
 2716+ break;
 2717+ }
 2718+ }
 2719+ } else {
 2720+ $onlyAuthor = false;
 2721+ }
 2722+
 2723+ // Generate the summary with a '$1' placeholder
 2724+ if ( $blank ) {
 2725+ // The current revision is blank and the one before is also
 2726+ // blank. It's just not our lucky day
 2727+ $reason = wfMsgForContent( 'exbeforeblank', '$1' );
 2728+ } else {
 2729+ if ( $onlyAuthor ) {
 2730+ $reason = wfMsgForContent( 'excontentauthor', '$1', $onlyAuthor );
 2731+ } else {
 2732+ $reason = wfMsgForContent( 'excontent', '$1' );
 2733+ }
 2734+ }
 2735+
 2736+ if ( $reason == '-' ) {
 2737+ // Allow these UI messages to be blanked out cleanly
 2738+ return '';
 2739+ }
 2740+
 2741+ // Replace newlines with spaces to prevent uglyness
 2742+ $contents = preg_replace( "/[\n\r]/", ' ', $contents );
 2743+ // Calculate the maximum amount of chars to get
 2744+ // Max content length = max comment length - length of the comment (excl. $1)
 2745+ $maxLength = 255 - ( strlen( $reason ) - 2 );
 2746+ $contents = $wgContLang->truncate( $contents, $maxLength );
 2747+ // Remove possible unfinished links
 2748+ $contents = preg_replace( '/\[\[([^\]]*)\]?$/', '$1', $contents );
 2749+ // Now replace the '$1' placeholder
 2750+ $reason = str_replace( '$1', $contents, $reason );
 2751+
 2752+ return $reason;
26172753 }
26182754
26192755
26202756 /*
26212757 * UI entry point for page deletion
2622 - * @deprecated since 1.18
26232758 */
26242759 public function delete() {
2625 - return Action::factory( 'delete', $this )->show();
 2760+ global $wgOut, $wgRequest;
 2761+
 2762+ $confirm = $wgRequest->wasPosted() &&
 2763+ $wgOut->getUser()->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );
 2764+
 2765+ $this->DeleteReasonList = $wgRequest->getText( 'wpDeleteReasonList', 'other' );
 2766+ $this->DeleteReason = $wgRequest->getText( 'wpReason' );
 2767+
 2768+ $reason = $this->DeleteReasonList;
 2769+
 2770+ if ( $reason != 'other' && $this->DeleteReason != '' ) {
 2771+ // Entry from drop down menu + additional comment
 2772+ $reason .= wfMsgForContent( 'colon-separator' ) . $this->DeleteReason;
 2773+ } elseif ( $reason == 'other' ) {
 2774+ $reason = $this->DeleteReason;
 2775+ }
 2776+
 2777+ # Flag to hide all contents of the archived revisions
 2778+ $suppress = $wgRequest->getVal( 'wpSuppress' ) && $wgOut->getUser()->isAllowed( 'suppressrevision' );
 2779+
 2780+ # This code desperately needs to be totally rewritten
 2781+
 2782+ # Read-only check...
 2783+ if ( wfReadOnly() ) {
 2784+ $wgOut->readOnlyPage();
 2785+
 2786+ return;
 2787+ }
 2788+
 2789+ # Check permissions
 2790+ $permission_errors = $this->mTitle->getUserPermissionsErrors( 'delete', $wgOut->getUser() );
 2791+
 2792+ if ( count( $permission_errors ) > 0 ) {
 2793+ $wgOut->showPermissionsErrorPage( $permission_errors );
 2794+
 2795+ return;
 2796+ }
 2797+
 2798+ $wgOut->setPagetitle( wfMsg( 'delete-confirm', $this->mTitle->getPrefixedText() ) );
 2799+
 2800+ # Better double-check that it hasn't been deleted yet!
 2801+ $dbw = wfGetDB( DB_MASTER );
 2802+ $conds = $this->mTitle->pageCond();
 2803+ $latest = $dbw->selectField( 'page', 'page_latest', $conds, __METHOD__ );
 2804+ if ( $latest === false ) {
 2805+ $wgOut->showFatalError(
 2806+ Html::rawElement(
 2807+ 'div',
 2808+ array( 'class' => 'error mw-error-cannotdelete' ),
 2809+ wfMsgExt( 'cannotdelete', array( 'parse' ), $this->mTitle->getPrefixedText() )
 2810+ )
 2811+ );
 2812+ $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
 2813+ LogEventsList::showLogExtract(
 2814+ $wgOut,
 2815+ 'delete',
 2816+ $this->mTitle->getPrefixedText()
 2817+ );
 2818+
 2819+ return;
 2820+ }
 2821+
 2822+ # Hack for big sites
 2823+ $bigHistory = $this->isBigDeletion();
 2824+ if ( $bigHistory && !$this->mTitle->userCan( 'bigdelete' ) ) {
 2825+ global $wgLang, $wgDeleteRevisionsLimit;
 2826+
 2827+ $wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
 2828+ array( 'delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
 2829+
 2830+ return;
 2831+ }
 2832+
 2833+ if ( $confirm ) {
 2834+ $this->doDelete( $reason, $suppress );
 2835+
 2836+ if ( $wgRequest->getCheck( 'wpWatch' ) && $wgOut->getUser()->isLoggedIn() ) {
 2837+ $this->doWatch();
 2838+ } elseif ( $this->mTitle->userIsWatching() ) {
 2839+ $this->doUnwatch();
 2840+ }
 2841+
 2842+ return;
 2843+ }
 2844+
 2845+ // Generate deletion reason
 2846+ $hasHistory = false;
 2847+ if ( !$reason ) {
 2848+ $reason = $this->generateReason( $hasHistory );
 2849+ }
 2850+
 2851+ // If the page has a history, insert a warning
 2852+ if ( $hasHistory && !$confirm ) {
 2853+ global $wgLang;
 2854+
 2855+ $skin = $wgOut->getSkin();
 2856+ $revisions = $this->estimateRevisionCount();
 2857+ //FIXME: lego
 2858+ $wgOut->addHTML( '<strong class="mw-delete-warning-revisions">' .
 2859+ wfMsgExt( 'historywarning', array( 'parseinline' ), $wgLang->formatNum( $revisions ) ) .
 2860+ wfMsgHtml( 'word-separator' ) . $skin->link( $this->mTitle,
 2861+ wfMsgHtml( 'history' ),
 2862+ array( 'rel' => 'archives' ),
 2863+ array( 'action' => 'history' ) ) .
 2864+ '</strong>'
 2865+ );
 2866+
 2867+ if ( $bigHistory ) {
 2868+ global $wgDeleteRevisionsLimit;
 2869+ $wgOut->wrapWikiMsg( "<div class='error'>\n$1\n</div>\n",
 2870+ array( 'delete-warning-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
 2871+ }
 2872+ }
 2873+
 2874+ return $this->confirmDelete( $reason );
26262875 }
26272876
26282877 /**
26292878 * @return bool whether or not the page surpasses $wgDeleteRevisionsLimit revisions
2630 - * @deprecated since 1.18
26312879 */
26322880 public function isBigDeletion() {
26332881 global $wgDeleteRevisionsLimit;
2634 - return $wgDeleteRevisionsLimit && $this->estimateRevisionCount() > $wgDeleteRevisionsLimit;
 2882+
 2883+ if ( $wgDeleteRevisionsLimit ) {
 2884+ $revCount = $this->estimateRevisionCount();
 2885+
 2886+ return $revCount > $wgDeleteRevisionsLimit;
 2887+ }
 2888+
 2889+ return false;
26352890 }
26362891
26372892 /**
@@ -2699,19 +2954,150 @@
27002955 }
27012956
27022957 /**
 2958+ * Output deletion confirmation dialog
 2959+ * FIXME: Move to another file?
 2960+ * @param $reason String: prefilled reason
 2961+ */
 2962+ public function confirmDelete( $reason ) {
 2963+ global $wgOut;
 2964+
 2965+ wfDebug( "Article::confirmDelete\n" );
 2966+
 2967+ $deleteBackLink = $wgOut->getSkin()->linkKnown( $this->mTitle );
 2968+ $wgOut->setSubtitle( wfMsgHtml( 'delete-backlink', $deleteBackLink ) );
 2969+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 2970+ $wgOut->addWikiMsg( 'confirmdeletetext' );
 2971+
 2972+ wfRunHooks( 'ArticleConfirmDelete', array( $this, $wgOut, &$reason ) );
 2973+
 2974+ if ( $wgOut->getUser()->isAllowed( 'suppressrevision' ) ) {
 2975+ $suppress = "<tr id=\"wpDeleteSuppressRow\">
 2976+ <td></td>
 2977+ <td class='mw-input'><strong>" .
 2978+ Xml::checkLabel( wfMsg( 'revdelete-suppress' ),
 2979+ 'wpSuppress', 'wpSuppress', false, array( 'tabindex' => '4' ) ) .
 2980+ "</strong></td>
 2981+ </tr>";
 2982+ } else {
 2983+ $suppress = '';
 2984+ }
 2985+ $checkWatch = $wgOut->getUser()->getBoolOption( 'watchdeletion' ) || $this->mTitle->userIsWatching();
 2986+
 2987+ $form = Xml::openElement( 'form', array( 'method' => 'post',
 2988+ 'action' => $this->mTitle->getLocalURL( 'action=delete' ), 'id' => 'deleteconfirm' ) ) .
 2989+ Xml::openElement( 'fieldset', array( 'id' => 'mw-delete-table' ) ) .
 2990+ Xml::tags( 'legend', null, wfMsgExt( 'delete-legend', array( 'parsemag', 'escapenoentities' ) ) ) .
 2991+ Xml::openElement( 'table', array( 'id' => 'mw-deleteconfirm-table' ) ) .
 2992+ "<tr id=\"wpDeleteReasonListRow\">
 2993+ <td class='mw-label'>" .
 2994+ Xml::label( wfMsg( 'deletecomment' ), 'wpDeleteReasonList' ) .
 2995+ "</td>
 2996+ <td class='mw-input'>" .
 2997+ Xml::listDropDown( 'wpDeleteReasonList',
 2998+ wfMsgForContent( 'deletereason-dropdown' ),
 2999+ wfMsgForContent( 'deletereasonotherlist' ), '', 'wpReasonDropDown', 1 ) .
 3000+ "</td>
 3001+ </tr>
 3002+ <tr id=\"wpDeleteReasonRow\">
 3003+ <td class='mw-label'>" .
 3004+ Xml::label( wfMsg( 'deleteotherreason' ), 'wpReason' ) .
 3005+ "</td>
 3006+ <td class='mw-input'>" .
 3007+ Html::input( 'wpReason', $reason, 'text', array(
 3008+ 'size' => '60',
 3009+ 'maxlength' => '255',
 3010+ 'tabindex' => '2',
 3011+ 'id' => 'wpReason',
 3012+ 'autofocus'
 3013+ ) ) .
 3014+ "</td>
 3015+ </tr>";
 3016+
 3017+ # Disallow watching if user is not logged in
 3018+ if ( $wgOut->getUser()->isLoggedIn() ) {
 3019+ $form .= "
 3020+ <tr>
 3021+ <td></td>
 3022+ <td class='mw-input'>" .
 3023+ Xml::checkLabel( wfMsg( 'watchthis' ),
 3024+ 'wpWatch', 'wpWatch', $checkWatch, array( 'tabindex' => '3' ) ) .
 3025+ "</td>
 3026+ </tr>";
 3027+ }
 3028+
 3029+ $form .= "
 3030+ $suppress
 3031+ <tr>
 3032+ <td></td>
 3033+ <td class='mw-submit'>" .
 3034+ Xml::submitButton( wfMsg( 'deletepage' ),
 3035+ array( 'name' => 'wpConfirmB', 'id' => 'wpConfirmB', 'tabindex' => '5' ) ) .
 3036+ "</td>
 3037+ </tr>" .
 3038+ Xml::closeElement( 'table' ) .
 3039+ Xml::closeElement( 'fieldset' ) .
 3040+ Html::hidden( 'wpEditToken', $wgOut->getUser()->editToken() ) .
 3041+ Xml::closeElement( 'form' );
 3042+
 3043+ if ( $wgOut->getUser()->isAllowed( 'editinterface' ) ) {
 3044+ $skin = $wgOut->getSkin();
 3045+ $title = Title::makeTitle( NS_MEDIAWIKI, 'Deletereason-dropdown' );
 3046+ $link = $skin->link(
 3047+ $title,
 3048+ wfMsgHtml( 'delete-edit-reasonlist' ),
 3049+ array(),
 3050+ array( 'action' => 'edit' )
 3051+ );
 3052+ $form .= '<p class="mw-delete-editreasons">' . $link . '</p>';
 3053+ }
 3054+
 3055+ $wgOut->addHTML( $form );
 3056+ $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
 3057+ LogEventsList::showLogExtract( $wgOut, 'delete',
 3058+ $this->mTitle->getPrefixedText()
 3059+ );
 3060+ }
 3061+
 3062+ /**
27033063 * Perform a deletion and output success or failure messages
2704 - * @deprecated since 1.18
27053064 */
27063065 public function doDelete( $reason, $suppress = false ) {
2707 - return DeleteAction::doDeleteArticle(
2708 - $this,
2709 - $this->getContext(),
2710 - array(
2711 - 'Suppress' => $suppress !== false,
2712 - 'Reason' => $reason,
2713 - ),
2714 - true
2715 - );
 3066+ global $wgOut;
 3067+
 3068+ $id = $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
 3069+
 3070+ $error = '';
 3071+ if ( $this->doDeleteArticle( $reason, $suppress, $id, $error ) ) {
 3072+ $deleted = $this->mTitle->getPrefixedText();
 3073+
 3074+ $wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
 3075+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 3076+
 3077+ $loglink = '[[Special:Log/delete|' . wfMsgNoTrans( 'deletionlog' ) . ']]';
 3078+
 3079+ $wgOut->addWikiMsg( 'deletedtext', $deleted, $loglink );
 3080+ $wgOut->returnToMain( false );
 3081+ } else {
 3082+ if ( $error == '' ) {
 3083+ $wgOut->showFatalError(
 3084+ Html::rawElement(
 3085+ 'div',
 3086+ array( 'class' => 'error mw-error-cannotdelete' ),
 3087+ wfMsgExt( 'cannotdelete', array( 'parse' ), $this->mTitle->getPrefixedText() )
 3088+ )
 3089+ );
 3090+
 3091+ $wgOut->addHTML( Xml::element( 'h2', null, LogPage::logName( 'delete' ) ) );
 3092+
 3093+ LogEventsList::showLogExtract(
 3094+ $wgOut,
 3095+ 'delete',
 3096+ $this->mTitle->getPrefixedText()
 3097+ );
 3098+ } else {
 3099+ $wgOut->showFatalError( $error );
 3100+ }
 3101+ }
27163102 }
27173103
27183104 /**
@@ -2727,19 +3113,143 @@
27283114 * @param $id int article ID
27293115 * @param $commit boolean defaults to true, triggers transaction end
27303116 * @return boolean true if successful
2731 - *
2732 - * @deprecated since 1.18
27333117 */
27343118 public function doDeleteArticle( $reason, $suppress = false, $id = 0, $commit = true, &$error = '' ) {
2735 - return DeleteAction::doDeleteArticle(
2736 - $this,
2737 - $this->getContext(),
 3119+ global $wgDeferredUpdateList, $wgUseTrackbacks;
 3120+ global $wgUser;
 3121+
 3122+ wfDebug( __METHOD__ . "\n" );
 3123+
 3124+ if ( ! wfRunHooks( 'ArticleDelete', array( &$this, &$wgUser, &$reason, &$error ) ) ) {
 3125+ return false;
 3126+ }
 3127+ $dbw = wfGetDB( DB_MASTER );
 3128+ $t = $this->mTitle->getDBkey();
 3129+ $id = $id ? $id : $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
 3130+
 3131+ if ( $t === '' || $id == 0 ) {
 3132+ return false;
 3133+ }
 3134+
 3135+ $u = new SiteStatsUpdate( 0, 1, - (int)$this->isCountable( $this->getRawText() ), -1 );
 3136+ array_push( $wgDeferredUpdateList, $u );
 3137+
 3138+ // Bitfields to further suppress the content
 3139+ if ( $suppress ) {
 3140+ $bitfield = 0;
 3141+ // This should be 15...
 3142+ $bitfield |= Revision::DELETED_TEXT;
 3143+ $bitfield |= Revision::DELETED_COMMENT;
 3144+ $bitfield |= Revision::DELETED_USER;
 3145+ $bitfield |= Revision::DELETED_RESTRICTED;
 3146+ } else {
 3147+ $bitfield = 'rev_deleted';
 3148+ }
 3149+
 3150+ $dbw->begin();
 3151+ // For now, shunt the revision data into the archive table.
 3152+ // Text is *not* removed from the text table; bulk storage
 3153+ // is left intact to avoid breaking block-compression or
 3154+ // immutable storage schemes.
 3155+ //
 3156+ // For backwards compatibility, note that some older archive
 3157+ // table entries will have ar_text and ar_flags fields still.
 3158+ //
 3159+ // In the future, we may keep revisions and mark them with
 3160+ // the rev_deleted field, which is reserved for this purpose.
 3161+ $dbw->insertSelect( 'archive', array( 'page', 'revision' ),
27383162 array(
2739 - 'Suppress' => $suppress !== false,
2740 - 'Reason' => $reason,
2741 - ),
2742 - $commit
 3163+ 'ar_namespace' => 'page_namespace',
 3164+ 'ar_title' => 'page_title',
 3165+ 'ar_comment' => 'rev_comment',
 3166+ 'ar_user' => 'rev_user',
 3167+ 'ar_user_text' => 'rev_user_text',
 3168+ 'ar_timestamp' => 'rev_timestamp',
 3169+ 'ar_minor_edit' => 'rev_minor_edit',
 3170+ 'ar_rev_id' => 'rev_id',
 3171+ 'ar_text_id' => 'rev_text_id',
 3172+ 'ar_text' => '\'\'', // Be explicit to appease
 3173+ 'ar_flags' => '\'\'', // MySQL's "strict mode"...
 3174+ 'ar_len' => 'rev_len',
 3175+ 'ar_page_id' => 'page_id',
 3176+ 'ar_deleted' => $bitfield
 3177+ ), array(
 3178+ 'page_id' => $id,
 3179+ 'page_id = rev_page'
 3180+ ), __METHOD__
27433181 );
 3182+
 3183+ # Delete restrictions for it
 3184+ $dbw->delete( 'page_restrictions', array ( 'pr_page' => $id ), __METHOD__ );
 3185+
 3186+ # Now that it's safely backed up, delete it
 3187+ $dbw->delete( 'page', array( 'page_id' => $id ), __METHOD__ );
 3188+ $ok = ( $dbw->affectedRows() > 0 ); // getArticleId() uses slave, could be laggy
 3189+
 3190+ if ( !$ok ) {
 3191+ $dbw->rollback();
 3192+ return false;
 3193+ }
 3194+
 3195+ # Fix category table counts
 3196+ $cats = array();
 3197+ $res = $dbw->select( 'categorylinks', 'cl_to', array( 'cl_from' => $id ), __METHOD__ );
 3198+
 3199+ foreach ( $res as $row ) {
 3200+ $cats [] = $row->cl_to;
 3201+ }
 3202+
 3203+ $this->updateCategoryCounts( array(), $cats );
 3204+
 3205+ # If using cascading deletes, we can skip some explicit deletes
 3206+ if ( !$dbw->cascadingDeletes() ) {
 3207+ $dbw->delete( 'revision', array( 'rev_page' => $id ), __METHOD__ );
 3208+
 3209+ if ( $wgUseTrackbacks )
 3210+ $dbw->delete( 'trackbacks', array( 'tb_page' => $id ), __METHOD__ );
 3211+
 3212+ # Delete outgoing links
 3213+ $dbw->delete( 'pagelinks', array( 'pl_from' => $id ) );
 3214+ $dbw->delete( 'imagelinks', array( 'il_from' => $id ) );
 3215+ $dbw->delete( 'categorylinks', array( 'cl_from' => $id ) );
 3216+ $dbw->delete( 'templatelinks', array( 'tl_from' => $id ) );
 3217+ $dbw->delete( 'externallinks', array( 'el_from' => $id ) );
 3218+ $dbw->delete( 'langlinks', array( 'll_from' => $id ) );
 3219+ $dbw->delete( 'redirect', array( 'rd_from' => $id ) );
 3220+ }
 3221+
 3222+ # If using cleanup triggers, we can skip some manual deletes
 3223+ if ( !$dbw->cleanupTriggers() ) {
 3224+ # Clean up recentchanges entries...
 3225+ $dbw->delete( 'recentchanges',
 3226+ array( 'rc_type != ' . RC_LOG,
 3227+ 'rc_namespace' => $this->mTitle->getNamespace(),
 3228+ 'rc_title' => $this->mTitle->getDBkey() ),
 3229+ __METHOD__ );
 3230+ $dbw->delete( 'recentchanges',
 3231+ array( 'rc_type != ' . RC_LOG, 'rc_cur_id' => $id ),
 3232+ __METHOD__ );
 3233+ }
 3234+
 3235+ # Clear caches
 3236+ Article::onArticleDelete( $this->mTitle );
 3237+
 3238+ # Clear the cached article id so the interface doesn't act like we exist
 3239+ $this->mTitle->resetArticleID( 0 );
 3240+
 3241+ # Log the deletion, if the page was suppressed, log it at Oversight instead
 3242+ $logtype = $suppress ? 'suppress' : 'delete';
 3243+ $log = new LogPage( $logtype );
 3244+
 3245+ # Make sure logging got through
 3246+ $log->addEntry( 'delete', $this->mTitle, $reason, array() );
 3247+
 3248+ if ( $commit ) {
 3249+ $dbw->commit();
 3250+ }
 3251+
 3252+ wfRunHooks( 'ArticleDeleteComplete', array( &$this, &$wgUser, $reason, $id ) );
 3253+ return true;
27443254 }
27453255
27463256 /**
Index: trunk/phase3/includes/Setup.php
@@ -270,14 +270,6 @@
271271 $wgHiddenPrefs[] = 'enotifminoredits';
272272 }
273273
274 -# $wgDisabledActions is deprecated as of 1.18
275 -foreach( $wgDisabledActions as $action ){
276 - $wgActions[$action] = false;
277 -}
278 -if( !$wgAllowPageInfo ){
279 - $wgActions['info'] = false;
280 -}
281 -
282274 if ( !$wgHtml5Version && $wgHtml5 && $wgAllowRdfaAttributes ) {
283275 # see http://www.w3.org/TR/rdfa-in-html/#document-conformance
284276 if ( $wgMimeType == 'application/xhtml+xml' ) {
Index: trunk/phase3/includes/EditPage.php
@@ -1153,9 +1153,9 @@
11541154 $dbw = wfGetDB( DB_MASTER );
11551155 $dbw->begin();
11561156 if ( $this->watchthis ) {
1157 - Action::factory( 'watch', $this->mArticle )->execute();
 1157+ $this->mArticle->doWatch();
11581158 } else {
1159 - Action::factory( 'watch', $this->mArticle )->execute();
 1159+ $this->mArticle->doUnwatch();
11601160 }
11611161 $dbw->commit();
11621162 }
Index: trunk/phase3/includes/api/ApiWatch.php
@@ -59,11 +59,11 @@
6060 if ( $params['unwatch'] ) {
6161 $res['unwatched'] = '';
6262 $res['message'] = wfMsgExt( 'removedwatchtext', array( 'parse' ), $title->getPrefixedText() );
63 - $success = Action::factory( 'unwatch', $article )->execute();
 63+ $success = $article->doUnwatch();
6464 } else {
6565 $res['watched'] = '';
6666 $res['message'] = wfMsgExt( 'addedwatchtext', array( 'parse' ), $title->getPrefixedText() );
67 - $success = Action::factory( 'watch', $article )->execute();
 67+ $success = $article->doWatch();
6868 }
6969 if ( !$success ) {
7070 $this->dieUsageMsg( array( 'hookaborted' ) );
Index: trunk/phase3/includes/api/ApiDelete.php
@@ -123,6 +123,11 @@
124124 * @return Title::getUserPermissionsErrors()-like array
125125 */
126126 public static function delete( &$article, $token, &$reason = null ) {
 127+ global $wgUser;
 128+ if ( $article->isBigDeletion() && !$wgUser->isAllowed( 'bigdelete' ) ) {
 129+ global $wgDeleteRevisionsLimit;
 130+ return array( array( 'delete-toobig', $wgDeleteRevisionsLimit ) );
 131+ }
127132 $title = $article->getTitle();
128133 $errors = self::getPermissionsError( $title, $token );
129134 if ( count( $errors ) ) {
@@ -131,29 +136,22 @@
132137
133138 // Auto-generate a summary, if necessary
134139 if ( is_null( $reason ) ) {
135 - $reason = DeleteAction::getAutoReason( $article );
 140+ // Need to pass a throwaway variable because generateReason expects
 141+ // a reference
 142+ $hasHistory = false;
 143+ $reason = $article->generateReason( $hasHistory );
136144 if ( $reason === false ) {
137145 return array( array( 'cannotdelete' ) );
138146 }
139147 }
140148
141 - $action = Action::factory( 'delete', $article );
142 - $data = array(
143 - 'Reason' => $reason,
144 - 'Suppress' => false, // The thought of people doing this through the API is scary...
145 - );
146 -
147 - try {
148 - $action->execute( $data, false );
 149+ $error = '';
 150+ // Luckily, Article.php provides a reusable delete function that does the hard work for us
 151+ if ( $article->doDeleteArticle( $reason, false, 0, true, $error ) ) {
 152+ return array();
 153+ } else {
 154+ return array( array( 'cannotdelete', $article->mTitle->getPrefixedText() ) );
149155 }
150 - catch ( ErrorPageError $e ){
151 - if( $e->msg == 'delete-toobig' ){
152 - global $wgDeleteRevisionsLimit;
153 - return array( array( 'delete-toobig', $wgDeleteRevisionsLimit ) );
154 - } else {
155 - array( array( 'cannotdelete', $article->mTitle->getPrefixedText() ) );
156 - }
157 - }
158156 }
159157
160158 /**
Index: trunk/phase3/includes/api/ApiBase.php
@@ -645,9 +645,9 @@
646646
647647 $articleObj = new Article( $titleObj );
648648 if ( $value ) {
649 - Action::factory( 'watch', $articleObj )->execute();
 649+ $articleObj->doWatch();
650650 } else {
651 - Action::factory( 'unwatch', $articleObj )->execute();
 651+ $articleObj->doUnwatch();
652652 }
653653 }
654654
Index: trunk/phase3/includes/AutoLoader.php
@@ -14,7 +14,6 @@
1515
1616 $wgAutoloadLocalClasses = array(
1717 # Includes
18 - 'Action' => 'includes/Action.php',
1918 'AjaxDispatcher' => 'includes/AjaxDispatcher.php',
2019 'AjaxResponse' => 'includes/AjaxResponse.php',
2120 'AlphabeticPager' => 'includes/Pager.php',
@@ -52,6 +51,7 @@
5352 'ConfEditorToken' => 'includes/ConfEditor.php',
5453 'ConstantDependency' => 'includes/CacheDependency.php',
5554 'CreativeCommonsRdf' => 'includes/Metadata.php',
 55+ 'Credits' => 'includes/Credits.php',
5656 'CSSJanus' => 'includes/libs/CSSJanus.php',
5757 'CSSMin' => 'includes/libs/CSSMin.php',
5858 'DependencyWrapper' => 'includes/CacheDependency.php',
@@ -274,12 +274,6 @@
275275 'ZhClient' => 'includes/ZhClient.php',
276276 'ZipDirectoryReader' => 'includes/ZipDirectoryReader.php',
277277
278 - # includes/actions
279 - 'CreditsAction' => 'includes/actions/CreditsAction.php',
280 - 'DeleteAction' => 'includes/actions/DeleteAction.php',
281 - 'UnwatchAction' => 'includes/actions/WatchAction.php',
282 - 'WatchAction' => 'includes/actions/WatchAction.php',
283 -
284278 # includes/api
285279 'ApiBase' => 'includes/api/ApiBase.php',
286280 'ApiBlock' => 'includes/api/ApiBlock.php',
Index: trunk/phase3/includes/Wiki.php
@@ -471,16 +471,9 @@
472472 return;
473473 }
474474
475 - $act = $this->getAction();
 475+ $action = $this->getAction();
476476
477 - $action = Action::factory( $this->getAction(), $article );
478 - if( $action instanceof Action ){
479 - $action->show();
480 - wfProfileOut( __METHOD__ );
481 - return;
482 - }
483 -
484 - switch( $act ) {
 477+ switch( $action ) {
485478 case 'view':
486479 $this->context->output->setSquidMaxage( $this->getVal( 'SquidMaxage' ) );
487480 $article->view();
@@ -491,6 +484,9 @@
492485 $raw->view();
493486 wfProfileOut( __METHOD__ . '-raw' );
494487 break;
 488+ case 'watch':
 489+ case 'unwatch':
 490+ case 'delete':
495491 case 'revert':
496492 case 'rollback':
497493 case 'protect':
@@ -500,7 +496,7 @@
501497 case 'render':
502498 case 'deletetrackback':
503499 case 'purge':
504 - $article->$act();
 500+ $article->$action();
505501 break;
506502 case 'print':
507503 $article->view();
@@ -521,6 +517,9 @@
522518 $rdf->show();
523519 }
524520 break;
 521+ case 'credits':
 522+ Credits::showPage( $article );
 523+ break;
525524 case 'submit':
526525 if ( session_id() == '' ) {
527526 // Send a cookie so anons get talk message notifications
@@ -533,7 +532,7 @@
534533 $external = $this->context->request->getVal( 'externaledit' );
535534 $section = $this->context->request->getVal( 'section' );
536535 $oldid = $this->context->request->getVal( 'oldid' );
537 - if ( !$this->getVal( 'UseExternalEditor' ) || $act == 'submit' || $internal ||
 536+ if ( !$this->getVal( 'UseExternalEditor' ) || $action == 'submit' || $internal ||
538537 $section || $oldid || ( !$this->context->user->getOption( 'externaleditor' ) && !$external ) ) {
539538 $editor = new EditPage( $article );
540539 $editor->submit();
@@ -562,7 +561,7 @@
563562 $special->execute( '' );
564563 break;
565564 default:
566 - if ( wfRunHooks( 'UnknownAction', array( $act, $article ) ) ) {
 565+ if ( wfRunHooks( 'UnknownAction', array( $action, $article ) ) ) {
567566 $this->context->output->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
568567 }
569568 }
Index: trunk/phase3/includes/FileDeleteForm.php
@@ -125,9 +125,9 @@
126126 if( $article->doDeleteArticle( $reason, $suppress, $id, false ) ) {
127127 global $wgRequest;
128128 if( $wgRequest->getCheck( 'wpWatch' ) && $wgUser->isLoggedIn() ) {
129 - Action::factory( 'watch', $article )->execute();
 129+ $article->doWatch();
130130 } elseif( $title->userIsWatching() ) {
131 - Action::factory( 'unwatch', $article )->execute();
 131+ $article->doUnwatch();
132132 }
133133 $status = $file->delete( $reason, $suppress );
134134 if( $status->ok ) {
Index: trunk/phase3/includes/DefaultSettings.php
@@ -27,10 +27,12 @@
2828 }
2929
3030 # Create a site configuration object. Not used for much in a default install
31 -if ( !defined( 'MW_COMPILED' ) ) {
32 - require_once( "$IP/includes/SiteConfiguration.php" );
 31+if ( !defined( 'MW_PHP4' ) ) {
 32+ if ( !defined( 'MW_COMPILED' ) ) {
 33+ require_once( "$IP/includes/SiteConfiguration.php" );
 34+ }
 35+ $wgConf = new SiteConfiguration;
3336 }
34 -$wgConf = new SiteConfiguration;
3537 /** @endcond */
3638
3739 /** MediaWiki version number */
@@ -5022,38 +5024,6 @@
50235025 /** @} */ # end special pages }
50245026
50255027 /*************************************************************************//**
5026 - * @name Actions
5027 - * @{
5028 - */
5029 -
5030 -/**
5031 - * Array of allowed values for the title=foo&action=<action> parameter. Syntax is:
5032 - * 'foo' => 'ClassName' Load the specified class which subclasses Action
5033 - * 'foo' => true Load the class FooAction which subclasses Action
5034 - * 'foo' => false The action is disabled; show an error message
5035 - * Unsetting core actions will probably cause things to complain loudly.
5036 - */
5037 -$wgActions = array(
5038 - 'credits' => true,
5039 - 'delete' => true,
5040 - 'unwatch' => true,
5041 - 'watch' => true,
5042 -);
5043 -
5044 -/**
5045 - * Array of disabled article actions, e.g. view, edit, dublincore, delete, etc.
5046 - * @deprecated since 1.18; just set $wgActions['action'] = false instead
5047 - */
5048 -$wgDisabledActions = array();
5049 -
5050 -/**
5051 - * Allow the "info" action, very inefficient at the moment
5052 - */
5053 -$wgAllowPageInfo = false;
5054 -
5055 -/** @} */ # end actions }
5056 -
5057 -/*************************************************************************//**
50585028 * @name Robot (search engine crawler) policy
50595029 * See also $wgNoFollowLinks.
50605030 * @{
@@ -5318,10 +5288,18 @@
53195289 * @{
53205290 */
53215291
 5292+/** Allow the "info" action, very inefficient at the moment */
 5293+$wgAllowPageInfo = false;
 5294+
53225295 /** Name of the external diff engine to use */
53235296 $wgExternalDiffEngine = false;
53245297
53255298 /**
 5299+ * Array of disabled article actions, e.g. view, edit, dublincore, delete, etc.
 5300+ */
 5301+$wgDisabledActions = array();
 5302+
 5303+/**
53265304 * Disable redirects to special pages and interwiki redirects, which use a 302
53275305 * and have no "redirected from" link. Note this is only for articles with #Redirect
53285306 * in them. URL's containing a local interwiki prefix (or a non-canonical special
Index: trunk/phase3/includes/specials/SpecialMovepage.php
@@ -359,11 +359,8 @@
360360 $article = new Article( $nt );
361361
362362 # Disallow deletions of big articles
363 - global $wgDeleteRevisionsLimit;
364 - if ( $wgDeleteRevisionsLimit
365 - && $this->estimateRevisionCount() > $wgDeleteRevisionsLimit
366 - && !$nt->userCan( 'bigdelete' ) )
367 - {
 363+ $bigHistory = $article->isBigDeletion();
 364+ if( $bigHistory && !$nt->userCan( 'bigdelete' ) ) {
368365 global $wgDeleteRevisionsLimit;
369366 $this->showForm( array('delete-toobig', $wgLang->formatNum( $wgDeleteRevisionsLimit ) ) );
370367 return;
@@ -376,10 +373,7 @@
377374 }
378375
379376 // This may output an error message and exit
380 - Action::factory( 'delete', $article )->execute(
381 - array( 'Reason' => wfMsgForContent( 'delete_and_move_reason' ) ),
382 - false // Do not capture exceptions
383 - );
 377+ $article->doDelete( wfMsgForContent( 'delete_and_move_reason' ) );
384378 }
385379
386380 # don't allow moving to pages with # in
Index: trunk/phase3/includes/Credits.php
@@ -0,0 +1,238 @@
 2+<?php
 3+/**
 4+ * Formats credits for articles
 5+ *
 6+ * Copyright 2004, Evan Prodromou <evan@wikitravel.org>.
 7+ *
 8+ * This program is free software; you can redistribute it and/or modify
 9+ * it under the terms of the GNU General Public License as published by
 10+ * the Free Software Foundation; either version 2 of the License, or
 11+ * (at your option) any later version.
 12+ *
 13+ * This program is distributed in the hope that it will be useful,
 14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 16+ * GNU General Public License for more details.
 17+ *
 18+ * You should have received a copy of the GNU General Public License
 19+ * along with this program; if not, write to the Free Software
 20+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 21+ *
 22+ * @file
 23+ * @author <evan@wikitravel.org>
 24+ */
 25+
 26+class Credits {
 27+ /**
 28+ * This is largely cadged from PageHistory::history
 29+ * @param $article Article object
 30+ */
 31+ public static function showPage( Article $article ) {
 32+ global $wgOut;
 33+
 34+ wfProfileIn( __METHOD__ );
 35+
 36+ $wgOut->setPageTitle( $article->mTitle->getPrefixedText() );
 37+ $wgOut->setSubtitle( wfMsg( 'creditspage' ) );
 38+ $wgOut->setArticleFlag( false );
 39+ $wgOut->setArticleRelated( true );
 40+ $wgOut->setRobotPolicy( 'noindex,nofollow' );
 41+
 42+ if ( $article->mTitle->getArticleID() == 0 ) {
 43+ $s = wfMsg( 'nocredits' );
 44+ } else {
 45+ $s = self::getCredits( $article, -1 );
 46+ }
 47+
 48+ $wgOut->addHTML( $s );
 49+
 50+ wfProfileOut( __METHOD__ );
 51+ }
 52+
 53+ /**
 54+ * Get a list of contributors of $article
 55+ * @param $article Article object
 56+ * @param $cnt Int: maximum list of contributors to show
 57+ * @param $showIfMax Bool: whether to contributors if there more than $cnt
 58+ * @return String: html
 59+ */
 60+ public static function getCredits( Article $article, $cnt, $showIfMax = true ) {
 61+ wfProfileIn( __METHOD__ );
 62+ $s = '';
 63+
 64+ if ( isset( $cnt ) && $cnt != 0 ) {
 65+ $s = self::getAuthor( $article );
 66+ if ( $cnt > 1 || $cnt < 0 ) {
 67+ $s .= ' ' . self::getContributors( $article, $cnt - 1, $showIfMax );
 68+ }
 69+ }
 70+
 71+ wfProfileOut( __METHOD__ );
 72+ return $s;
 73+ }
 74+
 75+ /**
 76+ * Get the last author with the last modification time
 77+ * @param $article Article object
 78+ */
 79+ protected static function getAuthor( Article $article ) {
 80+ global $wgLang;
 81+
 82+ $user = User::newFromId( $article->getUser() );
 83+
 84+ $timestamp = $article->getTimestamp();
 85+ if ( $timestamp ) {
 86+ $d = $wgLang->date( $article->getTimestamp(), true );
 87+ $t = $wgLang->time( $article->getTimestamp(), true );
 88+ } else {
 89+ $d = '';
 90+ $t = '';
 91+ }
 92+ return wfMsgExt( 'lastmodifiedatby', 'parsemag', $d, $t, self::userLink( $user ), $user->getName() );
 93+ }
 94+
 95+ /**
 96+ * Get a list of contributors of $article
 97+ * @param $article Article object
 98+ * @param $cnt Int: maximum list of contributors to show
 99+ * @param $showIfMax Bool: whether to contributors if there more than $cnt
 100+ * @return String: html
 101+ */
 102+ protected static function getContributors( Article $article, $cnt, $showIfMax ) {
 103+ global $wgLang, $wgHiddenPrefs;
 104+
 105+ $contributors = $article->getContributors();
 106+
 107+ $others_link = false;
 108+
 109+ # Hmm... too many to fit!
 110+ if ( $cnt > 0 && $contributors->count() > $cnt ) {
 111+ $others_link = self::othersLink( $article );
 112+ if ( !$showIfMax )
 113+ return wfMsgExt( 'othercontribs', 'parsemag', $others_link, $contributors->count() );
 114+ }
 115+
 116+ $real_names = array();
 117+ $user_names = array();
 118+ $anon_ips = array();
 119+
 120+ # Sift for real versus user names
 121+ foreach ( $contributors as $user ) {
 122+ $cnt--;
 123+ if ( $user->isLoggedIn() ) {
 124+ $link = self::link( $user );
 125+ if ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
 126+ $real_names[] = $link;
 127+ } else {
 128+ $user_names[] = $link;
 129+ }
 130+ } else {
 131+ $anon_ips[] = self::link( $user );
 132+ }
 133+
 134+ if ( $cnt == 0 ) {
 135+ break;
 136+ }
 137+ }
 138+
 139+ if ( count( $real_names ) ) {
 140+ $real = $wgLang->listToText( $real_names );
 141+ } else {
 142+ $real = false;
 143+ }
 144+
 145+ # "ThisSite user(s) A, B and C"
 146+ if ( count( $user_names ) ) {
 147+ $user = wfMsgExt(
 148+ 'siteusers',
 149+ 'parsemag',
 150+ $wgLang->listToText( $user_names ), count( $user_names )
 151+ );
 152+ } else {
 153+ $user = false;
 154+ }
 155+
 156+ if ( count( $anon_ips ) ) {
 157+ $anon = wfMsgExt(
 158+ 'anonusers',
 159+ 'parsemag',
 160+ $wgLang->listToText( $anon_ips ), count( $anon_ips )
 161+ );
 162+ } else {
 163+ $anon = false;
 164+ }
 165+
 166+ # This is the big list, all mooshed together. We sift for blank strings
 167+ $fulllist = array();
 168+ foreach ( array( $real, $user, $anon, $others_link ) as $s ) {
 169+ if ( $s ) {
 170+ array_push( $fulllist, $s );
 171+ }
 172+ }
 173+
 174+ # Make the list into text...
 175+ $creds = $wgLang->listToText( $fulllist );
 176+
 177+ # "Based on work by ..."
 178+ return strlen( $creds )
 179+ ? wfMsgExt( 'othercontribs', 'parsemag', $creds, count( $fulllist ) )
 180+ : '';
 181+ }
 182+
 183+ /**
 184+ * Get a link to $user's user page
 185+ * @param $user User object
 186+ * @return String: html
 187+ */
 188+ protected static function link( User $user ) {
 189+ global $wgUser, $wgHiddenPrefs;
 190+ if ( !in_array( 'realname', $wgHiddenPrefs ) && !$user->isAnon() ) {
 191+ $real = $user->getRealName();
 192+ } else {
 193+ $real = false;
 194+ }
 195+
 196+ $skin = $wgUser->getSkin();
 197+ $page = $user->isAnon() ?
 198+ SpecialPage::getTitleFor( 'Contributions', $user->getName() ) :
 199+ $user->getUserPage();
 200+
 201+ return $skin->link( $page, htmlspecialchars( $real ? $real : $user->getName() ) );
 202+ }
 203+
 204+ /**
 205+ * Get a link to $user's user page
 206+ * @param $user User object
 207+ * @return String: html
 208+ */
 209+ protected static function userLink( User $user ) {
 210+ $link = self::link( $user );
 211+ if ( $user->isAnon() ) {
 212+ return wfMsgExt( 'anonuser', array( 'parseinline', 'replaceafter' ), $link );
 213+ } else {
 214+ global $wgHiddenPrefs;
 215+ if ( !in_array( 'realname', $wgHiddenPrefs ) && $user->getRealName() ) {
 216+ return $link;
 217+ } else {
 218+ return wfMsgExt( 'siteuser', 'parsemag', $link, $user->getName() );
 219+ }
 220+ }
 221+ }
 222+
 223+ /**
 224+ * Get a link to action=credits of $article page
 225+ * @param $article Article object
 226+ * @return String: html
 227+ */
 228+ protected static function othersLink( Article $article ) {
 229+ global $wgUser;
 230+ $skin = $wgUser->getSkin();
 231+ return $skin->link(
 232+ $article->getTitle(),
 233+ wfMsgHtml( 'others' ),
 234+ array(),
 235+ array( 'action' => 'credits' ),
 236+ array( 'known' )
 237+ );
 238+ }
 239+}
Property changes on: trunk/phase3/includes/Credits.php
___________________________________________________________________
Added: svn:eol-style
1240 + native
Added: svn:keywords
2241 + Author Date Id Revision
Index: trunk/phase3/languages/messages/MessagesEn.php
@@ -998,9 +998,8 @@
999999 'unexpected' => 'Unexpected value: "$1"="$2".',
10001000 'formerror' => 'Error: could not submit form',
10011001 'badarticleerror' => 'This action cannot be performed on this page.',
1002 -'cannotdelete' => 'The page or file "$1" could not be deleted. It may have already been deleted by someone else. The deletion log is provided below for convenience.
1003 -
1004 -$2',
 1002+'cannotdelete' => 'The page or file "$1" could not be deleted.
 1003+It may have already been deleted by someone else.',
10051004 'badtitle' => 'Bad title',
10061005 'badtitletext' => 'The requested page title was invalid, empty, or an incorrectly linked inter-language or inter-wiki title.
10071006 It may contain one or more characters which cannot be used in titles.',
@@ -2784,7 +2783,7 @@
27852784 'delete-confirm' => 'Delete "$1"',
27862785 'delete-backlink' => '← $1', # only translate this message to other languages if you have to change it
27872786 'delete-legend' => 'Delete',
2788 -'historywarning' => "'''Warning:''' The page you are about to delete has a $2 with approximately $1 {{PLURAL:$1|revision|revisions}}:",
 2787+'historywarning' => "'''Warning:''' The page you are about to delete has a history with approximately $1 {{PLURAL:$1|revision|revisions}}:",
27892788 'confirmdeletetext' => 'You are about to delete a page along with all of its history.
27902789 Please confirm that you intend to do this, that you understand the consequences, and that you are doing this in accordance with [[{{MediaWiki:Policy-url}}|the policy]].',
27912790 'actioncomplete' => 'Action complete',
Index: trunk/extensions/LiquidThreads/LiquidThreads.php
@@ -118,7 +118,7 @@
119119 $wgHooks['ArticleDeleteComplete'][] = 'LqtDeletionController::onArticleDeleteComplete';
120120 $wgHooks['ArticleRevisionUndeleted'][] = 'LqtDeletionController::onArticleRevisionUndeleted';
121121 $wgHooks['ArticleUndelete'][] = 'LqtDeletionController::onArticleUndelete';
122 -$wgHooks['ActionBeforeFormDisplay'][] = 'LqtDeletionController::onActionBeforeFormDisplay';
 122+$wgHooks['ArticleConfirmDelete'][] = 'LqtDeletionController::onArticleConfirmDelete';
123123 $wgHooks['ArticleDelete'][] = 'LqtDeletionController::onArticleDelete';
124124
125125 // Moving
Index: trunk/extensions/LiquidThreads/classes/DeletionController.php
@@ -94,27 +94,22 @@
9595 return true;
9696 }
9797
98 - static function onActionBeforeFormDisplay( $action, HTMLForm &$form, $page ) {
99 - if( $action != 'delete' ){
 98+ static function onArticleConfirmDelete( $article, $out, &$reason ) {
 99+ if ( $article->getTitle()->getNamespace() != NS_LQT_THREAD ) {
100100 return true;
101101 }
102102
103 - if ( $page->getTitle()->getNamespace() != NS_LQT_THREAD ) {
104 - return true;
105 - }
 103+ $thread = Threads::withRoot( $article );
106104
107 - $thread = Threads::withRoot( $page );
108 -
109105 if ( !$thread ) {
110106 return true;
111107 }
112108
113109 if ( $thread->isTopmostThread() && count( $thread->replies() ) ) {
114 - $form->addHeaderText( Html::rawElement(
115 - 'strong',
116 - array(),
117 - wfMessage( 'lqt-delete-parent-warning' )->parse()
118 - ) );
 110+ $out->wrapWikiMsg(
 111+ '<strong>$1</strong>',
 112+ 'lqt-delete-parent-warning'
 113+ );
119114 }
120115
121116 return true;
Index: trunk/extensions/LiquidThreads/classes/Thread.php
@@ -112,7 +112,7 @@
113113 NewMessages::writeMessageStateForUpdatedThread( $thread, $change_type, $wgUser );
114114
115115 if ( $wgUser->getOption( 'lqt-watch-threads', false ) ) {
116 - Action::factory( 'watch', $thread->topmostThread()->root() )->execute();
 116+ $thread->topmostThread()->root()->doWatch();
117117 }
118118
119119 return $thread;
Index: trunk/extensions/MultilingualLiquidThreads/LiquidThreads/LiquidThreads.php
@@ -70,7 +70,7 @@
7171 $wgHooks['ArticleDeleteComplete'][] = 'LqtDeletionController::onArticleDeleteComplete';
7272 $wgHooks['ArticleRevisionUndeleted'][] = 'LqtDeletionController::onArticleRevisionUndeleted';
7373 $wgHooks['ArticleUndelete'][] = 'LqtDeletionController::onArticleUndelete';
74 -$wgHooks['ActionBeforeFormDisplay'][] = 'LqtDeletionController::onActionBeforeFormDisplay';
 74+$wgHooks['ArticleConfirmDelete'][] = 'LqtDeletionController::onArticleConfirmDelete';
7575 $wgHooks['ArticleDelete'][] = 'LqtDeletionController::onArticleDelete';
7676
7777 // Moving
Index: trunk/extensions/MultilingualLiquidThreads/LiquidThreads/classes/DeletionController.php
@@ -93,25 +93,20 @@
9494 return true;
9595 }
9696
97 - static function onActionBeforeFormDisplay( $action, HTMLForm &$form, $page ) {
98 - if( $action != 'delete' ){
 97+ static function onArticleConfirmDelete( $article, $out, &$reason ) {
 98+ if ( $article->getTitle()->getNamespace() != NS_LQT_THREAD ) {
9999 return true;
100100 }
101101
102 - if ( $page->getTitle()->getNamespace() != NS_LQT_THREAD ) {
103 - return true;
104 - }
 102+ $thread = Threads::withRoot( $article );
105103
106 - $thread = Threads::withRoot( $page );
107 -
108104 if ( !$thread ) return true;
109105
110106 if ( $thread->isTopmostThread() && count( $thread->replies() ) ) {
111 - $form->addHeaderText( Html::rawElement(
112 - 'strong',
113 - array(),
114 - wfMessage( 'lqt-delete-parent-warning' )->parse()
115 - ) );
 107+ $out->wrapWikiMsg(
 108+ '<strong>$1</strong>',
 109+ 'lqt-delete-parent-warning'
 110+ );
116111 }
117112
118113 return true;
Index: trunk/extensions/MultilingualLiquidThreads/LiquidThreads/classes/Thread.php
@@ -113,7 +113,7 @@
114114 NewMessages::writeMessageStateForUpdatedThread( $thread, $change_type, $wgUser );
115115
116116 if ( $wgUser->getOption( 'lqt-watch-threads', false ) ) {
117 - Action::factory( 'watch', $thread->topmostThread()->root() )->execute();
 117+ $thread->topmostThread()->root()->doWatch();
118118 }
119119
120120 return $thread;
Index: trunk/extensions/PureWikiDeletion/PureWikiDeletion.php
@@ -104,7 +104,8 @@
105105 return false;
106106 }
107107 if ( $summary == wfMsgForContent( 'autosumm-blank' ) ) {
108 - $summary = DeleteAction::getAutoReason( $article );
 108+ $hasHistory = false;
 109+ $summary = $article->generateReason( $hasHistory );
109110 }
110111 } else {
111112 $dbr = wfGetDB( DB_SLAVE );
Index: trunk/extensions/PureWikiDeletion/PureWikiDeletion.hooks.php
@@ -55,7 +55,8 @@
5656 $blankRevId = $revision->getId();
5757 if ( $text == "" ) {
5858 if ( $summary == wfMsgForContent( 'autosumm-blank' ) ) {
59 - $summary = DeleteAction::getAutoReason( $article );
 59+ $hasHistory = false;
 60+ $summary = $article->generateReason( $hasHistory );
6061 }
6162 $dbw = wfGetDB( DB_MASTER );
6263 $blank_row = array(
Index: trunk/extensions/MetavidWiki/includes/articlepages/MV_DataPage.php
@@ -61,18 +61,18 @@
6262 }
6363
6464 if ( $confirm ) {
65 - $this->doDeleteArticle( $reason );
 65+ $this->doDelete( $reason );
6666 if ( $wgRequest->getCheck( 'wpWatch' ) ) {
67 - Action::factory( 'watch', $this )->execute();
 67+ $this->doWatch();
6868 } elseif ( $this->mTitle->userIsWatching() ) {
69 - Action::factory( 'watch', $this )->execute();
 69+ $this->doUnwatch();
7070 }
7171 return;
7272 }
7373
7474 // Generate deletion reason
7575 $hasHistory = false;
76 - $reason = DeleteAction::getAutoReason( $this );
 76+ $reason = $this->generateReason( $hasHistory );
7777
7878 // If the page has a history, insert a warning
7979 if ( $hasHistory && !$confirm ) {
Index: trunk/extensions/ReplaceText/ReplaceTextJob.php
@@ -42,7 +42,8 @@
4343 $create_redirect = $this->params['create_redirect'];
4444 $this->title->moveTo( $new_title, true, $reason, $create_redirect );
4545 if ( $this->params['watch_page'] ) {
46 - Action::factory( 'watch', new Article( $new_title ) )->execute();
 46+ $article = new Article( $new_title );
 47+ $article->doWatch();
4748 }
4849 $wgUser = $actual_user;
4950 } else {

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r86001New infrastructure for actions, as discussed on wikitech-l. Fairly huge commit....happy-melon23:04, 13 April 2011

Status & tagging log