Merge "Remove Parser_LinkHooks and CoreLinkFunctions classes"
This commit is contained in:
commit
afd141c543
5 changed files with 1 additions and 426 deletions
|
|
@ -87,6 +87,7 @@ production.
|
|||
show the most up to date result always instead of being a revision behind.
|
||||
* A bias in wfRandomString() toward digits 1-7 has been corrected. Generated
|
||||
strings will now start with digits 0 and 8-f as often as they should.
|
||||
* (bug 45371) Removed Parser_LinkHooks and CoreLinkFunctions classes.
|
||||
|
||||
=== API changes in 1.22 ===
|
||||
* (bug 46626) xmldoublequote parameter was removed. Because of a bug, the
|
||||
|
|
|
|||
|
|
@ -773,12 +773,10 @@ $wgAutoloadLocalClasses = array(
|
|||
|
||||
# includes/parser
|
||||
'CacheTime' => 'includes/parser/CacheTime.php',
|
||||
'CoreLinkFunctions' => 'includes/parser/CoreLinkFunctions.php',
|
||||
'CoreParserFunctions' => 'includes/parser/CoreParserFunctions.php',
|
||||
'CoreTagHooks' => 'includes/parser/CoreTagHooks.php',
|
||||
'DateFormatter' => 'includes/parser/DateFormatter.php',
|
||||
'LinkHolderArray' => 'includes/parser/LinkHolderArray.php',
|
||||
'LinkMarkerReplacer' => 'includes/parser/Parser_LinkHooks.php',
|
||||
'MWTidy' => 'includes/parser/Tidy.php',
|
||||
'MWTidyWrapper' => 'includes/parser/Tidy.php',
|
||||
'PPCustomFrame_DOM' => 'includes/parser/Preprocessor_DOM.php',
|
||||
|
|
@ -806,7 +804,6 @@ $wgAutoloadLocalClasses = array(
|
|||
'ParserOptions' => 'includes/parser/ParserOptions.php',
|
||||
'ParserOutput' => 'includes/parser/ParserOutput.php',
|
||||
'Parser_DiffTest' => 'includes/parser/Parser_DiffTest.php',
|
||||
'Parser_LinkHooks' => 'includes/parser/Parser_LinkHooks.php',
|
||||
'Preprocessor' => 'includes/parser/Preprocessor.php',
|
||||
'Preprocessor_DOM' => 'includes/parser/Preprocessor_DOM.php',
|
||||
'Preprocessor_Hash' => 'includes/parser/Preprocessor_Hash.php',
|
||||
|
|
|
|||
|
|
@ -236,11 +236,6 @@ define( 'SFH_NO_HASH', 1 );
|
|||
define( 'SFH_OBJECT_ARGS', 2 );
|
||||
/**@}*/
|
||||
|
||||
/**
|
||||
* Flags for Parser::setLinkHook
|
||||
*/
|
||||
define( 'SLH_PATTERN', 1 );
|
||||
|
||||
/**
|
||||
* Flags for Parser::replaceLinkHolders
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,92 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Link functions provided by MediaWiki core; experimental
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Parser
|
||||
*/
|
||||
|
||||
/**
|
||||
* Various core link functions, registered in Parser::firstCallInit()
|
||||
* @ingroup Parser
|
||||
*/
|
||||
class CoreLinkFunctions {
|
||||
/**
|
||||
* @param $parser Parser_LinkHooks
|
||||
* @return bool
|
||||
*/
|
||||
static function register( $parser ) {
|
||||
$parser->setLinkHook( NS_CATEGORY, array( __CLASS__, 'categoryLinkHook' ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parser Parser
|
||||
* @param $holders LinkHolderArray
|
||||
* @param $markers LinkMarkerReplacer
|
||||
* @param Title $title
|
||||
* @param $titleText
|
||||
* @param null $displayText
|
||||
* @param bool $leadingColon
|
||||
* @return bool
|
||||
*/
|
||||
static function defaultLinkHook( $parser, $holders, $markers,
|
||||
Title $title, $titleText, &$displayText = null, &$leadingColon = false ) {
|
||||
if( isset( $displayText ) && $markers->findMarker( $displayText ) ) {
|
||||
# There are links inside of the displayText
|
||||
# For backwards compatibility the deepest links are dominant so this
|
||||
# link should not be handled
|
||||
$displayText = $markers->expand( $displayText );
|
||||
# Return false so that this link is reverted back to WikiText
|
||||
return false;
|
||||
}
|
||||
return $holders->makeHolder( $title, isset( $displayText ) ? $displayText : $titleText, array(), '', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parser Parser
|
||||
* @param $holders LinkHolderArray
|
||||
* @param $markers LinkMarkerReplacer
|
||||
* @param Title $title
|
||||
* @param $titleText
|
||||
* @param null $sortText
|
||||
* @param bool $leadingColon
|
||||
* @return bool|string
|
||||
*/
|
||||
static function categoryLinkHook( $parser, $holders, $markers,
|
||||
Title $title, $titleText, &$sortText = null, &$leadingColon = false ) {
|
||||
global $wgContLang;
|
||||
# When a category link starts with a : treat it as a normal link
|
||||
if( $leadingColon ) return true;
|
||||
if( isset( $sortText ) && $markers->findMarker( $sortText ) ) {
|
||||
# There are links inside of the sortText
|
||||
# For backwards compatibility the deepest links are dominant so this
|
||||
# link should not be handled
|
||||
$sortText = $markers->expand( $sortText );
|
||||
# Return false so that this link is reverted back to WikiText
|
||||
return false;
|
||||
}
|
||||
if( !isset( $sortText ) ) $sortText = $parser->getDefaultSort();
|
||||
$sortText = Sanitizer::decodeCharReferences( $sortText );
|
||||
$sortText = str_replace( "\n", '', $sortText );
|
||||
$sortText = $wgContLang->convertCategoryKey( $sortText );
|
||||
$parser->mOutput->addCategory( $title->getDBkey(), $sortText );
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,326 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Modified version of the PHP parser with hooks for wiki links; experimental
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @file
|
||||
* @ingroup Parser
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parser with LinkHooks experiment
|
||||
* @ingroup Parser
|
||||
*/
|
||||
class Parser_LinkHooks extends Parser {
|
||||
/**
|
||||
* Update this version number when the ParserOutput format
|
||||
* changes in an incompatible way, so the parser cache
|
||||
* can automatically discard old data.
|
||||
*/
|
||||
const VERSION = '1.6.4';
|
||||
|
||||
# Flags for Parser::setLinkHook
|
||||
# Also available as global constants from Defines.php
|
||||
const SLH_PATTERN = 1;
|
||||
|
||||
# Constants needed for external link processing
|
||||
# Everything except bracket, space, or control characters
|
||||
const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F]';
|
||||
const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)([^][<>"\\x00-\\x20\\x7F]+)
|
||||
\\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sx';
|
||||
|
||||
/**#@+
|
||||
* @private
|
||||
*/
|
||||
# Persistent:
|
||||
var $mLinkHooks;
|
||||
|
||||
/**#@-*/
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct( $conf = array() ) {
|
||||
parent::__construct( $conf );
|
||||
$this->mLinkHooks = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do various kinds of initialisation on the first call of the parser
|
||||
*/
|
||||
function firstCallInit() {
|
||||
parent::__construct();
|
||||
if ( !$this->mFirstCall ) {
|
||||
return;
|
||||
}
|
||||
$this->mFirstCall = false;
|
||||
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$this->setHook( 'pre', array( $this, 'renderPreTag' ) );
|
||||
CoreParserFunctions::register( $this );
|
||||
CoreLinkFunctions::register( $this );
|
||||
$this->initialiseVariables();
|
||||
|
||||
wfRunHooks( 'ParserFirstCallInit', array( &$this ) );
|
||||
wfProfileOut( __METHOD__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a link hook, e.g. [[Namepsace:...|display}}
|
||||
* The callback function should have the form:
|
||||
* function myLinkCallback( $parser, $holders, $markers,
|
||||
* Title $title, $titleText, &$sortText = null, &$leadingColon = false ) { ... }
|
||||
*
|
||||
* Or with SLH_PATTERN:
|
||||
* function myLinkCallback( $parser, $holders, $markers, )
|
||||
* &$titleText, &$sortText = null, &$leadingColon = false ) { ... }
|
||||
*
|
||||
* The callback may either return a number of different possible values:
|
||||
* String) Text result of the link
|
||||
* True) (Treat as link) Parse the link according to normal link rules
|
||||
* False) (Bad link) Just output the raw wikitext (You may modify the text first)
|
||||
*
|
||||
* @param $ns Integer or String: the Namespace ID or regex pattern if SLH_PATTERN is set
|
||||
* @param $callback Mixed: the callback function (and object) to use
|
||||
* @param $flags Integer: a combination of the following flags:
|
||||
* SLH_PATTERN Use a regex link pattern rather than a namespace
|
||||
*
|
||||
* @throws MWException
|
||||
* @return callback|null The old callback function for this name, if any
|
||||
*/
|
||||
public function setLinkHook( $ns, $callback, $flags = 0 ) {
|
||||
if( $flags & SLH_PATTERN && !is_string($ns) )
|
||||
throw new MWException( __METHOD__ . '() expecting a regex string pattern.' );
|
||||
elseif( $flags | ~SLH_PATTERN && !is_int( $ns ) )
|
||||
throw new MWException( __METHOD__ . '() expecting a namespace index.' );
|
||||
$oldVal = isset( $this->mLinkHooks[$ns] ) ? $this->mLinkHooks[$ns][0] : null;
|
||||
$this->mLinkHooks[$ns] = array( $callback, $flags );
|
||||
return $oldVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered link hook identifiers
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getLinkHooks() {
|
||||
return array_keys( $this->mLinkHooks );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process [[ ]] wikilinks
|
||||
* @param $s
|
||||
* @throws MWException
|
||||
* @return LinkHolderArray
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function replaceInternalLinks2( &$s ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
wfProfileIn( __METHOD__ . '-setup' );
|
||||
static $tc = false, $titleRegex; //$e1, $e1_img;
|
||||
if( !$tc ) {
|
||||
# the % is needed to support urlencoded titles as well
|
||||
$tc = Title::legalChars() . '#%';
|
||||
# Match a link having the form [[namespace:link|alternate]]trail
|
||||
//$e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
|
||||
# Match cases where there is no "]]", which might still be images
|
||||
//$e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
|
||||
# Match a valid plain title
|
||||
$titleRegex = "/^([{$tc}]+)$/sD";
|
||||
}
|
||||
|
||||
$holders = new LinkHolderArray( $this );
|
||||
|
||||
if( is_null( $this->mTitle ) ) {
|
||||
wfProfileOut( __METHOD__ . '-setup' );
|
||||
wfProfileOut( __METHOD__ );
|
||||
throw new MWException( __METHOD__ . ": \$this->mTitle is null\n" );
|
||||
}
|
||||
|
||||
wfProfileOut( __METHOD__ . '-setup' );
|
||||
|
||||
$offset = 0;
|
||||
$offsetStack = array();
|
||||
$markers = new LinkMarkerReplacer( $this, $holders, array( &$this, 'replaceInternalLinksCallback' ) );
|
||||
while( true ) {
|
||||
$startBracketOffset = strpos( $s, '[[', $offset );
|
||||
$endBracketOffset = strpos( $s, ']]', $offset );
|
||||
# Finish when there are no more brackets
|
||||
if( $startBracketOffset === false && $endBracketOffset === false ) break;
|
||||
# Determine if the bracket is a starting or ending bracket
|
||||
# When we find both, use the first one
|
||||
elseif( $startBracketOffset !== false && $endBracketOffset !== false )
|
||||
$isStart = $startBracketOffset <= $endBracketOffset;
|
||||
# When we only found one, check which it is
|
||||
else $isStart = $startBracketOffset !== false;
|
||||
$bracketOffset = $isStart ? $startBracketOffset : $endBracketOffset;
|
||||
if( $isStart ) {
|
||||
/** Opening bracket **/
|
||||
# Just push our current offset in the string onto the stack
|
||||
$offsetStack[] = $startBracketOffset;
|
||||
} else {
|
||||
/** Closing bracket **/
|
||||
# Pop the start pos for our current link zone off the stack
|
||||
$startBracketOffset = array_pop( $offsetStack );
|
||||
# Just to clean up the code, lets place offsets on the outer ends
|
||||
$endBracketOffset += 2;
|
||||
|
||||
# Only do logic if we actually have a opening bracket for this
|
||||
if( isset( $startBracketOffset ) ) {
|
||||
# Extract text inside the link
|
||||
@list( $titleText, $paramText ) = explode( '|',
|
||||
substr( $s, $startBracketOffset + 2, $endBracketOffset - $startBracketOffset - 4 ), 2 );
|
||||
# Create markers only for valid links
|
||||
if( preg_match( $titleRegex, $titleText ) ) {
|
||||
# Store the text for the marker
|
||||
$marker = $markers->addMarker( $titleText, $paramText );
|
||||
# Replace the current link with the marker
|
||||
$s = substr( $s, 0, $startBracketOffset ) .
|
||||
$marker .
|
||||
substr( $s, $endBracketOffset );
|
||||
# We have modified $s, because of this we need to set the
|
||||
# offset manually since the end position is different now
|
||||
$offset = $startBracketOffset+strlen( $marker );
|
||||
continue;
|
||||
}
|
||||
# ToDo: Some LinkHooks may allow recursive links inside of
|
||||
# the link text, create a regex that also matches our
|
||||
# <!-- LINKMARKER ### --> sequence in titles
|
||||
# ToDO: Some LinkHooks use patterns rather than namespaces
|
||||
# these need to be tested at this point here
|
||||
}
|
||||
}
|
||||
# Bump our offset to after our current bracket
|
||||
$offset = $bracketOffset+2;
|
||||
}
|
||||
|
||||
# Now expand our tree
|
||||
wfProfileIn( __METHOD__ . '-expand' );
|
||||
$s = $markers->expand( $s );
|
||||
wfProfileOut( __METHOD__ . '-expand' );
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $holders;
|
||||
}
|
||||
|
||||
function replaceInternalLinksCallback( $parser, $holders, $markers, $titleText, $paramText ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
$wt = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
|
||||
wfProfileIn( __METHOD__ . "-misc" );
|
||||
|
||||
# Don't allow internal links to pages containing
|
||||
# PROTO: where PROTO is a valid URL protocol; these
|
||||
# should be external links.
|
||||
if( preg_match( '/^\b(?i:' . wfUrlProtocols() . ')/', $titleText ) ) {
|
||||
wfProfileOut( __METHOD__ . "-misc" );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $wt;
|
||||
}
|
||||
|
||||
# Make subpage if necessary
|
||||
if( $this->areSubpagesAllowed() ) {
|
||||
$titleText = $this->maybeDoSubpageLink( $titleText, $paramText );
|
||||
}
|
||||
|
||||
# Check for a leading colon and strip it if it is there
|
||||
$leadingColon = $titleText[0] == ':';
|
||||
if( $leadingColon ) $titleText = substr( $titleText, 1 );
|
||||
|
||||
wfProfileOut( __METHOD__ . "-misc" );
|
||||
# Make title object
|
||||
wfProfileIn( __METHOD__ . "-title" );
|
||||
$title = Title::newFromText( $this->mStripState->unstripNoWiki( $titleText ) );
|
||||
if( !$title ) {
|
||||
wfProfileOut( __METHOD__ . "-title" );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $wt;
|
||||
}
|
||||
$ns = $title->getNamespace();
|
||||
wfProfileOut( __METHOD__ . "-title" );
|
||||
|
||||
# Default for Namespaces is a default link
|
||||
# ToDo: Default for patterns is plain wikitext
|
||||
$return = true;
|
||||
if( isset( $this->mLinkHooks[$ns] ) ) {
|
||||
list( $callback, $flags ) = $this->mLinkHooks[$ns];
|
||||
if( $flags & SLH_PATTERN ) {
|
||||
$args = array( $parser, $holders, $markers, $titleText, &$paramText, &$leadingColon );
|
||||
} else {
|
||||
$args = array( $parser, $holders, $markers, $title, $titleText, &$paramText, &$leadingColon );
|
||||
}
|
||||
# Workaround for PHP bug 35229 and similar
|
||||
if ( !is_callable( $callback ) ) {
|
||||
throw new MWException( "Tag hook for namespace $ns is not callable\n" );
|
||||
}
|
||||
$return = call_user_func_array( $callback, $args );
|
||||
}
|
||||
if( $return === true ) {
|
||||
# True (treat as plain link) was returned, call the defaultLinkHook
|
||||
$return = CoreLinkFunctions::defaultLinkHook( $parser, $holders, $markers, $title,
|
||||
$titleText, $paramText, $leadingColon );
|
||||
}
|
||||
if( $return === false ) {
|
||||
# False (no link) was returned, output plain wikitext
|
||||
# Build it again as the hook is allowed to modify $paramText
|
||||
$return = isset( $paramText ) ? "[[$titleText|$paramText]]" : "[[$titleText]]";
|
||||
}
|
||||
# Content was returned, return it
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LinkMarkerReplacer {
|
||||
|
||||
protected $markers, $nextId, $parser, $holders, $callback;
|
||||
|
||||
function __construct( $parser, $holders, $callback ) {
|
||||
$this->nextId = 0;
|
||||
$this->markers = array();
|
||||
$this->parser = $parser;
|
||||
$this->holders = $holders;
|
||||
$this->callback = $callback;
|
||||
}
|
||||
|
||||
function addMarker( $titleText, $paramText ) {
|
||||
$id = $this->nextId++;
|
||||
$this->markers[$id] = array( $titleText, $paramText );
|
||||
return "<!-- LINKMARKER $id -->";
|
||||
}
|
||||
|
||||
function findMarker( $string ) {
|
||||
return (bool) preg_match( '/<!-- LINKMARKER [0-9]+ -->/', $string );
|
||||
}
|
||||
|
||||
function expand( $string ) {
|
||||
return StringUtils::delimiterReplaceCallback( "<!-- LINKMARKER ", " -->", array( &$this, 'callback' ), $string );
|
||||
}
|
||||
|
||||
function callback( $m ) {
|
||||
$id = intval( $m[1] );
|
||||
if( !array_key_exists( $id, $this->markers ) ) return $m[0];
|
||||
$args = $this->markers[$id];
|
||||
array_unshift( $args, $this );
|
||||
array_unshift( $args, $this->holders );
|
||||
array_unshift( $args, $this->parser );
|
||||
return call_user_func_array( $this->callback, $args );
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue