Archive for the 'Development' category

Grouping Zend Framework controllers in subdirectories

published on April 16, 2011.

Thanks to a discussion on the Zend Framework mailing list I learned about a new feature, a feature that allows for grouping action controllers in subdirectories! Well, this is more of an unknown and undocumented feature than new, as it is the part of the framework for at least 3 years.

Subdirectories example

Why am I so hyped about this? Because it allows for better code organisation on larger projects. Heck, it might be useful on smaller ones too. For example, if a module Foo has both a backend and a frontend, what I was doing so far was to have the file and class names prefixed with an Admin prefix for the backend files and no prefix for the frontend files, so I can actually see what file belongs where. This can go out of control quite easily.

On the other hand, with this grouping of controllers I can make an Admin directory and just place all the backend related controllers there. Easy, clean and much more easier to see what’s where. In my opinion at least :)

Example

Best part is that this feature requires no additional configuration. Create a subdirectory under the controllers directory and place the controller file under that subdirectory. In that pretty screenshot image you can see a FooController.php in the directory called Sub; the class name in that example is Sub_FooController and is accessible via the sub_foo/controller URI. The corresponding view files should be placed in views/scripts/sub/foo/ directory.

A few notes on this:

  • the subdirectory separator in the URI is the underscore and not the slash.
  • The subdirectory name is uppercase: Subdirectory, not subdirectory. In the URI it's lowercase.
  • The view directories for these subdirectories are lowercased, and not uppercase.

The uppercase subdirectory sounds weird, but meh. If needed, the underscore can be “changed” to the slash with a route.

I think the level of possible subdirectories is not limited, but I really can’t see an use-case for more than one subdirectory.

Happy hackin’!

A hack for Zend Framework's translated route segments

published on April 14, 2011.

Today I came across on a little “gotcha” when using the translated route segments in a multilanguage web site and thought about sharing the dirty little hack I used to get around it.

Note: I"ve changed the title on this post. The first one sounded a bit like that ZF code itself contains a hack and not that I wrote a hack to solve a particular problem of mine. Sorry about that.

The set up of the router and translator is done “by the book”, err, by the manual.

The problem

The web site’s default locale, language, is English. If the user has no locale in the session/cookie, she, or he, will get the English version of the web site. If, for example, the user’s first visit is on the http://example.com/news URL, there’s no problem, the router will route that URI to the news module, index controller, index action and the user will get the news, in English, because the default locale is English.

But! If the user’s first visit is on the http://example.com/vesti URL (“vesti” is “news” in Serbian), the router can’t route that because it depends on the locale and the default locale is English and not Serbian, thus directing the user to the 404 page. Of course, that is not good, because the requested URL is perfectly valid, just in a different language and the user should get the news in Serbian and not an error page.

The solution dirty hack

I hacked up a front controller plugin which in the postDispatch hook, if needed, changes the web sites locale to Serbian and dispatches the request all over again. If all goes well, the router will now route correctly the URL and the user will get the content.

<?php

class App_Plugin_TranslatedRoute extends Zend_Controller_Plugin_Abstract
{

    public function postDispatch(Zend_Controller_Request_Abstract $request)
    {
        $request = $this->getRequest();
        $action = $request->getActionName();

        if($action != 'error') {
            return false;
        }

        $translator = Zend_Registry::get('Zend_Translate');
        $locale = $translator->getLocale();

        // English is the default
        // if the current locale is not the default, we might have been here earlier...
        if($locale != 'en') {
            return false;
        }

        $translator->setLocale('sr');
        Zend_Registry::set('Zend_Translate', $translator);

        $front = Zend_Controller_Front::getInstance();
        $front->getResponse()->clearBody();
        try {
            $front->dispatch();
        } catch(Exception $e) {
            // Haven't figured out a nicer way to redirect the user to the error controller
            header("Location: " . $request->getRequestUri());
            exit();
        }
    }
}

The hack for the hack

That terrible, ugly, I-should-have-never-written-it piece of code at the end, the one with the header(“Location… code in it is a hack for a hack. If in the second dispatching some error occurs, which at this point is a “valid” error, the user should be directed to the error controller/action. I haven’t figured out a nicer way to do this. I tried several different things like doing the dispatch for the 3rd time, setting the request’s controller/action to the error controller/action and whatnot but to no avail, every time I just end up a with blank page (yes, with error reporting turned on. Y’know, I’m one of those nuts who develops with E_NOTICEs on).

If anyone has some tips on fixing this problem in a more cleaner way, please do share them.

Happy hackin’!

Speaking at DORS/CLUC 2011

published on April 12, 2011.

DORS/CLUC is a conference about GNU/Linux and everything open source which takes place in Zagreb, Croatia, on May 16-18. I sent two talk proposals and both got accepted! Yey! The first talk will about PHPPlaneta.net, the story behind it, the ideas, the plans… The second talk will be an introduction to Zend Framework. I know, zf2 is right behind the corner with all it’s PHP5.3 goodness, but we are still, and unfortunately will be for a while, stuck with hosting providers running php5.2.

Hopefully I’m not going to be the only PHP dev there and someone will find the talk(s) worth their time :D

More than anything I’m looking forward to finally visiting Croatia and meeting fellow hackers :)

Tags: conference, dors/cluc, talk.
Categories: Blablabla, Development.

pecl install apc fails on Ubuntu

published on April 10, 2011.

I was just installing APC on an Ubuntu server (what else to do on a Sunday morning?) with the standard set of commands:

sudo apt-get install php-pear php5-dev
sudo pecl install apc

but the pecl install apc died with a bunch of “/tmp/pear/temp/APC/apc.c:430: error: “apc_regex” has no member named “preg”” and similar messages. Luckily, I can use google which led me to this serverfault answer: I was missing the “libpcre3-dev” package. After doing a quick sudo apt-get install libcpre3-dev APC got installed correctly.

Tags: apc, libpcre3, pecl.
Categories: Development, Software.

Installing FreeBSD 8.2

published on March 27, 2011.

As I’m currently in the progress of installing FreeBSD on my first machine (out of 4), writing the process down for future reference sounds like a pretty good idea :)

I’ve installed it from the CD image. The installation process was straightforward, altho either the boot loader or freebsd was getting confused in the first few attempts because I was installing it on the slave HDD. After installing it on the master, everything went fine.

On this machine I’m using a LevelOne WNC0305 USB wireless card which uses realtek’s dreaded RTL8187 chipset. After a bit of a googling, I ended up on the freebsd 8.2 hardware notes page, which in the wireless section lists all the available wireless drivers. From there I figured I need to use the urtw driver, that is to add:

if_urtw_load="YES"

to the /boot/loader.conf file. After rebooting the machine, it recognised my wireless card as urtw0. Hooray! Now to connect to the wireless router and onto the world.

For that, this message about (not) getting the ifconfig scan results helped me out, this bit to be precise:

# ifconfig wlan0 create wlandev urtw0
# ifconfig wlan0 up list scan

and it listed my router correctly. To make it stay that way after rebooting, I’ve added this to the /etc/rc.conf file (I might note that it was empty before this):

wlans_urtw0="wlan0"

At this time I figured I just could ssh to one of the servers in the office (we run freebsds there) and “steal” rest of the configuration, so I ended up with a /etc/rc.conf file something like this:

hostname="freebsd_box"
wlans_urtw0="wlan0"
ifconfig_wlan0="inet 192.168.0.100 netmask 255.255.255.0"
defaultrouter="192.168.0.1"

Reboot once again and I can ping anything via IP, but not via hostnames. Again, this (ooold) message about DNS settings in freebsd showed me the right direction - /etc/resolv.conf:

nameserver ip.of.name.server1
nameserver ip.of.name.server2

Reboot and everything is working fine! Victory!

Next step was (is) to fetch/update the ports database:

# csup -L 2 -h cvsup.freebsd.org /usr/share/examples/cvsup/ports-supfile

From here I believe it’s all about installing software from the ports which should be all fine.

Happy hackin’!

Robert Basic

Robert Basic

Software developer making web applications better.

Let's work together!

I would like to help you make your web application better.

Robert Basic © 2008 — 2020
Get the feed