Petite astuce que je viens de mettre en place sur un projet sur lequel j'avais une dizaine de Models possédant un slug.

L'idée consiste à utiliser la fonction beforeSave de l'AppModel et de rajouter à la volée le slug en BDD pour tous les Models qui l'utilisent.

public function beforeSave() {
        if(!$this->id && !isset($this->data$this->alias]$this->primaryKey])):
            $Model = $this->alias;
            if($Model::hasField('slug')):
                if(empty($this->data$Model]'slug'])):
                    $slug = Inflector::slug($this->data$Model]'name'], '-');
                    $slug = strtolower($slug);
                    $count = $Model::find('count', array('conditions' => array($Model.'.slug LIKE' => $slug.'%')));
                    echo $count;
                    if($count):
                        $slug = $slug.'-'.($count+1);
                    endif;
                    $this->data$Model]'slug'] = $slug;
                endif;
            endif;
        endif;
        return true;
    }

La fonction récupère le model courant via $this->alias, vérifie si celui-ci possède un champ slug dans la table, et si c'est le cas, on va le remplir en utilisant l'Inflector::slug sur le champ name.

En espérant que ça puisse servir à certains d'entre vous ;)

PS : Petite édition du code pour gérer l'incrémentation du slug dans la mesure où on l'a défini comme clé unique. Dans ce cas là, si le slug existe déjà, on le suffixe avec "-1" la première fois, puis on incrémente ce chiffre autant que nécessaire par la suite.

PS 2 : Deuxième édition pour ajouter le traitement à la création uniquement, et pas à la mise à jour.

2 réponses


maxfr
Réponse acceptée

Pas mal, mais cela implique que tu as également un champ name pour ton model, ce qui peut parfois ne pas être le cas.
Un plugin permettrai plus de souplesse (https://github.com/Grafikart/CakePHP-Sluggable). Mais ton astuce est pas mal :)

Pakito
Auteur
Réponse acceptée

Dans l'absolu, j'y ai pensé, on peut vérifier la présence d'un champ name ou d'un champ title et s'en servir pour créer le slug (en sachant que ce sont les deux champs par défaut supportés pour les list dans les conventions cake).

J'avoue que pour le coup, j'ai même pas pensé à vérifier s'il existait un plugin.

Cela dit, si on a un nombre élevé de Models à slug, cela devient vite long à implémenter et à maintenir pour attacher le comportement Sluggable à chacun d'entre eux, alors qu'avec le beforeSave() et en respectant les conventions Cake, tout ça roule tout seul.