Index: tags/extensions/HashTables/REL_0_7/HashTables.i18n.magic.php |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +<?php |
| 3 | +#coding: utf-8 |
| 4 | + |
| 5 | +/** |
| 6 | + * Internationalization file for magic words of the 'HashTables' extension. |
| 7 | + * |
| 8 | + * @since 0.6.3 |
| 9 | + * |
| 10 | + * @file HashTables.i18n.magic.php |
| 11 | + * @ingroup HashTables |
| 12 | + * @author Daniel Werner < danweetz@web.de > |
| 13 | + */ |
| 14 | + |
| 15 | +$magicWords = array(); |
| 16 | + |
| 17 | +$magicWords['en'] = array( |
| 18 | + |
| 19 | + # hash construction: |
| 20 | + 'hashdefine' => array( 0, 'hashdefine' ), |
| 21 | + 'parameterstohash' => array( 0, 'parameterstohash' ), |
| 22 | + |
| 23 | + # output: |
| 24 | + 'hashprint' => array( 0, 'hashprint' ), |
| 25 | + 'hashvalue' => array( 0, 'hashvalue' ), |
| 26 | + 'hashsize' => array( 0, 'hashsize' ), |
| 27 | + 'hashkeyexists' => array( 0, 'hashkeyexists' ), |
| 28 | + |
| 29 | + # Alteration: |
| 30 | + 'hashinclude' => array( 0, 'hashinclude' ), |
| 31 | + 'hashexclude' => array( 0, 'hashexclude' ), |
| 32 | + 'hashreset' => array( 0, 'hashreset' ), |
| 33 | + |
| 34 | + # Interaction between hash tables: |
| 35 | + 'hashmerge' => array( 0, 'hashmerge' ), |
| 36 | + 'hashmix' => array( 0, 'hashmix' ), |
| 37 | + 'hashdiff' => array( 0, 'hashdiff' ), |
| 38 | + 'hashintersect' => array( 0, 'hashintersect' ), |
| 39 | + |
| 40 | + # Interaction with 'ArrayExtension': |
| 41 | + 'hashtoarray' => array( 0, 'hashtoarray' ), |
| 42 | + 'arraytohash' => array( 0, 'arraytohash' ), |
| 43 | + |
| 44 | + # Experimental: |
| 45 | + 'hashtotemplate' => array( 0, 'hashtotemplate' ), |
| 46 | +); |
Property changes on: tags/extensions/HashTables/REL_0_7/HashTables.i18n.magic.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 47 | + native |
Index: tags/extensions/HashTables/REL_0_7/HashTables.i18n.php |
— | — | @@ -0,0 +1,84 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalization file of the 'HashTables' extension. |
| 5 | + * |
| 6 | + * @since 0.6.3 |
| 7 | + * |
| 8 | + * @file HashTables.i18n.php |
| 9 | + * @ingroup HashTables |
| 10 | + * @author Daniel Werner < danweetz@web.de > |
| 11 | + */ |
| 12 | + |
| 13 | +$messages = array(); |
| 14 | + |
| 15 | +/** English |
| 16 | + * @author Daniel Werner |
| 17 | + */ |
| 18 | +$messages['en'] = array( |
| 19 | + 'hashtables-desc' => 'Parser functions allowing to work with hash tables in a page scoped context', |
| 20 | +); |
| 21 | + |
| 22 | +/** German (Deutsch) |
| 23 | + * @author Daniel Werner |
| 24 | + * @author Kghbln |
| 25 | + */ |
| 26 | +$messages['de'] = array( |
| 27 | + 'hashtables-desc' => 'Ergänzt Parserfunktionen die assoziative Datenfelder (Hashes) auf Wikiseiten ermöglichen sowie nutzbar machen', |
| 28 | +); |
| 29 | + |
| 30 | +/** French (Français) |
| 31 | + * @author Gomoko |
| 32 | + */ |
| 33 | +$messages['fr'] = array( |
| 34 | + 'hashtables-desc' => "Fonctions du parseur permettant de travailler avec des tables de hachage dans le contexte d'une page.", |
| 35 | +); |
| 36 | + |
| 37 | +/** Galician (Galego) |
| 38 | + * @author Toliño |
| 39 | + */ |
| 40 | +$messages['gl'] = array( |
| 41 | + 'hashtables-desc' => 'Funcións analíticas destinadas ás páxinas que permiten traballar con táboas hash', |
| 42 | +); |
| 43 | + |
| 44 | +/** Upper Sorbian (Hornjoserbsce) |
| 45 | + * @author Michawiki |
| 46 | + */ |
| 47 | +$messages['hsb'] = array( |
| 48 | + 'hashtables-desc' => 'Parserowe funkcije, kotrež tabele hašow (asociatiwne datowe pola) zmóžnjeja', |
| 49 | +); |
| 50 | + |
| 51 | +/** Interlingua (Interlingua) |
| 52 | + * @author McDutchie |
| 53 | + */ |
| 54 | +$messages['ia'] = array( |
| 55 | + 'hashtables-desc' => 'Functiones del analysator syntactic que permitte laborar con tabellas de hash in un "page scoped context"', |
| 56 | +); |
| 57 | + |
| 58 | +/** Luxembourgish (Lëtzebuergesch) |
| 59 | + * @author Robby |
| 60 | + */ |
| 61 | +$messages['lb'] = array( |
| 62 | + 'hashtables-desc' => 'Parserfonctiounen déi et erlabe fir mat assoziativen Datefelder (hash tables) am Kontext vu Wikisäiten ze schaffen', |
| 63 | +); |
| 64 | + |
| 65 | +/** Macedonian (Македонски) |
| 66 | + * @author Bjankuloski06 |
| 67 | + */ |
| 68 | +$messages['mk'] = array( |
| 69 | + 'hashtables-desc' => 'Парсерски функции што овозможуваат работа со тарабни табели во контекст со опфатност определена во страница', |
| 70 | +); |
| 71 | + |
| 72 | +/** Dutch (Nederlands) |
| 73 | + * @author Siebrand |
| 74 | + */ |
| 75 | +$messages['nl'] = array( |
| 76 | + 'hashtables-desc' => 'Parserfuncties die het mogelijk maken om met hashtabellen te werken in een paginacontext', |
| 77 | +); |
| 78 | + |
| 79 | +/** Piedmontese (Piemontèis) |
| 80 | + * @author Borichèt |
| 81 | + */ |
| 82 | +$messages['pms'] = array( |
| 83 | + 'hashtables-desc' => "Funsion ëd parser ch'a përmëtto ëd travajé con tàule ëd taj ant ël contest ëd na pàgina", |
| 84 | +); |
| 85 | + |
Property changes on: tags/extensions/HashTables/REL_0_7/HashTables.i18n.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 86 | + native |
Index: tags/extensions/HashTables/REL_0_7/HashTables.php |
— | — | @@ -0,0 +1,686 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +/** |
| 5 | + * Defines a subset of parser functions to handle hash tables. Inspired by the ArrayExtension |
| 6 | + * (http://www.mediawiki.org/wiki/Extension:ArrayExtension). |
| 7 | + * |
| 8 | + * @version: 0.7 |
| 9 | + * @author: Daniel Werner < danweetz@web.de > |
| 10 | + * @license: ISC license |
| 11 | + * |
| 12 | + * Documentation: http://www.mediawiki.org/wiki/Extension:HashTables |
| 13 | + * Support: http://www.mediawiki.org/wiki/Extension_talk:HashTables |
| 14 | + * Source code: http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/HashTables |
| 15 | + * |
| 16 | + * @file HashTables.php |
| 17 | + * @ingroup HashTables |
| 18 | + * |
| 19 | + * @ToDo: |
| 20 | + * ====== |
| 21 | + * - binding one hash tables instance per initialized parser instead of having one global one. |
| 22 | + * Thinking about: |
| 23 | + * - Sort function |
| 24 | + * - Search function |
| 25 | + * |
| 26 | + */ |
| 27 | + |
| 28 | +if( !defined( 'MEDIAWIKI' ) ) { |
| 29 | + die( 'This file is a MediaWiki extension, it is not a valid entry point' ); |
| 30 | +} |
| 31 | + |
| 32 | +$wgExtensionCredits['parserhook'][] = array( |
| 33 | + 'path' => __FILE__, |
| 34 | + 'name' => 'HashTables', |
| 35 | + 'descriptionmsg' => 'hashtables-desc', |
| 36 | + 'version' => ExtHashTables::VERSION, |
| 37 | + 'author' => '[http://www.mediawiki.org/wiki/User:Danwe Daniel Werner]', |
| 38 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:HashTables', |
| 39 | +); |
| 40 | + |
| 41 | +$wgHooks['ParserFirstCallInit'][] = 'efHashTablesParserFirstCallInit'; |
| 42 | + |
| 43 | +$dir = dirname( __FILE__ ); |
| 44 | + |
| 45 | +$wgExtensionMessagesFiles['HashTables' ] = $dir . '/HashTables.i18n.php'; |
| 46 | +$wgExtensionMessagesFiles['HashTablesMagic'] = $dir . '/HashTables.i18n.magic.php'; |
| 47 | + |
| 48 | +unset( $dir ); |
| 49 | + |
| 50 | +/** |
| 51 | + * Extension class with all the hash table functionality |
| 52 | + */ |
| 53 | +class ExtHashTables { |
| 54 | + |
| 55 | + /** |
| 56 | + * Version of the 'HashTables' extension. |
| 57 | + * |
| 58 | + * @since 0.6.1 |
| 59 | + * |
| 60 | + * @var string |
| 61 | + */ |
| 62 | + const VERSION = '0.7'; |
| 63 | + |
| 64 | + /** |
| 65 | + * @since 0.1 |
| 66 | + * |
| 67 | + * @var array |
| 68 | + * @private |
| 69 | + */ |
| 70 | + var $mHashTables = array(); |
| 71 | + |
| 72 | + function __construct() { |
| 73 | + global $wgHooks; |
| 74 | + $wgHooks['ParserClearState'][] = &$this; |
| 75 | + } |
| 76 | + |
| 77 | + function onParserClearState( &$parser ) { |
| 78 | + // remove all hash tables to avoid conflicts with job queue or Special:Import |
| 79 | + $this->mHashTables = array(); |
| 80 | + return true; |
| 81 | + } |
| 82 | + |
| 83 | + /** |
| 84 | + * Define an hash by a list of 'values' deliminated by 'itemsDelimiter'. |
| 85 | + * Hash keys and their values are deliminated by 'innerDelimiter'. |
| 86 | + * Both delimiters can be perl regular expression patterns. |
| 87 | + * Syntax: {{#hashdefine:hashId |values |itemsDelimiter |innerDelimiter}} |
| 88 | + */ |
| 89 | + function hashdefine( &$parser, $hashId, $value='', $itemsDelimiter = '/\s*,\s*/', $innerDelimiter = '/\s*;\s*/' ) { |
| 90 | + if( !isset($hashId) ) { |
| 91 | + return ''; |
| 92 | + } |
| 93 | + $this->mHashTables[ $hashId ] = array(); |
| 94 | + |
| 95 | + if( $value !== '' ) { |
| 96 | + |
| 97 | + // Build delimiters: |
| 98 | + if ( ! $this->isValidRegEx($itemsDelimiter,'/') ) |
| 99 | + $itemsDelimiter = '/\s*' . preg_quote( $itemsDelimiter, '/' ) . '\s*/'; |
| 100 | + |
| 101 | + if ( ! $this->isValidRegEx($innerDelimiter,'/') ) |
| 102 | + $innerDelimiter = '/\s*' . preg_quote( $innerDelimiter, '/' ) . '\s*/'; |
| 103 | + |
| 104 | + $items = preg_split( $itemsDelimiter, $value ); // All hash Items |
| 105 | + |
| 106 | + foreach ( $items as $itemName => $itemVal ) |
| 107 | + { |
| 108 | + $hashPair = preg_split( $innerDelimiter, $itemVal, 2 ); |
| 109 | + |
| 110 | + if( count($hashPair) < 2 ) |
| 111 | + $this->mHashTables[ $hashId ][ $itemVal ] = ''; // only hash-Name given, could be even '', no value |
| 112 | + else |
| 113 | + $this->mHashTables[ $hashId ][ $hashPair[0] ] = $hashPair[1]; |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + return ''; |
| 118 | + } |
| 119 | + |
| 120 | + /** |
| 121 | + * Returns the value of the hash table item identified by a given item name. |
| 122 | + */ |
| 123 | + function hashvalue( &$parser, $hashId, $key, $default = '' ) { |
| 124 | + if( !isset($hashId) || !isset($key) ) |
| 125 | + return ''; |
| 126 | + |
| 127 | + $value = $this->getHashValue( $hashId, $key, '' ); |
| 128 | + |
| 129 | + if( $value === '' ) { |
| 130 | + $value = $default; |
| 131 | + } |
| 132 | + |
| 133 | + return $value; |
| 134 | + } |
| 135 | + |
| 136 | + /** |
| 137 | + * Returns the size of a hash table. Returns '' if the table doesn't exist. |
| 138 | + */ |
| 139 | + function hashsize( &$parser, $hashId) { |
| 140 | + if( ! isset($hashId) || ! $this->hashExists($hashId) ) { |
| 141 | + return ''; |
| 142 | + } |
| 143 | + return count( $this->mHashTables[ $hashId ] ); |
| 144 | + } |
| 145 | + |
| 146 | + /** |
| 147 | + * Returns "1" or the third parameter (if set) if the hash item key 'key' exists inside the hash |
| 148 | + * table 'hashId'. Otherwise the output will be a void string or the fourth (if set). |
| 149 | + */ |
| 150 | + function hashkeyexists( Parser &$parser, PPFrame $frame, $args ) { |
| 151 | + $hashId = trim( $frame->expand( $args[0] ) ); |
| 152 | + $key = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : ''; |
| 153 | + |
| 154 | + // get hash or null: |
| 155 | + $hash = $this->getHash( $hashId ); |
| 156 | + |
| 157 | + // only expand the one argument needed: |
| 158 | + if( $hash !== null && array_key_exists( $key, $hash ) ) { |
| 159 | + return isset( $args[2] ) ? trim( $frame->expand( $args[2] ) ) : '1'; // true '1' |
| 160 | + } |
| 161 | + else { |
| 162 | + return isset( $args[3] ) ? trim( $frame->expand( $args[3] ) ) : ''; // false '' |
| 163 | + } |
| 164 | + } |
| 165 | + |
| 166 | + /** |
| 167 | + * Allows to print all entries of a hash table seperated by a delimiter. |
| 168 | + * Syntax: |
| 169 | + * {{#hashprint:hashID |seperator |keyPattern |valuePattern |subject |printOrderArrayId}} |
| 170 | + */ |
| 171 | + function hashprint( Parser &$parser, PPFrame $frame, $args ) { |
| 172 | + if( ! isset( $args[0] ) ) { |
| 173 | + return ''; |
| 174 | + } |
| 175 | + $hashId = trim( $frame->expand( $args[0] ) ); |
| 176 | + $values = $this->getHash( $hashId ); |
| 177 | + |
| 178 | + if( $values === null ) { |
| 179 | + return ''; |
| 180 | + } |
| 181 | + |
| 182 | + // parameter validation: |
| 183 | + $seperator = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : ', '; |
| 184 | + /* |
| 185 | + * PPFrame::NO_ARGS and PPFrame::NO_TEMPLATES for expansion make a lot of sense here since the patterns getting replaced |
| 186 | + * in $subject before $subject is being parsed. So any template or argument influence in the patterns wouldn't make any |
| 187 | + * sense in any sane scenario. |
| 188 | + */ |
| 189 | + $keyPattern = isset( $args[2] ) ? trim( $frame->expand( $args[2], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : ''; |
| 190 | + $valuePattern = isset( $args[3] ) ? trim( $frame->expand( $args[3], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : '@@@@'; |
| 191 | + $subject = isset( $args[4] ) ? trim( $frame->expand( $args[4], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : '@@@@'; |
| 192 | + $printOrderArrayId = isset( $args[5] ) ? trim( $frame->expand( $args[5] ) ) : null; |
| 193 | + |
| 194 | + if( $printOrderArrayId !== null ) { |
| 195 | + global $wgArrayExtension; |
| 196 | + |
| 197 | + if( ! isset( $wgArrayExtension ) ) { |
| 198 | + return ''; // array extension not found |
| 199 | + } |
| 200 | + // if array with print order doesn't exist |
| 201 | + if( ! array_key_exists( $printOrderArrayId, $wgArrayExtension->mArrayExtension ) ) { |
| 202 | + return ''; |
| 203 | + } |
| 204 | + $printOrderArray = $wgArrayExtension->mArrayExtension[ $printOrderArrayId ]; |
| 205 | + } |
| 206 | + else { |
| 207 | + // No print order given, copy hash keys in print order array |
| 208 | + $printOrderArray = array_keys( $values ); |
| 209 | + } |
| 210 | + |
| 211 | + $renderedResults = array(); |
| 212 | + |
| 213 | + foreach( $printOrderArray as $itemKey ) { |
| 214 | + if( ! array_key_exists($itemKey, $values) ) { |
| 215 | + continue; |
| 216 | + } |
| 217 | + $itemVal = $values[ $itemKey ]; // get value of the current print item from the values array |
| 218 | + |
| 219 | + $rawResult = $subject; |
| 220 | + if( $keyPattern !== '' ) { |
| 221 | + $rawResult = str_replace($keyPattern, $itemKey, $rawResult); |
| 222 | + } |
| 223 | + if( $valuePattern !== '' ) { |
| 224 | + $rawResult = str_replace($valuePattern, $itemVal, $rawResult); |
| 225 | + } |
| 226 | + |
| 227 | + /** @todo: it doesn't make sense to check whether we are in template or not |
| 228 | + * Parser::PTD_FOR_INCLUSION should be used in any case propably. |
| 229 | + */ |
| 230 | + $rawResult = $parser->preprocessToDom( $rawResult, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 ); |
| 231 | + $rawResult = trim( $frame->expand( $rawResult ) ); |
| 232 | + |
| 233 | + $renderedResults[] = $rawResult ; |
| 234 | + } |
| 235 | + return array( implode( $seperator, $renderedResults) , 'noparse' => false, 'isHTML' => false ); |
| 236 | + } |
| 237 | + |
| 238 | + /** |
| 239 | + * Define an hash filled with all given parameters of the current template. |
| 240 | + * In case there are no parameters, the hash will be void. |
| 241 | + */ |
| 242 | + function parameterstohash( &$parser, PPFrame $frame, $args) { |
| 243 | + if( ! isset( $args[0] ) ) { |
| 244 | + return ''; |
| 245 | + } |
| 246 | + $hashId = trim( $frame->expand( $args[0] ) ); |
| 247 | + $this->mHashTables[ $hashId ] = array(); // create empty hash table |
| 248 | + |
| 249 | + // in case the page is not used as template i.e. when displayed on its own |
| 250 | + if( ! $frame->isTemplate() ) { |
| 251 | + return ''; |
| 252 | + } |
| 253 | + |
| 254 | + $templateArgs = $frame->getArguments(); |
| 255 | + |
| 256 | + foreach ( $templateArgs as $argName => $argVal ) { |
| 257 | + $this->mHashTables[ $hashId ][ trim( $argName ) ] = trim( $argVal ); |
| 258 | + } |
| 259 | + return ''; |
| 260 | + } |
| 261 | + |
| 262 | + /** |
| 263 | + * Resets the hashes given in parameter 1 to n. If there are no parameters given, |
| 264 | + * the function will reset all hashes. |
| 265 | + */ |
| 266 | + function hashreset( &$parser, $frame, $args) { |
| 267 | + // reset all hash tables if no specific tables are given: |
| 268 | + if( !isset( $args[0] ) || ( $args[0] === '' && count( $args ) == 1 ) ) { |
| 269 | + $this->mHashTables = array(); |
| 270 | + } |
| 271 | + else { |
| 272 | + foreach ( $args as $arg ) |
| 273 | + { |
| 274 | + $argVal = trim( $frame->expand($arg) ); |
| 275 | + $this->removeHash( $argVal ); |
| 276 | + } |
| 277 | + } |
| 278 | + return ''; |
| 279 | + } |
| 280 | + |
| 281 | + /** |
| 282 | + * Adds new keys and values to a hash table. This function can also be used as alternative |
| 283 | + * way to create hash tables. |
| 284 | + * Syntax: |
| 285 | + * {{#hashinclude:hashID |key1=val1 |key2=val2 |... |key n=val n}} |
| 286 | + */ |
| 287 | + function hashinclude( &$parser, $frame, $args) { |
| 288 | + // get hash table ID from first parameter: |
| 289 | + $hashId = trim( $frame->expand($args[0] ) ); |
| 290 | + unset( $args[0] ); |
| 291 | + |
| 292 | + if( !$this->hashExists($hashId) ) |
| 293 | + $this->mHashTables[ $hashId ] = array(); |
| 294 | + |
| 295 | + // all following parameters contain hash table keys and values '|key=value' |
| 296 | + foreach ( $args as $arg ) |
| 297 | + { |
| 298 | + $argString = $frame->expand($arg); |
| 299 | + $argItem = explode( '=', $argString, 2 ); |
| 300 | + $argName = trim( $argItem[0] ); |
| 301 | + $argVal = ( count( $argItem ) > 1 ) ? trim( $argItem[1] ) : ''; |
| 302 | + |
| 303 | + $this->mHashTables[ $hashId ][ $argName ] = $argVal; |
| 304 | + } |
| 305 | + return ''; |
| 306 | + } |
| 307 | + |
| 308 | + /** |
| 309 | + * Removes certain given keys from a hash table. |
| 310 | + * Syntax: |
| 311 | + * {{#hashexclude:hashID |key1 |key2 |... |key n}} |
| 312 | + */ |
| 313 | + function hashexclude( &$parser, $frame, $args) { |
| 314 | + // get hash table ID from first parameter: |
| 315 | + $hashId = trim( $frame->expand($args[0]) ); |
| 316 | + unset( $args[0] ); |
| 317 | + |
| 318 | + if( !$this->hashExists($hashId) ) |
| 319 | + return''; |
| 320 | + |
| 321 | + // all following parameters contain hash table keys and values '|key=value' |
| 322 | + foreach ( $args as $arg ) |
| 323 | + { |
| 324 | + $argName = trim( $frame->expand($arg) ); |
| 325 | + unset( $this->mHashTables[ $hashId ][ $argName ] ); |
| 326 | + } |
| 327 | + return ''; |
| 328 | + } |
| 329 | + |
| 330 | + /** |
| 331 | + * Merge two or more hash tables like the php function 'array_merge' would merge them. |
| 332 | + * Syntax: |
| 333 | + * {{#hashmerge:hashID |hash1 |hash2 |... |hash n}} |
| 334 | + */ |
| 335 | + function hashmerge( &$parser, $frame, $args) { |
| 336 | + $this->multiHashOperation( $frame, $args, __FUNCTION__, true ); |
| 337 | + return ''; |
| 338 | + } |
| 339 | + private function multi_hashmerge( $hash1, $hash2 = array() ) { |
| 340 | + return array_merge( $hash1, $hash2 ); |
| 341 | + } |
| 342 | + |
| 343 | + /** |
| 344 | + * Mix two or more hash tables. For the most part this function works like 'hashmerge' with one exception: |
| 345 | + * Numeric hash table keys will be treated like string keys. |
| 346 | + * Syntax: |
| 347 | + * {{#hashmix:hashID |hash1 |hash2 |... |hash n}} |
| 348 | + */ |
| 349 | + function hashmix( &$parser, $frame, $args) { |
| 350 | + $this->multiHashOperation( $frame, $args, __FUNCTION__, false ); |
| 351 | + return ''; |
| 352 | + } |
| 353 | + private function multi_hashmix( $hash1, $hash2 ) { |
| 354 | + // copy all entries from hash2 to hash1 |
| 355 | + foreach($hash2 as $key => $value) { |
| 356 | + $hash1[ $key ] = $value; |
| 357 | + } |
| 358 | + return $hash1; |
| 359 | + } |
| 360 | + |
| 361 | + /** |
| 362 | + * Compare two or more hash tables like the php function 'array_diff_key' would compare them. |
| 363 | + * All items contained in the first array but in none of the other ones will end up in the |
| 364 | + * new hash table. |
| 365 | + * Syntax: |
| 366 | + * {{#hashdiff:hashID |hash1 |hash2 |... |hash n}} |
| 367 | + */ |
| 368 | + function hashdiff( &$parser, $frame, $args) { |
| 369 | + $this->multiHashOperation( $frame, $args, __FUNCTION__, false ); |
| 370 | + return ''; |
| 371 | + } |
| 372 | + private function multi_hashdiff( $hash1, $hash2 ) { |
| 373 | + return array_diff_key( $hash1, $hash2 ); |
| 374 | + } |
| 375 | + |
| 376 | + /** |
| 377 | + * Compare two or more hash tables like the php function 'array_intersect_key' would compare them. |
| 378 | + * Creates a new hash table containing all entries of 'hash1' which are present in the other |
| 379 | + * hash tables given in parameters 3 to n. |
| 380 | + * Syntax: |
| 381 | + * {{#hashintersect:hashID |hash1 |hash2 |... |hash n}} |
| 382 | + */ |
| 383 | + function hashintersect( &$parser, $frame, $args) { |
| 384 | + $this->multiHashOperation( $frame, $args, __FUNCTION__, false ); |
| 385 | + return ''; |
| 386 | + } |
| 387 | + private function multi_hashintersect( $hash1, $hash2 ) { |
| 388 | + return array_intersect_key( $hash1, $hash2 ); |
| 389 | + } |
| 390 | + |
| 391 | + /** |
| 392 | + * Create an array from a hash tables values. Optional a seccond array with the keys. If the 'valArrayID' |
| 393 | + * equals the 'keyArrayID', the array will contain only the key names and not the values. |
| 394 | + * Syntax: |
| 395 | + * {{#hashtoarray:valArrayID |hashID |keyArrayID}} |
| 396 | + */ |
| 397 | + function hashtoarray( &$parser, $valArrayId, $hashId, $keyArrayId = null) { |
| 398 | + |
| 399 | + if( !isset($hashId) || !isset($valArrayId) ) |
| 400 | + return ''; |
| 401 | + |
| 402 | + global $wgArrayExtension; |
| 403 | + |
| 404 | + // create void arrays in case hash doesn't exist |
| 405 | + $valArray = array(); |
| 406 | + $keyArray = array(); |
| 407 | + |
| 408 | + if( $this->hashExists($hashId) ) |
| 409 | + { |
| 410 | + $hash = $this->mHashTables[ $hashId ]; |
| 411 | + |
| 412 | + foreach( $hash as $hashKey => $hashVal ) { |
| 413 | + $valArray[] = $hashVal; |
| 414 | + if( $keyArrayId !== null ) |
| 415 | + $keyArray[] = $hashKey; |
| 416 | + } |
| 417 | + } |
| 418 | + |
| 419 | + |
| 420 | + |
| 421 | + $wgArrayExtension->mArrayExtension[ $valArrayId ] = $valArray; |
| 422 | + if( $keyArrayId !== null ) { |
| 423 | + $wgArrayExtension->mArrayExtension[ $keyArrayId ] = $keyArray; |
| 424 | + } |
| 425 | + return ''; |
| 426 | + } |
| 427 | + |
| 428 | + /** |
| 429 | + * Create a hash table from an array. |
| 430 | + * Syntax: |
| 431 | + * {{#arraytohash:hashID |valuesArrayID |keysArrayID}} |
| 432 | + * |
| 433 | + * The 'keysArrayID' is optional. If set the items in this array will end up as keys in |
| 434 | + * the new hash table. |
| 435 | + */ |
| 436 | + function arraytohash( &$parser, $hashId, $valArrId, $keyArrId = null) { |
| 437 | + |
| 438 | + if( !isset($hashId) ) |
| 439 | + return ''; |
| 440 | + |
| 441 | + global $wgArrayExtension; |
| 442 | + |
| 443 | + // if array doesn't exist |
| 444 | + if( !array_key_exists( $valArrId, $wgArrayExtension->mArrayExtension ) ) |
| 445 | + $arrExtValArray = array(); |
| 446 | + else |
| 447 | + $arrExtValArray = $wgArrayExtension->mArrayExtension[ $valArrId ]; |
| 448 | + |
| 449 | + $newHash = array(); |
| 450 | + |
| 451 | + // if no key array is given OR the key array doesn't exist |
| 452 | + if( !isset($keyArrId) || !array_key_exists( $keyArrId, $wgArrayExtension->mArrayExtension ) ) |
| 453 | + { |
| 454 | + // Copy the whole array. Result will be a hash with numeric keys |
| 455 | + $newHash = $arrExtValArray; |
| 456 | + } |
| 457 | + else |
| 458 | + { |
| 459 | + $keyArray = $wgArrayExtension->mArrayExtension[ $keyArrId ]; |
| 460 | + $valArray = $arrExtValArray; |
| 461 | + |
| 462 | + for( $i=0; $i < count($keyArray); $i++ ) { |
| 463 | + $currVal = array_key_exists( $i, $valArray ) ? $valArray[$i] : ''; |
| 464 | + $newHash[ $keyArray[$i] ] = $currVal; |
| 465 | + } |
| 466 | + } |
| 467 | + $this->mHashTables[ $hashId ] = $newHash; |
| 468 | + return ''; |
| 469 | + } |
| 470 | + |
| 471 | + |
| 472 | + /** |
| 473 | + * Allows to call a template with keys of a hash table as parameters and their values as parameter values. |
| 474 | + * The pipe-replace parameter allows to define a string which will replace '|' pipes. Can be useful to preserve |
| 475 | + * links. Default replacement string is '|'. '{{((}}!{{))}}' could be useful in case those templates exist. |
| 476 | + * Syntax: |
| 477 | + * {{#hashtotemplate:template |hash |pipe-replacer}} |
| 478 | + */ |
| 479 | + function hashtotemplate( &$parser, $frame, $args ) { |
| 480 | + if( ! isset($args[0]) || ! isset($args[1]) ) |
| 481 | + return ''; |
| 482 | + |
| 483 | + $template = trim( $frame->expand($args[0] ) ); |
| 484 | + $hashId = trim( $frame->expand($args[1] ) ); |
| 485 | + $pipeReplacer = isset($args[2]) ? trim( $frame->expand( $args[2] ) ) : '|'; |
| 486 | + |
| 487 | + if( !$this->hashExists( $hashId ) ) |
| 488 | + return ''; |
| 489 | + |
| 490 | + $params = $this->mHashTables[ $hashId ]; |
| 491 | + $templateCall = '{{' . $template; |
| 492 | + |
| 493 | + foreach ($params as $paramKey => $paramValue){ |
| 494 | + // replace '{', '}' and '|' to avoid template call manipulation |
| 495 | + $paramValue = str_replace( array( '{', '}', '|' ), array( '{', '}', $pipeReplacer ), $paramValue ); |
| 496 | + $templateCall .= "|$paramKey=$paramValue"; |
| 497 | + } |
| 498 | + $templateCall .= '}}'; |
| 499 | + |
| 500 | + // parse template call: |
| 501 | + $result = $parser->preprocessToDom( $templateCall, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 ); |
| 502 | + $result = trim( $frame->expand( $result ) ); |
| 503 | + |
| 504 | + // we don't have to set 'noparse' to false since parsing is done above |
| 505 | + return array( $result , 'noparse' => true, 'isHTML' => false ); |
| 506 | + } |
| 507 | + |
| 508 | + /* ============================ */ |
| 509 | + /* ============================ */ |
| 510 | + /* === === */ |
| 511 | + /* === HELPER FUNCTIONS === */ |
| 512 | + /* === === */ |
| 513 | + /* ============================ */ |
| 514 | + /* ============================ */ |
| 515 | + |
| 516 | + /** |
| 517 | + * Returns a value within a hash. If key or hash doesn't exist, this will return null |
| 518 | + * or another predefined default. |
| 519 | + * |
| 520 | + * @since 0.7 |
| 521 | + * |
| 522 | + * @param string $hashId |
| 523 | + * @param string $key |
| 524 | + * @param mixed $default value to return in cas the value doesn't exist. null by default. |
| 525 | + * @return string |
| 526 | + */ |
| 527 | + public function getHashValue( $hashId = '', $key = '', $default = null ) { |
| 528 | + $hashId = trim( $hashId ); |
| 529 | + if( $this->hashExists( $hashId ) && array_key_exists( $key, $this->mHashTables[ $hashId ] ) ) |
| 530 | + return $this->mHashTables[ $hashId ][ $key ]; |
| 531 | + else |
| 532 | + return $default; |
| 533 | + } |
| 534 | + |
| 535 | + /** |
| 536 | + * Returns an hash identified by $hashId. If it doesn't exist this will return null. |
| 537 | + * |
| 538 | + * @since 0.6 |
| 539 | + * |
| 540 | + * @param string $hashId |
| 541 | + * @return array|null |
| 542 | + */ |
| 543 | + public function getHash( $hashId = '' ) { |
| 544 | + if( $this->hashExists( $hashId ) ) |
| 545 | + return $this->mHashTables[ $hashId ]; |
| 546 | + else |
| 547 | + return null; |
| 548 | + } |
| 549 | + |
| 550 | + /** |
| 551 | + * Returns whether a hash exists within the page scope. |
| 552 | + * |
| 553 | + * @since 0.6 |
| 554 | + * |
| 555 | + * @param string $hashId |
| 556 | + * @return boolean |
| 557 | + */ |
| 558 | + public function hashExists( $hashId = '' ) { |
| 559 | + return array_key_exists( trim( $hashId ), $this->mHashTables ); |
| 560 | + } |
| 561 | + |
| 562 | + /** |
| 563 | + * This will add a new hash or overwrite an existing one. Values should be delliverd as array |
| 564 | + * values in form of a string. |
| 565 | + * |
| 566 | + * @since 0.6 |
| 567 | + * |
| 568 | + * @param string $hashId |
| 569 | + * @param array $hashTable |
| 570 | + */ |
| 571 | + public function createHash( $hashId = '', $hashTable = array() ) { |
| 572 | + $this->mHashTables[ trim( $hashId ) ] = $hashTable; |
| 573 | + } |
| 574 | + |
| 575 | + /** |
| 576 | + * Removes an existing hash. If the hash doesn't exist this will return false, otherwise true. |
| 577 | + * |
| 578 | + * @since 0.6 |
| 579 | + * |
| 580 | + * @param string $hashId |
| 581 | + * @return boolean |
| 582 | + */ |
| 583 | + public function removeHash( $hashId = '' ) { |
| 584 | + $hashId = trim( $hashId ); |
| 585 | + if( $this->hashExists( $hashId ) ) { |
| 586 | + unset( $this->mHashTables[ $hashId ] ); |
| 587 | + return true; |
| 588 | + } else { |
| 589 | + return false; |
| 590 | + } |
| 591 | + } |
| 592 | + |
| 593 | + /** |
| 594 | + * Base function for operations with multiple hashes given thru n parameters |
| 595 | + * $operationFunc expects a function name prefix (suffix 'multi_') with two parameters |
| 596 | + * $hash1 and $hash2 which will perform an action between $hash1 and hash2 which will |
| 597 | + * result into a new $hash1. There can be 1 to n $hash2 in the whole process. |
| 598 | + * |
| 599 | + * @param $frame PPFrame |
| 600 | + * @param $args array |
| 601 | + * @param $operationFunc string name of the function calling this. There must be a counterpart |
| 602 | + * function with prefix 'multi_' which should have two parameters. Both parameters |
| 603 | + * will receive a hash (array), the function must return the result hash of the |
| 604 | + * processing. |
| 605 | + * @param $runFuncOnSingleHash boolean whether the $operationFunc function should be run in case |
| 606 | + * only one hash table id is given. If not, the original hash will end up in the new hash. |
| 607 | + */ |
| 608 | + protected function multiHashOperation( PPFrame $frame, array $args, $operationFunc, $runFuncOnSingleHash = true ) { |
| 609 | + $lastHash = null; |
| 610 | + $operationRan = false; |
| 611 | + $finalHashId = trim( $frame->expand( $args[0] ) ); |
| 612 | + $operationFunc = 'multi_' . $operationFunc; |
| 613 | + |
| 614 | + // For all hashes given in parameters 2 to n (ignore 1 because this is the new hash) |
| 615 | + for( $i = 1; $i < count( $args ); $i++ ) |
| 616 | + { |
| 617 | + if( ! array_key_exists( $i, $args ) ) { |
| 618 | + continue; |
| 619 | + } |
| 620 | + $argHashId = trim( $frame->expand( $args[ $i ] ) ); |
| 621 | + |
| 622 | + if( $this->hashExists( $argHashId ) ) { |
| 623 | + $argHash = $this->mHashTables[ $argHashId ]; |
| 624 | + if( $lastHash === null ) { |
| 625 | + // first valid hash table, process together with second... |
| 626 | + $lastHash = $argHash; |
| 627 | + } |
| 628 | + else { |
| 629 | + // second or later hash table, process with previous: |
| 630 | + $lastHash = $this->{ $operationFunc }( $lastHash, $argHash ); // perform action between last and current hash |
| 631 | + $operationRan = true; |
| 632 | + } |
| 633 | + } |
| 634 | + } |
| 635 | + // in case no hash was given at all: |
| 636 | + if( $lastHash === null ) { |
| 637 | + $lastHash = array(); |
| 638 | + } |
| 639 | + // if the operation didn't run because there was only one or no array: |
| 640 | + if( $operationRan == false && $runFuncOnSingleHash ) { |
| 641 | + $lastHash = $this->{ $operationFunc }( $lastHash ); |
| 642 | + } |
| 643 | + $this->mHashTables[ $finalHashId ] = $lastHash; |
| 644 | + } |
| 645 | + |
| 646 | + /** |
| 647 | + * Decides for the given $pattern whether its a valid regular expression acceptable for |
| 648 | + * HashTables parser functions or not. |
| 649 | + * |
| 650 | + * @param string $pattern regular expression including delimiters and optional flags |
| 651 | + * @return boolean |
| 652 | + */ |
| 653 | + function isValidRegEx( $pattern ) { |
| 654 | + return preg_match( '/^([\\/\\|%]).*\\1[imsSuUx]*$/', $pattern ); |
| 655 | + } |
| 656 | +} |
| 657 | + |
| 658 | + |
| 659 | + |
| 660 | +function efHashTablesParserFirstCallInit( Parser &$parser ) { |
| 661 | + global $wgHashTables, $wgArrayExtension; |
| 662 | + |
| 663 | + $wgHashTables = new ExtHashTables(); |
| 664 | + |
| 665 | + $parser->setFunctionHook( 'hashdefine', array( &$wgHashTables, 'hashdefine' ) ); |
| 666 | + $parser->setFunctionHook( 'hashvalue', array( &$wgHashTables, 'hashvalue' ) ); |
| 667 | + $parser->setFunctionHook( 'hashsize', array( &$wgHashTables, 'hashsize' ) ); |
| 668 | + $parser->setFunctionHook( 'hashkeyexists', array( &$wgHashTables, 'hashkeyexists' ), SFH_OBJECT_ARGS ); |
| 669 | + $parser->setFunctionHook( 'hashprint', array( &$wgHashTables, 'hashprint' ), SFH_OBJECT_ARGS ); |
| 670 | + $parser->setFunctionHook( 'parameterstohash', array( &$wgHashTables, 'parameterstohash' ), SFH_OBJECT_ARGS ); |
| 671 | + $parser->setFunctionHook( 'hashtotemplate', array( &$wgHashTables, 'hashtotemplate' ), SFH_OBJECT_ARGS ); |
| 672 | + $parser->setFunctionHook( 'hashinclude', array( &$wgHashTables, 'hashinclude' ), SFH_OBJECT_ARGS ); |
| 673 | + $parser->setFunctionHook( 'hashexclude', array( &$wgHashTables, 'hashexclude' ), SFH_OBJECT_ARGS ); |
| 674 | + $parser->setFunctionHook( 'hashreset', array( &$wgHashTables, 'hashreset' ), SFH_OBJECT_ARGS ); |
| 675 | + $parser->setFunctionHook( 'hashmerge', array( &$wgHashTables, 'hashmerge' ), SFH_OBJECT_ARGS ); |
| 676 | + $parser->setFunctionHook( 'hashmix', array( &$wgHashTables, 'hashmix' ), SFH_OBJECT_ARGS ); |
| 677 | + $parser->setFunctionHook( 'hashdiff', array( &$wgHashTables, 'hashdiff' ), SFH_OBJECT_ARGS ); |
| 678 | + $parser->setFunctionHook( 'hashintersect', array( &$wgHashTables, 'hashintersect' ), SFH_OBJECT_ARGS ); |
| 679 | + |
| 680 | + // if array extension is available, rgister array-hash interactions: |
| 681 | + if( isset( $wgArrayExtension ) ) { |
| 682 | + $parser->setFunctionHook( 'hashtoarray', array( &$wgHashTables, 'hashtoarray' ) ); |
| 683 | + $parser->setFunctionHook( 'arraytohash', array( &$wgHashTables, 'arraytohash' ) ); |
| 684 | + } |
| 685 | + |
| 686 | + return true; |
| 687 | +} |
Property changes on: tags/extensions/HashTables/REL_0_7/HashTables.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 688 | + native |
Index: tags/extensions/HashTables/REL_0_7/RELEASE-NOTES |
— | — | @@ -0,0 +1,61 @@ |
| 2 | + Changelog: |
| 3 | + ========== |
| 4 | + |
| 5 | + * November 4, 2011 version 0.7 |
| 6 | + - buggy behavior in 'hashkeyexists' which led to expanding both arguments 'yes' and 'no' in |
| 7 | + case custom arguments were given is solved. Now only the one actual case is being expanded. |
| 8 | + - 'hashtotemplate' now changes '{' to '{' since '{{' made some problems in some cases. |
| 9 | + - 'hashprint' last parameter for print order now evaluates templates and arguments as it should |
| 10 | + always have done. |
| 11 | + - 'hashmerge' on single hash will re-asign its numeric keys in ascending order instead of doing nothing. |
| 12 | + - using hook 'ParserFirstCallInit' now. |
| 13 | + - some gernal cleanup done. |
| 14 | + - put into wikimedia.org svn (http://svn.wikimedia.org/svnroot/mediawiki/trunk/extensions/HashTables/) |
| 15 | + - distributed under ISC license. |
| 16 | + |
| 17 | + |
| 18 | + * August 3, 2011 version 0.6.3 |
| 19 | + - minor bug in 'parameterstohash' function solved. |
| 20 | + |
| 21 | + * March 29, 2011 version 0.6.2 |
| 22 | + - 'hashtotemplate' has a new parameter to define a string which will replace pipes '|'. Can be |
| 23 | + useful to preserve links. |
| 24 | + |
| 25 | + * January 24, 2011 version 0.6.1 |
| 26 | + - Constant VERSION and function getHash() added to class ExtHashTables. |
| 27 | + |
| 28 | + * January 19, 2011 version 0.6 |
| 29 | + - New public class methods for creating and removing hash tables. Good for use by other extensions. |
| 30 | + - New experimental function 'hashtotemplate'. |
| 31 | + |
| 32 | + |
| 33 | + * August 3, 2010 version 0.5.1 |
| 34 | + - Hashinclude didn't trim key and value so keys with ending space ' ' and values with leading |
| 35 | + space were possible when defining something like {{#hashinclude: a | a = 1}} |
| 36 | + |
| 37 | + * August 1, 2010 version 0.5 |
| 38 | + - New parameter for function 'hashtoarray' which allows to specify the name of a second array |
| 39 | + which will contain the key names. |
| 40 | + - Function 'arraytohash' doesn't mind non existent arrays in parameter 2 anymore. This allows |
| 41 | + to create an hash table with keys only. |
| 42 | + |
| 43 | + |
| 44 | + * July 20, 2010 version 0.4 |
| 45 | + - Removed critical bug. Some kind of "Superglobal" HashTables on page imports and job queue jobs. |
| 46 | + Values were passed from one page to another page. |
| 47 | + |
| 48 | + |
| 49 | + * June 11, 2010 version 0.3 |
| 50 | + - Third parameter for 'arraytohash' allows to set a key array. |
| 51 | + - New function 'hashkeyexists'. |
| 52 | + |
| 53 | + |
| 54 | + * June 6, 2010 version 0.2 |
| 55 | + - New functions 'hashmerge', 'hashmix', 'hashdiff', 'hashinclude' and 'hashexclude'. |
| 56 | + - New functions if 'ArrayExtension' is available in the wiki: 'hashtoarray' and 'arraytohash'. |
| 57 | + - New parameter for 'hashprint' which allows to define the print order thru an array. |
| 58 | + |
| 59 | + |
| 60 | + * Mai 30, 2010 version 0.1 |
| 61 | + - First version of HashTables featuring the functions 'hashdefine', 'hashvalue', 'hashsize', |
| 62 | + 'hashprint', 'hashreset' and 'parameterstohash'. |
Property changes on: tags/extensions/HashTables/REL_0_7/RELEASE-NOTES |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 63 | + native |
Index: tags/extensions/HashTables/REL_0_7/COPYING |
— | — | @@ -0,0 +1,13 @@ |
| 2 | +Copyright (c) 2010 - 2011 by Daniel Werner < danweetz@web.de > |
| 3 | + |
| 4 | +Permission to use, copy, modify, and/or distribute this software for any |
| 5 | +purpose with or without fee is hereby granted, provided that the above |
| 6 | +copyright notice and this permission notice appear in all copies. |
| 7 | + |
| 8 | +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 9 | +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 10 | +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 11 | +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 12 | +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 13 | +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 14 | +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
\ No newline at end of file |
Property changes on: tags/extensions/HashTables/REL_0_7/COPYING |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 15 | + native |
Index: tags/extensions/HashTables/REL_0_7/README |
— | — | @@ -0,0 +1,28 @@ |
| 2 | +== About == |
| 3 | + |
| 4 | +The ''HashTables'' extension Enhances the parser with hash table functions and a function |
| 5 | +to store all parameters given to a template. |
| 6 | + |
| 7 | +Notes on installing ''HashTables'' are found in the file 'INSTALL'. |
| 8 | + |
| 9 | +* Website: http://www.mediawiki.org/wiki/Extension:HashTables |
| 10 | +* Author: Daniel Werner < danweetz@web.de > |
| 11 | +* License: ISC license |
| 12 | + |
| 13 | + |
| 14 | +== Installation == |
| 15 | + |
| 16 | +Once you have downloaded the code, place the 'HashTables' directory within your |
| 17 | +MediaWiki 'extensions' directory. Then add the following code to your |
| 18 | +[[Manual:LocalSettings.php|LocalSettings.php]] file: |
| 19 | + |
| 20 | + # HashTables |
| 21 | + require_once( "$IP/extensions/HashTables/HashTables.php" ); |
| 22 | + |
| 23 | + |
| 24 | +== Contributing == |
| 25 | + |
| 26 | +If you have bug reports or feature requests, please add them to the ''HashTables'' |
| 27 | +Talk page [0]. You can also send them to Daniel Werner < danweetz@web.de > |
| 28 | + |
| 29 | +[0] http://www.mediawiki.org/w/index.php?title=Extension_talk:HashTables |
Property changes on: tags/extensions/HashTables/REL_0_7/README |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 30 | + native |