PHP with gettext support on Mac OS X

PHP comes installed on OS X by default but it doesn’t come compiled with gettext support. So once you try to do something with gettext you will likely see something like this error message:

Fatal error: Call to undefined function bindtextdomain()

At this point you might be tempted to recompile PHP to add gettext but in fact there’s a better way, you can simply add it as a dynamically loaded library.

To do that download your version of php and do the following:

(inside the php directory)
cd ext/gettext
phpize
MACOSXDEPLOYMENTTARGET=10.6 CFLAGS="-arch i386 -arch x86_64 -g -Os -pipe -no-cpp-precomp" CCFLAGS="-arch i386 -arch x86_64 -g -Os -pipe" CXXFLAGS="-arch i386 -arch x86_64 -g -Os -pipe" LDFLAGS="-arch i386 -arch x86_64 -bindatload" ./configure
make
sudo make install

When done, edit your php.ini (normally located in /etc) and add:

extension=/usr/lib/php/extensions/no-debug-non-zts-20090626/gettext.so

Next just restart apache and you should be all done.

Update: Also you can get a binary package from http://php-osx.liip.ch/

WordPress Development Course and stuff

I will be running a WordPress Development course of P2PU, starting from the 26th of January 2010. For more information visit the course page.

As a sign-up task for this course I thought that it would be fun for people to modify the Hello Dolly plugin with their favorite quotes. One of the plugins that resulted from this exercise is one with quotes from Da Vinci, which I find to be brilliant.

http://p2pu.org/webcraft/wordpress-development

http://wordpress.org/extend/plugins/hello-da-vinci/

Thanks to all of you that signed up for this course, I was really suprissed to see so many people interested and now I’m really looking forward to it and I intend to do my best. Thanks!

WPMU posts return 404 not found

I’ve installed WordPress MU on a fresh Apache httpd and I go to try it out. I start by clicking on the ‘hello world’ post that comes as default and the page returns a 404 “not found” message. What is happening? This keeps happening to me all the time so I might as well share it here for others.

This can be fixed this by setting “AllowOverride to All” in the httpd.conf file, in the relevant Directory directive section where MU is installed.

Authentication by POST/GET in WordPress

For a project I’m working on I needed to trigger an action in a remote WordPress installation. I had a bit of trouble understanding how I could authenticate myself against the remote site. Eventually I found a clean and nice way and I want to share it here with you. Of course, if you’re not into WordPress you can safely skip this post.

The Problem

Where I first stumbled was when from my plugin I tried to access directly the other plugin in the remote site. The code I was using for doing this was something like:


// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, "http://wordpress.mu/wp-admin/admin.php?page=myplugin");
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
// print the result of the whole request:
print "CONTENT = ".$output;

And this wouldn’t work because although I was authenticated in the remote site via the browser, the session that the curl request creates is not, and so this request results in us being redirected to the login page.

What to do?

Ideally we want to do a POST request that we execute before and that authenticates us. I searched around on how to do this but couldn’t find anything. What I found was one of the many third-party applications that allow talking to WordPress remotely. I then looked at how they work and how they authenticate themselves.

Instead of doing a POST request to the plugin page like before, they do a POST request to the site’s index.php. A plugin is registered to catch a particular POST request. Then you simple use the WordPress function user_pass_ok(), that authenticates the user against the database.

Here I demonstrate how to do this using a GET request, because its simpler, but the same thing would work with a POST request.

add_action('plugins_loaded', 'unpackimport_createblog', -1);
function unpackimport_createblog() {
if(isset($_GET['myplugin'])) {
if(user_pass_ok($_REQUEST['username'], $_REQUEST['password']))
echo 'Authentication successful';
}

And the client request:

curl_setopt($ch, CURLOPT_URL, "http://wordpress.mu/index.php?myplugin=true&username=test&password=testpass");

Screencast

I wanted to show a working example rather than just saying this works so I did this screencast. You can also download the plugins yourself and try them out.

Download

unpack_import_demo.tar.gz
dump_pack_demo.tar.gz

WordPress Media Buttons


If you know WordPress, you know it is a great publishing platform. For a particular plugin I wanted to build I started looking at how to add one of those little icons you have access while writing a post, e.g. ‘Add an Image’, etc.

I was looking at how other plugins do this and found this code:


function wp_myplugin_media_button() {
$context = __('Add media: %s');
$wp_myplugin_media_button_image = '/path/media_button.gif';
$wp_myplugin_media_button = '
".' %s';
return sprintf($context, $wp_myplugin_media_button);
}
add_filter('media_buttons_context', 'wp_myplugin_media_button');

But when I tried this in my plugin something weird happened. If both my plugin and the one from where I took this code were active, then only the button from the other plugin would appear. If I disabled the second one then it worked. Why, oh why? After struggling a bit I found the answer.

The way the function is receiving the context is not correct. Both functions are asking for the default “context” (this is the media buttons themselves) and then adding something to it. The correct way to receive the context is to have it as an argument of the function. In that way it can be updated without a problem. Example follows:


function wp_myplugin_media_button($context) {
$wp_myplugin_media_button_image = '/path/media_button.gif';
$wp_myplugin_media_button = '
".' %s';
return sprintf($context, $wp_myplugin_media_button);
}
add_filter('media_buttons_context', 'wp_myplugin_media_button');

Update: if you want to add the button to the end of the media button list just append the %s first, e.g.:


function wp_myplugin_media_button($context) {
$wp_myplugin_media_button_image = '/path/media_button.gif';
$wp_myplugin_media_button = ' %s' . '
";
return sprintf($context, $wp_myplugin_media_button);
}
add_filter('media_buttons_context', 'wp_myplugin_media_button');

Hope it helps someone. Cheers.