"mw-changeslist-line-watched" or "mw-changeslist-line-not-watched", and the
title itself is surrounded by <span></span> tags with class "mw-title".
* Added ContribsPager::reallyDoQuery hook allowing extensions to data to MyContribs
+* Added new hook ParserAfterParse to allow extensions to affect parsed output
+ after the parse is complete but before block level processing, link holder
+ replacement, and so on.
+* (bug 34678) Added InternalParseBeforeSanitize hook which gets called during Parser's
+ internalParse method just before the parser removes unwanted/dangerous HTML tags.
=== Bug fixes in 1.20 ===
* (bug 30245) Use the correct way to construct a log page title.
* The paraminfo module now also contains result properties for most modules
* (bug 32348) Allow descending order for list=alllinks
* (bug 31777) Upload unknown error ``fileexists-forbidden''
+* (bug 32382) Allow descending order for list=iwbacklinks
+* (bug 32381) Allow descending order for list=backlinks, list=embeddedin and list=imageusage
+* (bug 32383) Allow descending order for list=langbacklinks
=== Languages updated in 1.20 ===
&$iwData: output array describing the interwiki with keys iw_url, iw_local,
iw_trans and optionally iw_api and iw_wikiid.
+'InternalParseBeforeSanitize': during Parser's internalParse method just before the
+parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/
+onlyinclude and other processings. Ideal for syntax-extensions after template/parser
+function execution which respect nowiki and HTML-comments.
+&$parser: Parser object
+&$text: string containing partially parsed text
+&$stripState: Parser's internal StripState object
+
'InternalParseBeforeLinks': during Parser's internalParse method before links
-but after noinclude/includeonly/onlyinclude and other processing.
+but after nowiki/noinclude/includeonly/onlyinclude and other processings.
&$parser: Parser object
&$text: string containing partially parsed text
&$stripState: Parser's internal StripState object
this hook and append its values to the key.
$hash: reference to a hash key string which can be modified
+'ParserAfterParse': Called from Parser::parse() just after the call to
+Parser::internalParse() returns
+$parser: parser object
+$text: text being parsed
+$stripState: stripState used (object)
+
'ParserAfterStrip': Same as ParserBeforeStrip
'ParserAfterTidy': Called after Parser::tidy() in Parser::parse()
private $rootTitle;
private $params, $contID, $redirID, $redirect;
- private $bl_ns, $bl_from, $bl_table, $bl_code, $bl_title, $bl_sort, $bl_fields, $hasNS;
+ private $bl_ns, $bl_from, $bl_table, $bl_code, $bl_title, $bl_fields, $hasNS;
/**
* Maps ns and title to pageid
$this->hasNS = $moduleName !== 'imageusage';
if ( $this->hasNS ) {
$this->bl_title = $prefix . '_title';
- $this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
$this->bl_fields = array(
$this->bl_ns,
$this->bl_title
);
} else {
$this->bl_title = $prefix . '_to';
- $this->bl_sort = "{$this->bl_title}, {$this->bl_from}";
$this->bl_fields = array(
$this->bl_title
);
$this->addWhereFld( 'page_namespace', $this->params['namespace'] );
if ( !is_null( $this->contID ) ) {
- $this->addWhere( "{$this->bl_from}>={$this->contID}" );
+ $op = $this->params['dir'] == 'descending' ? '<' : '>';
+ $this->addWhere( "{$this->bl_from}$op={$this->contID}" );
}
if ( $this->params['filterredir'] == 'redirects' ) {
}
$this->addOption( 'LIMIT', $this->params['limit'] + 1 );
- $this->addOption( 'ORDER BY', $this->bl_from );
+ $sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' );
+ $this->addOption( 'ORDER BY', $this->bl_from . $sort );
$this->addOption( 'STRAIGHT_JOIN' );
}
// We can't use LinkBatch here because $this->hasNS may be false
$titleWhere = array();
+ $allRedirNs = array();
+ $allRedirDBkey = array();
foreach ( $this->redirTitles as $t ) {
- $titleWhere[] = "{$this->bl_title} = " . $db->addQuotes( $t->getDBkey() ) .
- ( $this->hasNS ? " AND {$this->bl_ns} = {$t->getNamespace()}" : '' );
+ $redirNs = $t->getNamespace();
+ $redirDBkey = $t->getDBkey();
+ $titleWhere[] = "{$this->bl_title} = " . $db->addQuotes( $redirDBkey ) .
+ ( $this->hasNS ? " AND {$this->bl_ns} = {$redirNs}" : '' );
+ $allRedirNs[] = $redirNs;
+ $allRedirDBkey[] = $redirDBkey;
}
$this->addWhere( $db->makeList( $titleWhere, LIST_OR ) );
$this->addWhereFld( 'page_namespace', $this->params['namespace'] );
if ( !is_null( $this->redirID ) ) {
+ $op = $this->params['dir'] == 'descending' ? '<' : '>';
$first = $this->redirTitles[0];
$title = $db->addQuotes( $first->getDBkey() );
$ns = $first->getNamespace();
$from = $this->redirID;
if ( $this->hasNS ) {
- $this->addWhere( "{$this->bl_ns} > $ns OR " .
+ $this->addWhere( "{$this->bl_ns} $op $ns OR " .
"({$this->bl_ns} = $ns AND " .
- "({$this->bl_title} > $title OR " .
+ "({$this->bl_title} $op $title OR " .
"({$this->bl_title} = $title AND " .
- "{$this->bl_from} >= $from)))" );
+ "{$this->bl_from} $op= $from)))" );
} else {
- $this->addWhere( "{$this->bl_title} > $title OR " .
+ $this->addWhere( "{$this->bl_title} $op $title OR " .
"({$this->bl_title} = $title AND " .
- "{$this->bl_from} >= $from)" );
+ "{$this->bl_from} $op= $from)" );
}
}
if ( $this->params['filterredir'] == 'redirects' ) {
}
$this->addOption( 'LIMIT', $this->params['limit'] + 1 );
- $this->addOption( 'ORDER BY', $this->bl_sort );
+ $orderBy = array();
+ $sort = ( $this->params['dir'] == 'descending' ? ' DESC' : '' );
+ // Don't order by namespace/title if it's constant in the WHERE clause
+ if( $this->hasNS && count( array_unique( $allRedirNs ) ) != 1 ) {
+ $orderBy[] = $this->bl_ns . $sort;
+ }
+ if( count( array_unique( $allRedirDBkey ) ) != 1 ) {
+ $orderBy[] = $this->bl_title . $sort;
+ }
+ $orderBy[] = $this->bl_from . $sort;
+ $this->addOption( 'ORDER BY', $orderBy );
$this->addOption( 'USE INDEX', array( 'page' => 'PRIMARY' ) );
}
ApiBase::PARAM_ISMULTI => true,
ApiBase::PARAM_TYPE => 'namespace'
),
+ 'dir' => array(\r
+ ApiBase::PARAM_DFLT => 'ascending',\r
+ ApiBase::PARAM_TYPE => array(\r
+ 'ascending',\r
+ 'descending'\r
+ )\r
+ ),
'filterredir' => array(
ApiBase::PARAM_DFLT => 'all',
ApiBase::PARAM_TYPE => array(
'pageid' => "Pageid to search. Cannot be used together with {$this->bl_code}title",
'continue' => 'When more results are available, use this to continue',
'namespace' => 'The namespace to enumerate',
+ 'dir' => 'The direction in which to list',
);
if ( $this->getModuleName() != 'embeddedin' ) {
return array_merge( $retval, array(
}
$db = $this->getDB();
+ $op = $params['dir'] == 'descending' ? '<' : '>';
$prefix = $db->addQuotes( $cont[0] );
$title = $db->addQuotes( $this->titleToKey( $cont[1] ) );
$from = intval( $cont[2] );
$this->addWhere(
- "iwl_prefix > $prefix OR " .
+ "iwl_prefix $op $prefix OR " .
"(iwl_prefix = $prefix AND " .
- "(iwl_title > $title OR " .
+ "(iwl_title $op $title OR " .
"(iwl_title = $title AND " .
- "iwl_from >= $from)))"
+ "iwl_from $op= $from)))"
);
}
$this->addFields( array( 'page_id', 'page_title', 'page_namespace', 'page_is_redirect',
'iwl_from', 'iwl_prefix', 'iwl_title' ) );
+ $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
if ( isset( $params['prefix'] ) ) {
$this->addWhereFld( 'iwl_prefix', $params['prefix'] );
if ( isset( $params['title'] ) ) {
$this->addWhereFld( 'iwl_title', $params['title'] );
- $this->addOption( 'ORDER BY', 'iwl_from' );
+ $this->addOption( 'ORDER BY', 'iwl_from' . $sort );
} else {
$this->addOption( 'ORDER BY', array(
- 'iwl_title',
- 'iwl_from'
+ 'iwl_title' . $sort,
+ 'iwl_from' . $sort
));
}
} else {
$this->addOption( 'ORDER BY', array(
- 'iwl_prefix',
- 'iwl_title',
- 'iwl_from'
+ 'iwl_prefix' . $sort,
+ 'iwl_title' . $sort,
+ 'iwl_from' . $sort
));
}
'iwtitle',
),
),
+ 'dir' => array(
+ ApiBase::PARAM_DFLT => 'ascending',
+ ApiBase::PARAM_TYPE => array(
+ 'ascending',
+ 'descending'
+ )
+ ),
);
}
' iwtitle - Adds the title of the interwiki',
),
'limit' => 'How many total pages to return',
+ 'dir' => 'The direction in which to list',
);
}
}
$db = $this->getDB();
+ $op = $params['dir'] == 'descending' ? '<' : '>';
$prefix = $db->addQuotes( $cont[0] );
$title = $db->addQuotes( $this->titleToKey( $cont[1] ) );
$from = intval( $cont[2] );
$this->addWhere(
- "ll_lang > $prefix OR " .
+ "ll_lang $op $prefix OR " .
"(ll_lang = $prefix AND " .
- "(ll_title > $title OR " .
+ "(ll_title $op $title OR " .
"(ll_title = $title AND " .
- "ll_from >= $from)))"
+ "ll_from $op= $from)))"
);
}
$this->addFields( array( 'page_id', 'page_title', 'page_namespace', 'page_is_redirect',
'll_from', 'll_lang', 'll_title' ) );
+ $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
if ( isset( $params['lang'] ) ) {
$this->addWhereFld( 'll_lang', $params['lang'] );
if ( isset( $params['title'] ) ) {
$this->addWhereFld( 'll_title', $params['title'] );
- $this->addOption( 'ORDER BY', 'll_from' );
+ $this->addOption( 'ORDER BY', 'll_from' . $sort );
} else {
$this->addOption( 'ORDER BY', array(
- 'll_title',
- 'll_from'
+ 'll_title' . $sort,
+ 'll_from' . $sort
));
}
} else {
$this->addOption( 'ORDER BY', array(
- 'll_lang',
- 'll_title',
- 'll_from'
+ 'll_lang' . $sort,
+ 'll_title' . $sort,
+ 'll_from' . $sort
));
}
'lltitle',
),
),
+ 'dir' => array(
+ ApiBase::PARAM_DFLT => 'ascending',
+ ApiBase::PARAM_TYPE => array(
+ 'ascending',
+ 'descending'
+ )
+ ),
);
}
' lltitle - Adds the title of the language ink',
),
'limit' => 'How many total pages to return',
+ 'dir' => 'The direction in which to list',
);
}
# No more strip!
wfRunHooks( 'ParserAfterStrip', array( &$this, &$text, &$this->mStripState ) );
$text = $this->internalParse( $text );
+ wfRunHooks( 'ParserAfterParse', array( &$this, &$text, &$this->mStripState ) );
$text = $this->mStripState->unstripGeneral( $text );
$text = $this->replaceVariables( $text );
}
+ wfRunHooks( 'InternalParseBeforeSanitize', array( &$this, &$text, &$this->mStripState ) );
$text = Sanitizer::removeHTMLtags( $text, array( &$this, 'attributeStripCallback' ), false, array_keys( $this->mTransparentTagHooks ) );
wfRunHooks( 'InternalParseBeforeLinks', array( &$this, &$text, &$this->mStripState ) );
--- /dev/null
+<?php\r
+/**\r
+ * Description: This script takes $wgHiddenPrefs and removes their preference from the DB. [[bugzilla:30976]]\r
+ * @author TyA <tya.wiki@gmail.com>\r
+ * @ingroup Maintenance\r
+ */\r
+\r
+require_once( dirname( __FILE__ ) . '/Maintenance.php' );\r
+\r
+class CleanupPreferences extends Maintenance {\r
+ public function execute() {\r
+ global $wgHiddenPrefs;\r
+\r
+ $dbw = wfGetDB( DB_MASTER );\r
+ $dbw->begin();\r
+ foreach( $wgHiddenPrefs as $item ) {\r
+ $dbw->delete(\r
+ 'user_properties',\r
+ array( 'up_property' => $item ),\r
+ __METHOD__\r
+ );\r
+ };\r
+ $dbw->commit();\r
+ $this->output( "Finished!\n" );\r
+ }\r
+}\r
+\r
+$maintClass = 'CleanupPreferences'; // Tells it to run the class\r
+require_once( RUN_MAINTENANCE_IF_MAIN );\r
* Generates a random user session ID (32 alpha-numeric characters).
*
* This information would potentially be stored in a cookie to identify a user during a
- * session or series of sessions. It's uniqueness should not be depended on.
+ * session or series of sessions. Its uniqueness should not be depended on.
*
* @return String: Random set of 32 alpha-numeric characters
*/
// This is kind of ugly but we're stuck with this for b/c reasons
mw.user = new User( mw.user.options, mw.user.tokens );
-})(jQuery);
\ No newline at end of file
+})(jQuery);