header image with round borders
 

Workaround for Zend_Dojo_Form when you render elements individually and dijit.byId() returns ‘undefined’

June 11th, 2010 @biophonc

Problem: When you render the form as a whole (i.e: <?php echo $this->form ?>), everything works fine, but when you render each element separate, the zendDijit {"id":"yourFormId","params":{"dojoType":"dijit.form.Form"}} is missing. This causes to break the validation/xhr process, because dijit.byId() returns only an ‘undefined’ value.

Solution: Go to your View, where you render your form and add the following:

$form = $this->form;
$this->dojo()->setDijit($form->getId(), array('dojoType' => 'dijit.form.Form')); 

// add form tag ...
// add elements ...

It took me nearly 3 hours to figure this out ;)
Hope this helps someone.


The one and only correct way to use sprites.

August 11th, 2009 @biophonc

In this post I’ll show you the one and only correct way to use sprites and the very little benefit if you use sprites the wrong way.

It’s in everyones mouth but a lot of people do not understand fully what sprites are supposed to optimize. Well we want so badly to reduce the HTTP requests but as I’ll show you, a lot of people do not understand how to write efficient selectors for sprites.

Here’s a meaningfull chart I’m going to explain a few pixel down.
css sprites the wrong and correct way

The first “wrong way” uses multiple images and no sprites and show you what you might except. For each image a request gets done. 22ms were used.

The second wrong way shows you something, a lot of people wouldn’t have guessed. For each CSS selector a request is made! The reason is, that the Browser does not know that the image has been already requested and requests it again. The browser then, when it does it’s pre-processing understands, that tghe ressource has been already requested and grabs it ideally from the browser-cache. However that’s just 4ms faster than without sprites.

.icon-mail 			{ background: transparent url(images/sprite.png) 0 0 no-repeat }
.icon-mail-add 		{ background: transparent url(images/sprite.png) 0 -40px no-repeat }
.icon-mail-attach 		{ background: transparent url(images/sprite.png) 0 -80px no-repeat }
.icon-mail-delete 		{ background: transparent url(images/sprite.png) 0 -120px no-repeat }
.icon-mail-edit 		{ background: transparent url(images/sprite.png) 0 -160px no-repeat }
.icon-mail-error 		{ background: transparent url(images/sprite.png) 0 -200px no-repeat }
.icon-mail-go 			{ background: transparent url(images/sprite.png) 0 -240px no-repeat }
.icon-mail-link 		{ background: transparent url(images/sprite.png) 0 -280px no-repeat }
.icon-nail-open 		{ background: transparent url(images/sprite.png) 0 -320px no-repeat }
.icon-mail-open-image 	{ background: transparent url(images/sprite.png) 0 -360px no-repeat }

The third and correct way uses one selector containing the sprite and a few others to change only the position of the sprite. As you can see in my fancy chart, the benefit is: 4ms for the whole test document. Thats 5.5 times faster than the first example and unbelievable 4 times faster than the second example, which uses the very same sprite!

.icons { background-image: url(images/sprite.png); background-repeat: none }
.icon-mail 			{ background-position: 0 0 }
.icon-mail-add 		{ background-position: 0 -40px }
.icon-mail-attach 		{ background-position: 0 -80px }
.icon-mail-delete 		{ background-position: 0 -120px }
.icon-mail-edit 		{ background-position: 0 -160px }
.icon-mail-error 		{ background-position: 0 -200px }
.icon-mail-go 			{ background-position: 0 -240px }
.icon-mail-link 		{ background-position: 0 -280px }
.icon-nail-open 		{ background-position: 0 -320px }
.icon-mail-open-image 	{ background-position: 0 -360px }

ps: You need something like firebug or httpwatch to check it for yourself.


Permission denied in Unknown on line 0

May 13th, 2009 @biophonc

if you install apache/php and get the following error:
Warning: Unknown: failed to open stream: Permission denied in Unknown on line 0
Then consider to check the permissions.

What user/group has the apache?
ps -ef | grep apache

Who owns the files in your htdocs?

Because it is most likely that you need to chown your htdocs, and or add a user to the correct group.


work around for zend validate’s markAsError respectively addError

February 5th, 2009 @biophonc

Yesterday I ran into a problem with zend form and zend validate which was quite confusing. I wanted to check if a multiCheckbox has less or equal 2 selections. I really thought there would be some “shipped” validator but there isn’t. Then I’ve tried to write my own validator for that purpose, but Zend Validate didn’t pass the MultiCheckbox values as an array but as strings and I wasnt in the mood to hack the Zend “core” itself. Then I tried to use addError(), markAsError() or set _errorsExists explicit but that didn’t work either, as described here. Maybe I am blind and there is an much easier way … but the following works quite fine for me.

  1. Create an Validator which always fails.
  2. Check right after the isPost() condition if “your condition” matches.
  3. Assign the “will-always-fail” validator to your element and you’re done.
// save as 'Zend/Validate/CustomError.php
require_once 'Zend/Validate/Abstract.php';

class Zend_Validate_CustomError extends Zend_Validate_Abstract  {

    const SOME_ERROR = 'someError';

	// configure to whatever you like, or override it with setMessage()
    protected $_messageTemplates = array(
        self::SOME_ERROR => "is not valid"
    );

	// sets the element as invalid
    public function isValid($value)
    {
        $valueString = (string) $value;
        $this->_setValue($valueString);
		$this->_error();
        return false;
    }

}

And in your form controller add right after the isPost() condition:

if(sizeof($_POST['yourelement'])>2) {
	$customError = new Zend_Validate_CustomError();
	$customError->setMessage('You must select less than 2');
	self::getElement('yourelement')->addValidator($customError);
}

flickr.groups.pools.getPhotos and php_serial

December 4th, 2008 @biophonc

If you try to get a serialized array (php_serial) from the flicker api from a group (flickr.groups.pools.getPhotos), you may find your self a little bit lost, because you do not get the photos you want, only the amount of how many. You double check if everything is set to public, your account is ok and even try to upgrade it – but that’s not it. You used the usefull API querybuilder from flicker and then it works in that case and you wonder why it doesn’t in your application. The simple solution is, it doesn’t work with the php_serial format. Skip this parameter and you get your set as XML response. The only thing you need to do is, use the XMLReader and iterate through the result set.

It took me quite a while to figure this out – like 1,5 hours – so eventually this post is usefull for someone ;)


simple method to add a safari css

November 5th, 2008 @biophonc

There are some selector hacks out there, but I don’t like them – ie: (@media screen and (-webkit-min-device-pixel-ratio:0) {}). My personal favourite is done with Prototype because I use it a lot and it is pretty simple:

<link rel="stylesheet" type="text/css" media="none" href="/css/safari.css" id="safari" />
<script type="text/javascript">
	// matches all safari/chrome versions
	if(Prototype.Browser.WebKit) {
		$('safari').media="all";
	}
</script>

If you set the media attribute to none – no media device will display it. By adding the little if statement, you can check if the Browser is WebKit, which is the engine name of safari or chrome and alter the media value to all.

If you do not use prototype, you can do it like this:

<script type="text/javascript">
	// targets safari 3 - not 2!
	if(window.devicePixelRatio) {
		document.getElementById('safari')media="all";
	}

	// targets all safari or better said webKit engines
	if(navigator.userAgent.indexOf('AppleWebKit/') > -1) {
		document.getElementById('safari')media="all";
	}

	// prototype way + targeting old and new webKit with two stylesheets
	if(Prototype.Browser.WebKit) {
		var mySafari = (window.devicePixelRatio) ? 'safari3' : 'safari2';
		document.getElementById(mySafari)media="all";
	}
</script>

Note, this method shouldn’t be used for “accessible” Websites, because it relies on javascript. You can do it then serverside as well by “sniffing” the UserAgent from the HTTP Request and add your little switch there – whereas this isn’t a 100% safe method though, because some people alter their UserAgent strings and there are tons of vendors/versions thus your detection may fail from time to time.

An alternative to this way is to load the needed script on the fly, so you can reduce a HTTP Request, by writing the link tag dynamically to your document. However – the describe method above is shorter ;)


new theme

October 26th, 2008 @biophonc

it was time for a change – so I’ve made a new theme for my blog. Nothing special but it looks quite ok (haven’t tested it in IE, I don’t care bout it – but in safari, firefox, chrome and opera it looks good). At least YSlow say it has Grade B and if only the google syntax highlighter plugin would produce valid xhtml, then it would be valid … ;)


new protosafe released

October 24th, 2008 @biophonc

just in time. One of our clients requested it (minified + packed) last week and today I found an updated version and it seems t work fine: http://code.google.com/p/protosafe/


how to cut a string with regex (the neat way)

October 9th, 2008 @biophonc

It is fairy a common task to cut a string – ie when a teaser text should not be longer than n characters. A lot of people use substring() or substr(), depending on their favourite language. However with regex it is really easy and you do not need to cut a word:

// in php it would be:
preg_match("/(.{1,15}(\s))/", $yourString, $matches);

// or in java something like this - maybe ; )
Pattern myPattern = Pattern.compile((.{1,15}(\\s)));
Matcher myMatch = myPattern.matcher(yourString);

To put it in plain english:
* get the first 15 characters (same as substring)
* BUT – and here goes the magic: match less until you find a whitespace character and cut the rest.

So it could look like this in php:

<?php
// you could check the length of the string but actually you don't need to ...
$myString = "People seem to enjoy things more when they know a lot of other people have been left out of the pleasure.";

preg_match("/(.{1,15}(\s))/", $yourString, $matches);
echo $matches[0]." ...";

// would print:
// People seem to ...
// and with {1,27}
// People seem to enjoy things ...
?>

beer o’clock! cheers :)


MySQL EXPLAIN aka DESCRIBE for UPDATE/DELETE

September 21st, 2008 @biophonc

Ever tryed to “explain” a delete or an update statement? It will fail. It took me nearly an hour to figure this out. Actually I’ve never needed to explain a simple DELETE statement, but in todays case I did and was wondering why my query always failed. It is too bad that there is no such “feature”. With InnoDB you can use of course the ON DELETE/UPDATE stuff but in my case I didn’t want to alter the existing DB.

However, if you need to delete multiple rows over multiple tables, you may do something like this: ;)

DELETE stats, links, logins
FROM promo_stats AS stats
LEFT JOIN promo_links AS links USING(promo_link_id)
LEFT JOIN promo_logins AS logins USING(promo_login_id)
WHERE stats.promo_item_id=6;

 

footer image with round borders