Salut à toutes et à tous!

J'ai un petit problème avec mon controller Posts. Je voudrais qu'il puisse soit créer un nouvel article et le sauvegarder, soit s'il détecte un id, l'éditer. C'est la technique qu'utilise Jonathan dans son tuto créer un site avec cakephp.
La création d'un nouvel article se passe très bien : les données sont enregistrées et la photo est uploadée dans un dossier créé si il n'existe pas. Par contre quand j'édite ce même article, les données s'affichent dans les inputs (sauf celui de l'image qui est le bouton enctype_data) et quand je valide il me créé un nouvel article au lieu de modifier l'existant.

Voici mon action edit de mon PostsController :

<?php
function admin_edit($id=null){
        if ($this->request->is('put') || $this->request->is('post')) {
            $data = $this->request->data'Post'];
            $dir = IMAGES.'news';
            if (!file_exists($dir)) {
                mkdir($dir,0777);
            }
            $f = explode('.',$data'file']'name']);
            $ext = '.'.end($f);
            $filename = Inflector::slug(implode('.', array_slice($f, 0, -1)),'-');
            // Sauvegarde en BDD
            $success = $this->Post->save(array(
                'name' => $data'name'],
                'slug' => $data'slug'],
                'photo' => $filename.$ext,
                'content' => $data'content'],
                'online' => $data'online']
                ));         
            if ($success) {
                move_uploaded_file($data'file']'tmp_name'], $dir.DS.$filename.$ext);
                $this->Session->setFlash("Le contenu a bien été édité","notif");
                $this->redirect(array('action' => 'index'));
                debug($this->request->data);
                echo $dir.DS.$filename.$ext;
            }else{
                $this->Session->setFlash("L'image n'est pas au bon format",'notif', array('type' => 'error'));
            }
        }
        elseif($id){
            $this->Post->id = $id;
            $this->request->data = $this->Post->read();
        }
    }
?>

2 questions, pourquoi quand j'édite je créé un nouvel article? Et comment fait on pour afficher le nom de l'image avec un input enctype quand on édite pour éviter de télécharger à nouveau l'image?

Merci d'avance pour votre préieuse aide! :)

9 réponses


Nightbringer
Réponse acceptée

Nickel !! C'est correct tu pourrais juste enregistrer la variable qui contient les requêtes dans une seule genre :

$ma_requete = array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    );

si ya pas d'image et

$ma_requete = array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => $filename.$ext,
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    );

si il y a une image

et ensuite la la place de ton if($success) tu peux mettre :

if($this->Post->save($ma_requete))

Mais ça c'est juste des notations, ça évite d'avoir 2 save(); mais ça revient exactement au même.

Good job !
RESOLU

J'ai trouvé le problème lié à l'édition d'un article qui au lieu d'éditer, créait un nouvel article.
Il suffisait de rajouter la variable id dans la tableau $success : 'id' => $id.

Par contre si vous savez comment je peux faire pour récupérer le nom de mon image quand j'édite pour éviter d'avoir à la ré-uploader, je vous en serez reconnaissant.

Merci d'avance!

Bonjour,
tu tests si avant de save, le champs upload est rempli

if (!empty($data'file']'name']))

en gros si tu renvois pas de nouveau fichier, il upload rien et tu saves seulement le reste de l'article sans l'image et si le champs est rempli

else

, tu uploads le fichier.
Si tu peux passer ta vue ça pourrai aider.

Merci pour ton intérêt Nightbringer.

Suivant tes conseils j'ai modifié l'action admin_edit de mon PostsController de la façon suivante :

<?php
    function admin_edit($id=null){
        if ($this->request->is('put') || $this->request->is('post')) {
            $data = $this->request->data'Post'];
            if (!empty($data'file']'name']) && !empty($data'photo'])) {
                echo 'if';
                $dir = IMAGES.'news';
                if (!file_exists($dir)) {
                    mkdir($dir,0777);
                }
                $photo = preg_replace('~^\w-\.]~', '-', strtolower($data'photo']));
                $f = explode('.',$data'file']'name']);
                $ext = '.'.end($f);
                $filename = $photo.date('-YmdHis');
                // Sauvegarde en BDD
                $success = $this->Post->save(array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => $filename.$ext,
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    )); 
                move_uploaded_file($data'file']'tmp_name'], $dir.DS.$filename.$ext);    
            }elseif(!empty($data'photo'])){
                echo "elseif";
            // Sauvegarde en BDD
                $success = $this->Post->save(array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    ));     
            }
            if ($success) {
                $this->Session->setFlash("Le contenu a bien été édité","notif");
                $this->redirect(array('action' => 'index'));
            }else{
                $this->Session->setFlash("L'image n'est pas au bon format",'notif', array('type' => 'error'));
            }
        }
        elseif($id){
            $this->Post->id = $id;
            $this->request->data = $this->Post->read();
        }
    }
?>

Ca fonctionne, aucun problème, par contre je ne suis pas sûr que ce soit la bonne manière de faire. Qu'en penses tu?
Merci d'avance! :)

Merci Nightbringer!
C'est pas tout à fait terminé vu que je veux gérer plusieurs choses :

  • Le formulaire est entièrement rempli, j'enregistre toutes les données
  • La photo n'est pas uploadée mais il y a un nom dans le champs photo, alors je laisse le nom et ne touche pas à la photo précedemment uploadée.
  • La photo n'est pas uploadée et le champ photo est vide, j'insère une photo par défaut et j'enregistre le reste.

Voilà en gros ce à quoi correspond le code ci-dessous :

<?php
    function admin_edit($id=null){
        if ($this->request->is('put') || $this->request->is('post')) {
            $data = $this->request->data'Post'];
            if (!empty($data'file']'name']) && !empty($data'photo'])) {
                echo 'if';
                $dir = IMAGES.'news';
                if (!file_exists($dir)) {
                    mkdir($dir,0777);
                }
                $photo = preg_replace('~^\w-\.]~', '-', strtolower($data'photo']));
                $f = explode('.',$data'file']'name']);
                $ext = '.'.end($f);
                $filename = $photo.date('-YmdHis');
                // Sauvegarde en BDD
                $success = $this->Post->save(array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => $filename.$ext,
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    )); 
                move_uploaded_file($data'file']'tmp_name'], $dir.DS.$filename.$ext);    
            }elseif(!empty($data'photo'])){
                echo "elseif";
            // Sauvegarde en BDD
                $success = $this->Post->save(array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    ));     
            }elseif(empty($data'photo']) && empty($data'file']'name'])) {
                // Sauvegarde en BDD
                $success = $this->Post->save(array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => 'default.jpg',
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    ));
            }
            if ($success) {
                $this->Session->setFlash("Le contenu a bien été édité","notif");
                $this->redirect(array('action' => 'index'));
            }else{
                $this->Session->setFlash("L'image n'est pas au bon format",'notif', array('type' => 'error'));
            }
        }
        elseif($id){
            $this->Post->id = $id;
            $this->request->data = $this->Post->read();
        }
    }
?>

Y a t-il moyen de simplifier ce code pour l'optimiser et qu'il soit plus propre?
Merci d'avance et ce sera ma dernière requête! :)

Bonjour,
Bah tu fais comme je t'ai dit plus haut, tu prépares tes requêtes dans tes conditions, et tu n'exécutes ta requête qu'une seule fois avec

if($this->Post->save($ma_requete))

.

Cordialement

Désolé pour cette réponse tardive, j'ai été pas mal occupé.
Je viens de modifier selon tes conseils et voilà ce que ça donne :

<?php
    function admin_edit($id=null){
        if ($this->request->is('put') || $this->request->is('post')) {
            $data = $this->request->data'Post'];
            if (!empty($data'file']'name']) && !empty($data'photo'])) {
                echo 'if';
                $dir = IMAGES.'news';
                if (!file_exists($dir)) {
                    mkdir($dir,0777);
                }
                $photo = preg_replace('~^\w-\.]~', '-', strtolower($data'photo']));
                $f = explode('.',$data'file']'name']);
                $ext = '.'.end($f);
                $filename = $photo.date('-YmdHis');
                // Sauvegarde en BDD
                $success = array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => $filename.$ext,
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    );  
                move_uploaded_file($data'file']'tmp_name'], $dir.DS.$filename.$ext);    
            }elseif(!empty($data'photo'])){
                echo "elseif";
            // Sauvegarde en BDD
                $success = array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    );      
            }elseif(empty($data'photo']) && empty($data'file']'name'])) {
                // Sauvegarde en BDD
                $success = array(
                    'name' => $data'name'],
                    'slug' => $data'slug'],
                    'photo' => 'default.jpg',
                    'content' => $data'content'],
                    'online' => $data'online'],
                    'id' => $id
                    );
            }
            if ($this->Post->save($success)) {
                $this->Session->setFlash("Le contenu a bien été édité","notif");
                $this->redirect(array('action' => 'index'));
            }else{
                $this->Session->setFlash("L'image n'est pas au bon format",'notif', array('type' => 'error'));
            }
        }
        elseif($id){
            $this->Post->id = $id;
            $this->request->data = $this->Post->read();
        }
    }
?>

Merci à toi pour ton aide! :)

Parfait, après ce serai du chipotage.
Bref mets le sujet en résolu, ça pourra surement servir pour d'autre ^^
Cdlt

Merci pour ton aide Nightbringer! :)