Après la création du schéma de la base avec DBDesigner, nous allons maintenant utiliser propel, pour générer tous ce qui concerne les accès à la base de données.
Pour que tout fonctionne vérifions la présence de tout ce qui est nécessaire :
Tapez la commande propel-gen dans un shell, vous devez obtenir quelque chose de similaire à ceci :
fabrice@kimsufi:~/dev/ForumPHP$ propel-gen
Buildfile: /usr/share/php/data/propel_generator/pear-build.xml
[resolvepath] Resolved to /home/fabrice/dev/ForumPHP/
propel-project-builder > projdircheckExists:
propel-project-builder > projdircheck:
[echo] =====================================================
[echo] Project directory not specified or invalid. You must
[echo] specify the path to your project directory and your
[echo] project directory must contain your build.properties
[echo] and schema.xml files.
[echo]
[echo] Usage:
[echo]
[echo] $> propel-gen /path/to/projectdir [target]
[echo]
[echo] =====================================================
Execution of target "projdircheck" failed for the following reason: /usr/share/p hp/data/propel_generator/pear-build.xml:47:15: No project directory specified.
BUILD FAILED
/usr/share/php/data/propel_generator/pear-build.xml:47:15: No project directory specified.
Total time: 0.4103 seconds
fabrice@kimsufi:~/dev/ForumPHP$
Si ça n'est pas le cas, votre installation de Propel est défaillante.
Maintenant, nous allons devoir transformer du xml, il nous faut xsltproc, tapez dans un shell la commande xsltproc –version, vous devez obtenir quelque chose ressemblant à ça :
fabrice@kimsufi:~/dev/ForumPHP$ xsltproc --version Using libxml 20630, libxslt 10121 and libexslt 813 xsltproc was compiled against libxml 20629, libxslt 10121 and libexslt 813 libxslt 10121 was compiled against libxml 20629 libexslt 813 was compiled against libxml 20629 fabrice@kimsufi:~/dev/ForumPHP$
Si la version n'est pas exactement la même il est probable que cela fonctionne quand même.
Je suppose que vous avez accès a une base (et que votre compte peut créer des bases) . Le type de la base importe peu car Propel, support les plus courantes. En général, vous avez PostgreSQL ou MySQL. Dans mon cas, je vais faire le reste de ce document sur PostgreSQL, mais je préciserai les lignes à modifier pour appliquer les actions à une base MySQL.
Supposons que mon serveur de base de données soit sur le même serveur que le serveur où s'exécute mon shell, soit localhost, et que mon compte de connexion soit forum avec le mot de passe toto.
Afin d'éviter tout warning lors de la génération, il est préférable d'avoir une base forum existante sur le serveur.
Je doit pouvoir exécuter la commande psql -h localhost -U forum template1
fabrice@kimsufi:~/dev/ForumPHP$ psql -U forum -h localhost template1
Mot de passe pour l'utilisateur forum :
Bienvenue dans psql 8.2.7, l'interface interactive de PostgreSQL.
Tapez: \copyright pour les termes de distribution
\h pour l'aide-mémoire des commandes SQL
\? pour l'aide-mémoire des commandes psql
\g ou point-virgule en fin d'instruction pour exécuter la requête
\q pour quitter
Connexion SSL (chiffrement : DHE-RSA-AES256-SHA, bits : 256)
template1=> \q
fabrice@kimsufi:~/dev/ForumPHP$
Je doit pouvoir exécuter la commande mysql -u forum -p forum
fabrice@kimsufi:~/dev/ForumPHP$ mysql -u forum -p forum Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12299 Server version: 5.0.45-Debian_1ubuntu3.3-log Debian etch distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> Bye fabrice@kimsufi:~/dev/ForumPHP$
Donc, après ces vérifications nous avons un environnement de développement fonctionnel. Il nous reste à configurer propel. Pour fonctionner, celui-ci a besoin de 3 fichiers :
build.propertiesruntime-conf.xmlLe fichier XML de la base sera généré à partir du fichier xml de DBDesigner. Les 2 autres fichiers se ressemblent, on retrouve y souvent des informations similaires.
Ce fichier pilote le générateur de source.
Voici un exemple de fichier :
# The name of the project
propel.project = forum
# The database driver
propel.database = pgsql
# The connection parameters (optional)
propel.database.url=pgsql:host=localhost;dbname=forum
propel.database.user = forum
propel.database.password = toto
# Add for compatibility
propel.disableIdentifierQuoting=true
propel.targetPackage = ${propel.project}
propel.addGenericAccessors = false
propel.addGenericMutators = false
propel.addSaveMethod = true
propel.addTimeStamp = true
propel.basePrefix = Base
propel.complexObjectModel = true
propel.targetPlatform = php5
propel.packageObjectModel = false
propel.useDateTimeClass = true
# For postgresql only
propel.disableIdentifierQuoting = true
Il peut probablement être utilisé tel quel si votre serveur de base est de type PostgreSQL, si non il suffit de mettre le bon database driver à la place de pgsql, ainsi qu'un propel.database.url adapté en conséquence.
Un exemple de fichier :
1: <?xml version="1.0" encoding="ISO-8859-1"?> 2: <config> 3: <log> 4: <ident>propel-forum</ident> 5: <level>7</level> 6: <name>/tmp/forum.log</name> 7: </log> 8: <propel> 9: <datasources default="forum"> 10: <datasource id="forum"> 11: <!-- the Propel adapter (usually same as phptype of connection DSN) --> 12: <adapter>pgsql</adapter> 13: <connection> 14: <dsn>pgsql:host=localhost;dbname=forum</dsn> 15: <user>forum</user> 16: <password>toto</password> 17: </connection> 18: </datasource> 19: </datasources> 20: </propel> 21: </config>
Plus d'explications ici
Seule les ligne 14, 15 et 16 seront peut-être différentes sur votre serveur. Ce sont les ligne qui spécifient la base sur laquelle on se connecte ainsi que l'utilisateur et le mot de passe associés.
Nous allons générer le schéma Propel à partir du schéma DBDesigner en utilisant une feuille de style. Pour cela, il faut se placer dans le répertoire où se trouve le xml DBDesigner et utiliser la commande xsltproc de la manière suivante :
fabrice@kimsufi:~/dev/ForumPHP/propel$ xsltproc /opt/dbd2propel/dbd2propel.xsl forum.xml > schema.xml
Une fois cette opération réalisée, vous devriez avoir un fichier schema.xml dans le même répertoire, celui-ci doit contenir ces informations :
<?xml version="1.0" encoding="UTF-8"?>
<database defaultIdMethod="native" name="forum">
<table name="utilisateurs">
<column name="idutilisateurs" type="INTEGER" primaryKey="true" required="true" autoIncrement="true"/>
<column name="nom" type="VARCHAR"/>
<column name="mp" type="VARCHAR"/>
</table>
<table name="message">
<column name="idmessage" type="INTEGER" primaryKey="true" required="true" autoIncrement="true"/>
<column name="discusion_iddiscusion" type="INTEGER" required="true"/>
<column name="utilisateurs_idutilisateurs" type="INTEGER" required="true"/>
<column name="message" type="VARCHAR"/>
<column name="date" type="TIMESTAMP"/>
<foreign-key foreignTable="utilisateurs" name="Message_Utilisateurs" onDelete="restrict">
<reference local="utilisateurs_idutilisateurs" foreign="idutilisateurs"/>
</foreign-key>
<foreign-key foreignTable="discusion" name="Messages_De_La_Discussion" onDelete="restrict">
<reference local="discusion_iddiscusion" foreign="iddiscusion"/>
</foreign-key>
</table>
<table name="forum">
<column name="idforum" type="INTEGER" primaryKey="true" required="true" autoIncrement="true"/>
<column name="titre" type="VARCHAR"/>
<column name="resume" type="VARCHAR"/>
</table>
<table name="discusion">
<column name="iddiscusion" type="INTEGER" primaryKey="true" required="true" autoIncrement="true"/>
<column name="forum_idforum" type="INTEGER" required="true"/>
<column name="sujet" type="VARCHAR"/>
<column name="date" type="TIMESTAMP"/>
<column name="message" type="VARCHAR"/>
<foreign-key foreignTable="forum" name="Discussions_Du_Forum" onDelete="restrict">
<reference local="forum_idforum" foreign="idforum"/>
</foreign-key>
</table>
</database>
Il doit être possible maintenant de générer le projet avec propel en utilisant la commande propel-gen dans le même répertoire que celui contenant le fichier schema.xml.
fabrice@kimsufi:~/dev/ForumPHP/propel$ propel-gen
Buildfile: /usr/share/php/data/propel_generator/pear-build.xml
[resolvepath] Resolved to /home/fabrice/dev/ForumPHP/propel/
propel-project-builder > projdircheckExists:
propel-project-builder > projdircheck:
propel-project-builder > configure:
[echo] Loading project-specific props from /build.properties
[property] Loading /home/fabrice/dev/ForumPHP/propel/build.properties
propel-project-builder > main:
[phing] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'main'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > mysqli-check:
propel > main:
[phingcall] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'sql'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > check-run-only-on-schema-change:
propel > sql-check:
propel > pgsql-quoting-check:
propel > mysqli-check:
propel > sql:
[echo] +------------------------------------------+
[echo] | |
[echo] | Generating SQL for YOUR Propel project! |
[echo] | |
[echo] +------------------------------------------+
[phingcall] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'sql-template'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > sql-template:
[propel-sql] Processing: schema.xml
[propel-sql] Writing to SQL file: /home/fabrice/dev/ForumPHP/propel/build/sql/schema.sql
[propel-sql] + utilisateurs [builder: PgsqlDDLBuilder]
[propel-sql] + message [builder: PgsqlDDLBuilder]
[propel-sql] + forum [builder: PgsqlDDLBuilder]
[propel-sql] + discusion [builder: PgsqlDDLBuilder]
[phingcall] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'om'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > check-run-only-on-schema-change:
propel > om-check:
propel > mysqli-check:
propel > om:
[echo] +------------------------------------------+
[echo] | |
[echo] | Generating Peer-based Object Model for |
[echo] | YOUR Propel project! |
[echo] | |
[echo] +------------------------------------------+
[phingcall] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'om-template'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > om-template:
[propel-om] Processing: schema.xml
[propel-om] Processing Datamodel : schema.xml
[propel-om] - processing database : forum
[propel-om] + utilisateurs
[propel-om] -> BaseUtilisateursPeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseUtilisateurs [builder: PHP5ObjectBuilder]
[propel-om] -> UtilisateursMapBuilder [builder: PHP5MapBuilderBuilder]
[propel-om] -> (exists) UtilisateursPeer
[propel-om] -> (exists) Utilisateurs
[propel-om] + message
[propel-om] -> BaseMessagePeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseMessage [builder: PHP5ObjectBuilder]
[propel-om] -> MessageMapBuilder [builder: PHP5MapBuilderBuilder]
[propel-om] -> (exists) MessagePeer
[propel-om] -> (exists) Message
[propel-om] + forum
[propel-om] -> BaseForumPeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseForum [builder: PHP5ObjectBuilder]
[propel-om] -> ForumMapBuilder [builder: PHP5MapBuilderBuilder]
[propel-om] -> (exists) ForumPeer
[propel-om] -> (exists) Forum
[propel-om] + discusion
[propel-om] -> BaseDiscusionPeer [builder: PHP5PeerBuilder]
[propel-om] -> BaseDiscusion [builder: PHP5ObjectBuilder]
[propel-om] -> DiscusionMapBuilder [builder: PHP5MapBuilderBuilder]
[propel-om] -> (exists) DiscusionPeer
[propel-om] -> (exists) Discusion
[phingcall] Calling Buildfile '/usr/share/php/data/propel_generator/build-propel.xml' with target 'convert-conf'
[property] Loading /usr/share/php/data/propel_generator/./build.properties
[property] Loading /usr/share/php/data/propel_generator/./default.properties
propel > convert-conf:
[echo] +------------------------------------------+
[echo] | |
[echo] | Converting runtime config file to an |
[echo] | array dump for improved performance. |
[echo] | |
[echo] +------------------------------------------+
[echo] Output file: forum-conf.php
[echo] XMLFile: /home/fabrice/dev/ForumPHP/propel//runtime-conf.xml
[propel-convert-conf] Processing: schema.xml
[propel-convert-conf] Adding class mapping: UtilisateursMapBuilder => forum/map/UtilisateursMapBuilder.php
[propel-convert-conf] Adding class mapping: UtilisateursPeer => forum/UtilisateursPeer.php
[propel-convert-conf] Adding class mapping: Utilisateurs => forum/Utilisateurs.php
[propel-convert-conf] Adding class mapping: MessageMapBuilder => forum/map/MessageMapBuilder.php
[propel-convert-conf] Adding class mapping: MessagePeer => forum/MessagePeer.php
[propel-convert-conf] Adding class mapping: Message => forum/Message.php
[propel-convert-conf] Adding class mapping: ForumMapBuilder => forum/map/ForumMapBuilder.php
[propel-convert-conf] Adding class mapping: ForumPeer => forum/ForumPeer.php
[propel-convert-conf] Adding class mapping: Forum => forum/Forum.php
[propel-convert-conf] Adding class mapping: DiscusionMapBuilder => forum/map/DiscusionMapBuilder.php
[propel-convert-conf] Adding class mapping: DiscusionPeer => forum/DiscusionPeer.php
[propel-convert-conf] Adding class mapping: Discusion => forum/Discusion.php
[propel-convert-conf] Creating PHP runtime conf file: /home/fabrice/dev/ForumPHP/propel/build/conf/forum-conf.php
BUILD FINISHED
Total time: 1.6260 second
fabrice@kimsufi:~/dev/ForumPHP/propel$
Si tout s'est bien déroulé, vous devez avez avoir maintenant un répertoire build avec le résultat de la génération. Dans celui-ci vous trouverez 3 autres répertoires :
On va créer un petit script PHP qui va remplir la base avec des valeurs par defaut :
1: <?php 2: 3: /* 4: * On commence par ajouter le repertoire contenant les classes 5: * générées par propel au chemin de recherche 6: */ 7: set_include_path(get_include_path() . PATH_SEPARATOR . './build/classes/'); 8: 9: /* 10: * On inclue maintenant les classes que nous allons utiliser 11: */ 12: require_once('propel/Propel.php'); 13: require_once('forum/Utilisateur.php'); 14: require_once('forum/Forum.php'); 15: 16: /* 17: * On initialise Propel avec la configuration générée 18: */ 19: Propel::init("./build/conf/forum-conf.php"); 20: 21: /* 22: * Creation de l'utilisateur 23: */ 24: print "Utilisateurs par defaut\n"; 25: $user=new Utilisateur(); 26: $user->setNom("toto"); 27: $user->setMp("titi"); 28: $user->save(); 29: 30: $guest=new Utilisateur(); 31: $guest->setNom("guest"); 32: $guest->setMp("guest"); 33: $guest->save(); 34: 35: /* 36: * Creation des forum 37: */ 38: print "Forums par defaut\n"; 39: $forums=array(array("Acceuil","Ici on acceuille"),array("Auberge","Ici on mange"),array("Amélioration","Ici on améliore")); 40: foreach($forums as $forum) { 41: $for=new Forum(); 42: $for->setTitre($forum[0]); 43: $for->setResume($forum[1]); 44: $for->save(); 45: } 46: 47: /* On va creer un message d'acceuil dans le forum "Acceuil" */ 48: $for=ForumPeer::retrieveByPK(1); 49: 50: 51: /* Création d'une discussion */ 52: print "Creation d'une discussion\n"; 53: $discussion=new Discussion(); 54: $discussion->setUtilisateur($user); 55: $discussion->setForum($for); 56: $discussion->setSujet("Bienvenue sur ForumPHP"); 57: $discussion->setMessage("Ce forum a été realisé grace a Agavi/Propel"); 58: $discussion->save(); 59: 60: 61: 62: /* Creation d'un message */ 63: print "Creation d'un message\n"; 64: $message=new Message(); 65: $message->setUtilisateur($guest); 66: $message->setDiscussion($discussion); 67: $message->setMessage("Ouais c'est tip top !!"); 68: $message->setDate(Date('c')); 69: $message->save(); 70: 71: 72: print "Fin\n"; 73: ?>
Lorsque l'on crée une application, il est courant de faire des modifications du schéma, de vouloir réinitialiser la base, etc. Il peut être donc intéressant d'avoir un script de génération de base, en voici un simplisime :
#!/bin/bash USER="forum" DATABASE="forum" HOST=localhost export PGPASSWORD="toto" echo "Generating schema" xsltproc /opt/dbd2propel/dbd2propel.xsl forum.xml > schema.xml echo "Generating Propel Classes" propel-gen `pwd`/ echo "Recreate database" echo "DROP DATABASE forum; CREATE DATABASE forum;" |psql -U $USER -h $HOST template1 psql -U $USER -h $HOST $DATABASE < build/sql/schema.sql php ./createdefault.php
Il marche avec une base PostgreSQL, pour Mysql, il faudra probablement modifier les parties qui se connectent à la base.
Voilà, nous avons un système propel qui fonctionne, il faut maintenant l'intégrer dans agavi.
~~DISCUSSION~~