Symfony comes bundled with the sfFinder class that lets you conveniently search for files and directories. It has a simple fluent interface that lets you tell what you’re looking for and where to look for it:

May 21, 2008

We’ve just released the initial version of sfToboAds, a Symfony plugin allowing for integration with ToboAds, an advertising network offering contextual text and graphic advertising to the masses (banners are contextual!). The initial release is pending PEAR packaging before being offered as a compressed download, for now, it’s available via the subversion repository on the following URL:

http://toboads-plugins.googlecode.com/svn/trunk/symfony_plugin

This is part of our wider package of plugins for different platforms and is fully LGPL licensed. A solid release with updated documentation will be available soon.

EDIT: Symlinks don’t work this way because of the working directory being in C:\PHP where the symlink is located. See below for modified instructions.

First, check out the SVN branch for 1.1 to a directory of your choosing – this can be located anywhere on any storage volume. When the checkout’s done, open a command prompt and navigate into your PHP directory where symfony.bat is already located. In my case, this is C:\PHP and my checkout is D:\Projects\symfony-1.1. As Vista comes with an NTFS file system capable of UNIX-like (not quite, but close enough) symlinks (thanks to camason on #symfony for pointing that out to me), you can create a symlink to Symfony 1.1’s batch file using mklink (you’ll need a command prompt with elevated privileges for this to work):

This creates a symbol link to the symfony.bat executable – now I can (assuming I have PATH set to C:\PHP) run symfony-1.1 at the command prompt from anywhere and can use the new branch with the same ease of use as the original article.

Unfortunately, due to symlinks executing with the working directory being in C:\PHP, you’ll get Symfony v. 1.0.x instead. To overcome this, delete the symlink and create a symfony-1.1.bat with the following contents:

@cmd /c d:\Projects\symfony-1.1\data\bin\symfony.bat %*

That will fix the working directory problem and correctly execute Symfony 1.1.

February 19, 2008

A while back, I’ve stumbled upon an interesting, yet exotic, project – PAMP. It promises to bring the full Apache/MySQL/PHP stack to the Symbian phone. So, on a whim, I decided to try it out.

After following the installation instructions (installing on a Nokia N95 with the installation for memory cards) and starting up the PAMP stack, I’ve connected to the home LAN network and navigated my computer’s browser to the phone’s LAN IP. Lo and behold – the almighty “It works!” sign showed up. Even phpinfo() says it’s got most of the bundled extensions enabled (including GD2 and mbstring!).

So, on another whim, I decided to stress test the bugger and see if it runs Symfony. To spare you the excitement – it doesn’t run. Copying the files via USB messes up the file casing, so I had to re-copy the whole shebang using the phone’s sync software (which I’m still doing).

One thing to add though – while copying, I’ve noticed some files will not copy and I’m guessing the culprit is the lenght of the absolute path and name of the file. The first one in question is located inside $sf_data_dir/sfPropelCrud/ somewhere (the damn thing won’t show me which), there are probably more (I’m still copying files by hand). While I’m not using the generator in the test application, it seems there will have to be some workaround to get it working on a this phone (but the question really is – is Symfony really meant to run on phones?).

More to follow.

Edit:

It seems that using the phone software’s bundled File Manager solves the file casing issue. I still haven’t managed to copy all the files, but those that can’t be copied I’m sure won’t get used anyways (some generator skeletons and such).

Edit nr.2:

Well, all things said and done, it seems PHP segfaults before symfony has even a chance of running anything, but no way of seeing what error is produced, exactly. I haven’t been able to find any Apache logs written anywhere. And no, no Symfony logs to speak of as of now (it segfaults before that point). It could be something to do with UTF-8 encoding – I’ve tried opening a file on the phone with the default file manager and all the YAML files were messed up. I’m not even sure which encoding the phone is using. It’d be a shame if it was limited to ISO-8859-2 or such.

February 6, 2008

Yeah, I’ve been away a while, had no time to update this blog, but still have been active on freenode’s #symfony channel.

Just a quick tip for anyone interested or looking for a better solution than XAMP – it’s called The Uniform Server. It unzips into a convenient folder anywhere on your computer and sits there until invoked. It’s portable (USB key server, anyone?), self-contained and can be secured and managed via the control panel after you get the server up and running.

It took me just 10 seconds to unzip and start the server (including opening the command prompt and typing Start_server.bat). That’s the fastest Apache/PHP5/MySQL setup I’ve ever done. Maybe not very newbie friendly, but for anyone used to working with LAMP, it should be a breeze.

November 27, 2007

Before I start off, this isn’t a Mac vs. PC bash article. Nor is it a comparison between the two. I disclaim any statements about the superiority of each platform, since this will not be an article discussing these topics. That said, let’s move on to the topic of relevant interest.

As any self-respecting web developer, I try to cover as much ground as possible when it comes to the population of browsers that inhabit our Internet. It’s a pain in the ass, but we have to do it. Much of it is alleviated by the numerous JS and CSS libraries that I use to leverage the complexity of being cross-browser compatible (jQuery, Blueprint CSS, YUI CSS, just to mention a few). Still, it’s a daunting task.

Recently, Apple announced that it would be bringing the Safari browser to Windows and I thought “Gee whiz, it’d be great not to have to buy a Mac just to see IF my site works on a Mac.” I downloaded a copy, had it installed in less than a minute and was pretty impressed by the painlessness of the process. Nice job, Jobs (pun intended). My only gripe was the page loading time – everytime I’d start it up, it would take anywhere from 10-20 seconds to load up the first page, subsequent loads were quicker. I surfed a few pages thinking that it was good that it had its own typography rendering engine (nice to see how fonts look on Mac natively – very important for making accessible designs). Also, it seemed kind of… different. The pages I was looking at seemed more vibrant in colour. Then it hit me – of course, Macs have a gamma of 1.8 whereas Windows has 2.2. It must be using that preset to render colours within the browser. Neato, I thought, since most sites looked better.

What I was thrown off the chair for was testing a design I threw up with the help of a friend of mine. Nothing special, just a few background images and some JPEGs. Nothing special. Everything looked perfect on Linux and Windows (the two targets I test for primarily), worked on Opera, Firefox, IE6 + 7, Konqueror and a few other minor browser that I just felt like testing in. Finally I thought, “okay, moment of truth!” Fired up Safari on Windows and lo and behold, HTML colour space was different than the image colour space, be it PNG, JPEG or GIF (I even tried removing colour profiles from the images, to no avail). In plain terms, #00aa00 (HTML) != #00aa00 (image). All the backgrounds were now fractured at the seems and the page seemed like it was thrown together at gun point.

Now, I ask, what is the point of having your own colour space calibration if you don’t apply it consistently? While I don’t have a minimal test case for when this happens, I presume I just wasn’t paying attention at the other sites to notice a similar effect. Or I may be missing the point.

But the point is, I wasn’t expecting an image colour space misalignment problem, more of CSS and JS-related problems. I guess until Apple sorts this colour space problem in the Windows version of Safari, it’s widely unusable for anything but functional and layout testing purposes. It seems browsing the web on Windows is best left to non-Apple browsers. That, or depending on your colour blindness to counter the colour problem present.

October 17, 2007

When creating truly internationalized content, you need to think of a few things – first, what country your are in, and secondly, what the locale is in that country. Why should you care? User input.

While Symfony does have handy features via sfI18N, it doesn’t expose some of the methods needed to correctly parse strings. While string parsing isn’t meant to be the scope of this post, I’ll explain how to get your hands on the number formatting information to enable your application to correctly parse input strings and/or display them in templates (although, I might remind you of the Number helper and its application within the view layer, to aviod logic duplication when that’s already been taken care of).

When you want to get number format information, you simply create an instance of sfCultureInfo, like so:

This gives you the chance to write your own number parser according to the expected format and/or use locale-specific settings for different purposes for user-friendly input, not just sfI18N::getTimestampForCulture().

October 3, 2007

I’ve never liked Opera that much – have been trying to use it since version 7, but never got around to actually keep myself using it. I actually prefer IE7 over Opera 9 any given day of the week. Now, it seems, there’s yet another reason why I dislike Opera even more, but will have to keep an eye on it after all, even more so, after I discovered a nasty “feature.”

It all boils down to semantics, really. Opera prides itself on being the fastest browser on the planet. Well, from a user’s standpoint, I’d agree, pages do load smoothly in Opera, rendering is a shitload faster than Firefox (especially when it comes down to sliders, for example) and IE. Yes, I admit, it seems to work faster than other browsers. But there’s a price to pay – it doesn’t block scripts when they try accessing CSS properties when listening for the DOMContentLoaded event.

Why should that matter? Case in point: when you want to enable a user interface which uses unobtrusive scripting, the event fires BEFORE any external stylesheets get loaded. As a consequence, all hell breaks loose when you try styling elements. Say, for example, you want to position some div element to the left of some other, like so:

In this case, IE, Firefox and Konqueror (and, by induction, Safari) will load CSS first, then apply the CSS properties. Opera does not and fires the DOMContentLoaded event on a bare DOM. It helps when you use inline styling (jQuery then gets the correct styles), but what’s the point of using CSS if you declare everything inline anyways?

Opera sucks. From a developer’s point of view. And no, it’s not jQuery’s fault. It’s Opera’s implementation and interpretation of the aforementioned event.

Oh, and if you’re looking for a solution, there’s no way around using the onLoad. I know, you’re thinking “but the content flashes if you use onLoad!” You are correct. But Opera already flashes unstyled content before loading the external CSS (at least in my tests with an empty cache), so this shouldn’t bother you. It will bother the crowd (all 2% of them), but hey, at least the GUI works!

UPDATE: It seems the only consistent implementation of DOMContentLoaded within other browser is waiting for all elements (including scripts and CSS) to load before actually firing the event (up to Gecko 1.9+, Trident-based browsers don’t implement this event and must be simulated). The rationale behind this is that scripts loaded in the head might use styled elements after the CSS is applied, so that, for example, boxes are aligned or moved according to other elements’ positions and/or sizes. Even copying calculated styles from one element to the other.

Opera goes the other way around – it defined the event as the moment is stops parsing the bare HTML, leaving it up to the programmer to figure out cases when any of the files loads in a different order or if at all. It does improve responsiveness, showing the content before the actual styles are applied, but the downside is flashing unstyled content and gripes about checking applied styles first before trying to actually do anything with dynamically modifying interfaces.

September 26, 2007

AJAX can be really useful sometimes. We all agree on that. We’ve pretty much solved the cross-browser divide when it comes to the XHR object by using libraries, but one thing still remains – what about the GUI?

I know this might seem like just another post about using AJAX and fancy GUI updates, but let me point out that it isn’t. It’s about a major error I’ve found in IE7 (and possibly 6) that kinda blows your whole client-side dynamic updates. I’m talking about rendering errors regarding lists in IE. The dynamically rendered ones.

A test case involves an unordered list (possibly ordered, too), which is empty by default (on page load) and gets populated after the AJAX request fires. What my script did was it took a JSON response and appended li elements to the list. You’d think something as simple as this would pose no problem to the new and improved Trident, but it does. The list expands as though the list items are there, but they’re transparent. If you want to see the contents, you have to drag a selection over the text (and even then renders only the letters that were actually selected), but they dissapear upon re-rendering.

The first solution I could come up with is to apply a CSS transformation to the text after adding li elements. Which is a major pain in the ass. I just did a quick .fadeOut(1).fadeIn(1) to force change in opacity:

// lang javascript
jQuery("ul.error").fadeOut(1).fadeIn(1);

That way, no blinking would be noticed by the user since the animation would be faster than a screen redraw, thus eliminating the problem.

Haven’t done a baseline test on this one, but it shows just how grimey stuff gets when you’re not developing straight onto IE7 in the first place, then porting to others.

Long live Trident. You bastard.

UPDATE: I’ve managed to identify the culprit causing this disastrous behaviour – it has to do with floated elements and clearing elements. Also known as the Peekaboo bug. While this solution might not be appropriate for you, it worked for me in the given situation.

Basically, this problem manifests itself when you try to use floats, then a clearing element after them to ensure they are fully contained within a parent container div. The problem is solved by assigning the following style to the clearing element:

// lang html
<div>&nbsp;</div>

The only problem here I can see is that it breaks pixel accuracy – while you can assign padding and margin of 0, you cannot style it with height:0 or font-size:0. And also, adds to the semantics of the page, which I personally dislike. Sure, you can class the style in the above example, but you still need to put a non-breaking space in there.

This was supposed to be fixed in IE7, as the link says. Guess not. (Tested on IE 7.0.5730.11, update version 0, Windows XP SP2 fully patched.)

July 23, 2007

Well, it seems there’s a few other things that aren’t as they seem in Symfony – if they’re expected or not, they are things I’ve noticed and needed a few minutes (or in a another case) or just over two hours to figure out.

All of them have to do with Symfony’s output escaper using PHPView. The first one is concerned with custom ResultSet objects that you pass into the template using a simple $this-&gt;anything assignation within an action or a component. Say you’re got a simple SQL query within a component or action that you want returned as a ResultSet (using Creole):

You’d expect to have $results contain a ResultSet object that you can iterate over using a while($results-&gt;next()) {}, but you’re in for a surprise – it doesn’t work.

If you look closely at the variable within the template printed out using print_r(), you can see that the object is wrapped within an sfOutputEscaper (or variant of) object that intercepts certain functions. This is what seems to happen when using a ResultSet object – the wrapper escaper object overloads the methods and prevents ResultSet’s methods from being invoked.

The solution? Place $results = $results-&gt;getRawValue() somewhere before the while loop and everything works fine.

I’ll probably enter a ticket for this one, after I grab something to eat.