Sunday, May 25, 2008

PHP and AJAX *head desk*

So, Thursday afternoon I broke my brain for the weekend trying to figure out why the heck a script that is working perfectly well on one server isn't working right on another server. Day one was wasted trying to figure out HOW to figure out what the heck was going on. The logs told me nothing. The page itself was not giving any hints. Since the whole thing was happening in AJAX land, behind the scenes and without giving any useful output to the browser, I couldn't use debugging tricks like echo and print_r to figure out what was going on with my variables. This morning, however, my brain was in better gear than it was Thursday afternoon, so I started the day off by actually doing something useful.

When you need a script to give you useful information in the browser, and the page in question is using AJAX to send information (but not, at the moment, receive information), then (DUH!) use AJAX to give you the information you need!!!

In my case I had a handy editor box in which to plunk the response text from the AJAX request.

xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4) {

document.forms["editorbox"].editorBox.value = xmlhttp.responseText;
}
}

At one point, I used alert(xmlhttp.responseText) instead of the editorbox, but that wasn't as useful because the alert box doesn't let you select and copy stuff if you need it. Also, my editorbox had a handy-dandy scroll bar, and the errors coming out of my responseText were numerous.

In order to make the responseText useful, you may want to echo out certain variables and then exit; so that the info you want -- and only the info you want -- will show up where you need it.

Now, as to what was actually wrong with the script I was messing with today... It appears that a difference in php.ini files was my problem. In the version of the script that was NOT working, all the quotes were getting escaped as they got soaked up into the PHP script. When I then tried to dom->loadXML($myXML) the script was complaining that my XML was no good. Well, of course it's no good, there's all these darned escape characters before the quotes!

I don't want to change the php.ini on the server, so I have to get rid of those escapes some other way. preg_replace to the rescue!


$pat = '/\\\"/';
$rep = "'";
$myXML = preg_replace($pat, $rep, $myXML);


All better. :)

Tuesday, May 13, 2008

Good User Interfaces

I have a friend who loves to complain about the user interfaces in current technology. He has a million great things to say about how things should be made, and he says them with a cantankerous grumble. I adore him for so many reasons, but this is definitely one of them. He opens my eyes again and again to my own tendency to develop for geeks like me instead of the person on the street who really should be getting a better thought out and better built product. Because of him, I also notice even more when someone does something really right.

A couple of weeks ago he and I were in an elevator and he hit the wrong button by accident. He grumbled and hit the correct button and then said, "You know, if elevators were made correctly, I'd be able to cancel that wrong choice. I should be able to hit that button again and make it turn off."

Today, when I got into the elevator at work, someone else got in, pressed the wrong button, noticed the mistake and pressed the button again to cancel the request. Then they pressed the floor they really wanted. Oo! I was so excited I had to twitter it right there in the elevator.

It turns out that all new Mitsubishi elevators have that functionality. Way to go Mitsubishi.

Another one of my friend's pet peeves is that you have to save files. Why should you have to do an action to save a file? It should be automatic, right? Why would I create a file if I didn't want to save it? Well, it's getting to be automatic in some places like Google Docs for instance. Well, today I found another really cool app that deals with the saving thing right along with at least a dozen other major UI annoyances.

Skitch is unfortunately a Mac only application and it's still in beta, but it looks absolutely awesome. They get so many things right. They have a great way to share things, to snap screenshots, to draw and manipulate images, and you don't have to save your file from a menu or a keystroke. You can just drag it to where you want it to live, or drag it to an email to share it. Very, very nice.

Monday, May 12, 2008

Having Trouble Importing Drupal Translation Packs?

OMG I just spent way too long pulling my hair out over the Drupal 6 translation import feature. To put it simply, the handbook and help information is very UNCLEAR about what you are supposed to do.

The instructions say to download the translation pack into your install directory and unzip it. So, if, like me, you don't have access to the server that will allow you to unzip a folder on the server, logic says that you should be able to unzip the folder on your own machine and simply ftp the folder into place, right? Wrong. Well, at least sort of wrong.

Let's say you have the he-6.x-1.0 translation pack. You've unzipped it, and now it's sitting on your PC's desktop. You want to move it to your server. DO NOT copy that whole folder over to the server so that you end up with something like /webroot/drupal/he-6.x-10 on your server.

What you DO want to do is copy the CONTENTS of he-6.x-10 over onto the server so that the internal directory structures plop into place inside the existing directory structure in drupal. That way you will have something like /webroot/drupal/modules/aggregator/translations/modules-aggregator.he.po and so forth.

As you can see here, each directory that has translations (modules, themes, etc. anything that has t() strings, really) gets it own translations directory and language po files go in there.

The easiest way to get all of those files to plonk into the right place is, in fact, to un-zip the file insitu at your server rather than trying to ftp the files over post-expansion.

Thursday, May 1, 2008

Interesting tidbit about PHP objects

I'm doing some XML stuff right now, using SimpleXML in PHP. One of the element groups I need to create is a list of descriptions in different languages. My original attempt looked like this:

$descriptions = array(
'en' => 'An awsome app.',
'es' => 'Una aplicacion chevere.',
'he' => 'אפליקציה מעולה',
);

foreach($descriptions as $loc => $desc) {
$d->addChild('description', $desc);
$d->description->addAttribute('locale', $loc);
}
echo $xml_post->asXML();


But that gave me an error:
Warning: SimpleXMLElement::addAttribute() [function.SimpleXMLElement-addAttribute]: Attribute already exists in...


When I looked at the code, the attribute was only getting plunked into the first <description> tag. The PHP engine thought that each time I went through the loop I was talking about the same $d->description when I asked it to stick a locale attribute in there. Weird. I expected the object to be treated like any other variable and get treated as a fresh thing. Nope.

If you put

echo $d->description . "<br />"

after the addChild() above, you'll see that it echoes out

an awesome app.
an awesome app.


If, however you change that block of code to

foreach($descriptions as $loc => $desc) {
$tag = $d->addChild('description', $desc);
echo $tag . "<br />";
}

you'll see that $tag prints out the correct description line for that pass through the loop:

An awsome app.
Una aplicacion chevere.
אפליקציה מעולה


So, the correct code to create the XML I want is

$descriptions = array(
'en' => 'An awsome app.',
'es' => 'Una aplicacion chevere.',
'he' => 'אפליקציה מעולה',
);
foreach($descriptions as $loc => $desc) {
$tag = $d->addChild('description', $desc);
$tag->addAttribute('locale', $loc);
}
echo $xml_post->asXML();


And then the XML comes out right.

<description locale="en">An awsome app.</description>
<description locale="es">Una aplicacion chevere.</description>
<description locale="he">אפליקציהמעולה</description>

Wednesday, April 30, 2008

CodeBlocks: Cross Platform C++ IDE

This is late, but you know what they say... better than never, right?

CodeBlocks has finally released a new version. For ages they weren't doing releases, just nightly builds. When I was working with Shlomi Peleg at SparkThing this app was a staple of our work environment. I haven't used the new release yet, but Peleg says that it's great.

So, if you write C++ and want an excellent open source IDE to work in, check it out.

Monday, April 28, 2008

Cool iPhone Thingy

We had a training at work today all about how the GSM phone system works. At the end, the speaker showed us how to find out all sorts of information about your GSM connection on an iPhone. You can see information about a call in progress, network information, which cell phone towers your phone can see, information about your GPRS (internet) connection, and what firmware version you are running.

One of the cool things about this is that you can see how walking around in a room, say, makes your connection to any given tower stronger or weaker.

If you have an iPhone, check it out. Dial *3001#12345#* then hit call.

And no, I don't have an iPhone. The company has a few for testing our apps, so we got to play with those. My current phone is a Nokia N80.

Sunday, April 13, 2008

Computing Everywhere?

A friend of mine hates the state of computing today. He points out that it's developed by geeks for geeks, and the rest of the world has to bend to our twisted way of thinking. Really, computers should be more than just ubiquitous, they should be invisible. They should bend to the needs of humans, not the other way around.

One of the areas where this is actually making strides forward is in the area of always accessible data. As my friend would say, "Why should I have to manage three or four address books? I shouldn't! The computer, my home phone, my cell phone, and all of the apps on them should be able to get what I need from one central place where I keep that data." So true.

APIs for cross-application development and mashups are getting us closer to that kind of thing, and tools like OpenID and OAuth are also moving us in the right direction. But, what about that data thing? How can I have my data in one place?

One possibility is the advent of serious online storage solutions and wifi based file sharing through applications like *Fring. There's a blog article about just that at the Fring site called "Is Fring the missing link for mobile online storage services?". Yeah, I think that it can be.

We're still a long way from where my friend dreams, but I truly believe that we are in the midst of an evolution that is heading in that direction. One side of me says that we shouldn't be too impatient because all of these things are moving forward one step at a time, but on the other hand, it's precisely the impatience of developers and entrepreneurs that is pushing us forward in this evolution so quickly.

The next time you look at the design of an application you are working on, ask yourself: "How is this going to tie in with the computing needs of the user at home, on their smart phone, in the car... and everywhere else they are computing?" And "Can we make it work together with a single data source and invisible syncing?" Because if you can deal with those two issues now, you are going to put your app ahead of the curve and make it that much more invaluable to your end user. Which might just be yourself. (or me!) ;)

*Just so you know: I work for Fring now. :)