Expand your Windows Taskbar: Dual Monitor Taskbar

If you use multiple monitors with Windows, and ever wanted to have the $%#ยง! taskbar spread across all monitors, here’s your cure:

http://sourceforge.net/projects/dualmonitortb/

It can also be set up to let the Windows only appear on the taskbar of the actual screen. This is very handy.

It’s free, but it hasn’t been updated for a while. Better get your copy now.

Typo3 Extbase: Object not saved

Recently I stumbled upon a nasty problem with Typo3′s Extbase. The instance of an object was not updated, but as usual (for Flow/Extbase, that is) there were no exceptions, no log entries, no hints… Extbase just silently refused to save the object. Great!

After debugging through the code once more (my number 1 source of information regarding Extbase nowadays), I found that 1 of 80 columns of the related table was missing in the TCA array! How dare it! After adding it, everything was working as expected.

The core problem: when fetching the object from the repository, Extbase only populates those class members that are configured in the TCA (which in Extbase will be the DataMap later on). This also means that the class member I forgot in the TCA was missing! Then I used a Setter to set a the mentioned missing value, which added the class member.

Extbase uses spl_object_hash() to keep track of the objects during a request. Of course, due to the missing member, the existing object and the to be updated object had different hashes … got it? Yeah…

I really wished Extbase would communicate more with the developer. Just silently refusing to do stuff is not ok, in my opinion.

How to use the MySQL GUI client HeidiSQL with a remote DB server

Most IDEs nowadays work nicely with remote servers. But how about MySQL? phpMyAdmin is ok when you only have to use it once in a while, but a pain in the a… for everyday work.

So I wondered if my favorite MySQL Client HeidiSQL (which has a slightly stupid name, but this shouldn’t keep you off from trying it!) was able to help…

… and it was! You simply have to use the connection type “MySQL (SSH tunnel)” and set up the two tabs in the Connection Manager correctly:

1. Tab "Settings":
- Hostname: 127.0.0.1
- User: [mysql-user]
- Password: [mysql-pwd]
- Port: 3306 (default)

2. Tab "SSH tunnel"
- SSH Host: [server-name]
- Port: 22 (default)
- Username: [ssh-user]
- Password: [ssh-pwd]
- Local port: 3306

(thanks to Thomas Haller for the nice aggregation!)

It simply works like a charm (given a decent internet connection, of course) and gives you all the comfort a lazy Windows user wants (and needs :-).

Another tip from Thomas blog: if you experience problems with the connection, try to delete the path to the plink.exe. This will show the error messages which otherwise would be suppressed.

cwmobileredirect v1.4.3 released

After more than two years of no active development on my Typo3-Extension cwmobileredirect I decided to release a new version, because it is still in use by quite some people. I’m really glad it was helpful for others so far!

Amongst small bugfixes and changes it is now prepared for Typo3 6.x and comes with a handy update script which will allow easier updates in the future.

For those of you who have not yet heard of this cwmobileredirect (there might be one or two people still out there): this little extension, that was developed in the Pre-Responsive-Web-Era, detects mobile devices and redirects the user appropriately. Actually it does a little more, so if you’re interested you can read more in the official Typo3 Repository (TER): http://typo3.org/extensions/repository/view/cwmobileredirect.

When curl is refusing to work as you expect…

…you probably need to look at the many options curl offers. But let me start from the beginning.

Problem:

    $curl = curl_init();

    $url = 'http://api.somewebsite.com/whatever';
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

was returning an empty string, while

    $result = file_get_contents($url);

worked fine. Now I’m not the biggest fan of opening an URL using file_get_contents(), so I tried some of the many options and finally found the one that solved my problem.

    $curl = curl_init();

    $url = 'http://api.somewebsite.com/whatever';
    curl_setopt($curl, CURLOPT_URL, $url);
    // important option goes here...
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

    $result = curl_exec($curl);

Trap events

If you have cronjobs running to trigger a queue, you probably would like to take care that queue is not triggered multiple times, e.g. when the previous run is not finished yet. This can easily be done using a lock file which is written upon the next queue run and removed when it is done. So far, so good.

But what happens if the server crashed, or some Admins are restarting the VMs once a week to “solve strange problems”? Then you have to take care that the lock file is removed, otherwise your queue might not run again upon restart.

On Linux, this is very easy due to the handy “trap” command:

trap 'rm -f "my_lock_file.lock" >/dev/null 2>&1' EXIT HUP KILL INT QUIT TERM

The rm command that removes the log file is executed when either the EXIT, HUP, KILL, INT, QUIT or TERM signal is send. Now we don’t have to delete the file manually after a shutdown.

Accessing the ServiceManager from the ViewHelperManager in ZF2

Sometimes the new ServiceManager(s) in Zend Framework 2 are a bit confusing. We don’t have one, we have several instances.

So recently I was writing a factory for a ViewHelper and wanted to access the application configuration from there. As usual, I was attempting it like this

    /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return MyConfiguration
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $instance       = new MyConfiguration();
        $configuration  = $serviceLocator->get('configuration');

        // haha - nope!

        if(!empty($configuration['whatever'])) {
            $instance->setConfiguration($configuration['whatever']);
        }

        return $instance;
    }

It ended up throwing an exception, saying the configuration could not be found. To make it short, after some searching I found this one

$serviceManager = $serviceLocator->getServiceLocator();

Intuitive, isn’t it? But it seems to work, so the factory looks like this now:

     /**
     * @param ServiceLocatorInterface $serviceLocator
     * @return MyConfiguration
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        $serviceManager = $serviceLocator->getServiceLocator();
        $instance       = new MyConfiguration();
        $configuration  = $serviceManager->get('configuration');

        if(!empty($configuration['whatever'])) {
            $instance->setConfiguration($configuration['whatever']);
        }

        return $instance;
    }

Pitfall: php_admin_flag vs. php_flag

Today I was almost going crazy about the PHP ini setting “display_errors”, which just couldn’t be convinced to be “On”. After some searching on the Internet without a result (“Must be an undiscovered bug … dammit”) I was about to give up. Hey, what do we have an error log for? But then good-old intuition stroke again – how about the vhost configuration?

Bingo:

php_admin_flag display_errors off

Who the f…? Well, me of course! I copied a bunch of these statements when taking another vhost configuration file as template, without having a closer look.

“php_admin_flag” is surely nice for hosters etc., because it sets the PHP ini value once and for all. That’s probably tricky, because ini_set() will simply return false, with no more information.

Note to myself: if setting ini values via vhost is really needed, better use “php_flag” instead. This way the value can still be overwritten.