Bonjour à tous,
Après avoir mis en place ma gestion des utilisateurs, je me retrouve confronté à un nouveau problème (une fois n'est pas coutume ^^).

Pour faire simple, mes articles possèdent des tags que je gère grâce au plugin de Grafikart avec une liaison HABTM.
Lorsque j'édite un article, j'ai une erreur lors de la sauvegarde mais uniquement pour le compte "auteur" que le champ "Tags" soit renseigné ou pas... (avec le compte Admin, je n'ai aucun soucis).
Lors de la sauvegarde, je me retrouve avec une erreur de type : Undefined index : unique [CORE/Cake/Model/Model.php, line 1958].
Si le champs "Tags" est renseigné, lors de la sauvegarde de l'article, il me recréé un champ dans la bdd avec les mêmes infos.
Exemple :

  • id : X, ref : Post, ref_id : 22, term_id : 4
  • id : Y, ref : Post, ref_id: 22, term_id : 4

D'après ce que j'ai compris, c'est au niveau de la sauvegarde des Terms que cela pose problème. Par contre, j'ai eu beau chercher sur internet, je n'ai pas trouvé de solution à ce problème.

Pour info, voici ma fonction edit du controller Post si ça peux vous aider :

function edit($id = null){      
    if ($this->isAuthorFromPost($id, $this->Auth->user('id'))) {        
        $this->Post->contain('Category', 'Thumb', 'Media', 'Term'); 
            if ($this->request->is('put')) {    
                if ($this->Post->save($this->request->data)) {                          
                    $this->Session->setFlash("L'article a bien été sauvegardé", 'notif');
                    $this->redirect($this->referer());                  
                }
            } elseif ($id) {
                $this->Post->id = $id;
                $this->request->data = $this->Post->read();
            } else {
                $this->request->data = $this->Post->getDraft('post');
            }       
            $this->loadModel('Category');
            $d['categories'] = $this->Category->find('list');       
            $this->set($d);
        } else {
            $this->Session->setFlash("Vous ne pouvez pas modifier cet article", 'notif', array('type' => 'error'));
            $this->redirect(array('action' => 'index'));
    }
}

Si vous voulez plus d'infos, n'hésitez pas à me demander ;)
Rom

14 réponses


Romano83
Auteur
Réponse acceptée

Je viens de trouver la solution !!!
C'est en fait au niveau de ma fonction isAuthorFromPost que ça pose problème...
Cette fonction revoie l'ensemble des données du post que j'édite donc forcement, quand je sauvegarde les données, elles sont en double... D'où le Undefined index : unique pour les terms !!!
En tout cas, merci à toi Lartak de m'avoir aidé à résoudre ce problème ;)

Tu peux me montrer ce que contient

$this->request->data
Romano83
Auteur

Voici le debug de $this->request->data :

 /app/Controller/PostsController.php (line 220)

array(
    'Post' => array(
        'id' => '29',
        'name' => 'test',
        'slug' => 'test',
        'excerpt' => 'test',
        'content' => '<p>test</p>',
        'meta' => '',
        'online' => '0',
        'created' => '30-11--0001 00:00:00',
        'modified' => '30-11--0001 00:00:00',
        'media_id' => '66',
        'category_id' => '3',
        'user_id' => '23',
        'comment_count' => '0',
        'thumb' => '/img/uploads/2014/12/home_office_336377_1920.jpg',
        'terms' => array(
            'tag' => array(
                (int) 7 => '7'
            )
        ),
        'link' => array(
            'controller' => 'posts',
            'action' => 'view',
            'slug' => 'test'
        )
    ),
    'Category' => array(
        'id' => '3',
        'name' => 'Wordpress',
        'slug' => 'wordpress',
        'post_count' => '1',
        'link' => array(
            'controller' => 'posts',
            'action' => 'category',
            'slug' => 'wordpress'
        )
    ),
    'User' => array(
        'password' => '*****',
        'id' => '23',
        'username' => 'user',
        'mail' => 'guillemin_r@yahoo.fr',
        'created' => '2014-12-25 12:35:10',
        'active' => '1',
        'role' => 'author',
        'post_count' => '1'
    ),
    'Thumb' => array(
        'id' => '66',
        'ref' => 'Post',
        'ref_id' => '29',
        'file' => '/img/uploads/2014/12/home_office_336377_1920.jpg',
        'position' => '0',
        'type' => 'pic',
        'icon' => '/img/uploads/2014/12/home_office_336377_1920.jpg'
    ),
    'Comment' => array(),
    'Media' => array(
        (int) 66 => array(
            'id' => '66',
            'ref' => 'Post',
            'ref_id' => '29',
            'file' => '/img/uploads/2014/12/home_office_336377_1920.jpg',
            'position' => '0',
            'type' => 'pic',
            'icon' => '/img/uploads/2014/12/home_office_336377_1920.jpg'
        )
    ),
    'Term' => array(
        (int) 0 => array(
            'id' => '7',
            'name' => 'test',
            'slug' => 'test',
            'type' => 'tag',
            'TermR' => array(
                'id' => '69',
                'ref' => 'Post',
                'ref_id' => '29',
                'term_id' => '7'
            ),
            'link' => array(
                'controller' => 'posts',
                'action' => 'listTags',
                'slug' => 'test'
            )
        )
    ),
    'Taxonomy' => array(
        'tag' => array(
            (int) 7 => array(
                'id' => '7',
                'name' => 'test',
                'slug' => 'test',
                'type' => 'tag',
                'TermR' => array(
                    'id' => '69',
                    'ref' => 'Post',
                    'ref_id' => '29',
                    'term_id' => '7'
                ),
                'link' => array(
                    'controller' => 'posts',
                    'action' => 'listTags',
                    'slug' => 'test'
                )
            )
        )
    )
)

Bonsoir.
Juste une idée comme ça.
Ce ne serait pas dû à une de tes règles de validation d'un de tes modèles, dans laquelle tu aurais mis unique au lieu de isUnique ?

Romano83
Auteur

@Lartak : je viens de vérifier et non, je n'ai pas mis de unique à la place de isUnique
Si tu veux, je peux afficher les données que me renvoie l'erreur (partie Code et partie Contexte) peut être que ça pourrait aider...

Romano83
Auteur

Je me permets de faire un petit up mais toujours pas d'idées ?

Bonsoir.
Lorsque j'édite un article, j'ai une erreur lors de la sauvegarde mais uniquement pour le compte "auteur" que le champ "Tags" soit renseigné ou pas... (avec le compte Admin, je n'ai aucun soucis).
Le plugin étant prévu pour fonctionner dans une interface d'administration et non publique, il est possible que ça vienne de ça.
Tu ne crois pas ?

Romano83
Auteur

@Lartak : Effectivement, c'est possible. Mais je ne pense pas que se soit ça le problème. Au niveau du TermsController, j'ai rajouté ceci :

public function isAuthorized($user = null){
    return true;
}

car je ne pouvais pas accéder aux actions liées aux terms avec le compte "auteur".
Maintenant, je peux ajouter /supprimer les terms mais c'est vraiment au niveau de la sauvegarde du post que ça pose problème.
Voici le détail de l'erreur que j'obtiens en voulant sauvegarder :

Notice (8): Undefined index: unique [CORE/Cake/Model/Model.php, line 1958]
Code Context

Model::_saveMulti() - CORE/Cake/Model/Model.php, line 1958
Model::save() - CORE/Cake/Model/Model.php, line 1845
PostsController::author_edit() - APP/Controller/PostsController.php, line 258 // Correspond à if ($this->Post->save($this->request->data)) de la fonction edit
ReflectionMethod::invokeArgs() - [internal], line ??
Controller::invokeAction() - CORE/Cake/Controller/Controller.php, line 490
Dispatcher::_invoke() - CORE/Cake/Routing/Dispatcher.php, line 185
Dispatcher::dispatch() - CORE/Cake/Routing/Dispatcher.php, line 160
[main] - APP/webroot/index.php, line 108

Quand je regarde au niveau du lien Code, j'ai ceci :

$keepExisting = $habtm['unique'] === 'keepExisting';
            if ($habtm['unique']) {

D'où le Undefined index : unique je pense...
Je te fais grâce du lien Context car il y a beaucoup trop de lignes ^^

Oui je me doute.
Mais d'après ce que je vois, tu as un préfixe pour les "auteurs", ce qui explique pourquoi tu as des problèmes avec les "auteurs" et non avec l'admin.
Ensuite, ce n'est pas parce que tu modifies ou ajoute la fonction isAuthorized du controller Terms du plugin, que ça corrigera le problème.
Comme je te l'ai dit dans ma réponse précédente, le plugin Taxonomy est prévu pour une utilisation en interface d'administration, il te faut donc modifier le plugin pour l'adapter à ton application.

Romano83
Auteur

En fait, j'ai déjà essayé de modifié le plugin pour l'adapter en fonction des utilisateurs... J'ai enlevé le préfixe admin des fonctions et modifié les liens, dans succès. J'ai copié les fonctions préfixées admin et remplacé le préfixe par "auteur", sans succès...
J'avoue ne plus trop voir où aller ni quoi faire...

Et la gestion des permissions/préfixes/rôles de ton application, elle est comment ?

Romano83
Auteur

Au niveau de mon AppController j'ai :

function beforeFilter(){
        $this->Auth->loginAction = array('controller' => 'users', 'action' => 'login', 'admin' => false, 'author' => false);
        $this->Auth->authorize = array('Controller');

        if(!isset($this->request->params['prefix'])){
            $this->Auth->allow();
        }       
        if(isset($this->request->params['prefix']) && $this->request->params['prefix'] == 'admin'){
            $this->layout = 'admin';
        }
        if(isset($this->request->params['prefix']) && $this->request->params['prefix'] == 'author'){
            $this->layout = 'author';
        }               
        if($this->request->is('ajax')){
            $this->layout = null;
        }
    }
public function isAuthorized($user){
        if(!isset($this->request->params['prefix'])){
            return true;
        }
        $roles = array(
            'admin' => 10,
            'author' => 5
        );
        if(isset($roles[$this->request->params['prefix']])){
            $lvlAction = $roles[$this->request->params['prefix']];
            $lvlUser = $roles[$user['role']];
            if($lvlUser >= $lvlAction){
                return true;
            }else{
                return false;
            }
        }
        return false;       
    }

Au niveau de mon controller Post, j'ai doublé certaines fonctions (dont la fonction edit) avec le préfixe admin ou author car certaines parties des fonctions ne sont pas identiques.
C'est à peu près tout ce que j'ai fait en suivant les tutos de Grafikart et la doc de Cake ;)

Donc tu as bien un système de prefix pour chaque rôle.
Il y a une chose que tu ne dois pas oublier, c'est que quand tu définies à nouveau la fonction beforeFilter et/ou la fonction isAuthorized, sur un controller qui étend de AppConntroller, il te faut ajouter parent::beforeFilter()/parent::isAuthorized($user).
Pour ajouter/modifier/supprimer un comportement de l'AppController sur l'une de ces fonctions.

De rien. :)