Time for a lesson in basic PHP.
A bug was introduced in r25374 by Aaron, last September, and despite half a dozen people editing the few lines around that point, nobody picked it up. Simetrical eventually fixed it in r29156, blaming a bug in PHP's array_diff(). It was not.
$permErrors += array_diff( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors );
I used to make the same error myself. Although I learnt from my mistakes, we obviously haven't learnt as a team.
http://www.php.net/manual/en/language.operators.array.php
"The + operator appends elements of remaining keys from the right handed array to the left handed, whereas duplicated keys are NOT overwritten."
That explains the behaviour of the array plus operator in its entirety. If you add two arrays, and both have an element with a key of zero, the one on the left-hand side wins. The elements are NOT renumbered.
For example:
print_r( array( 'foo' ) + array( 'bar' ) );
Array ( [0] => foo )
print_r( array( 'foo' ) + array( 'bar', 'baz' ) );
Array ( [0] => foo [1] => baz )
If you want the elements to be renumbered, use array_merge().
-- Tim Starling
On Wed, Feb 20, 2008 at 6:52 AM, Tim Starling tstarling@wikimedia.org wrote:
A bug was introduced in r25374 by Aaron, last September, and despite half a dozen people editing the few lines around that point, nobody picked it up. Simetrical eventually fixed it in r29156, blaming a bug in PHP's array_diff(). It was not.
$permErrors += array_diff( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors );
What I said is another reason the code didn't work, though, AFAICT.
http://www.php.net/manual/en/function.array-diff.php
"Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same."
In particular, any array is equal to "Array" when cast to a string, and so any two arrays are equal for this purpose, as I said in the comment accompanying my fix. Both $permErrors and the return value of getUserPermissionsErrors() were arrays of arrays, and *any* two arrays of arrays will have an empty difference according to array_diff(). Even if the code had been
$permErrors = array_merge( $permErrors, array_diff( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors ));
it would have included no reasons for why the user couldn't edit, because you're merging with an empty array. Am I wrong?
Simetrical wrote:
On Wed, Feb 20, 2008 at 6:52 AM, Tim Starling tstarling@wikimedia.org wrote:
A bug was introduced in r25374 by Aaron, last September, and despite half a dozen people editing the few lines around that point, nobody picked it up. Simetrical eventually fixed it in r29156, blaming a bug in PHP's array_diff(). It was not.
$permErrors += array_diff( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors );
What I said is another reason the code didn't work, though, AFAICT.
http://www.php.net/manual/en/function.array-diff.php
"Note: Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same."
In particular, any array is equal to "Array" when cast to a string, and so any two arrays are equal for this purpose, as I said in the comment accompanying my fix. Both $permErrors and the return value of getUserPermissionsErrors() were arrays of arrays, and *any* two arrays of arrays will have an empty difference according to array_diff(). Even if the code had been
$permErrors = array_merge( $permErrors, array_diff( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors ));
it would have included no reasons for why the user couldn't edit, because you're merging with an empty array. Am I wrong?
Yes, two bugs on the same line. You could have fixed the array comparison problem using array_udiff(), but then you would have been left with the array plus problem.
-- Tim Starling
wikitech-l@lists.wikimedia.org