Pages

Sunday, September 7, 2008

The wonders of PHP programming

I decided to update my working copy of regexBlock extension and finish up some work I started doing a long time ago - integrating changes from Wikia's SVN.

Everything looked nice until the update finished. I've got not only one but two files in conflicted state. I fix them and svn up again. Now I've got a clean-ish working copy and I can retry applying the Wikia modifications to my local copy.

One of the major annoyances of Wikia codebase is EasyTemplate class. The class supposedly allows "for easy mixing [of] HTML/JavaScript/CSS/PHP code". If you've ever written code for MediaWiki or taken a look at MediaWiki's source code, you're aware of public function addHTML in OutputPage.php. It does exactly what Wikia's EasyTemplate does, and even a bit easier IMO.

So the first thing I had to do to get the new regexBlock code working was to kill the EasyTemplate dependency. Thankfully that's about the easiest task there can be. Just replace the code referring to EasyTemplate with $wgOut->addHTML( 'code goes here' ); and that's almost about it (not quite, but let's not get into too technical details). Now I've got a working version of the extension in front of me, yay! Time to test it, so I'll add the extension into the LocalSettings.php of my local testing wiki, add the required tables to the database and go to the wiki to see any and all possible issues.

Okay, the special page loads, although the interface looked like as if there was at least one unclosed <div> tag. And then there was something other noteworthy too: one PHP notice (E_NOTICE) and one PHP warning (E_WARNING). The notice was about an "invalid argument supplied to foreach() on line..." and the warning was about an error within a function that used PHP's array_combine function. The warning related to array_combine function was actually very easy to fix, although I could've sworn that the first, obvious and correct fix didn't work the first time I tried it. After a while of trying, the error went away. That was the easy part of the upgrade...

What was remaining was the notice about an invalid argument to some foreach loop. It sounds relatively easy now, doesn't it? It certainly wasn't such. The current code (which does not raise any notices or errors) looks like this:


$selected = htmlspecialchars( ($k == $this->mRegexBlockedExpire) ) ? 'selected="selected"' : '';
foreach( $expiries as $k => $v ) {
$wgOut->addHTML('<option value="'.$selected.'">'.htmlspecialchars($v).'</option>');
}



But when I had moved the code to the main .php file from the template file, I had pretty much copy-pasted parts of the code and it looked like this:


foreach( $expiries as $k => $v ) {
$wgOut->addHTML('<option value="'.htmlspecialchars( ($k == $this->mRegexBlockedExpire) ) ? 'selected="selected"' : ''.'">'.htmlspecialchars($v).';</option>');
}



I do understand the people that hate PHP a bit better now. After I had fixed a couple errors like this, the interface worked relatively nicely.
Of course, I had to fix a couple message names - internationalization (i18n) support was added for regexBlock ages ago, but Wikia had added i18n on their own, which led to a new issue: a message containing some string, say, "permanent block" was called 'regexblock_permament_block' (sic) in Wikia's version and 'regexblock-view-block-infinite' in the official version.
Well, this was relatively easy task to be honest. After all, I only had to compare the two i18n files against each other and alter the message names in SpecialRegexBlock.php.

So, now what? Now I had a working, improved version of regexBlock extension that is error-free. Or that's what I thought myself. I tested the actual blocking mechanism and whoops:


Expiry time invalid.


No wonder that there are comments like "Fuck you, PHP. Fuck you in the ear!" around the MediaWiki codebase.

So, it's back to the drawing board for me, so to say. Maybe I'll have this extension upgrade finished before Christmas 2008, who knows.

No comments: