r109678 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r109677‎ | r109678 | r109679 >
Date:06:57, 21 January 2012
Author:krinkle
Status:resolved (Comments)
Tags:bug27930, core 
Comment:
Reinstate r109223 per CR + fixes
* Action/Context stuff is pretty deeply nested everywhere.
* Should be okay now, at last.
* Reverts reverting r109243
* Same as r109223, except adding this:

+ if ( !$context->canUseWikiPage() ) {
+ return 'view';
+ }
Modified paths:
  • /trunk/phase3/includes/Action.php (modified) (history)
  • /trunk/phase3/includes/OutputPage.php (modified) (history)
  • /trunk/phase3/includes/Wiki.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Wiki.php
@@ -34,11 +34,6 @@
3535 private $context;
3636
3737 /**
38 - * @var string
39 - */
40 - private $performedAction = 'nosuchaction';
41 -
42 - /**
4338 * @param $x null|WebRequest
4439 * @return WebRequest
4540 */
@@ -81,6 +76,7 @@
8277 $request = $this->context->getRequest();
8378 $curid = $request->getInt( 'curid' );
8479 $title = $request->getVal( 'title' );
 80+ $action = $request->getVal( 'action', 'view' );
8581
8682 if ( $request->getCheck( 'search' ) ) {
8783 // Compatibility with old search URLs which didn't use Special:Search
@@ -90,7 +86,7 @@
9187 } elseif ( $curid ) {
9288 // URLs like this are generated by RC, because rc_title isn't always accurate
9389 $ret = Title::newFromID( $curid );
94 - } elseif ( $title == '' && $this->getAction() != 'delete' ) {
 90+ } elseif ( $title == '' && $action != 'delete' ) {
9591 $ret = Title::newMainPage();
9692 } else {
9793 $ret = Title::newFromURL( $title );
@@ -310,40 +306,17 @@
311307 }
312308
313309 /**
314 - * Returns the action that will be executed, not necessarily the one passed
315 - * passed through the "action" parameter. Actions disabled in
316 - * $wgDisabledActions will be replaced by "nosuchaction".
 310+ * Returns the name of the action that will be executed.
317311 *
318 - * The return value is merely a suggestion, not the actually performed action,
319 - * which may be different. The actually performed action is determined by performAction().
320 - * Requests like action=nonsense will make this function return "nonsense".
321 - * Use getPerformedAction() to get the performed action.
322 - *
323312 * @return string: action
324313 */
325314 public function getAction() {
326 - global $wgDisabledActions;
327 -
328 - $request = $this->context->getRequest();
329 - $action = $request->getVal( 'action', 'view' );
330 -
331 - // Check for disabled actions
332 - if ( in_array( $action, $wgDisabledActions ) ) {
333 - return 'nosuchaction';
 315+ static $action = null;
 316+
 317+ if ( $action === null ) {
 318+ $action = Action::getActionName( $this->context );
334319 }
335320
336 - // Workaround for bug #20966: inability of IE to provide an action dependent
337 - // on which submit button is clicked.
338 - if ( $action === 'historysubmit' ) {
339 - if ( $request->getBool( 'revisiondelete' ) ) {
340 - return 'revisiondelete';
341 - } else {
342 - return 'view';
343 - }
344 - } elseif ( $action == 'editredlink' ) {
345 - return 'edit';
346 - }
347 -
348321 return $action;
349322 }
350323
@@ -510,14 +483,12 @@
511484
512485 $action = Action::factory( $act, $article );
513486 if ( $action instanceof Action ) {
514 - $this->performedAction = $act;
515487 $action->show();
516488 wfProfileOut( __METHOD__ );
517489 return;
518490 }
519491
520492 if ( wfRunHooks( 'UnknownAction', array( $act, $article ) ) ) {
521 - $this->performedAction = 'nosuchaction';
522493 $output->showErrorPage( 'nosuchaction', 'nosuchactiontext' );
523494 }
524495
@@ -525,18 +496,6 @@
526497 }
527498
528499 /**
529 - * Returns the real action as determined by performAction.
530 - * Do not use internally in this class as it depends on the actions by this class.
531 - *
532 - * @since 1.19
533 - *
534 - * @return string: action
535 - */
536 - public function getPerformedAction() {
537 - return $this->performedAction;
538 - }
539 -
540 - /**
541500 * Run the current MediaWiki instance
542501 * index.php just calls this
543502 */
Index: trunk/phase3/includes/Action.php
@@ -87,6 +87,52 @@
8888 }
8989
9090 /**
 91+ * Get the action that will be executed, not necessarily the one passed
 92+ * passed through the "action" request parameter. Actions disabled in
 93+ * $wgDisabledActions will be replaced by "nosuchaction".
 94+ *
 95+ * @param $context IContextSource
 96+ * @return string: action name
 97+ */
 98+ public final static function getActionName( IContextSource $context ) {
 99+ global $wgDisabledActions;
 100+
 101+ $request = $context->getRequest();
 102+ $actionName = $request->getVal( 'action', 'view' );
 103+
 104+ // Check for disabled actions
 105+ if ( in_array( $actionName, $wgDisabledActions ) ) {
 106+ $actionName = 'nosuchaction';
 107+ }
 108+
 109+ // Workaround for bug #20966: inability of IE to provide an action dependent
 110+ // on which submit button is clicked.
 111+ if ( $actionName === 'historysubmit' ) {
 112+ if ( $request->getBool( 'revisiondelete' ) ) {
 113+ $actionName = 'revisiondelete';
 114+ } else {
 115+ $actionName = 'view';
 116+ }
 117+ } elseif ( $actionName == 'editredlink' ) {
 118+ $actionName = 'edit';
 119+ }
 120+
 121+ // Trying to get a WikiPage for NS_SPECIAL etc. will result
 122+ // in WikiPage::factory throwing "Invalid or virtual namespace -1 given."
 123+ // For SpecialPages et al, default to action=view.
 124+ if ( !$context->canUseWikiPage() ) {
 125+ return 'view';
 126+ }
 127+
 128+ $action = Action::factory( $actionName, $context->getWikiPage() );
 129+ if ( $action instanceof Action ) {
 130+ return $action->getName();
 131+ }
 132+
 133+ return 'nosuchaction';
 134+ }
 135+
 136+ /**
91137 * Check if a given action is recognised, even if it's disabled
92138 *
93139 * @param $name String: name of an action
Index: trunk/phase3/includes/OutputPage.php
@@ -2380,7 +2380,7 @@
23812381 * @return String: The doctype, opening <html>, and head element.
23822382 */
23832383 public function headElement( Skin $sk, $includeStyle = true ) {
2384 - global $wgContLang, $mediaWiki;
 2384+ global $wgContLang;
23852385
23862386 $userdir = $this->getLanguage()->getDir();
23872387 $sitedir = $wgContLang->getDir();
@@ -2426,7 +2426,7 @@
24272427 }
24282428 $bodyAttrs['class'] .= ' ' . $sk->getPageClasses( $this->getTitle() );
24292429 $bodyAttrs['class'] .= ' skin-' . Sanitizer::escapeClass( $sk->getSkinName() );
2430 - $bodyAttrs['class'] .= ' action-' . Sanitizer::escapeClass( $mediaWiki->getPerformedAction() );
 2430+ $bodyAttrs['class'] .= ' action-' . Sanitizer::escapeClass( Action::getActionName( $this->getContext() ) );
24312431
24322432 $sk->addToBodyAttributes( $this, $bodyAttrs ); // Allow skins to add body attributes they need
24332433 wfRunHooks( 'OutputPageBodyAttributes', array( $this, $sk, &$bodyAttrs ) );
@@ -2824,7 +2824,7 @@
28252825 * @return array
28262826 */
28272827 public function getJSVars() {
2828 - global $wgUseAjax, $wgEnableMWSuggest, $mediaWiki;
 2828+ global $wgUseAjax, $wgEnableMWSuggest;
28292829
28302830 $title = $this->getTitle();
28312831 $ns = $title->getNamespace();
@@ -2860,7 +2860,7 @@
28612861 'wgCurRevisionId' => $title->getLatestRevID(),
28622862 'wgArticleId' => $title->getArticleId(),
28632863 'wgIsArticle' => $this->isArticle(),
2864 - 'wgAction' => $mediaWiki->getPerformedAction(),
 2864+ 'wgAction' => Action::getActionName( $this->getContext() ),
28652865 'wgUserName' => $this->getUser()->isAnon() ? null : $this->getUser()->getName(),
28662866 'wgUserGroups' => $this->getUser()->getEffectiveGroups(),
28672867 'wgCategories' => $this->getCategories(),

Sign-offs

UserFlagDate
Nikerabbitinspected17:20, 21 January 2012

Follow-up revisions

RevisionCommit summaryAuthorDate
r109684+@since for getActionName (r109678)krinkle17:21, 21 January 2012
r109689[Action] Fix action=ajax...krinkle20:13, 21 January 2012
r110716Please review carefully, I cannot see negative side effects from this patch. ...wikinaut11:00, 5 February 2012

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r108343[mw.config] wgAction shouldn't use direct URL values...krinkle01:34, 8 January 2012
r109223[Actions] Move action logic out of MediaWiki::getAction/MediaWiki::performAct...krinkle21:49, 17 January 2012
r109243Reverted r109223 per CRaaron23:07, 17 January 2012

Comments

#Comment by Tim Starling (talk | contribs)   19:19, 21 January 2012

This breaks action=ajax. Wiki::getAction() returns nosuchaction because ajax is not in $wgActions, so Action::factory() fails.

#Comment by Krinkle (talk | contribs)   20:15, 21 January 2012

Thanks, fixed in r109689 based on our IRC convo. That is really the last exception there is in MediaWiki's action-handling, right?

#Comment by Nikerabbit (talk | contribs)   08:34, 26 January 2012

This breaks SemantifForms action=formedit, but reverting this and followups causes fatals!

#Comment by Krinkle (talk | contribs)   20:48, 27 January 2012

That's not a lot of information, but from quickly glancing at the source code of SemanticForms, it seems it should either:

  • Quick fix: Check the $request->getVal('action') instead of the $action argument
  • Long-term fix: Instead of injecting the action handling via the UnknownAction hook, register the action through $wgActions and subclass Action for the logic/view.
#Comment by Krinkle (talk | contribs)   23:49, 7 February 2012

Fixed by r110716.

#Comment by GWicke (talk | contribs)   18:10, 17 February 2012

I had a quick look at this, but am worried about other action-using extensions. Would need to spend more time on this to be able to do a proper review. Will wait for Tim and Nikerabbit to have a look at it first before spending too much time on this.

#Comment by Krinkle (talk | contribs)   19:33, 17 February 2012

Behavior should be unchanged for extensions. All this only affects core, and in core all actions have been converted to Action classes.

Extensions still get the raw value in all other cases (to use for custom actions). I initially did that wrong (which soft-broke SemanticForms and others) but this old-style behavior was quickly fixed/recovered (as it should be) by r110716. Passing the parsed value made no sense as the only value extensions would be able to get at would be 'nosuchaction'.

Status & tagging log