/** mediawiki-extensions-Arrays-REL1_37 ExtArrays.php
* Usage:
* {{#arraydiff:arrayid_new |array1 |array2 |... |array n}}
*
* Set operation, {white} = {red, white} - {red}
* See: http://www.php.net/manual/en/function.array-diff.php
*/
public static function pfObj_arraydiff( &$parser, $frame, $args ) {
self::get( $parser )->multiArrayOperation( $frame, $args, __FUNCTION__, false );
return '';
}
private function multi_arraydiff( $array1, $array2 ) {
// keys will be preserved!
return array_diff( $array1, $array2 );
}
/**
* Base function for operations with multiple arrays given thru n parameters
* $operationFunc expects a function name prefix (suffix 'multi_') with two parameters
* $array1 and $array2 which will perform an action between $array1 and $array2 which
* will result into a new $array1. There can be 1 to n $hash2 in the whole process.
*
* Note: This function is similar to that of Extension:HashTables.
*
* @since 2.0
*
* @param PPFrame $frame
* @param array $args
* @param string $operationFunc name of the function calling this. There must be a counterpart
* function with prefix 'multi_' which should have two parameters. Both parameters
* will receive an array, the function must return the result array of the processing.
* @param bool $runFuncOnSingleArray whether the operationFunc function should be run in case
* only one array id is given. If not, the original array will end up in the new array.
*/
protected function multiArrayOperation( PPFrame $frame, array $args, $operationFunc, $runFuncOnSingleArray = true ) {
$args = array_values( $args );
$numArgs = count( $args );
$lastArray = null;
$operationRan = false;
$finalArrayId = trim( $frame->expand( $args[0] ) );
$operationFunc = 'multi_' . preg_replace( '/^pfObj_/', '', $operationFunc );
// For all arrays given in parameters 2 to n (ignore 1 because this is the name of the new array)
for ( $i = 1; $i < $numArgs; $i++ ) {
$argArrayId = trim( $frame->expand( $args[ $i ] ) );
// ignore all tables which do not exist
if ( $this->arrayExists( $argArrayId ) ) {
$argArray = $this->getArray( $argArrayId );
if ( $lastArray === null ) {
// first valid array, process together with second...
$lastArray = $argArray;
} else {
// second or later hash table, process with previous:
$lastArray = $this->{ $operationFunc }( $lastArray, $argArray ); // perform action between last and current array
$operationRan = true;
}
}
}
// in case no array was given at all:
if ( $lastArray === null ) {
$lastArray = [];
}
global $egArraysCompatibilityMode;
if ( !$operationRan && $egArraysCompatibilityMode
&& $operationFunc !== 'multi_arraymerge' // only exception was 'arraymerge'
) {
/*
* COMPATIBILITY-MODE:
* Before version 2.0 we didn't create a new array in case only one array was given.
* The only exception was 'arraymerge' which did duplicate the array.
*/
return;
}
// if the operation didn't run because there was only one or no array:
if ( !$operationRan && $runFuncOnSingleArray ) {
$lastArray = $this->{ $operationFunc }( $lastArray );
}
// re-organize all keys since some 'multi_' functions will preserve keys!
$lastArray = array_merge( $lastArray );
$this->setArray( $finalArrayId, $lastArray );
}