Last modified: 2012-11-16 13:55:38 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T32854, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 30854 - Broken Log Formatting for Page Moves
Broken Log Formatting for Page Moves
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
Special pages (Other open bugs)
1.20.x
All All
: High major with 1 vote (vote)
: ---
Assigned To: Niklas Laxström
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2011-09-11 11:52 UTC by DaSch
Modified: 2012-11-16 13:55 UTC (History)
3 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments
Suggested patch (1.12 KB, patch)
2011-09-13 19:58 UTC, DaSch
Details

Description DaSch 2011-09-11 11:52:00 UTC
When accessing Special:Recent_Changes I get this error. Other pages work normal and logging is disabled in my configuration.

Warning: Invalid argument supplied for foreach() in /.../httpdocs/includes/logging/LogFormatter.php on line 179

Catchable fatal error: Argument 1 passed to LogFormatter::makePageLink() must be an instance of Title, null given, called in /.../httpdocs/includes/logging/LogFormatter.php on line 337 and defined in /var/www/vhosts/wecowi.de/httpdocs/includes/logging/LogFormatter.php on line 206
Comment 1 Niklas Laxström 2011-09-11 13:02:22 UTC
Can you add this code to LogFormatter before line 179 and post the results
		if ( !is_array( $entry->getParameters() ) ) {
			var_dump( $entry ); die();
		}

Or can you provide the results of this mysql command:
select rc_log_type, rc_log_action, rc_params from recentchanges where rc_type = 3 order by rc_id desc limit 50;
Comment 2 DaSch 2011-09-11 15:17:54 UTC
That's the result

object(RCDatabaseLogEntry)#502 (3) { ["row:protected"]=> object(stdClass)#498 (30) { ["rc_id"]=> string(5) "92568" ["rc_timestamp"]=> string(14) "20110906212954" ["rc_cur_time"]=> string(14) "20110906212954" ["rc_user"]=> string(1) "1" ["rc_user_text"]=> string(5) "DaSch" ["rc_namespace"]=> string(1) "0" ["rc_title"]=> string(38) "Sympathy_for_the_Devil_(One_Tree_Hill)" ["rc_comment"]=> string(0) "" ["rc_minor"]=> string(1) "0" ["rc_bot"]=> string(1) "0" ["rc_new"]=> string(1) "0" ["rc_cur_id"]=> string(5) "15933" ["rc_this_oldid"]=> string(1) "0" ["rc_last_oldid"]=> string(1) "0" ["rc_type"]=> string(1) "3" ["rc_moved_to_ns"]=> string(1) "0" ["rc_moved_to_title"]=> string(0) "" ["rc_patrolled"]=> string(1) "1" ["rc_ip"]=> string(13) "92.224.225.44" ["rc_old_len"]=> NULL ["rc_new_len"]=> NULL ["rc_deleted"]=> string(1) "0" ["rc_logid"]=> string(5) "41633" ["rc_log_type"]=> string(4) "move" ["rc_log_action"]=> string(4) "move" ["rc_params"]=> string(36) "Stunde der Wahrheit (One Tree Hill) " ["wl_user"]=> string(1) "1" ["wl_notificationtimestamp"]=> NULL ["page_latest"]=> string(6) "110655" ["ts_tags"]=> NULL } ["params"]=> string(36) "Stunde der Wahrheit (One Tree Hill) " ["legacy"]=> bool(false) }
Comment 3 DaSch 2011-09-11 15:22:00 UTC
And that is the result of the SQL command

rc_log_type 	rc_log_action 	rc_params
upload 	upload 	[BLOB - 0Bytes]
move 	move 	[BLOB - 36Bytes]
move 	move 	[BLOB - 35Bytes]
move 	move 	[BLOB - 38Bytes]
move 	move 	[BLOB - 41Bytes]
move 	move 	[BLOB - 36Bytes]
move 	move 	[BLOB - 35Bytes]
move 	move 	[BLOB - 41Bytes]
move 	move 	[BLOB - 32Bytes]
move 	move 	[BLOB - 27Bytes]
move 	move 	[BLOB - 36Bytes]
move 	move 	[BLOB - 42Bytes]
move 	move 	[BLOB - 52Bytes]
delete 	delete 	[BLOB - 0Bytes]
move 	move 	[BLOB - 60Bytes]
delete 	delete 	[BLOB - 0Bytes]
move 	move 	[BLOB - 32Bytes]
move 	move 	[BLOB - 31Bytes]
move 	move 	[BLOB - 37Bytes]
move 	move 	[BLOB - 40Bytes]
import 	interwiki 	[BLOB - 0Bytes]
move 	move 	[BLOB - 15Bytes]
move 	move 	[BLOB - 19Bytes]
upload 	upload 	[BLOB - 0Bytes]
move 	move 	[BLOB - 24Bytes]
import 	interwiki 	[BLOB - 0Bytes]
move 	move 	[BLOB - 26Bytes]
move 	move 	[BLOB - 29Bytes]
move 	move 	[BLOB - 19Bytes]
move 	move 	[BLOB - 25Bytes]
move 	move 	[BLOB - 34Bytes]
move 	move 	[BLOB - 27Bytes]
move 	move 	[BLOB - 31Bytes]
move 	move 	[BLOB - 30Bytes]
move 	move 	[BLOB - 28Bytes]
move 	move 	[BLOB - 23Bytes]
move 	move 	[BLOB - 24Bytes]
move 	move 	[BLOB - 26Bytes]
move 	move 	[BLOB - 22Bytes]
move 	move 	[BLOB - 22Bytes]
move 	move 	[BLOB - 21Bytes]
move 	move 	[BLOB - 20Bytes]
move 	move 	[BLOB - 25Bytes]
move 	move 	[BLOB - 28Bytes]
move 	move 	[BLOB - 26Bytes]
move 	move 	[BLOB - 23Bytes]
move 	move 	[BLOB - 22Bytes]
import 	interwiki 	[BLOB - 0Bytes]
import 	interwiki 	[BLOB - 0Bytes]
import 	interwiki 	[BLOB - 0Bytes]
Comment 4 Niklas Laxström 2011-09-11 18:00:09 UTC
Which revision is this? I don't understand how the current code would return non-array:

["params"]=> string(36) "Stunde der Wahrheit (One Tree Hill) " ["legacy"]=> bool(false)

The relevant code is here:

public function getParameters() {
	if ( !isset( $this->params ) ) {
		$blob = $this->getRawParameters();
		wfSuppressWarnings();
		$params = unserialize( $blob );
		wfRestoreWarnings();
		if ( $params !== false ) {
			$this->params = $params;
			$this->legacy = false;
		} else {
			$params = FormatJson::decode( $blob, true /* array */ );
			if ( $params !== null ) {
				$this->params = $params;
				$this->legacy = false;
			} else {
				$this->params = $blob === '' ? array() : explode( "\n", $blob );
				$this->legacy = true;
			}
		}
	}
	return $this->params;
}
Comment 5 DaSch 2011-09-11 18:53:31 UTC
I have r96776 and have no idea about this :(
Maybe this error is caused by the changes from r96585
Comment 6 Niklas Laxström 2011-09-11 18:57:10 UTC
I can't think of anything else, but that either unserialize() doesn't return false, or FormatJson::decode doesn't return null. Can you play around with the code and check if that is the case?
Comment 7 DaSch 2011-09-11 19:13:30 UTC
it seams that $this->params is already set when entering the function getParameters
I added this before the return
else { echo "already set to: "; var_dump($this->params); }
and got this result: 
already set to: string(36) "Stunde der Wahrheit (One Tree Hill) "
Comment 8 Niklas Laxström 2011-09-11 19:18:02 UTC
You probably see that because that function is called twice, first through isLegacy() and then getParameters() directly. Otherwise $this->legacy would have been unset.
Comment 9 DaSch 2011-09-11 19:48:26 UTC
I have the impression that the numbering of the params is not correct

I added this
if ( !isset($params[3]) ) {$params[3]="WARNING: Missing!";}
in getMessageParameters before return

the result you can see here

http://www.wecowi.de/wiki/Spezial:Logbuch/move

The targetPage is missing
Comment 10 Niklas Laxström 2011-09-11 19:56:52 UTC
Of course it is missing, that's why the PHP complains.

You should be investigating what happens inside DatabaseLogEntry::getParameters() method.
Comment 11 DaSch 2011-09-11 20:03:33 UTC
The strange thing is, that the missing string is what is given through $entry->getParameters()
it is a string like I added through the if. But when using
$params[3] = $entry->getParameters();
it does not work
altough printing $params[3] after setting it gives the correct page name
but somehow it disappears short after
Comment 12 DaSch 2011-09-11 20:18:58 UTC
To avoid that DatabaseLogEntry::getParameters() return a string instead of an array I added this before the return
		if ( is_string($this->params) ) {
			$paramString = $this->params;
			$this->params = array();
			$this->params[0] = $paramString;
		}
The warning disappears but the error remains
so somehow even if the array exists how it should the target page still is not added correctly
Comment 13 DaSch 2011-09-11 20:42:42 UTC
I added
$this->legacy = true;
to the if give above
Know in LogFormatter::getMessageParameters() in the if that checks for legacy the param is added correctly to position 3. And the params array is returned correctly with entrys 0-3 but in MoveLogFormatter::getMessageParameters it is still missing
Comment 14 DaSch 2011-09-11 21:07:37 UTC
I think the problem is, that
Title::newFromText( $params[3] ) 
returns NULL
Comment 15 DaSch 2011-09-11 21:26:13 UTC
I think the return value of Title::newFromText is not correct or not handled correctly
Comment 16 DaSch 2011-09-11 23:14:48 UTC
Can anybody check this for a clean install?
Will this be a migration issue or does the move-log not work at any enviorment?
Comment 17 Niklas Laxström 2011-09-12 07:44:57 UTC
Can you check the return values of unserialize( $blob ) and FormatJson::decode( $blob, true /* array */ ) in DatabaseLogEntry getParameters()?
Comment 18 DaSch 2011-09-12 21:06:20 UTC
In the database the value of rc_params is a string for move entries. So everything is correct. The string is correctly passed through DatabaseLogEntry when conversion from the string to an array like described above to $params[3]. But then when Title::newFromText( $params[3] ) is executed it returns NULL when the page exists and then the value is lost and then the creation of the pagelink fails.
Comment 19 Niklas Laxström 2011-09-13 05:29:41 UTC
This warning clearly says that it is *not* an array that is returned:
Warning: Invalid argument supplied for foreach() in
/.../httpdocs/includes/logging/LogFormatter.php on line 179
Comment 20 DaSch 2011-09-13 06:58:00 UTC
Therfore I added this
(In reply to comment #12)
> To avoid that DatabaseLogEntry::getParameters() return a string instead of an
> array I added this before the return
>         if ( is_string($this->params) ) {
>             $paramString = $this->params;
>             $this->params = array();
>             $this->params[0] = $paramString;
>         }
> The warning disappears but the error remains
> so somehow even if the array exists how it should the target page still is not
> added correctly

There can not be an array returend because the blob in the database is only a string
Comment 21 Niklas Laxström 2011-09-13 08:08:52 UTC
That function must always return an array. It should go through the legacy = true path, which uses explode( '\n' ) to make an array of the string. However, in this case it is taking one of the two other parts - why - that doesn't make any sense to me. That's why I'd like to know a) which path it is b) what is the value of $params when that path is taken.
Comment 22 DaSch 2011-09-13 17:00:12 UTC
But when there ist no \n in the string it can not create an array because there is nothing to explode

The point is that the real problem occures at the end. When Title::newFromText is applyed witch does not return an instance of Title, but null and forces makePagelink to fail!
Comment 23 Niklas Laxström 2011-09-13 17:02:19 UTC
But it doesn't even try to explode, I can see that from legacy=false.
If it would, it would return an array:

> var_dump( explode( "\n", "cat" ) );
array(1) {
  [0]=>
  string(3) "cat"
}
Comment 24 DaSch 2011-09-13 18:02:12 UTC
I have the impression that we totally talk past each other and have no idea what to test, to try or whatever
Comment 25 DaSch 2011-09-13 18:30:31 UTC
Okay... well
DatabaseLogEntry::getParameters()
returns the following

$params = unserialize( $blob );
var_dump($params);
is false

$params = FormatJson::decode( $blob, true /* array */ );
var_dump($params);
is string
Comment 26 DaSch 2011-09-13 19:02:07 UTC
BTW: when passing a string to json_decode it always return the same. Check
echo json_decode( "cat", false );
echo json_decode( "cat", true );
Comment 27 Niklas Laxström 2011-09-13 19:05:02 UTC
var_dump( json_decode( 'cat', false ) );
NULL

From PHP manual http://fi.php.net/json_decode:
NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.

What version of PHP?
Comment 28 Niklas Laxström 2011-09-13 19:09:28 UTC
Ah this is the bug: https://bugs.php.net/bug.php?id=45989

I will remove the JSON check, since it isn't even needed. That should fix this bug.
Comment 29 DaSch 2011-09-13 19:17:06 UTC
My PHP Version is 5.2.4
Comment 30 DaSch 2011-09-13 19:33:19 UTC
You could also change
if ( $params !== null )
to
if ( $params !== null and is_array($params) )
Comment 31 DaSch 2011-09-13 19:58:04 UTC
Created attachment 9056 [details]
Suggested patch
Comment 32 Niklas Laxström 2011-09-14 08:25:42 UTC
r97039 should fix this. Please test.
Comment 33 DaSch 2011-09-14 08:49:30 UTC
yes it works
Comment 34 Stefan Kaifer 2012-11-15 17:50:56 UTC
Hi

i've the same problem with 1.20.0.

Page moving not works:

<b>Warning</b>
: call_user_func_array() expects parameter 1 to be a valid callback, function 'MoveLogFormatter' not found or invalid function name in
<b>.../includes/logging/LogPage.php</b>
on line
<b>319</b>

Datenbankfehler
Wechseln zu: Navigation, Suche
Es ist ein Datenbankfehler aufgetreten. Der Grund kann ein Programmierfehler sein. Die letzte Datenbankabfrage lautete:

    (Die SQL-Datenbankabfrage ist verborgen.)

aus der Funktion «efUpdateCheckUserData». Die Datenbank meldete den Fehler «1048: Column 'cuc_actiontext' cannot be null (localhost)».


How can i fix this?

Best regards

Stefan
Comment 35 Nemo 2012-11-16 13:55:38 UTC
Stefan, you should check the documentation on how to upgrade your MediaWiki and then file a new bug for your issue.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links