SpecialWatchlist: Use FormOptions for parameter handling
authorBartosz Dziewoński <matma.rex@gmail.com>
Fri, 11 Oct 2013 19:39:00 +0000 (21:39 +0200)
committerOri.livneh <ori@wikimedia.org>
Sat, 11 Jan 2014 01:01:53 +0000 (01:01 +0000)
The SpecialWatchlistQuery hook now gets a FormOptions object as the last
parameter instead of an array (which is not bad as bad as it sounds, since
the class implements ArrayAccess).

Change-Id: Iec4aab870b6e9aa98d2b118010e78e25b1dbe437

RELEASE-NOTES-1.23
docs/hooks.txt
includes/specials/SpecialWatchlist.php

index a05d7a2..dbe598c 100644 (file)
@@ -157,12 +157,15 @@ changes to languages because of Bugzilla reports.
 * A page_links_updated field has been added to the page table.
 * SpecialPage::getTitle has been deprecated in favor of
   SpecialPage::getPageTitle.
-* BREAKING CHANGE: A potentially backwards-incompatible change has been made
+* BREAKING CHANGE: Two potentially backwards-incompatible changes have been made
   to the 'SpecialWatchlistQuery' hook's last parameter (array $values) to make
   the hook more consistent with the 'SpecialRecentChangesQuery' one:
 ** Several array keys have been renamed: hideMinor → hideminor,
    hideBots → hidebots, hideAnons → hideanons, hideLiu → hideliu,
    hidePatrolled → hidepatrolled, hideOwn → hidemyself.
+** The parameter value is now a FormOptions object, not a plain array (array
+   access operators should continue to work, as it implements the ArrayAccess
+   interface).
 * Option to mark hooks as deprecated has been added.
 
 ==== Removed classes ====
index 9dcd2f3..bbe1680 100644 (file)
@@ -2407,7 +2407,7 @@ $special: the special page object
 &$tables: array of tables to be queried
 &$join_conds: join conditions for the tables
 &$fields: array of query fields
-$values: array of variables with watchlist options
+$opts: A FormOptions object with watchlist options for the current request
 
 'SpecialWatchlistGetNonRevisionTypes': Called when building sql query for
 SpecialWatchlist. Allows extensions to register custom values they have
index 5a77b48..49a1494 100644 (file)
@@ -66,6 +66,65 @@ class SpecialWatchlist extends SpecialRecentChanges {
                $this->setContext( $context );
        }
 
+       /**
+        * Get a FormOptions object containing the default options
+        *
+        * @return FormOptions
+        */
+       public function getDefaultOptions() {
+               $opts = parent::getDefaultOptions();
+               $user = $this->getUser();
+
+               // Overwrite RC options with Watchlist options
+               // (calling #add() again is okay)
+               $opts->add( 'days', $user->getOption( 'watchlistdays' ), FormOptions::FLOAT );
+               $opts->add( 'hideminor', $user->getBoolOption( 'watchlisthideminor' ) );
+               $opts->add( 'hidebots', $user->getBoolOption( 'watchlisthidebots' ) );
+               $opts->add( 'hideanons', $user->getBoolOption( 'watchlisthideanons' ) );
+               $opts->add( 'hideliu', $user->getBoolOption( 'watchlisthideliu' ) );
+               $opts->add( 'hidepatrolled', $user->getBoolOption( 'watchlisthidepatrolled' ) );
+               $opts->add( 'hidemyself', $user->getBoolOption( 'watchlisthideown' ) );
+
+               // Add new ones
+               $opts->add( 'extended', $user->getBoolOption( 'extendwatchlist' ) );
+
+               return $opts;
+       }
+
+       /**
+        * Get custom show/hide filters
+        *
+        * @return array Map of filter URL param names to properties (msg/default)
+        */
+       protected function getCustomFilters() {
+               if ( $this->customFilters === null ) {
+                       $this->customFilters = array();
+                       wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ) );
+               }
+
+               return $this->customFilters;
+       }
+
+       /**
+        * Process $par and put options found if $opts. Not used for Watchlist.
+        *
+        * @param string $par
+        * @param FormOptions $opts
+        */
+       public function parseParameters( $par, FormOptions $opts ) {
+       }
+
+       /**
+        * Get the current FormOptions for this request
+        */
+       public function getOptions() {
+               if ( $this->rcOptions === null ) {
+                       $this->rcOptions = $this->setup( null );
+               }
+
+               return $this->rcOptions;
+       }
+
        /**
         * Execute
         * @param $par Parameter passed to the page
@@ -97,6 +156,7 @@ class SpecialWatchlist extends SpecialRecentChanges {
                        ) );
                }
 
+               $opts = $this->getOptions();
                $this->setHeaders();
                $this->outputHeader();
 
@@ -127,49 +187,14 @@ class SpecialWatchlist extends SpecialRecentChanges {
                        return;
                }
 
-               // @todo use FormOptions!
-               $defaults = array(
-               /* float */ 'days' => floatval( $user->getOption( 'watchlistdays' ) ),
-               /* bool  */ 'hideminor' => (int)$user->getBoolOption( 'watchlisthideminor' ),
-               /* bool  */ 'hidebots' => (int)$user->getBoolOption( 'watchlisthidebots' ),
-               /* bool  */ 'hideanons' => (int)$user->getBoolOption( 'watchlisthideanons' ),
-               /* bool  */ 'hideliu' => (int)$user->getBoolOption( 'watchlisthideliu' ),
-               /* bool  */ 'hidepatrolled' => (int)$user->getBoolOption( 'watchlisthidepatrolled' ),
-               /* bool  */ 'hidemyself' => (int)$user->getBoolOption( 'watchlisthideown' ),
-               /* bool  */ 'extended' => (int)$user->getBoolOption( 'extendwatchlist' ),
-               /* ?     */ 'namespace' => '', //means all
-               /* ?     */ 'invert' => false,
-               /* bool  */ 'associated' => false,
-               );
-               $this->customFilters = array();
-               wfRunHooks( 'SpecialWatchlistFilters', array( $this, &$this->customFilters ) );
-               foreach ( $this->customFilters as $key => $params ) {
-                       $defaults[$key] = $params['default'];
-               }
-
-               # Extract variables from the request, falling back to user preferences or
-               # other default values if these don't exist
-               $values = array();
-               $values['days'] = floatval( $request->getVal( 'days', $defaults['days'] ) );
-               $values['hideminor'] = (int)$request->getBool( 'hideminor', $defaults['hideminor'] );
-               $values['hidebots'] = (int)$request->getBool( 'hidebots', $defaults['hidebots'] );
-               $values['hideanons'] = (int)$request->getBool( 'hideanons', $defaults['hideanons'] );
-               $values['hideliu'] = (int)$request->getBool( 'hideliu', $defaults['hideliu'] );
-               $values['hidemyself'] = (int)$request->getBool( 'hidemyself', $defaults['hidemyself'] );
-               $values['hidepatrolled'] = (int)$request->getBool( 'hidepatrolled', $defaults['hidepatrolled'] );
-               $values['extended'] = (int)$request->getBool( 'extended', $defaults['extended'] );
-               foreach ( $this->customFilters as $key => $params ) {
-                       $values[$key] = (int)$request->getBool( $key, $defaults[$key] );
-               }
-
                # Get namespace value, if supplied, and prepare a WHERE fragment
-               $nameSpace = $request->getIntOrNull( 'namespace' );
-               $invert = $request->getBool( 'invert' );
-               $associated = $request->getBool( 'associated' );
-               if ( !is_null( $nameSpace ) ) {
+               $nameSpace = $opts['namespace'];
+               $invert = $opts['invert'];
+               $associated = $opts['associated'];
+
+               if ( $nameSpace !== '' ) {
                        $eq_op = $invert ? '!=' : '=';
                        $bool_op = $invert ? 'AND' : 'OR';
-                       $nameSpace = intval( $nameSpace ); // paranioa
                        if ( !$associated ) {
                                $nameSpaceClause = "rc_namespace $eq_op $nameSpace";
                        } else {
@@ -180,18 +205,11 @@ class SpecialWatchlist extends SpecialRecentChanges {
                                        " rc_namespace $eq_op $associatedNS";
                        }
                } else {
-                       $nameSpace = '';
                        $nameSpaceClause = '';
                }
-               $values['namespace'] = $nameSpace;
-               $values['invert'] = $invert;
-               $values['associated'] = $associated;
 
                // Dump everything here
-               $nondefaults = array();
-               foreach ( $defaults as $name => $defValue ) {
-                       wfAppendToArrayIfNotDefault( $name, $values[$name], $defaults, $nondefaults );
-               }
+               $nondefaults = $opts->getChangedValues();
 
                if ( ( $wgEnotifWatchlist || $wgShowUpdatedMarker ) && $request->getVal( 'reset' )
                        && $request->wasPosted()
@@ -204,27 +222,27 @@ class SpecialWatchlist extends SpecialRecentChanges {
                # Possible where conditions
                $conds = array();
 
-               if ( $values['days'] > 0 ) {
-                       $conds[] = 'rc_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( time() - intval( $values['days'] * 86400 ) ) );
+               if ( $opts['days'] > 0 ) {
+                       $conds[] = 'rc_timestamp > ' . $dbr->addQuotes( $dbr->timestamp( time() - intval( $opts['days'] * 86400 ) ) );
                }
 
                # Toggles
-               if ( $values['hidemyself'] ) {
+               if ( $opts['hidemyself'] ) {
                        $conds[] = 'rc_user != ' . $user->getId();
                }
-               if ( $values['hidebots'] ) {
+               if ( $opts['hidebots'] ) {
                        $conds[] = 'rc_bot = 0';
                }
-               if ( $values['hideminor'] ) {
+               if ( $opts['hideminor'] ) {
                        $conds[] = 'rc_minor = 0';
                }
-               if ( $values['hideliu'] ) {
+               if ( $opts['hideliu'] ) {
                        $conds[] = 'rc_user = 0';
                }
-               if ( $values['hideanons'] ) {
+               if ( $opts['hideanons'] ) {
                        $conds[] = 'rc_user != 0';
                }
-               if ( $user->useRCPatrol() && $values['hidepatrolled'] ) {
+               if ( $user->useRCPatrol() && $opts['hidepatrolled'] ) {
                        $conds[] = 'rc_patrolled != 1';
                }
                if ( $nameSpaceClause ) {
@@ -232,7 +250,7 @@ class SpecialWatchlist extends SpecialRecentChanges {
                }
 
                # Toggle watchlist content (all recent edits or just the latest)
-               if ( $values['extended'] ) {
+               if ( $opts['extended'] ) {
                        $limitWatchlist = $user->getIntOption( 'wllimit' );
                        $usePage = false;
                } else {
@@ -327,7 +345,7 @@ class SpecialWatchlist extends SpecialRecentChanges {
                }
 
                ChangeTags::modifyDisplayQuery( $tables, $fields, $conds, $join_conds, $options, '' );
-               wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields, $values ) );
+               wfRunHooks( 'SpecialWatchlistQuery', array( &$conds, &$tables, &$join_conds, &$fields, $opts ) );
 
                $res = $dbr->select( $tables, $fields, $conds, __METHOD__, $options, $join_conds );
                $numRows = $res->numRows();
@@ -336,13 +354,13 @@ class SpecialWatchlist extends SpecialRecentChanges {
 
                $lang = $this->getLanguage();
                $wlInfo = '';
-               if ( $values['days'] > 0 ) {
+               if ( $opts['days'] > 0 ) {
                        $timestamp = wfTimestampNow();
-                       $wlInfo = $this->msg( 'wlnote' )->numParams( $numRows, round( $values['days'] * 24 ) )->params(
+                       $wlInfo = $this->msg( 'wlnote' )->numParams( $numRows, round( $opts['days'] * 24 ) )->params(
                                $lang->userDate( $timestamp, $user ), $lang->userTime( $timestamp, $user ) )->parse() . "<br />\n";
                }
 
-               $cutofflinks = $this->cutoffLinks( $values['days'], $nondefaults ) . "<br />\n";
+               $cutofflinks = $this->cutoffLinks( $opts['days'], $nondefaults ) . "<br />\n";
 
                # Spit out some control panel links
                $filters = array(
@@ -353,7 +371,7 @@ class SpecialWatchlist extends SpecialRecentChanges {
                        'hidemyself' => 'rcshowhidemine',
                        'hidepatrolled' => 'rcshowhidepatr'
                );
-               foreach ( $this->customFilters as $key => $params ) {
+               foreach ( $this->getCustomFilters() as $key => $params ) {
                        $filters[$key] = $params['msg'];
                }
                // Disable some if needed
@@ -363,7 +381,7 @@ class SpecialWatchlist extends SpecialRecentChanges {
 
                $links = array();
                foreach ( $filters as $name => $msg ) {
-                       $links[] = $this->showHideLink( $nondefaults, $msg, $name, $values[$name] );
+                       $links[] = $this->showHideLink( $nondefaults, $msg, $name, $opts[$name] );
                }
 
                $hiddenFields = $nondefaults;