* @ingroup SpecialPage
*/
abstract class ChangesListSpecialPage extends SpecialPage {
- var $rcSubpage, $rcOptions; // @todo Rename these, make protected
- protected $customFilters;
+ /** @var string */
+ protected $rcSubpage;
- /**
- * The feed format to output as (either 'rss' or 'atom'), or null if no
- * feed output was requested
- *
- * @var string $feedFormat
- */
- protected $feedFormat;
+ /** @var FormOptions */
+ protected $rcOptions;
+
+ /** @var array */
+ protected $customFilters;
/**
* Main execution point
*/
public function execute( $subpage ) {
$this->rcSubpage = $subpage;
- $this->feedFormat = $this->including() ? null : $this->getRequest()->getVal( 'feed' );
- if ( $this->feedFormat !== 'atom' && $this->feedFormat !== 'rss' ) {
- $this->feedFormat = null;
- }
$this->setHeaders();
$this->outputHeader();
$this->addModules();
+ $rows = $this->getRows();
$opts = $this->getOptions();
- // Fetch results, prepare a batch link existence check query
- $conds = $this->buildMainQueryConds( $opts );
- $rows = $this->doMainQuery( $conds, $opts );
if ( $rows === false ) {
if ( !$this->including() ) {
$this->doHeader( $opts );
return;
}
- if ( !$this->feedFormat ) {
- $batch = new LinkBatch;
- foreach ( $rows as $row ) {
- $batch->add( NS_USER, $row->rc_user_text );
- $batch->add( NS_USER_TALK, $row->rc_user_text );
- $batch->add( $row->rc_namespace, $row->rc_title );
- }
- $batch->execute();
- }
- if ( $this->feedFormat ) {
- list( $changesFeed, $formatter ) = $this->getFeedObject( $this->feedFormat );
- /** @var ChangesFeed $changesFeed */
- $changesFeed->execute( $formatter, $rows, $this->checkLastModified( $this->feedFormat ), $opts );
- } else {
- $this->webOutput( $rows, $opts );
+ $batch = new LinkBatch;
+ foreach ( $rows as $row ) {
+ $batch->add( NS_USER, $row->rc_user_text );
+ $batch->add( NS_USER_TALK, $row->rc_user_text );
+ $batch->add( $row->rc_namespace, $row->rc_title );
}
+ $batch->execute();
+
+ $this->webOutput( $rows, $opts );
$rows->free();
}
+ /**
+ * Get the database result for this special page instance. Used by ApiFeedRecentChanges.
+ *
+ * @return bool|ResultWrapper Result or false
+ */
+ public function getRows() {
+ $opts = $this->getOptions();
+ $conds = $this->buildMainQueryConds( $opts );
+
+ return $this->doMainQuery( $conds, $opts );
+ }
+
/**
* Get the current FormOptions for this request
*
* @return array Map of filter URL param names to properties (msg/default)
*/
protected function getCustomFilters() {
- // @todo Fire a Special{$this->getName()}Filters hook here
- return array();
+ if ( $this->customFilters === null ) {
+ $this->customFilters = array();
+ wfRunHooks( 'ChangesListSpecialPageFilters', array( $this, &$this->customFilters ) );
+ }
+
+ return $this->customFilters;
}
/**
*
* Intended for subclassing, e.g. to add a backwards-compatibility layer.
*
- * @param FormOptions $parameters
+ * @param FormOptions $opts
* @return FormOptions
*/
protected function fetchOptionsFromRequest( $opts ) {
$opts->fetchValuesFromRequest( $this->getRequest() );
+
return $opts;
}
''
);
- // @todo Fire a Special{$this->getName()}Query hook here
- // @todo Uncomment and document
- // if ( !wfRunHooks( 'ChangesListSpecialPageQuery',
- // array( &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) )
- // ) {
- // return false;
- // }
+ if ( !wfRunHooks( 'ChangesListSpecialPageQuery',
+ array( $this->getName(), &$tables, &$fields, &$conds, &$query_options, &$join_conds, $opts ) )
+ ) {
+ return false;
+ }
$dbr = $this->getDB();
+
return $dbr->select(
$tables,
$fields,
abstract public function outputChangesList( $rows, $opts );
/**
- * Return the text to be displayed above the changes
+ * Set the text to be displayed above the changes
*
* @param FormOptions $opts
- * @return string XHTML
*/
public function doHeader( $opts ) {
$this->setTopText( $opts );
* @todo This should not be static, then we can drop the parameter
* @todo Not called by anything, should be called by doHeader()
*
- * @param $context the object available as $this in non-static functions
+ * @param IContextSource $context The object available as $this in non-static functions
* @return string
*/
public static function makeLegend( IContextSource $context ) {
global $wgRecentChangesFlags;
$user = $context->getUser();
# The legend showing what the letters and stuff mean
- $legend = Xml::openElement( 'dl' ) . "\n";
+ $legend = Html::openElement( 'dl' ) . "\n";
# Iterates through them and gets the messages for both letter and tooltip
$legendItems = $wgRecentChangesFlags;
- if ( !$user->useRCPatrol() ) {
+ if ( !( $user->useRCPatrol() || $user->useNPPatrol() ) ) {
unset( $legendItems['unpatrolled'] );
}
- foreach ( $legendItems as $key => $legendInfo ) { # generate items of the legend
- $label = $legendInfo['title'];
- $letter = $legendInfo['letter'];
- $cssClass = isset( $legendInfo['class'] ) ? $legendInfo['class'] : $key;
+ foreach ( $legendItems as $key => $item ) { # generate items of the legend
+ $label = isset( $item['legend'] ) ? $item['legend'] : $item['title'];
+ $letter = $item['letter'];
+ $cssClass = isset( $item['class'] ) ? $item['class'] : $key;
- $legend .= Xml::element( 'dt',
+ $legend .= Html::element( 'dt',
array( 'class' => $cssClass ), $context->msg( $letter )->text()
+ ) . "\n" .
+ Html::rawElement( 'dd', array(),
+ $context->msg( $label )->parse()
) . "\n";
- if ( $key === 'newpage' ) {
- $legend .= Xml::openElement( 'dd' );
- $legend .= $context->msg( $label )->escaped();
- $legend .= ' ' . $context->msg( 'recentchanges-legend-newpage' )->parse();
- $legend .= Xml::closeElement( 'dd' ) . "\n";
- } else {
- $legend .= Xml::element( 'dd', array(),
- $context->msg( $label )->text()
- ) . "\n";
- }
}
# (+-123)
- $legend .= Xml::tags( 'dt',
+ $legend .= Html::rawElement( 'dt',
array( 'class' => 'mw-plusminus-pos' ),
$context->msg( 'recentchanges-legend-plusminus' )->parse()
) . "\n";
- $legend .= Xml::element(
+ $legend .= Html::element(
'dd',
array( 'class' => 'mw-changeslist-legend-plusminus' ),
$context->msg( 'recentchanges-label-plusminus' )->text()
) . "\n";
- $legend .= Xml::closeElement( 'dl' ) . "\n";
+ $legend .= Html::closeElement( 'dl' ) . "\n";
# Collapsibility
$legend =
$out->addModules( 'mediawiki.special.changeslist.legend.js' );
}
- /**
- * Return an array with a ChangesFeed object and ChannelFeed object.
- *
- * This is intentionally not abstract not to require subclasses which don't
- * use feeds functionality to implement it.
- *
- * @param string $feedFormat Feed's format (either 'rss' or 'atom')
- * @return array
- */
- public function getFeedObject( $feedFormat ) {
- throw new MWException( "Not implemented" );
- }
-
- /**
- * Get last-modified date, for client caching. Not implemented by default
- * (returns current time).
- *
- * @param string $feedFormat
- * @return string|bool
- */
- public function checkLastModified( $feedFormat ) {
- return wfTimestampNow();
- }
-
protected function getGroupName() {
return 'changes';
}