To content | To menu | To search

Monday 13 August 2007

Zend_Db_Table and tables relationships

When developping a database tied application, you eventually come to a point where you get (at least) two tables with a parent/child relationship, such as for example a User table referenced by, say, a Post table (each post belonging to a specific user). That's basically the point where you need Zend_Db_Table relationships mechanism. the drawback of this mechanism is that, as far as I know, it does not produce joined queries to retrieve the parent data, but fires a query for each parent row. Thus instead of just using Zend_Db Relationships, I developped a simple yet effective auto-join mechanism that I called, in great simplicity, parent mapping. It supports multiple joins from multiple tables, remote fields specification and prefixing.

It is included in my db table class and you can see the interesting part of the code below for your convenience (Ignore the 3 first lines of the function as it is used for something else in my version of the framework).

Continue reading...

Saturday 11 August 2007

Stripping the logic: the Transfer Object

Sometimes you have to pass an object data to another object, or to another layer of your application (who said controller/view ?), while ensuring that the receiving entity will not be able to run business code encapsulated in your class. In the Zend Framework, several objects provide a toArray method, but that is not always sufficient as sometimes you'd like to keep with the $object->varname syntax.

That is where the Transfer Object arrives. While the preceding definition is not exact (that's not the real purpose of the Transfert Object in the J2EE spirit), This is the most common use that PHP Developers can make of it nowadays I think. So I came up with a very light implementation of a concept which I hope can prove useful for any folks getting by there.

See also:

Tuesday 31 July 2007

Zend Framework Pagination reloaded

UPDATE

A new version of this component is available.

I have a new version of my pagination component which solve the issue previously pointed out by Guy. This update comes along with a subclassed version of Zend_Db_Table which allows counting and specific columns selection respectively via the fetchCount() and fetchCols() methods. Btw, the fetchCols() method is very hackish at the moment, and I'll certainly end up with rewriting it using a plain Zend_Db_Select statement.

As always, any comment is appreciated. I'm thinking of subclassing the Rowset class to fill it with pagination info getters like getPageCount(), getNextPage(), etc, like in Symfony for those knowing, instead of relying on a getPaginationInfo() method. Future improvements will also include more view helper magic.

Also, I came up with a small new Riskle_Pattern namespace which I use to implement commonly used patterns, such as the Proxy Pattern. I'm not yet sure of the pertinence of this thing, so any comments are yet again very much appreciated on this topic :-)

Thursday 19 July 2007

Searching the Zend Framework's manual: Google Co-op to the rescue

While the Zend Framework's manual is somewhat quite good, it lacks a feature that make it a really good manual: search. I find it very frustrating to not be able to make a simple search and therefor having to browse through the extensive TOC to find what I'm actually looking for. Here enters the very handy Google co-op service which allows creation of custom search engines based on Google's indexes. It do not takes more than five minutes to setup a simple search engine, thus providing search capability to the manual :-)

And as a good news never comes alone, I also made the OpenSearch plugin for it.

UPDATE

I made a simpler url to remind of: http://zend.riskle.com/search/ and updated the opensearch thing to use that url.

Sunday 15 July 2007

Pagination with the Zend Framework

Yesterday I came up with a small pagination component for the Zend Frameworks. It implements the Proxy pattern around a Zend_Db_Table object, and overloads the fetchAll method. The main problem I encountered here was to retrieve the total number of rows for the table. I'm using a Zend_Db_Select query for now, but I'll have to improve that. The component also features a view helper to draw the pagination links.

You'll find the code for the component and the view helper on my SVN.

And here is how it is used in the controller:

    public function indexAction() {
        $urls = new Riskle_Db_Table_Paginate(new Urls, $this->_getParam('page'));
        $this->view->urlsList = $urls->fetchAll(null, 'datetime DESC');
        $this->view->paginationInfos = $urls->getPaginationInfos();
    }

The view helper takes paginationInfos as an argument:

echo $this->paginate($this->paginationInfos);

UPDATE

As pointed out by Guy, the _getPageCount method does not actually takes care of the $where condition, thus rendering the class inefficient as getting the real totel number of items. This issue will be adressed in an upcoming version of the class :-)

UPDATE

There's an updated version of this component available.

Saturday 14 July 2007

A Zend controller plugin to enable RESTful behaviour

This is a simple controller plugin for the Zend Framework which enable RESTful behaviour. It basically adds the HTTP method name to the action name, so that the URL http://example.com/foo/bar will be dispatched to FooController::barGetAction on a GET, FooController::barPostAction on a POST, etc.

Continue reading...

Sunday 1 July 2007

Get the current $view from a view helper

So you're making your own view helper and you need, for a reason, to access the running $view instance. Don't worry, all you have to do is implement a setView() method which will be called on your helper's instantiation, with the $view as argument:

class My_View_Helper_SpecialPurpose {
	
	protected $_view = null;
	
	public function setView($view) {
		$this->_view = $view;
	}

}

And voila !

Monday 25 June 2007

Zend Framework 1.0.0 RC3

Allez hop, la RC3 du Zend Framework est sortie (il y a 2 jours).

J'en profite pour faire un peu de pub pour zftalk, un chan IRC sympa.

Wednesday 13 June 2007

Zend Framework 1.0.0 RC2

Au fait, j'ai mis en ligne le package pear de la 1.0 RC2 du Zend Framework hier, avec un peu de retard donc, puisque j'étais occupé à imiter les oiseaux :)

Tuesday 29 May 2007

Zend Framework 1.0.0 RC1

Disponible sur le channel pear.

Voir aussi: le changelog

N.B.: je n'ai pas pu installer le package sur la machine qui héberge le channel via le channel, mais il semblerait que ce soit un cas isolé. Si vous rencontriez un problème (par exemple l'installeur PEAR qui vous dirait Nothing to upgrade) n'hésitez pas à me le signaler !

Monday 7 May 2007

Zend Framework 0.9.3

Dernière ligne droite avant les premières 1.0 RC, la beta 0.9.3 du Zend Framework est sortie, et son package est disponible sur le channel PEAR PHPMafia.

Thursday 12 April 2007

Éviter les appels de fonction en double en javascript

Dans un accès de désespoir vu l'activité débordante de ce blog en ce moment, je me lance et je vous propose cette petite librairie javascript qui va vous permettre d'éviter les appels de fonction en double:

var Defer = {
	config: {
		defaultTimeout: 1000
	},
	stack: {},
	schedule: function(id, fn, timeout) {
		if (typeof(timeout) == 'undefined') {
			timeout = Defer.config.defaultTimeout;
		}
		if (typeof(Defer.stack[id]) == 'undefined') {
			Defer.stack[id] = {defer: false, fn: fn, timeout: timeout };
			window.setTimeout('Defer.execute(\'' + id + '\')', timeout);
		} else {
			Defer.stack[id].defer = true;
		}
	},
	execute: function(id) {
		if (typeof(Defer.stack[id]) != 'undefined' && !Defer.stack[id].defer) {
			Defer.stack[id].fn();
			Defer.stack[id] = undefined;
		} else {
			Defer.stack[id].defer = false;
			window.setTimeout('Defer.execute(\'' + id + '\')', Defer.stack[id].timeout);
		}
	},
};

On peut l'utiliser ainsi par exemple (jquery requis):

$(document).ready(function() {
	$('#nickname').keyup(function() {
		Defer.schedule('chknickname', function() {
			$.get('/account/check_nickname.php', { nickname: $('#nickname').val() }, function(data) {
				data = eval(data);
				$('#nickname_availability').html(data ? 'Pseudo disponible' : 'Pseudo indisponible');
			});
		}, 2000);
	});
});

Concrétement, ce bout de code attache à un input un événement qui ne sera executé que s'il n'est pas répété avant une certaine période (2 secondes ici). C'est à dire qu'on évite de faire une requête xmlhttp à chaque keyup, on attend plutot que l'utilisateur arrête de taper un moment avant de balancer la sauce. A noter que de par la méthode utiliser, l'espace de nommage d'execution de la fonction change (par exemple ici, on ne peut pas utiliser this pour accéder a l'input).

Voila voila.

Débuter avec le Zend Framework

Pour info.

Je suis un peu triste parce que je voulais m'atteler à cette tâche, mais bon il faut croire que j'ai trop lambiné :)

Saturday 24 March 2007

Zend Framework 0.9.1

Le ZF est sorti en version 0.9.1 et est dispo sur le channel pear.

Voir aussi:

Sunday 18 March 2007

Zend Framework 0.9.0

La version 0.9 du ZF est disponible sur le channel PEAR phpmafia:

pear upgrade phpmafia/Zend-0.9.0

ATTENTION, cette version change pas mal de choses au niveau de la classe Zend: vos applis risquent de ne plus fonctionner suite à la mise à jour.

Voir aussi: L'annonce sur la mailing list Zend Announce

Thursday 22 February 2007

Zend Framework 0.8

Les beaux jours reviennent, le Zend Framework est de sortie, dans sa version 0.8, qui apporte son lot de belles choses, comme par exemple le passage Zend_Auth, Zend_Mail_Read et Zend_Rest_Server dans le core.

Youpi.

Wednesday 31 January 2007

Interfaces et Classes Abstraites

Les concepts de classes abstraites et d'interfaces sont souvents assez flous quand on débute dans la programmation objet, et on se fourvoie assez souvent sur leur utilisation et leur but. Voila une petite explication qui j'espère sera 1) juste et 2) assez claire pour tout le monde. Si vous pensez que je me fourvoie sur ces 2 concepts de base de la POO, n'hésitez pas à me le faire savoir !

Continue reading...

Sunday 17 December 2006

Annuler un changeset SVN

Méthode bourrin, je ne sais pas si il en existe une meilleure. Disons qu'on veut annuler la révision 329 (et que c'est la dernière en date):

$ svn update
$ svn merge -r 329:328 .
$ svn commit -m "cancel 329"

En tout cas chez moi ça a marché.

Tuesday 5 December 2006

Le firebug nouveau est arrivé

Firebug 1.0b1 est sorti. Et il est bien (tm).

Wednesday 29 November 2006

Collections, Object Chaining, et la vérité sur le Père Noël

Aujourd'hui je vais vous parler de deux concepts que j'aime beaucoup et que j'ai (re)découverts en travaillant sur mon projet personnel de conquête de l'univers: les Collections d'objets et l'Object Chaining.

Les collections, qui sont peut-être finalement un design pattern connu sous un autre nom, permettent d'executer aisément des méthodes sur plusieurs objets (une collection d'objets quoi). Concrétement, disons qu'on à une classe My_Collection, qui implémente les interfaces Iterator (et Countable tant qu'a faire) de la SPL, ainsi que la fonction magique __call suivante (je vous fait grace du docblock):

class My_Collection implements Iterator, Countable {
	public function __call($method, $args) {
		$calls = 0;
		foreach($this as $item) {
			if (method_exists($item, $method)) {
				call_user_func_array(array($item, $method), $args);
				$calls++;
			}
		}
		if ($calls > 0) {
			return $this;
		} else {
			throw new My_Collection_Exception('Method catched but could not be called: '.$method);
		}
	}
}

Ce dispositif permet d'utiliser le genre de code suivant (si les objets de la collection le permettent, bien évidemment, et disons qu'ici ce sont des objets représentant des images, supportant les méthodes move et createThumbnail):

# $array contient les objets My_Image
$collection = new My_Collection($array);
$collection->move('/new/path/')->createThumbnail();

Ce qui, comme vous l'aurez deviné, déplacera les fichiers de la collection vers /new/path, puis en créera des miniatures.

Deuxième chose, l'Object Chaining. On vient de le voir en fait, ça consiste à chainer les appels de méthodes grâce à un subtil return $this;, qui retourne donc une référence à l'objet courant. Exemple pratique, dans le Zend Framework, en étendant Zend_View:

class My_View extends Zend_View {
	public function assign($spec) {
		$args = func_get_args();
		call_user_func_array(array('parent', 'assign'), $args);
		return $this;
	}
}

Ce qui autorise le genre de code suivant (en admettant que vous ayiez une instance de My_View dans le registre):

Zend::registry('view')
	->assign('foo', $foo)
	->assign('foo', $bar)
	->render('template.php');

Et là c'est fort, parceque ça rejoint fortement quelque chose dont je parlais en janvier dernier (le truc qui parle de with), et donc j'en déduis une chose formidable: Le père noël existe, et il m'a entendu. Merci Santa Copain.

- page 2 of 8 -