r95787 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r95786‎ | r95787 | r95788 >
Date:15:51, 30 August 2011
Author:catrope
Status:resolved (Comments)
Tags:
Comment:
RL2: Add hooks that ensure the database is updated when Gadget definition: pages are deleted and undeleted
Modified paths:
  • /branches/RL2/extensions/Gadgets/GadgetHooks.php (modified) (history)
  • /branches/RL2/extensions/Gadgets/Gadgets.php (modified) (history)

Diff [purge]

Index: branches/RL2/extensions/Gadgets/Gadgets.php
@@ -92,7 +92,9 @@
9393 'gadgets-definition-delete'
9494 ) );
9595
 96+$wgHooks['ArticleDeleteComplete'][] = 'GadgetHooks::articleDeleteComplete';
9697 $wgHooks['ArticleSaveComplete'][] = 'GadgetHooks::articleSaveComplete';
 98+$wgHooks['ArticleUndelete'][] = 'GadgetHooks::articleUndelete';
9799 $wgHooks['BeforePageDisplay'][] = 'GadgetHooks::beforePageDisplay';
98100 $wgHooks['CanonicalNamespaces'][] = 'GadgetHooks::canonicalNamespaces';
99101 $wgHooks['GetPreferences'][] = 'GadgetHooks::getPreferences';
Index: branches/RL2/extensions/Gadgets/GadgetHooks.php
@@ -15,20 +15,103 @@
1616 class GadgetHooks {
1717
1818 /**
 19+ * ArticleDeleteComplete hook handler.
 20+ *
 21+ * @param $article Article
 22+ * @param $user User
 23+ * @param $reason String: Deletion summary
 24+ * @param $id Int: Page ID
 25+ */
 26+ public static function articleDeleteComplete( $article, $user, $reason, $id ) {
 27+ // FIXME: AARGH, duplication, refactor this
 28+ $title = $article->getTitle();
 29+ $name = $title->getText();
 30+ // Check that the deletion is in the Gadget definition: namespace and that the name ends in .js
 31+ if ( $title->getNamespace() !== NS_GADGET_DEFINITION || !preg_match( '!\.js$!u', $name ) ) {
 32+ return true;
 33+ }
 34+ // Trim .js from the page name to obtain the gadget name
 35+ $name = substr( $name, 0, -3 );
 36+
 37+ $repo = new LocalGadgetRepo( array() );
 38+ $repo->deleteGadget( $name );
 39+ // deleteGadget() may return an error if the Gadget didn't exist, but we don't care here
 40+ return true;
 41+ }
 42+
 43+ /**
1944 * ArticleSaveComplete hook handler.
2045 *
2146 * @param $article Article
2247 * @param $user User
2348 * @param $text String: New page text
 49+ * @param $summary String: Edit summary
 50+ * @param $isMinor Bool: Whether this was a minor edit
 51+ * @param $isWatch unused
 52+ * @param $section unused
 53+ * @param $flags: Int: Bitmap of flags passed to WikiPage::doEdit()
 54+ * @param $revision: Revision object for the new revision
2455 */
25 - public static function articleSaveComplete( $article, $user, $text ) {
26 - //update cache if MediaWiki:Gadgets-definition was edited
27 - $title = $article->mTitle;
28 - if( $title->getNamespace() == NS_MEDIAWIKI && $title->getText() == 'Gadgets-definition' ) {
29 - Gadget::loadStructuredList( $text );
 56+ public static function articleSaveComplete( $article, $user, $text, $summary, $isMinor,
 57+ $isWatch, $section, $flags, $revision )
 58+ {
 59+ $title = $article->getTitle();
 60+ $name = $title->getText();
 61+ // Check that the edit is in the Gadget definition: namespace, that the name ends in .js
 62+ // and that $revision isn't null (this happens for a no-op edit)
 63+ if ( $title->getNamespace() !== NS_GADGET_DEFINITION || !preg_match( '!\.js$!u', $name ) || !$revision ) {
 64+ return true;
3065 }
 66+ // Trim .js from the page name to obtain the gadget name
 67+ $name = substr( $name, 0, -3 );
 68+
 69+ $previousRev = $revision->getPrevious();
 70+ $prevTs = $previousRev instanceof Revision ? $previousRev->getTimestamp() : wfTimestampNow();
 71+
 72+ // Update the database entry for this gadget
 73+ $repo = new LocalGadgetRepo( array() );
 74+ // TODO: Timestamp in the constructor is ugly
 75+ $gadget = new Gadget( $name, $repo, $text, $prevTs );
 76+ $repo->modifyGadget( $gadget, $revision->getTimestamp() );
 77+
 78+ // modifyGadget() returns a Status object with an error if there was a conflict,
 79+ // but we don't care. If a conflict occurred, that must be because a newer edit's
 80+ // DB update occurred before ours, in which case the right thing to do is to occu
 81+
3182 return true;
3283 }
 84+
 85+ public static function articleUndelete( $title, $created, $comment ) {
 86+ // FIXME: AARGH, duplication, refactor this
 87+ $name = $title->getText();
 88+ // Check that the deletion is in the Gadget definition: namespace and that the name ends in .js
 89+ if ( $title->getNamespace() !== NS_GADGET_DEFINITION || !preg_match( '!\.js$!u', $name ) ) {
 90+ return true;
 91+ }
 92+ // Trim .js from the page name to obtain the gadget name
 93+ $name = substr( $name, 0, -3 );
 94+
 95+ // Check whether this undeletion changed the latest revision of the page, by comparing
 96+ // the timestamp of the latest revision with the timestamp in the DB
 97+ $repo = new LocalGadgetRepo( array() );
 98+ $gadget = $repo->getGadget( $name );
 99+ $gadgetTS = $gadget ? $gadget->getTimestamp() : 0;
 100+
 101+ $rev = Revision::newFromTitle( $title );
 102+ if ( wfTimestamp( TS_MW, $rev->getTimestamp() ) ===
 103+ wfTimestamp( TS_MW, $gadgetTS ) ) {
 104+ // The latest rev didn't change. Someone must've undeleted an older revision
 105+ return true;
 106+ }
 107+
 108+ // Update the database entry for this gadget
 109+ $newGadget = new Gadget( $name, $repo, $rev->getRawText(), $gadgetTS );
 110+ $repo->modifyGadget( $newGadget, $rev->getTimestamp() );
 111+
 112+ // modifyGadget() returns a Status object with an error if there was a conflict,
 113+ // but we do't care, see similar comment in articleSaveComplete()
 114+ return true;
 115+ }
33116
34117 /**
35118 * GetPreferences hook handler.
@@ -162,7 +245,9 @@
163246 }
164247
165248 public static function titleIsCssOrJsPage( $title, &$result ) {
166 - if ( $title->getNamespace() == NS_GADGET || $title->getNamespace() == NS_GADGET_DEFINITION ) {
 249+ if ( ( $title->getNamespace() == NS_GADGET || $title->getNamespace() == NS_GADGET_DEFINITION ) &&
 250+ preg_match( '!\.(css|js)$!u', $title->getText() ) )
 251+ {
167252 $result = true;
168253 }
169254 return true;

Follow-up revisions

RevisionCommit summaryAuthorDate
r98859[RL2] Address fixme on r95787: $revision can be null (happens for null edits)...catrope14:38, 4 October 2011

Comments

#Comment by Krinkle (talk | contribs)   21:16, 1 October 2011
+		$previousRev = $revision->getPrevious();
<pre>

Getting the following from the API in some cases when saving a gadget definition page:
<pre>
Fatal error: Call to a member function getPrevious() on a non-object in /Users/krinkle/Sites/mediawiki/branches/RL2/extensions/Gadgets/GadgetHooks.php on line 72
#Comment by Krinkle (talk | contribs)   21:17, 1 October 2011
+		$previousRev = $revision->getPrevious();

Getting the following from the API in some cases when saving a gadget definition page:

Fatal error: Call to a member function getPrevious() on a non-object in /Users/krinkle/Sites/mediawiki/branches/RL2/extensions/Gadgets/GadgetHooks.php on line 72

$revision is probably null ?

#Comment by Catrope (talk | contribs)   14:43, 4 October 2011

Yes, it turns out $revision is null for, how appropriate, null edits. Fixed in r98859.

Status & tagging log