Travailler sur les validateurs start_date end_date symfony
Mardi 11 octobre 2011 @ 10:19

Bonjour,

Voilà j’écris cet article pour partager une solution sur un formulaire symfony qui contient un widget start_date et end_date utilisant sfWidgetFormI18nDate.

Le problème était de pouvoir, en fonction de la start_date, définir une end_date minimale dans un validateur.

La solution était pour ce formulaire de surcharger la méthode doBind pour récupérer les valeurs du start_date et définir le minimum pour le end_date.

Voici le code pour la solution :

// on récupère d'abord la valeur de la start date dans une variable $date
$date = strtotime($values['start_date']['day']."/".$values['start_date']['month']."/".$values['start_date']['year']);
// Ensuite on ajoute la valeur minimale que l'on veut pour le end date
$date = strtotime("+ 5 month", $date);

// Enfin on met en place le validateur pour cette end date
$this->validatorSchema['end_date'] = new sfValidatorDate(array("min" => $date), array("min" => "La date doit être supérieure à %min%"));

Voilà j’espère que cette solution pourra aider du monde :)

Merci à Lermit et Yochima pour leur aide.

Comments (5) - Posted in Développement by  



[symfony] Intégration LDAP dans sfDoctrineGuard
Mardi 14 décembre 2010 @ 3:07

Vous l’aurez compris ces temps ci je fait du symfony ! Et aujourd’hui je vais tenter de présenter comment intégrer un annuaire LDAP au plugin sfDoctrineGuard.

Je passe sous silence l’installation qui est bien documenté dans la doc pour en venir directement au point manquant.

Vous trouverez la doc ici : http://www.symfony-project.org/plugins/sfDoctrineGuardPlugin

La documentation propose d’utiliser une option dans notre fichier app.yml  : check_password_callable. Ceci est exacte (bien heureusement) mais incomplet.

En effet la validation d’un utilisateur par sfGuard se fait en plusieurs étapes et ce paramètre ne permet que de valider l’exactitude du mot de passe. Il faut donc que les utilisateurs soit présent dans la base de données de sfGuard. Ceci ne nous convenant pas nous allons contourner le problème.

Les options dans app.yml

En plus de l’option check_password_callable nous allons devoir utiliser l’option retrieve_by_username_callable. Cette dernière option va nous permettre de spécifier quelle fonction statique nous utiliserons pour récupérer l’objet représentant notre utilisateur. Ce  qui nous donne donc pour notre fichier app.yml :

app:
sf_guard_plugin:
check_password_callable: [UserMap, checkPassword]
retrieve_by_username_callable: [UserMap, getByUsername]

Ici nous spécifions donc que pour contrôler la validité du mot de passe nous utilisons UserMap::checkPassword($username,$password) et pour récupérer l’objet utilisateur UserMap::getByUsername($username).

Voyons comment construire ces classes

Notre objet UserMap

Notre objet UserMap doit posséder deux fonctions statiques que nous avons spécifié dans notre configuration :

Ce qui nous donne une classe construite comme ceci (à adapter) :

class UserMap
{

public static function getByUsername($username)
{
$user = Ldap::getByUsername($username);
return $user;
return null;
}
public static function checkPassword($username, $password)
{
return $this->getByUsername($username)->checkPassword($password);
}
}

Ces fonctions agissent sur l’objet LdapUser que nous allons détailler.

Notre objet utilisateur

Pour pouvoir être utilisé par sfGuard notre objet LdapUser doit étendre la classe PluginsfGuardUser et redéfinir quelques fonctions :

Ceci nous donne donc

class PockostUser extends PluginsfGuardUser
{
public function checkPassword($password)
{
if(… verifier le mot de passe …)
return true;
else
return false;
}

public function getIsActive()
{
return … validité de l’utilisateur …;
}
}

Vous pouvez maintenant utiliser votre authentification sans problème !

Conclusion

Même si documentation de sfDoctrineGuard n’est pas des plus importante en cherchant un peu dans le code on trouve beaucoup de fonctionnalités intéressantes comme celle présenté ici pour surcharger la fonction de récupération d’utilisateur.

Comments (0) - Posted in Développement by  



[Symfony] Utilisation du plugin slapOrm.
Samedi 11 décembre 2010 @ 9:12

SlapORM

Depuis quelque temps je recherche une méthode simple d’accéder à mes entrées LDAP via symfony. Il existe bien plusieurs solutions pour authentifier nos utilisateurs depuis l’annuaire mais quand on parle de modification ceci est une toute autre histoire ! Nous allons donc voir ici comment manipuler nos entrées LDAP à l’aide du plugin slapOrm. Il va s’en dire que quelques bases de php/symfony ainsi que de l’architecture LDAP sont nécessaires à la compréhension de cet article.

slapOrm késako ?

Commençons par replacer les choses dans leurs contextes. Un annuaire LDAP est, comme son nom l’indique, un annuaire. Il stocke donc des données sous forme hiérarchique et ceci de manière optimisée pour la lecture. Le meilleur exemple pour vous schématiser ce concept est de vous imaginer l’annuaire téléphonique. Dans celui ci les numéro de téléphone sont stocké sous forme hiérarchique (L’annuaire, contient des noms de villes qui contiennent des personnes qui possèdent un à plusieurs numéros de téléphone.) aussi il est assez simple de retrouver un numéro de téléphone à l’aide de cette hiérarchie. Le revers de la médaille est la difficulté rencontrée pour écrire dans celui ci. Un simple rapport du temps que vous mettez à trouver un numéro de téléphone par rapport au temps que vous mettez pour apparaître dans l’annuaire vous montre clairement la limite ! Nous utiliserons dans cet article OpenLDAP comme serveur LDAP.
Un ORM pour object-relational mapping ou mapping objet-relationnel en français est une technique de programmation permettant d’accéder à des données d’une base de données relationnelle sous forme d’objet. Ici dire que nous utilisons un ORM pour accéder à notre annuaire est un abus de langage.
Ce que nous allons faire réellement est de créer un abstraction de la hiérarchie de l’annuaire pour pouvoir l’utiliser avec des objets simples. En gros nous allons spécifier que nos utilisateurs ce trouve dans tel branche de l’annuaire et nous allons avoir un objet pour pouvoir y accéder simplement.
Vous l’aurez compris c’est le plugin slapOrm qui nous permet de faire ceci. Aux vus du manque flagrant de documentations sur le projet je vais tenter d’exprimer aux mieux les différents points d’utilisation ici.

Installation

slapOrm ne bénéficit pas encore d’une validation dans les dépôts officiels des plugin de symfony aussi nous allons donc opter pour une installation manuel ! Le plus simple est de télécharger et d’extraire les sources du plugin dans le dossier « plugins » de symfony.

$ wget http://download.github.com/chanmix51-slapOrm-472ba3c.tar.gz
$ tar xvf chanmix51-slapOrm-472ba3c.tar.gz -C /path/vers/dossier/plugins/
$ mv /path/vers/dossier/plugins/chanmix51-slapOrm-472ba3c /path/vers/dossier/plugins/slapOrmPlugin

Ceci est bien entendu à adapter à la dernière version du plugin.

Une fois ceci effectué nous allons activer le plugin dans la configuration de symfony. Editer donc le fichier config/ProjectConfiguration.class.php et activer le plugin

$ vi config/ProjectConfiguration.class.php

public function setup()

{

$this->enablePlugins(‘slapOrmPlugin’);

….

}

Vous avez maintenant installé le plugin. Vous remarquerez que deux nouvelles actions sont disponible avec la commande symfony.

slaporm
:build-form                  Generate forms associated to the LDAP model classes
:build-model                 Generate LDAP model classes based on the schema definition

Sans plus attendre continuons la configuration pour nous connecter au serveur LDAP.

Connexion au serveur

La connexion au serveur LDAP se fait avec le fichier de configuration de l’application (les variables de configuration app_ldap_host, app_ldap_port, app_ldap_dn et app_ldap_pass). Nous allons donc éditer notre fichier de configuration app.yml de notre application (ici frontend) et remplir le fichier avec les options correspondantes à nos besoins.

$ vi apps/frontend/config/app.yml

all:
ldap:
host: 127.0.0.1
port: 389
dn: cn=admin,ou=users,dc=exemple,dc=com
pass: password

Création du schéma

Nous allons maintenant configurer le schéma de notre ORM. C’est ici que nous allons spécifier les emplacements de nos entrées dans l’annuaire ainsi que les classes et attributs qui lui sont liés. Ils nous faut donc savoir plusieurs choses :

- Le nom que nous voulons donner à l’objet (le nom de la classe qui sera généré)

- L’emplacement dans la hiérarchie des entités et leur nomination (le dn et rdn, ex : ou=users,dc=exemple,dc=com pour le dn et cn pour le rdn)

- Les « objectClass » utilisé par l’objet (ex: inetOrgPerson, posixAccount)

- les attributs utilisés (ex: sn, cn, mail, …)

Il nous faut ensuite construire un fichier schema.yml dans le dossier config/slaporm construit de la sorte

ObjectName:
dn: « ou=here,dc=exemple,dc=com »
objectClass: [objectClass1, objectClass2]
rdn: myRdn
attributes:
attributes1:         { type: attributeType, param1: value, param2: value }
attributes2:         { type: attributeType, param1: value, param2: value }
attributes3:         { type: attributeType, param1: value, param2: value }

Le paramètre type peut contenir une valeurs parmis les suivantes : dn, integer, mail ou string ceci modifiant le conportemant du plugin en ce qui concerne la génération automatique de formulaire.

Voici un exemple de fichier de configuration schema.yml

User:
dn: « ou=users,dc=exemple,dc=com »
objectClass: [posixAccount, inetOrgPerson]
rdn: cn
attributes:
cn:         { type: string, length: 32768, multiple: false, required: true }
gidNumber:  { type: string, length: 32768,  multiple: false, required: true }
givenName:  { type: string, length: 32768, multiple: false }
homeDirectory: { type: string, length: 32768, multiple: false, required: true }
mail:  { type: mail, multiple: false }
sn:         { type: string, length: 32768, multiple: false }
uid:         { type: string, length: 32768, multiple: true, required: true }
uidNumber:  { type: string, length; 32769, multiple: false, required: true }
userPassword:         { type: string, length: 32768, multiple: false }

Group:
dn: « ou=groups,dc=exemple,dc=com »
objectClass: [posixGroup]
rdn: cn
attributes:
cn:     { type: string, length: 32768, multiple: false, required: true }
gidnumber: { type: string, length: 32768, multiple: false, required: true }
userpassword: { type: string, length: 32768, multiple: false }
memberuid: { type: string, length: 32768, multiple: true }
description: { type: string, length: 32768, multiple: false }

Attention à bien respecter les espaces (toujours par groupe de deux).

Créer une entrée

La création d’une entrée est donc intimement lié à la création d’un objet ! Ici nous allons créer une entrée de type « User » définit plus haut. Pour cela nous instantion la classe User et utilisons les fonctions magique de type set et get pour spécifier les attributs de l’objet. Attention tout de même tout les fonctions set et get pour fonctionner doivent n’avoir qu’une majuscule : La première lettre du nom de l’attribut sa suite étant en minuscule. Si vous spécifier une autre majuscule elle sera automatiquement mis en minuscule et précédé par un « underscore » (_).

La sauvegarde de l’objet dans l’annuaire est quand à elle réalisé par la « classe map » de la classe entité expliqué ci dessus. Ainsi nous pouvons sur n’importe qu’elle classe entité utiliser la fonction getMapInstance().

Puisqu’il n’y a rien de plus compréhensible qu’un peu de code

$user = new User();
$user->setCn(« toto4″);
$user->setGidnumber(« 10001″);
$user->setHomedirectory(« /home/toto4″);
$user->setUid(array(« toto »));
$user->setUidnumber(« 1004″);
$user->setUserpassword(« toto »);
$user->setSn(array(‘toto4′));
$user->setMail(array(‘romain42@gmail.com’));
$user->getMapInstance()->save($user);

Attention tout de même si vous avez des attributs de type boolean (1.3.6.1.4.1.1466.115.121.1.7) vous devez spécifier TRUE ou FALSE (en majuscule).

Récupérer un ou plusieurs objets

Le plus simple pour récupérer des informations est de récupérer toutes les entités pour une classe entité données (Exemple: récupérer tout les utilisateurs). Pour ceci dans la classe Map il suffit d’exécuter la fonction findAll(). Exemple

$users   = SlapOrm::getMapInstanceOf(‘User’)->findAll();
?>
There are <?php echo count($users) ?> users in this result:
<ul>
<?php foreach($users as $user): ?>
<li><?php echo $user->getCn() ?> has mail : <?php echo $user->getMail() ?></li>
<?php endforeach ?>
</ul>

Il existe aussi la fonction getByRdn qui vous permet de rechercher une entités à l’aide de son RDN. Exemple

$user = SlapOrm::getMapInstanceOf(‘User’)->getByRdn(« lermit »);

Enfin pour rechercher au plus fin il existe aussi les fonctions addAndFilter et addOrFilter qui sont détaillées dans la documentation officielle.

Références

* GitHud de slapOrm : https://github.com/chanmix51/slapOrm/wiki
* Site du langage YAML : http://www.yaml.org/




[vim] vim, l’IDE et les plugin pour symfony (2/3)
Lundi 20 septembre 2010 @ 8:00

Les addons de vim

Vim à la possibilité d’étendre ses possibilités au moyen de petit (ou pas) script. Nous allons en voir quelques uns ici qui nous serons utile.

Navigation entre action et template

Nous allons commencer notre balade avec un script qui va nous permettre au moyen de la touche <F8> de passer d’un fichier action à un fichier template et inversement.

Cet addon s’appelle symfony.vim et est disponible ici dans se version 0.7. L’installation de ce script sera assez simple. Nous allons récupérer le script, le placer dans le dossier ~/.vim/plugin/ et l’activer dans notre fichier vimrc. En route !

$ wget http://www.vim.org/scripts/download_script.php?src_id=8739

100%[======================================>] 7 876       –.-K/s   ds 0,1s

2010-09-01 23:37:43 (61,9 KB/s) – «download_script.php?src_id=8739» sauvegardé [7876/7876]

$ mv download_script.php\?src_id\=8739 symfony.vim
$ mv symfony.vim ~/.vim/plugin/

Ajoutons à notre fichier vimrc ces quelques lignes

silent map <F8> :SfSwitchView <CR>

Ceci nous permet de lier la touche [F8] à l’action de changement de fichier entre action et template.

Fermer les balises HTML

Nous allons utiliser un deuxième script qui va nous permettre de fermer les balises HTML avec le raccourcie clavier [CTRL] + [_]. Le plugin se trouve ici dans sa version 0.9.1

L’installation est semblable

$ wget http://www.vim.org/scripts/download_script.php?src_id=4318

2010-09-01 23:46:40 (30,2 KB/s) – «download_script.php?src_id=4318» sauvegardé [12853]

$ mv download_script.php\?src_id\=4318 closetag.vim
$ mv closetag.vim ~/.vim/plugin/

Cette fois nous n’allons plus lier le script à une combinaison de touche mais à un type de fichier. Ici HTML, XML, XSL et PHP

au Filetype html,xml,xsl,php source ~/.vim/plugin/closetag.vim

Naviguer dans notre projet

Un des plugins les plus utiles pour transformer réellement vim en IDE est le plugin « Project » qui va nous permettre de voir l’arborescence de notre projet et de naviguer entre les dossiers de celui ci.

Le fonctionnement de Project est assez simple mais aussi très astucieux. En effet le plugin génère un fichier .vimproject à la racine de votre répertoire personnel qui servira de base à toute la hiérarchie, c’est à dire qu’il contiendra les noms des fichiers, leurs chemins, leurs dossiers parents, etc … Ce fichier n’étant pas super lisible tel quel, Project nous l’affiche de manière plus « userfrendly » à l’aide de la commande :Project. Passons tout de suite à l’installation, nous reviendrons sur l’utilisation plus tard.

Comme pour les autres plugin l’installation est très simple. Nous récupérons la dernière version à cette adresse, décompressons l’archive dans ~/.vim (il y a deux dossiers : plugin – le plugin – et doc – qui est la documentation du plugin et que nous allons laisser dans le dossier ~/.vim/doc/).

$ wget http://www.vim.org/scripts/download_script.php?src_id=6273 -O ~/.vim/project-1.4.1.tar.gz

$ tar xvf ~/.vim/project-1.4.1.tar.gz
plugin/project.vim
doc/project.txt
$ tar xvf project-1.4.1.tar.gz
plugin/project.vim
doc/project.txt

Notre plugin est installé !

Pour l’utiliser vous avez deux méthodes :

Une fois dans vim vous remarquerez une nouvelle « fenêtre » sur la gauche. C’est votre explorateur de projet qui est actuellement vide. Pour le remplir il faut utiliser la commande « \C » qui va nous posez quelques questions :

A ce moment là, vim va un peu mouliner jusqu’à trouver tout les fichiers respectant le filtre et va vous afficher votre arbre remplis sur la gauche. Une des première chose à faire est de refermer tout les « fold » avec la commande zm pour avoir une vue plus présentable. « Project » fonctionnant sur un fichier pour que votre arbre soit de nouveau là quand vous ré-ouvrirez vim faite une petite sauvegarde à l’aide de :w. Voyons maintenant une liste de commande pour se servire correctement de Project.

Le folding PHP

Avec Project nous avons vu que les dossiers pouvais s’ouvrir et se fermer (normal me direz vous !), ceci s’appelle du folding. Cette fonctionnalité bien connu de tout les IDE est aussi disponible sous vim via le plugin phpfolding.vim. Je ne vous refait pas l’installation c’est toujours et encore le même principe.

A partir de maintenant vous aurez dans vos fichiers PHP un folding automatique. Voici comment s’en servir :




[C++] Créer des tests unitaires en cpp avec Boost.Test
Mercredi 28 avril 2010 @ 8:07

Si vous vous demandez encore pourquoi utiliser des tests unitaires ou encore ce que sont les tests unitaires je vous conseil vivement de vous renseigner et de revenir dans quelques minutes sur cette page !! Le web est une mine d’information infinie !!

Nous alons donc voir comment implémenter des tests unitaires en C++ avec la bibliothèque Boost qui contient entre autre la bibliothèque Boost.Test dont nous allons nous servir.

Tout d’abord il faut installer Boost. Si vous êtes sous visual studio il existe un fichier exécutable sur le site de Boost pour les distributions Linux vous devriez trouver les sources dans vos dépots.

Créez un nouveau projet « de test » qui ne sera rien d’autre qu’un projet C++ vide. Nommez le HelloWorldTest (Nom du projet à tester suivit de Test). Ceci n’est pas une obligation mais permet de se retrouver plus facilement quand on a beaucoup de projet dans un même dossier.

Ajoutez maintenant la librairie boost_unit_test_framework au liker (sous eclipse : bouton de droite sur votre projet, property, C/C++ Build, Settings, GCC C++ Linker, Librairies et ajouter boost_unit_test_framework).

Nous allons écrire notre premier fichier de tests. Pour cela créez un fichier Test.cpp (par exemple) et inscrivez dans celui ci ceci :

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_TEST_DYN_LINK : Utiliser la bibliotheque dynamique de test de boost. (Celle que nous avons ajouter juste avant)
BOOST_TEST_MAIN : Genèrer une suite de tests principale (Master Test Suite)

Si vous compilez votre programme maintenant et que vous l’exécuter vous devriez avoir comme résultat

Test setup error: test tree is empty

Maintenant que nous avons un environnement de test fonctionnel nous allons passez à la rédaction de nos premiers tests.
Pour ceci renommer votre fichier Test.cpp en Test.h car à partir de maintenant nous l’inclurons dans tous nos fichiers de tests.
Dans votre programme à tester créez une classe Calculator avec des fonctions simples (add, sub, mul, div). Nous nous servirons de cette classe pour nos tests.

Dans votre programme de test créez un fichier CalculatorTest.cpp et incluez dans celui ci Test.h

#include « Test.h »

Nous avons besoins de faire référence à notre premier projet pour cela vous pouvez soit utiliser les fonctions de votre compilateur soit créer un lien symbolique de vos classes vers votre dossier source de test. Pour ma part, étant bien trop fainéant j’ai opté pour la deuxième solution. Mes classes étant dans le dossier Classes ceci me donne donc

ln -s ../HelloWorld/Classes/ ./

Nous rajoutons dans notre fichier CalculatorTest.cpp l’include de la classe que nous voulons tester.

#include « Classes/Calculator.h »

Et nous allons écrire un premier test !!

Pour cela nous allons utiliser plusieurs macro de Boost :
BOOST_AUTO_TEST_CASE : Qui va nous permettre de créer une « fonction virtuelle » de test
BOOST_REQUIRE_EQUAL : Qui va nous permettre de tester l’égalité d’un résultat et de retourner une valeur.
Ceci va ce présenter comme ça :

BOOST_AUTO_TEST_CASE(CalculatorAddTest1)
{
Calculator *myCalculator = new Calculator();
BOOST_REQUIRE_EQUAL(myCalculator->Add(1,2),3);//myCalculator->Add(1,2), 3);
}

Nous utilisons BOOST_AUTO_TEST_CASE pour créer une fonction de test que nous nommons CalculatorAddTest1. Nous créons un objet de type Calculator et le testons avec BOOST_REQUIRE_EQUAL.
Si vous compilez maintenant votre programme vous devriez obtenir un joli

Running 1 test case…

*** No errors detected

Il n’existe pas que BOOST_REQUIRE_EQUAL vous trouverez aussi BOOST_REQUIRE(expr), BOOST_REQUIRE_GE(left, right), BOOST_REQUIRE_GT(left, right), etc … Vous pouvez trouvez la liste de ces macros dans la documentation de Boost.

Nous avons vu comment mettre en place un projet de tests unitaires avec Boost.Test ce qui est déjà pas mal pour aujourd’hui ! Nous continurons donc plus tard ;) !

Comments (0) - Posted in Développement by  



[Eclipse] Compiler un programme (C ou CPP) utilisant la GLib
Dimanche 25 avril 2010 @ 9:46

Pour pouvoir compiler un programme utilisant la GLib avec eclipse il vous faut configurer des options pour le compilateur et le linker

Dans Eclipse
Bouton de droite sur votre projet, propriété, C/C++ Build, Setting
Dans l’onglet Tool Settings sélectionner GCC C++ Compilateur ou GCC C Compiler suivant si vous utiliser gcc ou g++.

Dans la textbox Command line pattern ajouter

`pkg-config –cflags glib-2.0`

De même dans GCC C/C++ Linker ajouter

`pkg-config –libs glib-2.0`

Et voilà vous pouvez enfin compiler votre application !

Comments (0) - Posted in Développement by  



[Java] The message has expired (WSSecurityEngine: Invalid timestamp The security semantics of message have expired)
Mercredi 12 août 2009 @ 2:01

Aujourd’hui j’ai buté sur une erreur … bête !
Si vous rencontrez ce message d’erreur

The message has expired (WSSecurityEngine: Invalid timestamp The security semantics of message have expired)

Vérifier le réglage de l’heure de vos serveurs ! En effet, c’est certainement dû à un décalage beaucoup trop grand entre l’heure de votre serveur et votre client !

Bonne Prog ;)

PS : Utiliser NTP !

Comments (0) - Posted in Développement by  



[Zend Framework] Validateur Alnum et Alpha : Autoriser les espaces.
Mercredi 8 avril 2009 @ 9:46

Dans la documentation officielle il est dit :

51.2.1. Alnum

Retourne true si et seulement si $value contient seulement des caractères alphabétiques et numériques. Ce validateur inclue une option permettant la validation possible des caractères espace.
51.2.2. Alpha

Retourne true si et seulement si $value contient seulement des caractères alphabétiques. Ce validateur inclue une option permettant la validation possible des caractères espace.

Mais il n’est pas dit comment faire ! Alors voila comment faire :

->addValidator(‘Alnum’, false, array(‘allowWhiteSpace’ => true));

Bonne validation ;)

Comments (1) - Posted in Développement by  



[PHP] Hacher un mot de pass pour stockage LDAP.
Jeudi 18 décembre 2008 @ 2:15

Si vous souhaitez comme moi modifier un mot de passe utilisateur LDAP via un script PHP il vous faudra calculer le hach de son mot de passe. Un simple md5() ne suffisant voici la syntaxe à employer :

$newPassword = ‘{md5}’ . base64_encode(pack(‘H*’, md5($password)));

Comments (0) - Posted in Développement by  



[Zend Framework] Faire un join
Lundi 15 septembre 2008 @ 1:53

Il se peut que vous rencontriez une erreur de type :
Select query cannot join with another table in /var/www/ etc …

Ceci est du à Zend Framework qui n’autorise pas par défaut de faire une simple jointure sur une table sous jacente.

L’objet Zend_Db_Table_Select est destiné à sélectionner des données sur une table précise. Des jointures peuvent être faites, mais il n’est pas possible de sélectionner des colonnes ne faisant pas partie de la table sous jacente. Cependant, ceci aurait pu être utile dans certains cas, et l’objet Zend_Db_Table_Select possède une clause spéciale déverrouillant cette limitation. Passez la valeur false à sa méthode setIntegrityCheck. Il est alors possible de sélectionner des colonnes hors table. Attention toutefois, l’objet row/rowset résultant sera verrouillé. Impossible d’y appeler save(), delete() ou même d’affecter une valeur à certains de ses champs. Une exception sera systématiquement levée.

Pour enlever cette protection vous devez spécifier setIntegrityCheck(false) dans votre requête.

Par exemple pour une classe simple de récupération de news j’ai :

<?php

/**
* News
*
* @author Lermit
* @version 1
*/

require_once ‘Zend/Db/Table/Abstract.php’;

class News extends Zend_Db_Table_Abstract {

protected $_name = ‘news’;
protected $_primary = ‘news_id’;
protected $_dependentTables = array(« Users »);
protected $_referenceMap = array(
    ’Reporter’ => array(
    ’columns’ => ‘user_id’,
    ’refTableClass’ => ‘Users’,
    ’refColumns’ => ‘user_id’
    )
);

/**
* getLast
* retourne les $numberOfNews dernières news à partir de $start
* @author lermit
* @version 1
* @param $numberOfNews nombre de news
* @param $start à partir de la n-ieme news
* @return les news
*/
public function getLast($numberOfNews,$start)
{
    $select = $this->select()
        ->setIntegrityCheck(false)
        ->from( array(‘n’ => $this->_name), array(‘text’,'date’,'user_id’))
        ->join(array(‘u’ =>’users’),’u.user_id=n.user_id’,'login’)
        ->order(‘date DESC’)
        ->limit($numberOfNews,$start);

    return $this->fetchAll($select);
}
}

Tout d’abord je spécifie le nom et la clef primaire de ma table puis les relations de jointure avec les autres tables.
$_dependentTable = tableau de la/les classe(s) de la(des) table(s) dépendante(s).
$_referenceMap = tableau de tableaux de dépendances. Chaque dépendance est listée sous la forme d’un tableau construisant comme suit :
‘columns’ => ‘colonne de la classe courante’,
‘refTableClass’ => ‘classe de la table à joindre’,
‘refColumns’ => ‘colonne de la table à joindre’
Bref ma requête utilise bien ->setIntegrityCheck(false) ce qui m’enlèvera cette fâcheuse erreur !!

Comments (2) - Posted in Développement by  



Older Posts »