r17979 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r17978‎ | r17979 | r17980 >
Date:17:02, 28 November 2006
Author:tstarling
Status:old
Tags:
Comment:
rel2abs function. Based on patch from bug 8021 by AzaTht, with significant changes by me for efficiency and style.
Modified paths:
  • /trunk/extensions/ParserFunctions/ParserFunctions.php (modified) (history)

Diff [purge]

Index: trunk/extensions/ParserFunctions/ParserFunctions.php
@@ -103,7 +103,64 @@
104104 return '';
105105 }
106106 }
107 -
 107+
 108+ /**
 109+ * Returns the absolute path to a subpage, relative to the current article
 110+ * title. Treats titles as slash-separated paths.
 111+ *
 112+ * Following subpage link syntax instead of standard path syntax, an
 113+ * initial slash is treated as a relative path, and vice versa.
 114+ */
 115+ public function rel2abs( &$parser , $to = '' ) {
 116+
 117+ $from = $parser->mTitle->getPrefixedText();
 118+ $to = rtrim( $to , ' /' );
 119+
 120+ // if we have an empty path, or just one containing a dot
 121+ if( $to == '' || $to == '.' ) {
 122+ return $from;
 123+ }
 124+
 125+ // if the path isn't relative
 126+ if ( substr( $to , 0 , 1) != '/' &&
 127+ substr( $to , 0 , 2) != './' &&
 128+ substr( $to , 0 , 3) != '../' &&
 129+ $to != '..' )
 130+ {
 131+ return $to;
 132+ }
 133+ // Make a long path, containing both, enclose it in /.../
 134+ $fullPath = '/' . $from . '/' . $to . '/';
 135+
 136+ // remove redundant current path dots
 137+ $fullPath = preg_replace( '!/(\./)+!', '/', $fullPath );
 138+
 139+ // remove double slashes
 140+ $fullPath = preg_replace( '!/{2,}!', '/', $fullPath );
 141+
 142+ // remove the enclosing slashes now
 143+ $fullPath = trim( $fullPath , '/' );
 144+ $exploded = explode ( '/' , $fullPath );
 145+ $newExploded = array();
 146+
 147+ foreach ( $exploded as $current ) {
 148+ if( $current == '..' ) { // removing one level
 149+ if( !count( $newExploded ) ){
 150+ // attempted to access a node above root node
 151+ return wfMsgForContent( 'pfunc_rel2abs_invalid_depth', $fullPath );
 152+ }
 153+ // remove last level from the stack
 154+ array_pop( $newExploded );
 155+ } else {
 156+ // add the current level to the stack
 157+ $newExploded[] = $current;
 158+ }
 159+ }
 160+
 161+ // we can now join it again
 162+ return implode( '/' , $newExploded );
 163+ }
 164+
108165 function ifexist( &$parser, $title = '', $then = '', $else = '' ) {
109166 $title = Title::newFromText( $title );
110167 return is_object( $title ) && $title->exists() ? $then : $else;
@@ -157,9 +214,11 @@
158215 $wgParser->setFunctionHook( 'switch', array( &$wgExtParserFunctions, 'switchHook' ) );
159216 $wgParser->setFunctionHook( 'ifexist', array( &$wgExtParserFunctions, 'ifexist' ) );
160217 $wgParser->setFunctionHook( 'time', array( &$wgExtParserFunctions, 'time' ) );
 218+ $wgParser->setFunctionHook( 'rel2abs', array( &$wgExtParserFunctions, 'rel2abs' ) );
161219
162220 $wgMessageCache->addMessage( 'pfunc_time_error', "Error: invalid time" );
163221 $wgMessageCache->addMessage( 'pfunc_time_too_long', "Error: too many #time calls" );
 222+ $wgMessageCache->addMessage( 'pfunc_rel2abs_invalid_depth', "Error: Invalid depth in path: \"$1\" (tried to access a node above the root node)" );
164223
165224 $wgHooks['ParserClearState'][] = array( &$wgExtParserFunctions, 'clearState' );
166225 }
@@ -185,6 +244,7 @@
186245 $magicWords['default'] = array( 0, '#default' );
187246 $magicWords['ifexist'] = array( 0, 'ifexist' );
188247 $magicWords['time'] = array( 0, 'time' );
 248+ $magicWords['rel2abs'] = array( 0, 'rel2abs' );
189249 }
190250 return true;
191251 }