[Symfony2][DoctrineExtension] Créer des slugs pour les caractéres non latin (Arabe particulièrement).

Le comportement Sluggable de la bibliothèque Doctrine extensions permet de créer facilement des URLs SEO-Friendly.
La mise en place du bundle est facile et ne nécessite pas beaucoup de configuration.

Dans le cas des url non-latin tel que l’arabe, le chinois, ou le japonais, le behavior Sluggable translittère les mots en latin, par exemple le mot « إقتصاد » sera translittéré en « qtsd » ce qui n’a aucun sens.

Dans cet article, nous allons voir comment installer et configurer le Bundle StofDoctrineExtensions pour bien créer des slugs pour les langues non-latin.

Installation du StofDoctrineExtensionsBundle

Le bundle StofDoctrineExtensionsBundle intègre la bibliothèque DoctrineExtensions .
L’installation se fait à travers le gestionnaire des dépendances composer :

composer require "doctrine/doctrine-fixtures-bundle:dev-master"
composer require "stof/doctrine-extensions-bundle:dev-master"

Par la suite, nous activons le bundle dans le fichier AppKernel.php

// app/AppKernel.php
// ...

public function registerBundles()
{
    $bundles = array(
        // ...
        new Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle(),
    );

    // ...
}

À la fin, nous ajoutons la configuration de bundle à la fin de notre fichier config.yml :

stof_doctrine_extensions:
    default_locale: en_US
    orm:
        default:
            sluggable:   true

Utilisation du comportement Sluggable

Dans notre exemple, nous allons créer un slug pour la propriété « name » de notre entity Post.

// src/Nm/CoreBundle/Entity/Post.php
// ...

use Gedmo\Mapping\Annotation as Gedmo;
// ...

class Post
{
    // ...

    /**
     * @Gedmo\Slug(fields={"name"}, updatable=false)
     * @ORM\Column(length=255, unique=true)
     */
    protected $slug;
}

Ce code permet de créer automatiquement des slugs sur la propriété « name ».
En ajoutant « updatable=false », cela indiquera que le slug ne sera jamais mis à jour une fois créée, même si nous changons la valeur de « name ».
C’est une bonne idée parce que le slug sera utilisé dans l’URL de l’événement, que nous ne voulons pas changer.

Par la suite nous mettons à jour notre base de données :

php app/console  doctrine:schema:update --force

Si vous avez des anciennes données vous allez vous trouver avec une erreur de contrainte d’intégrité, il faut donc vider la table de ces données et relancer la mise à jour, pour cela on peut supprimer toutes les tables et les recréer à nouveau à travers la console de symfony pour contourner ce problème :

php app/console doctrine:schema:drop
php app/console doctrine:schema:create

À ce niveau, l’installation et la configuration du comportement sluggable sont terminées. Vous pouvez faire les tests et voir que tout est fonctionnel.

Adaptation du comportement Sluggable pour les url non-latin

Comme je vous ai dit au début, le but de cet article est d’adapter ce behavior pour créer des slugs pour les langues non-latin.

Beaucoup de CMS, tel-que Drupal et WordPress possède un système de slugify puissant.
Pour notre cas, nous allons utiliser les fonctions utf8_uri_encode et slugify de wordpress.

Nous commencons par créer un service personnalisé et par la suite nous l’activons pour surcharger celui par défaut de DoctrineExtensions.

Maintenant vous pouvez slugify votre url facilement en gardant votre langue par défaut. Dans le cas de l’Arabe le mot « مال و أعمال » sera « مال-و-أعمال ».

Publicités

Premiers pas avec Doctrine 2 : Database Abstraction Layer (DBAL) -Partie 1-

Depuis quelques semaines, je me préparais à me lancer dans symfony2. J’avais une mauvaise expérience avec l’intégration de doctrine2 dans codeIgniter.
Donc j’ai décidé de s’attaquer à doctrine2 avant de commencer sf2.
J’espère que cette série d’articles, sera un petit guide pour débuter avec Doctrine2.

Le début sera avec dbal (Doctrine database abstraction & access layer) car pour comprendre bien doctrine, il faut commencer du plus bas niveau.

Dbal est une couche au dessus de PDO.

Installation :

Il y a quatre méthodes d’installation : avec svn, git, pear ou télécharger le Tarball. J’ai téléchargé la version 2.0.6 dans un dossier nommé dbal, en utilisant git :

git clone git://github.com/doctrine/dbal.git d2-dbal
cd d2-dbal
git checkout 2.0.6
git submodule update --init

la commande git submodule est pour télécharger les sous modules qui sont en réalité des projets externes, par exemple doctrine-common qui fournit un ensemble d’extensions pour PHP.

Ensuite, J’ai créer le fichier loader.php qui va contenir le chargeur automatique des classes, ce fichier sera appelé ensuite dans chaque fichier qu’on va créer pour les tests.

Configuration

loader.php

Comme on a dit, le chargeur permet de faire appel automatiquement aux classes qui seront utilisées. Le class loader proposé dans la documentation officielle ne permet pas de faire fonctionner DBAL, on obtient cette erreur :

PHP Warning: require(d2-dbal/lib/Doctrine/Common/EventManager.php): failed to open stream: No such file or directory in /var/www/dbal/d2-dbal/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php on line 148

Il indique seulement comment on charge doctrine/DBAL mais pas doctrine-common qui sera nécessaire pour faire fonctionner le premier. Voici le fichier loader.php que j’ai créé :

<?php
use Doctrine\Common\ClassLoader;
require 'd2-dbal/lib/vendor/doctrine-common/lib/Doctrine/Common/ClassLoader.php';$classLoader = new ClassLoader('Doctrine\Common', 'd2-dbal/lib/vendor/doctrine-common/lib');
$classLoader->register();
$classLoader = new ClassLoader('Doctrine', 'd2-dbal/lib');
$classLoader->register();

Connexion

La connexion est effectué à travers le class Doctrine\DBAL\DriverManager qui retourne une instance de Doctrine\DBAL\Connection. Doctrine\DBAL\Connection est un wrapper (Adaptateur).

<?php
require './loader.php';

$connParams = array(
'dbname' => 'blog_db',
'user' => 'root',
'password' => '',
'host' => 'localhost',
'driver' => 'pdo_mysql'
);

$conn = \Doctrine\DBAL\DriverManager::getConnection($connParams);
$sm = $conn->getSchemaManager();

On arrive à la fin de ce petit guide. Dans le prochain billet, on va voir comment manipuler les données (CRUD)