[PHP] CodeIgniter - Intégrer Doctrine 2

Par défaut, CodeIgniter n'est fourni avec aucun ORM, uniquement avec Active REcord, qui n'est pas du tout ORM, simplement des classes générant derrière les requêtes SQL.
Aujourd'hui un petit tuto qui va vous permettre d'intégrer assez facilement Doctrine 2 dans votre application favorite !
PRE REQUIS
- CodeIgniter 2.x.x installé et configuré
- Doctrine 2.x téléchargeable ici
Pour ma part j'ai testé sur la 2.0 et 2.1, la 2.2 étant maintenant stable ça devrait fonctionner aussi !
- Etre en PHP > 5.3 (pour l'utilisation des namespaces
- Et ... c'est tout !
INSTALLATION
1/ Extraire l'archive (sauf si vous êtes passé par GitHub ou PEAR, à ce moment là vos focihiers sont déjà extraits.
2/ Copier le dossier Doctrine et son contenu dans application/libraries/ de votre application CI
3/ Créer un fichier Doctrine.php dans application/libraries/ et y créer la classe suivante :
class Doctrine
{
// the Doctrine entity manager
public $em = null;
public function __construct()
{
// include our CodeIgniter application's database configuration
require APPPATH.'config/database.php';
// include Doctrine's fancy ClassLoader class
require_once APPPATH.'libraries/Doctrine/Common/ClassLoader.php';
// load the Doctrine classes
$doctrineClassLoader = new \Doctrine\Common\ClassLoader('Doctrine', APPPATH.'libraries');
$doctrineClassLoader----------->register();
// load Symfony2 helpers
// Don't be alarmed, this is necessary for YAML mapping files
$symfonyClassLoader = new \Doctrine\Common\ClassLoader('Symfony', APPPATH.'libraries/Doctrine');
$symfonyClassLoader->register();
// load the entities
$entityClassLoader = new \Doctrine\Common\ClassLoader('Entities', APPPATH.'models');
$entityClassLoader->register();
// load the proxy entities
$proxyClassLoader = new \Doctrine\Common\ClassLoader('Proxies', APPPATH.'models');
$proxyClassLoader->register();
// set up the configuration
$config = new \Doctrine\ORM\Configuration;
if(ENVIRONMENT == 'development') {
// set up simple array caching for development mode
$cache = new \Doctrine\Common\Cache\ArrayCache;
} else {
// set up caching with APC for production mode
//$cache = new \Doctrine\Common\Cache\ApcCache;
}
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
// set up proxy configuration
$config->setProxyDir(APPPATH.'models/Proxies');
$config->setProxyNamespace('Proxies');
// auto-generate proxy classes if we are in development mode
$config->setAutoGenerateProxyClasses(ENVIRONMENT == 'development');
// set up annotation driver
$yamlDriver = new \Doctrine\ORM\Mapping\Driver\YamlDriver(APPPATH.'models/Mappings');
$config->setMetadataDriverImpl($yamlDriver);
// Database connection information
$connectionOptions = array(
'driver' => 'pdo_mysql',
'user' => $db['default']['username'],
'password' => $db['default']['password'],
'host' => $db['default']['hostname'],
'dbname' => $db['default']['database']
);
// create the EntityManager
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
// store it as a member, for use in our CodeIgniter controllers.
$this->em = $em;
}
}
Cette lib va tout simplement se charger de loader tous les bons modules de Doctrine, en utilisant la configuration de votre DB faite dans le fichier config/database.php
4/ Auto loader la lib précédemment créée, en rajoutant dans config/autoload.php, 'doctrine' à l'array $autoload['libraries']
CREER SES MODELS
Ensuite il va maintenant falloir crééer ses Models correspondant à sa DB.
Si votre DB existe déja, vous pourrez utiliser la fonction convert-mapping de l'outil en ligne de commande pour générer les fichiers correspondants sans tout refaire à la main.
Doctrine fonctionne sur un principe de Models YAML, voici l'exemple de fichier YAML pour une table User que j'utilise :
Entities\User:
type: entity
table: user
fields:
userId:
id: true
type: integer
unsigned: false
nullable: false
column: user_id
generator:
strategy: IDENTITY
userName:
type: string
length: 255
fixed: false
nullable: false
column: user_name
userPassword:
type: string
length: 255
fixed: false
nullable: false
column: user_password
userEmail:
type: string
length: 255
fixed: false
nullable: false
column: user_email
userRights:
type: integer
unsigned: false
nullable: false
column: user_rights
lifecycleCallbacks: { }
Tous vos Models doivent être précédés de Entities\ (ici Entities\User à la 1ère ligne), je vous laisse vous reporter à la documentation Doctrine de votre version choisie pour voir tous les champs possible.
Créez un dossier Mappings dans application/models/ et mettez y vos models en les nommant Entities.XXX.dcm.yml (où XXX est le nom de votre table et/ou model)
Par la même occasion, crééez deux dossier Entities et Proxies toujours dans application/models/
OUTIL DOCTRINE EN LIGNE DE COMMANDE
Il vous faut maintenant mettre en place l'outil en ligne de commande pour la génération des models PHP, de la structure de la db, ...
Créer un fichier doctrine-cli.php dans le dossier application/ et collez y le code suivant :
require APPPATH.'libraries/Doctrine.php';
$doctrine = new Doctrine();
$helperSet = new \Symfony\Component\Console\Helper\HelperSet(array(
'db' => new \Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper($doctrine->em->getConnection()),
'em' => new \Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper($doctrine->em)
));
$cli = new \Symfony\Component\Console\Application('Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen)', Doctrine\ORM\Version::VERSION);
$cli->setCatchExceptions(true);
$cli->setHelperSet($helperSet);
$cli->addCommands(array(
// DBAL Commands
new \Doctrine\DBAL\Tools\Console\Command\RunSqlCommand(),
new \Doctrine\DBAL\Tools\Console\Command\ImportCommand(),
// ORM Commands
new \Doctrine\ORM\Tools\Console\Command\ClearCache\MetadataCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\ResultCommand(),
new \Doctrine\ORM\Tools\Console\Command\ClearCache\QueryCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\CreateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand(),
new \Doctrine\ORM\Tools\Console\Command\SchemaTool\DropCommand(),
new \Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand(),
new \Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand(),
new \Doctrine\ORM\Tools\Console\Command\RunDqlCommand(),
new \Doctrine\ORM\Tools\Console\Command\ValidateSchemaCommand(),
));
$cli->run();
En ligne de commande exécutez : php doctrine-cli.php, vous verrez alors toutes les commandes possible pour Doctrine :
Doctrine Command Line Interface (CodeIgniter integration by Joel Verhagen) version 2.0.5 Usage: [options] command [arguments] Options: --help -h Display this help message. --quiet -q Do not output any message. --verbose -v Increase verbosity of messages. --version -V Display this program version. --ansi -a Force ANSI output. --no-interaction -n Do not ask any interactive question. Available commands: help Displays help for a command (?) list Lists commands dbal :import Import SQL file(s) directly to Database. :run-sql Executes arbitrary SQL directly from the command line. orm :convert-d1-schema Converts Doctrine 1.X schema into a Doctrine 2.X schema. :convert-mapping Convert mapping information between supported formats. :ensure-production-settings Verify that Doctrine is properly configured for a production environment. :generate-entities Generate entity classes and method stubs from your mapping information. :generate-proxies Generates proxy classes for entity classes. :generate-repositories Generate repository classes from your mapping information. :run-dql Executes arbitrary DQL directly from the command line. :validate-schema Validate that the mapping files. orm:clear-cache :metadata Clear all metadata cache of the various cache drivers. :query Clear all query cache of the various cache drivers. :result Clear result cache of the various cache drivers. orm:schema-tool :create Processes the schema and either create it directly on EntityManager Storage Connection or generate the SQL output. :drop Drop the complete database schema of EntityManager Storage Connection or generate the corresponding SQL output. :update Processes the schema and either update the database schema of EntityManager Storage Connection or generate the SQL output.
Il ne vous reste plus qu'à générer tous les models grâce à cet outil :
php doctrine-cli.php orm:generate-entities models
Ainsi que les proxies :
php doctrine-cli.php orm:generate-proxies
Enfin, on vide la DB (si elle n'est pas déja vide) et la recréé à partir des fichiers yml créés précédemment :
php doctrine-cli.php orm:schema-tool:drop --force php doctrine-cli.php orm:schema-tool:create
UTILISATION
Prenons l'exemple d'une table nommée User, avec des champs de base (id, email, nickname), voici comment créer un User :
$user = new Entities\User;
$user->setNickname('Mon pseudo');
$user->setEmail('pseudo@monmail.fr);
$this->doctrine->em->persist($user);
$this->doctrine->em->save();
Sur cet même exemple, on peut récupérer un User par son id (ici id = 15) et afficher son pseudo :
$user = $this->doctrine->em->find('Entities\User', 15);
echo $user->getNickname();
Si vous voulez crééer vos propres méthodes pour une table, il vous suffit de modifier le models présent dans application/modles/Entities
Pour le reste, je vous laisse consulter la documentation Doctrine très complète
J'espère que ce tuto vous sera utile, n'hésitez pas si vous n'arrivez pas à installer / configurer ou si vous avez des questions !



