Setting Locale and Using PECL’s Imagick Library in PHP

I ran across an interesting issue today. An issue, that when I Googled it, appeared to have been resolved 2 years ago. However, I was using up-to-date versions of PHP, ImageMagick and the Imagick PECL library.

So, on to my issue. I have an abstract piece of code that when given the proper variables will set set the locale for my application. It sets the locale thusly:

setlocale(LC_ALL, 'fr_CA.utf8');

Later in the application, I was trying to draw a rectangle for a gauge that would graph a number against another number. When I tried to call the Imagick rectangle method, all hell broke loose.

$gauge = new ImagickDraw();
 
$x1 = $config->position->x1;
$y1 = $config->position->y1;
$x2 = $config->position->x2;
$y2 = $config->position->y2;
 
$gauge->rectangle($x1,$y1,$x2,$y2);

I then got this lovely message:

Fatal error: Uncaught exception 'ImagickException' with message 'Non-conforming drawing primitive definition `,' @ draw.c/DrawImage/3123'

Googled a bit and everything said this was fixed in the PECL library as of 2007. But it’s 2010 and I’m still having the issue!

Turns out if you set “LC_NUMERIC” to any French language locale, it can make interpreting floats difficult, because the French use commas (,) instead of periods (.) to delimit their fractions numerically. This caused the “rectangle” function of the “Imagick” PECL library to go crazy.

My Solution?

I altered my brash locale setting code to be a little more granular:

setlocale(LC_TIME, 'fr_CA.utf8');
setlocale(LC_MONETARY, 'fr_CA.utf8');

Setting locales for “LC_TIME” and “LC_MONETARY” was enough for me to get the programmatic localization I needed. And it made sure that “LC_NUMERIC” did not get set and cause localization on floats to interfere with external libraries.

This is “bang your head against the wall” stuff people. I hope this helps someone.

Convio Web Services in Python and PHP

Expanding on my last post about being able to successfully connect to Convio Web Services in three lines, I’d like to get a little more in depth and actually construct the necessary SOAP headers and make a simple call. I’ve written a small PHP implementation as well. I was able to make a successful log in to CWS in just 2 lines of PHP code!

Convio Logo

Now, as far as CWS goes, Python and PHP may not instantly be an obvious choice as far as languages go, mainly because they are both largely scripting languages. CWS is mainly for robust data syncing operations and those tasks generally go to languages like Java or C#, however, I’m a high level language guy, so I go with what I know. Also, Python and PHP both make SOAP exceedingly easy to work with, so there’s no real reason why you can’t, with a bit of discipline, write a perfectly excellent and robust data sync operation in either of these languages … especially Python.

So, here are my examples. They are exceedingly simple and easy once again. The Python example leverages suds once again and the PHP example is using PHP’s pretty impressive built in SOAP library. Each example shows you how to create the SOAP client using the Convio WSDL, make a successful log in to CWS, create a valid session header for subsequent calls, and how to make a call that grabs the number of constituents that have been added to the Convio database.

If you find either of these examples helpful, please let me know! Keep in mind these are just functional examples. There is no proper error handling or any sort of architecture here; they are just some bare bones examples on how to get data from CWS.

Python

from suds.client import Client
 
# Load the WSDL                                                                                                                                                                                                                                
client = Client('https://secureX.convio.net/1.0/CLIENT/wsdl')
 
# Log in to CWS                                                                                                                                                                                                                                
login = client.service.Login('apiadmin', 'password')
 
# Set the session header                                                                                                                                                                                                                       
session = client.factory.create('Session')
session.SessionId = login.SessionId
client.set_options(soapheaders=session)
 
# Get the number of constituents added since last sync                                                                                                                                                                                         
data = dict(PartitionId=1001, RecordType='Constituent', PageSize=1)
response = client.service.GetIncrementalInsertsCount(**data);
 
# Show the number of constituents added                                                                                                                                                                                                        
print '%d constituents have been added since the last sync.' % (int(response.RecordCount))

PHP

// Load the WSDL                                                                                                                                                                                                                               
$client = new SoapClient('https://secureX.convio.net/1.0/CLIENT/wsdl');
 
// Log in to CWS                                                                                                                                                                                                                               
$login = $client->Login(array('UserName'=>'apiadmin', 'Password'=>'password'));
 
// Set the session header                                                                                                                                                                                                                      
$headerBody = array('SessionId'=>$login->Result->SessionId);
$header     = new SoapHeader('urn:soap.convio.com', 'Session', $headerBody);
$client->__setSoapHeaders($header);
 
// Get the number of constituents added since last sync                                                                                                                                                                                        
$data = array
(
    'PartitionId' => 1001,
    'RecordType'  => 'Constituent',
    'PageSize'    => 1
);
$response = $client->GetIncrementalInsertsCount($data);
 
// Show the number of constituents added                                                                                                                                                                                                       
print(sprintf("%d constituents have been added since the last sync\n", (int) $response->Result->RecordCount));

PHP Library For Convio Open API

If any of you out there use Convio for your non-profit’s on-line presence, ie website, donations, email campaigns, I’ve created a PHP library for connecting to their Open API.

Convio Logo

I say it’s a “Library”… it’s really just a single wrapper file that aids in connecting to, making call to, and handling responses from, the Convio Open APIs.

There’s no documentation to speak of, but the two files included in the zip archive are pretty solidly commented, so you will probably be able to get a lot from them. The two files included in the zip are the library file itself and an example of how to implement it.

If you end up using it, let me know what you think!

Download the PHP Library for Convio Open API

Last.FM PHP Image Screen Scraper

I’m pretty avid user of Last.FM. I’m not big on this social networking fad, even if I do work in the industry, but I’ve found Last.FM very useful, mainly for finding new music. I’m currently building a web-based media manger in PHP and wanted a way to automatically get images for the artists.

I originally used the discogs.com API and although it was pretty easy to use and reasonably comprehensive, I was really disappointed in the quality of the images, not to mention I was constantly getting back images of electronic and ambient artists who had names similar to the rock bands in my collection, rather than the rock band themselves. I’m sorry, but when make a call to get images for “Cream” I don’t expect to get back some 14-year-old kid with a turntable and a DAT machine; I want freaking Clapton, Bruce, and Baker.

So, discogs.com left me a bit cold. But I soon learned about Last.FM and was delighted when I discovered their API. The image quality at Last.FM is superb, so I knew I wouldn’t be disappointed there. I started researching their API and realized that they didn’t really give me any info I needed other than the images and I didn’t want to have to sign up for an API key if all I wanted to do was download pictures of bands. Also, they only appear to provide three sizes of images and for many bands they have a whole slew of images available: large, medium, small, smaller, square; I wanted them all, not just the three provided by their API.

So, in the end I decided not to sign up for a Last.FM API key and instead wrote a very simple little PHP screen scraper that would bring back all of the images I wanted. Last.FM actually aided me in my goal by embedding a JSON string with just exactly what I needed right onto the artist page. It worked very well, so I decided to stick with it.

You can download my simple screen scraper script here. The zip file includes the class file and an example file.

It’ an incredibly simple script. Just a basic class file with only one useable method. It’s written so it can be expanded, but as Last.FM’s API is under constant development, it probably won’t be. But if you just want a simple script to grab artist images from Last.FM, please download my script and let me know if you like it.