r105143 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r105142‎ | r105143 | r105144 >
Date:23:45, 4 December 2011
Author:danwe
Status:deferred
Tags:
Comment:
Tag for 'HashTables' 0.7
Modified paths:
  • /tags/extensions/HashTables/REL_0_7 (added) (history)

Diff [purge]

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
147 + 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
186 + 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 '&#124;'. '{{((}}!{{))}}' 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] ) ) : '&#124;';
 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( '&#123;', '&#125;', $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
1688 + 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 '&#123;' 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
163 + 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
115 + 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
130 + native

Status & tagging log