r103805 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r103804‎ | r103805 | r103806 >
Date:13:13, 21 November 2011
Author:danwe
Status:deferred
Tags:
Comment:
Version increased to 2.0. We now store arrays per Parser instance, following Variables 2.0. #arrayindex now only expands its default when necessary + behavior adjusted to that of #var and #hashvalue. Lots of code cleanup done, less confusing private functions. 'ArrayExtension' class renamed to 'ExtArrayExtension'.
Modified paths:
  • /trunk/extensions/ArrayExtension/ArrayExtension.php (modified) (history)
  • /trunk/extensions/ArrayExtension/RELEASE-NOTES (modified) (history)

Diff [purge]

Index: trunk/extensions/ArrayExtension/ArrayExtension.php
@@ -44,9 +44,7 @@
4545 * get_total_col
4646 */
4747
48 -if ( ! defined( 'MEDIAWIKI' ) ) {
49 - die( 'This file is a MediaWiki extension, it is not a valid entry point' );
50 -}
 48+if ( ! defined( 'MEDIAWIKI' ) ) { die(); }
5149
5250 $wgExtensionCredits['parserhook'][] = array(
5351 'path' => __FILE__,
@@ -54,39 +52,41 @@
5553 'url' => 'http://www.mediawiki.org/wiki/Extension:ArrayExtension',
5654 'author' => array ( 'Li Ding', 'Jie Bao', '[http://www.mediawiki.org/wiki/User:Danwe Daniel Werner]' ),
5755 'descriptionmsg' => 'arrayext-desc',
58 - 'version' => ArrayExtension::VERSION
 56+ 'version' => ExtArrayExtension::VERSION
5957 );
6058
61 -$wgHooks['ParserFirstCallInit'][] = 'efArrayExtensionParserFirstCallInit';
 59+$wgExtensionMessagesFiles['ArrayExtension' ] = ExtArrayExtension::getDir() . '/ArrayExtension.i18n.php';
 60+$wgExtensionMessagesFiles['ArrayExtensionMagic'] = ExtArrayExtension::getDir() . '/ArrayExtension.i18n.magic.php';
6261
63 -$dir = dirname( __FILE__ );
 62+// hooks registration:
 63+$wgHooks['ParserFirstCallInit'][] = 'ExtArrayExtension::init';
 64+$wgHooks['ParserClearState' ][] = 'ExtArrayExtension::onParserClearState';
6465
65 -$wgExtensionMessagesFiles['ArrayExtension' ] = $dir . '/ArrayExtension.i18n.php';
66 -$wgExtensionMessagesFiles['ArrayExtensionMagic'] = $dir . '/ArrayExtension.i18n.magic.php';
6766
68 -unset( $dir );
69 -
7067 /**
7168 * Full compatbility to versions before 1.4
7269 *
73 - * @since 1.4
 70+ * @since 1.4 alpha
7471 *
7572 * @var boolean
7673 */
77 -$egArrayExtensionCompatbilityMode = true;
 74+$egArrayExtensionCompatbilityMode = false;
7875
7976
8077 /**
81 - * named arrays - an array has a list of values, and could be set to a SET
 78+ * Extension class with all the array functionality, also serves as store for arrays per
 79+ * Parser object and offers public accessors for interaction with ArrayExtension.
 80+ *
 81+ * @since 2.0 ('ArrayExtension' before and one global instance, also non-static parser functions)
8282 */
83 -class ArrayExtension {
 83+class ExtArrayExtension {
8484
8585 /**
8686 * Version of the ArrayExtension extension.
8787 *
88 - * @since 1.3.2
 88+ * @since 2.0 (before in 'ArrayExtension' class since 1.3.2)
8989 */
90 - const VERSION = '1.4 alpha';
 90+ const VERSION = '2.0 alpha';
9191
9292 /**
9393 * Store for arrays.
@@ -94,18 +94,67 @@
9595 * @var array
9696 * @private
9797 */
98 - var $mArrayExtension = array();
 98+ var $mArrays = array();
9999
100 - function __construct() {
101 - global $wgHooks;
102 - $wgHooks['ParserClearState'][] = &$this;
103 - }
 100+ /**
 101+ * Sets up parser functions
 102+ *
 103+ * @since 2.0
 104+ */
 105+ public static function init( Parser &$parser ) {
 106+ /*
 107+ * store for arrays per Parser object. This will solve several bugs related to
 108+ * 'ParserClearState' hook clearing all variables early in combination with certain
 109+ * other extensions. (since v2.0)
 110+ */
 111+ $parser->mExtArrayExtension = new self();
104112
105 - function onParserClearState( Parser &$parser ) {
106 - // remove all arrays to avoid conflicts with job queue or Special:Import or SMW semantic updates
107 - $this->mArrayExtension = array();
 113+ // SFH_OBJECT_ARGS available since MW 1.12
 114+ self::initFunction( $parser, 'arraydefine' );
 115+ self::initFunction( $parser, 'arrayprint', SFH_OBJECT_ARGS );
 116+ self::initFunction( $parser, 'arrayindex', SFH_OBJECT_ARGS );
 117+ self::initFunction( $parser, 'arraysize' );
 118+ self::initFunction( $parser, 'arraysearch', SFH_OBJECT_ARGS );
 119+ self::initFunction( $parser, 'arraysearcharray' );
 120+ self::initFunction( $parser, 'arrayslice' );
 121+ self::initFunction( $parser, 'arrayreset', SFH_OBJECT_ARGS );
 122+ self::initFunction( $parser, 'arrayunique' );
 123+ self::initFunction( $parser, 'arraysort' );
 124+ self::initFunction( $parser, 'arraymerge' );
 125+ self::initFunction( $parser, 'arrayunion' );
 126+ self::initFunction( $parser, 'arraydiff' );
 127+ self::initFunction( $parser, 'arrayintersect' );
 128+
108129 return true;
109130 }
 131+ private static function initFunction( Parser &$parser, $name, $flags = 0 ) {
 132+ // all parser functions with prefix:
 133+ $prefix = ( $flags & SFH_OBJECT_ARGS ) ? 'pfObj_' : 'pf_';
 134+ $functionCallback = array( __CLASS__, $prefix . $name );
 135+
 136+ $parser->setFunctionHook( $name, $functionCallback, $flags );
 137+ }
 138+
 139+ /**
 140+ * Returns the extensions base installation directory.
 141+ *
 142+ * @since 2.0
 143+ *
 144+ * @return boolean
 145+ */
 146+ public static function getDir() {
 147+ static $dir = null;
 148+
 149+ if( $dir === null ) {
 150+ $dir = dirname( __FILE__ );
 151+ }
 152+ return $dir;
 153+ }
 154+
 155+
 156+ ####################
 157+ # Parser Functions #
 158+ ####################
110159
111160 ///////////////////////////////////////////////////////////
112161 // PART 1. constructor
@@ -120,7 +169,7 @@
121170 * http://us2.php.net/manual/en/book.pcre.php
122171 * see also: http://us2.php.net/manual/en/function.preg-split.php
123172 */
124 - function arraydefine(
 173+ static function pf_arraydefine(
125174 Parser &$parser,
126175 $arrayId,
127176 $value = null,
@@ -157,7 +206,7 @@
158207 }
159208 else {
160209 // if no regex delimiter given, build one:
161 - if( ! $this->isValidRegEx( $delimiter ) ) {
 210+ if( ! self::isValidRegEx( $delimiter ) ) {
162211 $delimiter = '/\s*' . preg_quote( $delimiter, '/' ) . '\s*/';
163212 $trimDone = true; // spaces are part of the delimiter now
164213 }
@@ -166,16 +215,16 @@
167216
168217 // trim all values before unique if still necessary, otherwise unique might not work correctly
169218 if( ! $trimDone ) {
170 - $array = $this->sanitizeArray( $array );
 219+ $array = self::sanitizeArray( $array );
171220 }
172221
173222 // now parse the options, and do posterior process on the created array
174 - $arrayOptions = $this->parse_options( $options );
 223+ $arrayOptions = self::parse_options( $options );
175224
176225 // make it unique if option is set
177226 if( array_key_exists( 'unique', $arrayOptions ) ) {
178227 // unique like the parser function would do it
179 - $array = $this->array_unique( $array );
 228+ $array = self::array_unique( $array );
180229 }
181230
182231 /**
@@ -201,21 +250,21 @@
202251 */
203252
204253 // sort array if the option is set
205 - $this->arraysort( $parser, $arrayId, $this->array_value( $arrayOptions, 'sort' ) );
 254+ self::pf_arraysort( $parser, $arrayId, self::array_value( $arrayOptions, 'sort' ) );
206255
207256 // print the array upon request
208 - switch( $this->array_value( $arrayOptions, 'print' ) ) {
 257+ switch( self::array_value( $arrayOptions, 'print' ) ) {
209258 case 'list':
210 - $out = $this->arrayprint( $parser, $arrayId );
 259+ $out = self::pf_arrayprint( $parser, $arrayId );
211260 break;
212261
213 - case 'print':
214 - $out = $this->arrayprint( $parser, $arrayId, $delimiter2, $search, $subject, $frame );
 262+ case 'print':
 263+ $out = self::pf_arrayprint( $parser, $arrayId, $delimiter2, $search, $subject, $frame );
215264 break;
216265 }
217266 }
218 -
219 - $this->mArrayExtension[ $arrayId ] = $array;
 267+
 268+ self::get( $parser )->setArray( $arrayId, $array );
220269
221270 return $out;
222271 }
@@ -241,52 +290,47 @@
242291 * {{#arrayprint:b|<br/>|@@@|{{f.tag{{f.print.vbar}}prop{{f.print.vbar}}@@@}} }} -- embed template function
243292 * {{#arrayprint:b|<br/>|@@@|[[name::@@@]]}} -- make SMW links
244293 */
245 - function arrayprint( Parser &$parser, $arrayId , $delimiter = ', ', $search = '@@@@', $subject = '@@@@', $frame = null ) {
246 - $ret = $this->validate_array_by_arrayId( $arrayId );
247 - if ( $ret !== true ) {
248 - return $ret;
 294+ static function pf_arrayprint( Parser &$parser, $arrayId , $delimiter = ', ', $search = '@@@@', $subject = '@@@@', $frame = null ) {
 295+ // get array, null if non-existant:
 296+ $array = self::get( $parser )->getArray( $arrayId );
 297+
 298+ if( $array === null ) {
 299+ return '';
249300 }
250301
251 - $values = $this->mArrayExtension[$arrayId];
252302 $rendered_values = array();
253 - foreach ( $values as $v ) {
254 - $temp_result_value = str_replace( $search, $v, $subject );
255 - // frame is only available in newer MW versions
256 - if ( isset( $frame ) ) {
257 - /*
258 - * in case frame is given (new MW versions) the $subjectd still is un-expanded (this allows to use
259 - * some parser functions like {{FULLPAGENAME:@@@@}} directly without getting parsed before @@@@ is replaced.
260 - * Expand it so we replace templates like {{!}} which we need for the final parse.
261 - */
262 - $temp_result_value = $parser->preprocessToDom( $temp_result_value, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
263 - $temp_result_value = trim( $frame->expand( $temp_result_value ) );
264 - }
265 - $rendered_values[] = $temp_result_value;
 303+ foreach( $array as $val ) {
 304+ // replace place holder with current value:
 305+ $rawResult = str_replace( $search, $val, $subject );
 306+
 307+ /*
 308+ * $subjectd still is un-expanded (this allows to use some parser functions like
 309+ * {{FULLPAGENAME:@@@@}} directly without getting parsed before @@@@ is replaced.
 310+ * Expand it so we replace templates like {{!}} which we need for the final parse.
 311+ */
 312+ $rawResult = $parser->preprocessToDom( $rawResult, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
 313+ $rawResult = trim( $frame->expand( $rawResult ) );
 314+
 315+ $rendered_values[] = $rawResult;
266316 }
267317
268318 $output = implode( $delimiter, $rendered_values );
269319 $noparse = false;
270 -
271 - if ( isset( $frame ) ) {
272 - /*
273 - * don't leave the final parse to Parser::braceSubstitution() since there are some special cases where it
274 - * would produce unexpected output (it uses a new child frame and ignores whether the frame is a template!)
275 - */
276 - $noparse = true;
277320
278 - $output = $parser->preprocessToDom( $output, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
279 - $output = trim( $frame->expand( $output ) );
280 - }
 321+ /*
 322+ * don't leave the final parse to Parser::braceSubstitution() since there are some special cases where it
 323+ * would produce unexpected output (it uses a new child frame and ignores whether the frame is a template!)
 324+ */
 325+ $noparse = true;
 326+
 327+ $output = $parser->preprocessToDom( $output, $frame->isTemplate() ? Parser::PTD_FOR_INCLUSION : 0 );
 328+ $output = trim( $frame->expand( $output ) );
281329
282 - return array(
283 - $output,
284 - 'noparse' => $noparse,
285 - 'isHTML' => false
286 - );
 330+ return $output;
287331 }
288332
289 - function arrayprintObj( Parser &$parser, $frame, $args ) {
290 - // Set variables
 333+ static function pfObj_arrayprint( Parser &$parser, $frame, $args ) {
 334+ // Get Parameters
291335 $arrayId = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';
292336 $delimiter = isset( $args[1] ) ? trim( $frame->expand( $args[1] ) ) : ', ';
293337 /*
@@ -297,36 +341,52 @@
298342 $search = isset( $args[2] ) ? trim( $frame->expand( $args[2], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : '@@@@';
299343 $subject = isset( $args[3] ) ? trim( $frame->expand( $args[3], PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES ) ) : '@@@@';
300344
301 - return $this->arrayprint( $parser, $arrayId, $delimiter, $search, $subject, $frame );
 345+ return self::pf_arrayprint( $parser, $arrayId, $delimiter, $search, $subject, $frame );
302346 }
303 -
304 -
 347+
 348+
305349 /**
306350 * print the value of an array (identified by arrayid) by the index, invalid index results in the default value being printed. note the index is 0-based.
307351 * usage:
308352 * {{#arrayindex:arrayid|index}}
309353 */
310 - function arrayindex( Parser &$parser, $arrayId , $index , $defaultOrOptions = '' ) {
311 - // index must exist, strict check, non-numeric will fail:
312 - if( true !== $this->validate_array_by_arrayId( $arrayId )
313 - || ! $this->validate_array_index( $arrayId, $index, true )
314 - ) {
315 - // index doesn't exist, return default
316 - global $egArrayExtensionCompatbilityMode;
 354+ static function pfObj_arrayindex( Parser &$parser, PPFrame $frame, $args ) {
 355+ global $egArrayExtensionCompatbilityMode;
 356+
 357+ // Get Parameters
 358+ $arrayId = isset( $args[0] ) ? trim( $frame->expand( $args[0] ) ) : '';
 359+ $rawOptions = isset( $args[2] ) ? $args[2] : '';
 360+
 361+ if( ! isset( $args[1] ) ) {
 362+ return '';
 363+ }
 364+ $index = trim( $frame->expand( $args[1] ) );
 365+
 366+ // get value or null if it doesn't exist. Takes care of negative index as well
 367+ $val = self::get( $parser )->getArrayValue( $arrayId, $index );
 368+
 369+ if( $val === null || ( $val === '' && !$egArrayExtensionCompatbilityMode ) ) {
 370+ // index doesn't exist, return default (parameter 3)!
 371+ // without compatbility, also return default in case of empty string ''
317372
 373+ // only expand default when needed
 374+ $defaultOrOptions = trim( $frame->expand( $rawOptions ) );
 375+
318376 if( $egArrayExtensionCompatbilityMode ) {
319377 // COMPATBILITY-MODE
320378 // now parse the options, and do posterior process on the created array
321 - $ary_option = $this->parse_options( $defaultOrOptions );
322 - return $this->array_value( $ary_option, 'default' );
 379+ $options = self::parse_options( $defaultOrOptions );
 380+ $default = self::array_value( $options, 'default' );
323381 } else {
324 - return $defaultOrOptions;
 382+ $default = $defaultOrOptions;
325383 }
 384+
 385+ return $default;
326386 }
327 -
328 - return $this->mArrayExtension[ $arrayId ][ $index ];
 387+
 388+ return $val;
329389 }
330 -
 390+
331391 /**
332392 * returns the size of an array.
333393 * Print the size (number of elements) in the specified array and '' if array doesn't exist
@@ -335,18 +395,17 @@
336396 *
337397 * See: http://www.php.net/manual/en/function.count.php
338398 */
339 - function arraysize( Parser &$parser, $arrayId ) {
340 - if( ! $this->arrayExists( $arrayId ) ) {
 399+ static function pf_arraysize( Parser &$parser, $arrayId ) {
 400+ $store = self::get( $parser );
 401+
 402+ if( ! $store->arrayExists( $arrayId ) ) {
341403 return '';
342404 }
343405
344 - return count( $this->mArrayExtension[ $arrayId ] );
 406+ return count( $store->getArray( $arrayId ) );
345407 }
346408
347 -
348 -
349 -
350 -
 409+
351410 /**
352411 * locate the index of the first occurence of an element starting from the 'index'
353412 * - print "-1" (not found) or index (found) to show the index of the first occurence of 'value' in the array identified by arrayid
@@ -358,22 +417,24 @@
359418 * See: http://www.php.net/manual/en/function.array-search.php
360419 * note it is extended to support regular expression match and index
361420 */
362 - function arraysearch( Parser &$parser, PPFrame $frame, $args ) {
 421+ static function pfObj_arraysearch( Parser &$parser, PPFrame $frame, $args ) {
363422
364423 $arrayId = trim( $frame->expand( $args[0] ) );
365424 $index = isset( $args[2] ) ? trim( $frame->expand( $args[2] ) ) : 0;
366425
367 - if( $this->arrayExists( $arrayId )
368 - && $this->validate_array_index( $arrayId, $index, false )
 426+ $store = self::get( $parser );
 427+
 428+ if( $store->arrayExists( $arrayId )
 429+ && $store->validate_array_index( $arrayId, $index, false )
369430 ) {
370 - $array = $this->mArrayExtension[ $arrayId ];
 431+ $array = $store->getArray( $arrayId );
371432
372433 // validate/build search regex:
373434 if( isset( $args[1] ) ) {
374435
375436 $needle = trim( $frame->expand( $args[1] ) );
376437
377 - if ( ! $this->isValidRegEx( $needle ) ) {
 438+ if ( ! self::isValidRegEx( $needle ) ) {
378439 $needle = '/^\s*' . preg_quote( trim( $needle ), '/' ) . '\s*$/';
379440 }
380441 }
@@ -417,7 +478,7 @@
418479 * "needle" can be a regular expression or a string search value. If "needle" is a regular expression, "transform" can contain
419480 * "$n" where "n" stands for a number to access a variable from the regex result.
420481 */
421 - function arraysearcharray(
 482+ static function pf_arraysearcharray(
422483 Parser &$parser,
423484 $arrayId_new,
424485 $arrayId = null,
@@ -425,21 +486,23 @@
426487 $index = 0,
427488 $limit = -1,
428489 $transform = ''
429 - ) {
 490+ ) {
 491+ $store = self::get( $parser );
 492+
430493 if( $arrayId === null ) {
431494 global $egArrayExtensionCompatbilityMode;
432495 if( ! $egArrayExtensionCompatbilityMode ) { // COMPATBILITY-MODE
433 - $this->setArray( $arrayId_new );
 496+ $store->setArray( $arrayId_new );
434497 }
435498 return '';
436499 }
437500 // also takes care of negative index by calculating start index:
438 - $validIndex = $this->validate_array_index( $arrayId, $index, false );
 501+ $validIndex = $store->validate_array_index( $arrayId, $index, false );
439502
440503 // make sure at least empty array exists but don't overwrite data
441504 // we still need in case new array ID same as target array ID
442 - $array = $this->getArray( $arrayId );
443 - $this->setArray( $arrayId_new );
 505+ $array = $store->getArray( $arrayId );
 506+ $store->setArray( $arrayId_new );
444507
445508 if( $array === null || !$validIndex ) {
446509 return '';
@@ -453,7 +516,7 @@
454517
455518 $newArr = array();
456519
457 - if( !$this->isValidRegEx( $needle ) ) {
 520+ if( ! self::isValidRegEx( $needle ) ) {
458521 $needle = '/^\s*(' . preg_quote( $needle, '/' ) . ')\s*$/';
459522 }
460523
@@ -477,7 +540,7 @@
478541 }
479542
480543 // set new array:
481 - $this->setArray( $arrayId_new, $newArr );
 544+ $store->setArray( $arrayId_new, $newArr );
482545 return '';
483546 }
484547
@@ -493,7 +556,7 @@
494557 * {{#arrayreset:}}
495558 * {{#arrayreset:arrayid1,arrayid2,...arrayidn}}
496559 */
497 - function arrayreset( Parser &$parser, PPFrame $frame, $args) {
 560+ static function pfObj_arrayreset( Parser &$parser, PPFrame $frame, $args) {
498561 global $egArrayExtensionCompatbilityMode;
499562
500563 if( $egArrayExtensionCompatbilityMode && count( $args ) == 1 ) {
@@ -501,18 +564,20 @@
502565 * COMPATBILITY-MODE: before arrays were separated by ';' which is an bad idea since
503566 * the ',' is an allowed character in array names!
504567 */
505 - $args = preg_split( '/\s*,\s*/', $args[0] );
 568+ $args = preg_split( '/\s*,\s*/', trim( $frame->expand( $args[0] ) ) );
506569 }
507570
 571+ $store = self::get( $parser );
 572+
508573 // reset all hash tables if no specific tables are given:
509574 if( ! isset( $args[0] ) || ( $args[0] === '' && count( $args ) == 1 ) ) {
510 - $this->mArrayExtension = array();
 575+ $store->mArrays = array();
511576 }
512577 else {
513578 // reset specific hash tables:
514579 foreach( $args as $arg ) {
515580 $arrayId = trim( $frame->expand( $arg ) );
516 - $this->unsetArray( $arrayId );
 581+ $store->unsetArray( $arrayId );
517582 }
518583 }
519584 return '';
@@ -528,9 +593,13 @@
529594 *
530595 * see: http://www.php.net/manual/en/function.array-unique.php
531596 */
532 - function pf_arrayunique( Parser &$parser, $arrayId ) {
533 - if( $this->arrayExists( $arrayId ) ) {
534 - $this->mArrayExtension[ $arrayId ] = $this->array_unique( $this->mArrayExtension[ $arrayId ] );
 597+ static function pf_arrayunique( Parser &$parser, $arrayId ) {
 598+ $store = self::get( $parser );
 599+
 600+ if( $store->arrayExists( $arrayId ) ) {
 601+ $array = $store->getArray( $arrayId );
 602+ $array = self::array_unique( $array );
 603+ $store->setArray( $arrayId, $array );
535604 }
536605 return '';
537606 }
@@ -551,8 +620,10 @@
552621 * http://www.php.net/manual/en/function.shuffle.php
553622 * http://us3.php.net/manual/en/function.array-reverse.php
554623 */
555 - function arraysort( Parser &$parser, $arrayId , $sort = 'none' ) {
556 - if( ! $this->arrayExists( $arrayId ) ) {
 624+ static function pf_arraysort( Parser &$parser, $arrayId , $sort = 'none' ) {
 625+ $store = self::get( $parser );
 626+
 627+ if( ! $store->arrayExists( $arrayId ) ) {
557628 return '';
558629 }
559630
@@ -561,20 +632,20 @@
562633 case 'asc':
563634 case 'asce':
564635 case 'ascending':
565 - sort( $this->mArrayExtension[ $arrayId ] );
 636+ sort( $store->mArrays[ $arrayId ] );
566637 break;
567638
568639 case 'desc':
569640 case 'descending':
570 - rsort( $this->mArrayExtension[ $arrayId ] );
 641+ rsort( $store->mArrays[ $arrayId ] );
571642 break;
572643
573644 case 'random':
574 - shuffle( $this->mArrayExtension[ $arrayId ] );
 645+ shuffle( $store->mArrays[ $arrayId ] );
575646 break;
576647
577648 case 'reverse':
578 - $this->mArrayExtension[ $arrayId ] = array_reverse( $this->mArrayExtension[ $arrayId ] );
 649+ $store->mArrays[ $arrayId ] = array_reverse( $store->mArrays[ $arrayId ] );
579650 break;
580651 } ;
581652 }
@@ -592,30 +663,32 @@
593664 * merge values two arrayes identified by arrayid1 and arrayid2 into a new array identified by arrayid_new.
594665 * this merge differs from array_merge of php because it merges values.
595666 */
596 - function arraymerge( Parser &$parser, $arrayId_new, $arrayId1 = null, $arrayId2 = null ) {
597 - if( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) )
 667+ static function pf_arraymerge( Parser &$parser, $arrayId_new, $arrayId1 = null, $arrayId2 = null ) {
 668+ if( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) ) {
598669 return '';
599 -
600 - $ret = $this->validate_array_by_arrayId( $arrayId1 );
 670+ }
 671+ $store = self::get( $parser );
 672+
 673+ $ret = $store->validate_array_by_arrayId( $arrayId1 );
601674 if( $ret !== true ) {
602675 return '';
603676 }
604677
605678 $temp_array = array();
606 - foreach( $this->mArrayExtension[ $arrayId1 ] as $entry ) {
 679+ foreach( $store->mArrays[ $arrayId1 ] as $entry ) {
607680 array_push ( $temp_array, $entry );
608681 }
609682
610683 if( isset( $arrayId2 ) && strlen( $arrayId2 ) > 0 ) {
611 - $ret = $this->validate_array_by_arrayId( $arrayId2 );
 684+ $ret = $store->validate_array_by_arrayId( $arrayId2 );
612685 if( $ret === true ) {
613 - foreach( $this->mArrayExtension[ $arrayId2 ] as $entry ) {
 686+ foreach( $store->mArrays[ $arrayId2 ] as $entry ) {
614687 array_push ( $temp_array, $entry );
615688 }
616689 }
617690 }
618691
619 - $this->mArrayExtension[$arrayId_new] = $temp_array;
 692+ $store->mArrays[$arrayId_new] = $temp_array;
620693 return '';
621694 }
622695
@@ -627,19 +700,20 @@
628701 * extract a slice from an array
629702 * see: http://www.php.net/manual/en/function.array-slice.php
630703 */
631 - function arrayslice( Parser &$parser, $arrayId_new, $arrayId = null , $offset = 0, $length = null ) {
 704+ static function pf_arrayslice( Parser &$parser, $arrayId_new, $arrayId = null , $offset = 0, $length = null ) {
 705+ $store = self::get( $parser );
632706 if( $arrayId === null ) {
633707 global $egArrayExtensionCompatbilityMode;
634708 if( ! $egArrayExtensionCompatbilityMode ) { // COMPATBILITY-MODE
635 - $this->setArray( $arrayId_new );
 709+ $store->setArray( $arrayId_new );
636710 }
637711 return '';
638712 }
639713 // get target array before overwriting it in any way
640 - $array = $this->getArray( $arrayId );
 714+ $array = $store->getArray( $arrayId );
641715
642716 // make sure at least an empty array exists if we return early
643 - $this->setArray( $arrayId_new );
 717+ $store->setArray( $arrayId_new );
644718
645719 if( $array === null
646720 || ! is_numeric( $offset ) // don't ignore invalid offset
@@ -652,8 +726,8 @@
653727 }
654728
655729 // array_slice will re-organize keys
656 - $newArray = array_slice( $array, $offset, $length );
657 - $this->mArrayExtension[ $arrayId_new ] = $newArray;
 730+ $newArray = array_slice( $array, $offset, $length );
 731+ $store->setArray( $arrayId_new, $newArray );
658732
659733 return '';
660734 }
@@ -668,20 +742,21 @@
669743
670744 * similar to arraymerge, this union works on values.
671745 */
672 - function arrayunion( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
 746+ static function pf_arrayunion( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
 747+ $store = self::get( $parser );
673748 if ( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) ) {
674749 return '';
675750 }
676 - if( ! isset( $arrayId1 ) || ! $this->arrayExists( $arrayId1 ) ) {
 751+ if( ! isset( $arrayId1 ) || ! $store->arrayExists( $arrayId1 ) ) {
677752 return '';
678753 }
679 - if( ! isset( $arrayId2 ) || ! $this->arrayExists( $arrayId2 ) ) {
 754+ if( ! isset( $arrayId2 ) || ! $store->arrayExists( $arrayId2 ) ) {
680755 return '';
681756 }
682757
683 - $this->arraymerge( $parser, $arrayId_new, $arrayId1, $arrayId2 );
684 - $this->mArrayExtension[$arrayId_new] = array_unique ( $this->mArrayExtension[$arrayId_new] );
685 -
 758+ self::pf_arraymerge( $parser, $arrayId_new, $arrayId1, $arrayId2 );
 759+ $store->setArray( $arrayId_new, array_unique ( $store->getArray( $arrayId_new ) ) );
 760+
686761 return '';
687762 }
688763
@@ -691,22 +766,23 @@
692767 * {{#arrayintersect:arrayid_new|arrayid1|arrayid2}}
693768 * See: http://www.php.net/manual/en/function.array-intersect.php
694769 */
695 - function arrayintersect( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
 770+ static function pf_arrayintersect( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
 771+ $store = self::get( $parser );
696772 if ( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) ) {
697773 return '';
698774 }
699 - if( ! isset( $arrayId1 ) || ! $this->arrayExists( $arrayId1 ) ) {
 775+ if( ! isset( $arrayId1 ) || ! $store->arrayExists( $arrayId1 ) ) {
700776 return '';
701777 }
702 - if( ! isset( $arrayId2 ) || ! $this->arrayExists( $arrayId2 ) ) {
 778+ if( ! isset( $arrayId2 ) || ! $store->arrayExists( $arrayId2 ) ) {
703779 return '';
704780 }
705781
706782 // keys will be preserved...
707 - $newArray = array_intersect( array_unique( $this->mArrayExtension[$arrayId1] ), array_unique( $this->mArrayExtension[$arrayId2] ) );
 783+ $newArray = array_intersect( array_unique( $store->mArrays[$arrayId1] ), array_unique( $store->mArrays[$arrayId2] ) );
708784
709785 // ...so we have to reorganize the key order
710 - $this->mArrayExtension[$arrayId_new] = $this->sanitizeArray( $newArray );
 786+ $store->mArrays[$arrayId_new] = self::sanitizeArray( $newArray );
711787
712788 return '';
713789 }
@@ -719,32 +795,31 @@
720796 * set operation, {white} = {red, white} - {red}
721797 * see: http://www.php.net/manual/en/function.array-diff.php
722798 */
723 - function arraydiff( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
724 - if ( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) ) {
 799+ static function pf_arraydiff( Parser &$parser, $arrayId_new, $arrayId1 = null , $arrayId2 = null ) {
 800+ $store = self::get( $parser );
 801+ if( ! isset( $arrayId_new ) || ! isset( $arrayId1 ) || ! isset( $arrayId2 ) ) {
725802 return '';
726803 }
727 - if( ! isset( $arrayId1 ) || ! $this->arrayExists( $arrayId1 ) ) {
 804+ if( ! isset( $arrayId1 ) || ! $store->arrayExists( $arrayId1 ) ) {
728805 return '';
729806 }
730 - if( ! isset( $arrayId2 ) || ! $this->arrayExists( $arrayId2 ) ) {
 807+ if( ! isset( $arrayId2 ) || ! $store->arrayExists( $arrayId2 ) ) {
731808 return '';
732 - }
733 -
 809+ }
734810 // keys will be preserved...
735 - $newArray = array_diff( array_unique( $this->mArrayExtension[$arrayId1] ), array_unique( $this->mArrayExtension[$arrayId2] ) );
 811+ $newArray = array_diff( array_unique( $store->mArrays[$arrayId1] ), array_unique( $store->mArrays[$arrayId2] ) );
736812
737813 // ...so we have to reorganize the key order
738 - $this->mArrayExtension[$arrayId_new] = $this->sanitizeArray( $newArray );
 814+ $store->mArrays[$arrayId_new] = self::sanitizeArray( $newArray );
739815
740816 return '';
741817 }
 818+
 819+
 820+ ##################
 821+ # Private helper #
 822+ ##################
742823
743 -
744 -
745 - ///////////////////////////////////////////////// /
746 - // private functions
747 - ///////////////////////////////////////////////// /
748 -
749824 /**
750825 * Validates an index for an array and returns true in case the index is a valid index within
751826 * the array. This also changes the index value, which is given by reference, in case it is
@@ -758,9 +833,8 @@
759834 *
760835 * @return boolean
761836 */
762 - private function validate_array_index( $arrayId, &$index, $strictIndex = false ) {
763 -
764 - if ( ! is_numeric( $index ) ) {
 837+ protected function validate_array_index( $arrayId, &$index, $strictIndex = false ) {
 838+ if( ! is_numeric( $index ) ) {
765839 if( $strictIndex ) {
766840 return false;
767841 } else {
@@ -769,36 +843,41 @@
770844 }
771845 $index = (int)$index;
772846
773 - if( ! array_key_exists( $arrayId, $this->mArrayExtension ) )
 847+ if( ! array_key_exists( $arrayId, $this->mArrays ) ) {
774848 return false;
 849+ }
775850
776 - $array = $this->mArrayExtension[ $arrayId ];
 851+ $array = $this->mArrays[ $arrayId ];
777852
778853 // calculate start index for negative start indexes:
779 - if ( $index < 0 ) {
 854+ if( $index < 0 ) {
780855 $index = count( $array ) + $index;
781856 if ( $index < 0 && !$strictIndex ) {
782857 $index = 0;
783858 }
784859 }
785860
786 - if ( ! isset( $array ) ) {
 861+ if( ! isset( $array ) ) {
787862 return false;
788863 }
789 - if ( ! array_key_exists( $index, $array ) ) {
 864+ if( ! array_key_exists( $index, $array ) ) {
790865 return false;
791866 }
792867 return true;
793868 }
794 -
795 - // private function for validating array by name
796 - private function validate_array_by_arrayId( $arrayId ) {
797 - if( ! isset( $arrayId ) )
798 - return '';
799 -
800 - if( ! isset( $this->mArrayExtension )
801 - || ! array_key_exists( $arrayId, $this->mArrayExtension )
802 - || ! is_array( $this->mArrayExtension[ $arrayId ] )
 869+
 870+ /**
 871+ * private function for validating array by name
 872+ * @ToDo: get rid of this!
 873+ * @deprecated
 874+ */
 875+ protected function validate_array_by_arrayId( $arrayId ) {
 876+ if( ! isset( $arrayId ) ) {
 877+ return '';
 878+ }
 879+ if( ! isset( $this->mArrays )
 880+ || ! array_key_exists( $arrayId, $this->mArrays )
 881+ || ! is_array( $this->mArrays[ $arrayId ] )
803882 ) {
804883 global $egArrayExtensionCompatbilityMode;
805884 if( $egArrayExtensionCompatbilityMode ) {
@@ -808,49 +887,75 @@
809888 }
810889 }
811890
812 - return true;
 891+ return true;
813892 }
814893
815894 /**
816895 * Convenience function to get a value from an array. Returns '' in case the
817896 * value doesn't exist or no array was given
818897 */
819 - private function array_value( $array, $field ) {
 898+ protected static function array_value( $array, $field ) {
820899 if ( is_array( $array ) && array_key_exists( $field, $array ) ) {
821900 return $array[ $field ];
822 - } else {
823 - return '';
824901 }
 902+ return '';
825903 }
 904+
 905+ /**
 906+ * Parses a string of options separated by ','. Options can be just certain key-words or
 907+ * key-value pairs separated by '='. Options are case-insensitive and spacing between
 908+ * separators will be ignored.
 909+ */
 910+ protected static function parse_options( $options ) {
 911+ if( ! isset( $options ) ) {
 912+ return array();
 913+ }
826914
827 - private function parse_options( $options ) {
828 - if ( isset( $options ) ) {
829 - // now parse the options, and do posterior process on the created array
830 - $ary_option = preg_split ( '/\s*[,]\s*/', strtolower( $options ) );
831 - }
 915+ // now parse the options, and do posterior process on the created array
 916+ $options = preg_split( '/\s*,\s*/', strtolower( $options ) );
832917
833 - $ret = array();
834 - if ( isset( $ary_option ) && is_array( $ary_option ) && sizeof( $ary_option ) > 0 ) {
835 - foreach ( $ary_option as $option ) {
836 - $ary_pair = explode( '=', $option, 2 );
837 - if ( sizeof( $ary_pair ) == 1 ) {
838 - $ret[$ary_pair[0]] = true;
839 - } else {
840 - $ret[$ary_pair[0]] = $ary_pair[1];
841 - }
842 - }
843 - }
844 - return $ret;
 918+ $ret = array();
 919+ foreach( $options as $option ) {
 920+ $optPair = preg_split( '/\s*\=\s*/', $option, 2 );
 921+ if( sizeof( $optPair ) == 1 ) {
 922+ $ret[ $optPair[0] ] = true;
 923+ } else {
 924+ $ret[ $optPair[0] ] = $optPair[1];
 925+ }
 926+ }
 927+ return $ret;
845928 }
 929+
 930+ /**
 931+ * same as self::arrayUnique() but without sanitazation, only for internal use.
 932+ */
 933+ protected static function array_unique( array $array ) {
 934+ // delete duplicate values
 935+ $array = array_unique( $array );
 936+
 937+ $values = array();
 938+ foreach( $array as $key => $val ) {
 939+ // don't put emty elements into the array
 940+ if( $val !== '' ) {
 941+ $values[] = $val;
 942+ }
 943+ }
 944+
 945+ return $values;
 946+ }
846947
847 - /* ============================ */
848 - /* ============================ */
849 - /* === === */
850 - /* === HELPER FUNCTIONS === */
851 - /* === === */
852 - /* ============================ */
853 - /* ============================ */
854948
 949+ ##############
 950+ # Used Hooks #
 951+ ##############
 952+
 953+ static function onParserClearState( Parser &$parser ) {
 954+ // remove all arrays to avoid conflicts with job queue or Special:Import or SMW semantic updates
 955+ $parser->mExtArrayExtension = new self();
 956+ return true;
 957+ }
 958+
 959+
855960 ####################################
856961 # Public functions for interaction #
857962 ####################################
@@ -865,11 +970,11 @@
866971 * to a certain Parser object. Each parser has its own store which will be reset after
867972 * a parsing process [Parser::parse()] has finished.
868973 *
869 - * @since 1.4
 974+ * @since 2.0
870975 *
871976 * @param Parser &$parser
872977 *
873 - * @return ExtHashTables by reference so we still have the right object after 'ParserClearState'
 978+ * @return ExtArrayExtension by reference so we still have the right object after 'ParserClearState'
874979 */
875980 public static function &get( Parser &$parser ) {
876981 return $parser->mExtArrayExtension;
@@ -878,7 +983,7 @@
879984 /**
880985 * Returns an array identified by $arrayId. If it doesn't exist, null will be returned.
881986 *
882 - * @since 1.4
 987+ * @since 2.0
883988 *
884989 * @param string $arrayId
885990 *
@@ -887,7 +992,7 @@
888993 function getArray( $arrayId ) {
889994 $arrayId = trim( $arrayId );
890995 if( $this->arrayExists( $arrayId ) ) {
891 - return $this->mArrayExtension[ $arrayId ];
 996+ return $this->mArrays[ $arrayId ];
892997 }
893998 return null;
894999 }
@@ -900,18 +1005,20 @@
9011006 * @param array $array
9021007 */
9031008 public function createArray( $arrayId, $array = array() ) {
904 - $array = $this->sanitizeArray( $array );
905 - $this->mArrayExtension[ trim( $arrayId ) ] = $array;
 1009+ $array = self::sanitizeArray( $array );
 1010+ $this->mArrays[ trim( $arrayId ) ] = $array;
9061011 }
9071012
9081013 /**
909 - * Same as the public createArray but without sanitizing the array automatically
 1014+ * Same as the public function createArray() but without sanitizing the array automatically.
 1015+ * This is save and faster for internal usage, just be sure your array doesn't have un-trimmed
 1016+ * values or non-numeric or negative array keys and no gaps between keys.
9101017 *
9111018 * @param type $arrayId
9121019 * @param type $array
9131020 */
9141021 protected function setArray( $arrayId, $array = array() ) {
915 - $this->mArrayExtension[ trim( $arrayId ) ] = $array;
 1022+ $this->mArrays[ trim( $arrayId ) ] = $array;
9161023 }
9171024
9181025 /**
@@ -922,27 +1029,29 @@
9231030 * @return boolean
9241031 */
9251032 function arrayExists( $arrayId ) {
926 - return array_key_exists( trim( $arrayId ), $this->mArrayExtension );
 1033+ return array_key_exists( trim( $arrayId ), $this->mArrays );
9271034 }
9281035
9291036 /**
9301037 * Returns a value within an array. If key or array do not exist, this will return null
931 - * or another predefined default.
 1038+ * or another predefined default. $index can also be a negative value, in this case the
 1039+ * value that far from the end of the array will be returned.
9321040 *
933 - * @since 1.4
 1041+ * @since 2.0
9341042 *
9351043 * @param string $arrayId
936 - * @param string $key
 1044+ * @param string $index
9371045 * @param mixed $default value to return in case the value doesn't exist. null by default.
9381046 *
939 - * @return string
 1047+ * @return string|null
9401048 */
941 - function getArrayValue( $arrayId, $key, $default = null ) {
942 - $arrayId = trim( $arrayId );
 1049+ function getArrayValue( $arrayId, $index, $default = null ) {
 1050+ $arrayId = trim( $arrayId );
9431051 if( $this->arrayExists( $arrayId )
944 - && array_key_exists( $key, $this->mArrayExtension[ $arrayId ] )
 1052+ && $this->validate_array_index( $arrayId, $index, true )
 1053+ && array_key_exists( $index, $this->mArrays[ $arrayId ] )
9451054 ) {
946 - return $this->mArrayExtension[ $arrayId ][ $key ];
 1055+ return $this->mArrays[ $arrayId ][ $index ];
9471056 }
9481057 else {
9491058 return $default;
@@ -953,6 +1062,8 @@
9541063 /**
9551064 * Removes an existing array. If array didn't exist this will return false, otherwise true.
9561065 *
 1066+ * @since 2.0
 1067+ *
9571068 * @param string $arrayId
9581069 *
9591070 * @return boolean whether the array existed and has been removed
@@ -960,7 +1071,7 @@
9611072 public function unsetArray( $arrayId ) {
9621073 $arrayId = trim( $arrayId );
9631074 if( $this->arrayExists( $arrayId ) ) {
964 - unset( $this->mArrayExtension[ $arrayId ] );
 1075+ unset( $this->mArrays[ $arrayId ] );
9651076 return true;
9661077 }
9671078 return false;
@@ -970,10 +1081,12 @@
9711082 * Rebuild the array and reorganize all keys, trim all values.
9721083 * All gaps between array items will be closed.
9731084 *
 1085+ * @since 2.0
 1086+ *
9741087 * @param array $arr array to be reorganized
9751088 * @return array
9761089 */
977 - public function sanitizeArray( $array ) {
 1090+ public static function sanitizeArray( $array ) {
9781091 $newArray = array();
9791092 foreach( $array as $val ) {
9801093 $newArray[] = trim( $val );
@@ -985,34 +1098,16 @@
9861099 * Removes duplicate values and all empty elements from an array just like the
9871100 * arrayunique parser function would do it. The array will be sanitized internally.
9881101 *
989 - * @since 1.4
 1102+ * @since 2.0
9901103 *
9911104 * @param array $array
9921105 *
9931106 * @return array
9941107 */
995 - public function arrayUnique( array $array ) {
 1108+ public static function arrayUnique( array $array ) {
9961109 $arr = $this->sanitizeArray( $arr );
997 - $array = $this->array_unique( $array );
 1110+ $array = self::array_unique( $array );
9981111 }
999 -
1000 - /**
1001 - * same as self::arrayUnique() but without sanitazation, only for internal use.
1002 - */
1003 - private function array_unique( array $array ) {
1004 - // delete duplicate values
1005 - $array = array_unique( $array );
1006 -
1007 - $values = array();
1008 - foreach( $array as $key => $val ) {
1009 - // don't put emty elements into the array
1010 - if( $val !== '' ) {
1011 - $values[] = $val;
1012 - }
1013 - }
1014 -
1015 - return $values;
1016 - }
10171112
10181113 /**
10191114 * Decides for the given $pattern whether its a valid regular expression acceptable for
@@ -1022,7 +1117,7 @@
10231118 *
10241119 * @return boolean
10251120 */
1026 - function isValidRegEx( $pattern ) {
 1121+ static function isValidRegEx( $pattern ) {
10271122 if( ! preg_match( '/^([\\/\\|%]).*\\1[imsSuUx]*$/', $pattern ) ) {
10281123 return false;
10291124 }
@@ -1032,34 +1127,3 @@
10331128 return $isValid;
10341129 }
10351130 }
1036 -
1037 -function efArrayExtensionParserFirstCallInit( Parser &$parser ) {
1038 - global $wgArrayExtension;
1039 -
1040 - $wgArrayExtension = new ArrayExtension();
1041 - $parser->setFunctionHook( 'arraydefine', array( &$wgArrayExtension, 'arraydefine' ) );
1042 -
1043 - if ( defined( get_class( $parser ) . '::SFH_OBJECT_ARGS' ) ) {
1044 - $parser->setFunctionHook( 'arrayprint', array( &$wgArrayExtension, 'arrayprintObj' ), SFH_OBJECT_ARGS );
1045 - } else {
1046 - $parser->setFunctionHook( 'arrayprint', array( &$wgArrayExtension, 'arrayprint' ) );
1047 - }
1048 -
1049 - $parser->setFunctionHook( 'arraysize', array( &$wgArrayExtension, 'arraysize' ) );
1050 - $parser->setFunctionHook( 'arrayindex', array( &$wgArrayExtension, 'arrayindex' ) );
1051 - $parser->setFunctionHook( 'arraysearch', array( &$wgArrayExtension, 'arraysearch' ), SFH_OBJECT_ARGS );
1052 -
1053 - $parser->setFunctionHook( 'arraysort', array( &$wgArrayExtension, 'arraysort' ) );
1054 - $parser->setFunctionHook( 'arrayunique', array( &$wgArrayExtension, 'pf_arrayunique' ) );
1055 - $parser->setFunctionHook( 'arrayreset', array( &$wgArrayExtension, 'arrayreset' ), SFH_OBJECT_ARGS );
1056 -
1057 - $parser->setFunctionHook( 'arraymerge', array( &$wgArrayExtension, 'arraymerge' ) );
1058 - $parser->setFunctionHook( 'arrayslice', array( &$wgArrayExtension, 'arrayslice' ) );
1059 -
1060 - $parser->setFunctionHook( 'arrayunion', array( &$wgArrayExtension, 'arrayunion' ) );
1061 - $parser->setFunctionHook( 'arrayintersect', array( &$wgArrayExtension, 'arrayintersect' ) );
1062 - $parser->setFunctionHook( 'arraydiff', array( &$wgArrayExtension, 'arraydiff' ) );
1063 - $parser->setFunctionHook( 'arraysearcharray', array( &$wgArrayExtension, 'arraysearcharray' ) );
1064 -
1065 - return true;
1066 -}
Index: trunk/extensions/ArrayExtension/RELEASE-NOTES
@@ -1,7 +1,23 @@
22 Changelog:
33 ==========
44
5 - * (trunk) -- Version 1.4
 5+ * (trunk) -- Version 2.0
 6+ This release is built upon 1.4 alpha. See changes of 1.4 alpha as well.
 7+ - class 'ArrayExtension' renamed to 'ExtArrayExtension'
 8+ - '#arrayindex' will only expand options/default when required.
 9+ - Compatbility mode variable '$egArrayExtensionCompatbilityMode' is set to false by default. See
 10+ Version 1.4 alpha for further information. Further changes to the compatbility mode behavior
 11+ in version 2.0:
 12+ + '#arrayindex' will return its default also in case of existing index but empty value. This
 13+ makes the function consistent with Variables '#var' and hash tables '#hashvalue'.
 14+ + See 1.4 alpha for previous changes
 15+
 16+
 17+ * November 20, 2001 -- Version 1.4 alpha (r103716)
 18+ This release introduces some useful bugfixes and optional new behavior for various functionality.
 19+ This version never made it into a final stage because version 2.0 will introduce some rather
 20+ radical changes, so this alpha release allows to profit from bugfixes that might be quite useful
 21+ if you don't want to use Version 2.0 for some reason.
622 - Configuration variable '$egArrayExtensionCompatbilityMode' for deactivating the following newly
723 introduced breaking changes:
824 + '#arrayprint' no longer returns an error text in case the array doesn't exist.
@@ -11,7 +27,7 @@
1228 + '#arraysearch' returns an empty string '' instead of '-1' in case nothing was found.
1329 + '#arraysearcharray' and '#arrayslice' without all necessary parameters set will always create
1430 a new empty array.
15 - Compatbility mode is active by default, it will be disabled in version 2.0
 31+ Compatbility mode is active by default. In Version 2.0 it will be set to inactive by default.
1632 - '#arraysearch' will only expand 'yes' or 'no' if given, but never both.
1733 - negative indexes for '#arrayindex', '#arraysearch' and '#arraysearcharray' are possible now.
1834 - bugfix in '#arraysearcharray', index and limit working fine now.

Status & tagging log