Bonjour à tous, Voilà, cela fait 15 jours que je tourne en rond pour résoudre un problème de subquery. J'ai dévoré les tuto MVC de Grafikart sur la partie insertion en base, et j'ai voulu aller plus loin (dans la limite de mes connaissance :)). Dans le tuto, la requete PDO ne concerne que les champs d'une seule table. J'ai modifié cela pour pouvoir faire des jointures multiples. Mais j'ai un problème pour l'insertion. En effet, j'aimerai récupérer le dernier ID inscrit dans une table et l'inscrire dans une autre table. J'ai essayé avec les LAST_INSERT_ID(MAX(id)) de MYSQL, et autres que j'ai pu trouver sur les différents forums, mais là je suis à court d'idées. Ci-dessous, voici la dose de code que j'ai créé avec les explications. Si vous avez une idée, je suis preneur. Tout d'abord, voici mon controller ProductsController.php et la fonction admin_edit() (ne faites pas attention aux commentaires) [code] function admin_edit($id = null) { // on va récupérer le contenu de l'article à éditer // on charge le produit $this->loadModel('Products'); // on va stocker notre tableau de requete dans une variable vide $tab = array( // table prend comme paramètres un tableau ou non // s''il s'agit d'un tableau, en premier on demande le nom de la table et en deuxième son alias 'tables' => array( 'product' => 'p', 'product_seo' => 's', 'product_associated_category' => 'pac', //'category' => 'c', 'product_associated_image' => 'pai', 'image' => 'i' ), // si le champ field est un tableau // le premier paraamètre est l'alias de la table // le deuxième paramètre se sont les champs de la table 'fields' => array( 'p' => 'id,name,sku,shortcontent,content,online', 's' => 'id,title,metadesc,metakey,slug,product_id', 'pac' => 'id,category_id,product_id', //'c' => 'id,name,category_id', 'pai' => 'id,product_id,image_id,online,default_image', 'i' => 'id,file,online,name' ), // jointure est forcément un tableau 'jointure' => array( 's.product_id' => 'p.id', 'pac.product_id' => 'p.id', //'c.category_id' => 'pac.category_id', 'pai.product_id' => 'p.id', 'i.id' => 'pai.image_id' ), 'conditions' => array( 'p.id' => isset($id) ? $id : '1' ) ); // on va vérifier si des données on été envoyé if ($this->nomController->data) { $this->Products->save($this->nomController->data, 'p_id', $tab); // on accède aux methodes de la classe request avec nomController // on va préciser le tableau de données que l'on veut envoyer, ainsi que la clé primaire à utiliser //debug($this->nomController->data); $id = $this->Products->id; //debug($id); } //debug($d); // si on a un id de définit, on va afficher les informations qui doivent être modifiés, sinon, on fait un insert if ($id) { // on stocke le resultat fetch $d['products'] = $this->Products->findFirst($tab); $this->nomController->data = $d['products']; //debug($id); //debug($d); $this->set($d); } //debug($this->nomController->data); } [/code] Voici ensuite la fonction save() mais la partie INSERT qui ne fonctionne pas (pour l'UPDATE, c'est bon) [code] // /!\ à conserver les lignes du dessous $action = 'insert'; //debug($this->id); // on stock tous les tableaux nécessaires $insertTable = array(); $insertChamps = array(); $insertJoins = array(); $insertGlobal = array(); // tableau reprennant tous les insert // 1 on va récupérer tous les champs dont on a besoin // on récupère les tables if (isset($req['tables'])) { if (!is_array($req['tables'])) { $insertTable['table'] = $req['tables']; } else { foreach ($req['tables'] as $k => $v) { $insertTable[$v] = array( 'table' => $k, 'cle' => $v, 'table-alias' => $k . ' ' . $v ); } } } // on récupère les jointures if (isset($req['jointure'])) { if (!is_array($req['jointure'])) { $insertJoins['joins'] = $req['jointure']; } else { foreach ($req['jointure'] as $d => $s) { $insertJoins[$d] = $s; } } } // on récupère les fields if (isset($req['fields'])) { if (!is_array($req['fields'])) { $insertChamps['champs'] = $req['fields']; } else { foreach ($req['fields'] as $h => $n) { $insertChamps[$h]['fields'] = explode(',', $n); $insertChamps[$h]['as'] = $h; foreach ($insertChamps[$h]['fields'] as $g) { $insertChamps[$h]['champs'][':' . $h . '_' . $g] = $g . '=:' . $h . '_' . $g; $insertChamps[$h]['test'][$h . '.' . $g] = $g; $insertChamps[$h]['table'] = $insertTable[$h]['table']; $insertChamps[$h]['keys'] = $insertJoins; // on va faire nos jointures $insertChamps[$h]['joins'] = array_intersect_key($insertChamps[$h]['keys'], $insertChamps[$h]['test']); if (!empty($insertChamps[$h]['joins'])) { foreach ($insertChamps[$h]['joins'] as $q => $d) { $insertChamps[$h]['joins-explode'] = explode('.', $d); } //$insertChamps[$h]['joins-select'] = '( SELECT '.$insertChamps[$h]['joins'][$q].' FROM '. $insertChamps[$insertChamps[$h]['joins-explode'][0]]['table'] .' )'; $insertChamps[$h]['joins-select'] = array( //':' . str_replace('.', '_', $q) => '( SELECT LAST_INSERT_ID(' . $insertChamps[$h]['joins-explode'][1] . ') FROM ' . $insertChamps[$insertChamps[$h]['joins-explode'][0]]['table'] . ' )' ':' . str_replace('.', '_', $q) => '( SELECT MAX(' . $insertChamps[$h]['joins-explode'][1] . ') FROM ' . $insertChamps[$insertChamps[$h]['joins-explode'][0]]['table'] . ' )' //':' . str_replace('.', '_', $q) => $this->db->lastInsertId($insertChamps[$insertChamps[$h]['joins-explode'][0]]['table']) ); } $insertChamps[$h]['sql'] = 'INSERT INTO ' . $insertChamps[$h]['table'] . ' SET ' . implode(',', $insertChamps[$h]['champs']); } } } } // on va construire notre tableau définitif foreach ($insertChamps as $gindex => $gvalue) { $insertGlobal[$gindex]['champs'] = $insertChamps[$gindex]['champs']; // on va récupérer nos valeurs $insertGlobal[$gindex]['valeurs'] = array_intersect_key($result, $insertChamps[$gindex]['champs']); foreach ($insertGlobal[$gindex]['valeurs'] as $o => $y) { if (!empty($y)) { $insertGlobal[$gindex]['quotes'][$o] = $this->db->quote($y); //$insertGlobal[$gindex]['quotes'][$o] = $y; } elseif (is_numeric($y)) { $insertGlobal[$gindex]['quotes'][$o] = $y; } else { $insertGlobal[$gindex]['quotes'][$o] = 'NULL'; } } if (isset($insertChamps[$gindex]['joins-select'])) { $insertGlobal[$gindex]['select'] = $insertChamps[$gindex]['joins-select']; } // on va fusionner nos select avec nos valeurs if (!isset($insertGlobal[$gindex]['select'])) { $insertGlobal[$gindex]['valeur-fusion'] = $insertGlobal[$gindex]['quotes']; } else { $insertGlobal[$gindex]['valeur-fusion'] = array_merge($insertGlobal[$gindex]['quotes'], $insertGlobal[$gindex]['select']); } $insertGlobal[$gindex]['sql'] = $insertChamps[$gindex]['sql']; // on va debuguer notre requete foreach($insertGlobal[$gindex]['valeur-fusion'] as $uind=>$uval) { //$pattern = preg_match("/:[a-zA-Z]*\_/",$uind); $insertGlobal[$gindex]['valeur-fusion-debug'][$uind] = preg_replace("/:[a-zA-Z]*\_/", '', $uind).'='.$uval; } $insertGlobal[$gindex]['sql-debug'] = 'INSERT INTO ' . $insertChamps[$gindex]['table'] . ' SET ' . implode(',', $insertGlobal[$gindex]['valeur-fusion-debug']); //$insertGlobal[$gindex]['sql-debug'] = } // zone de debug //debug(array_keys($insertJoins)); //debug($result); //debug($result); debug($insertGlobal); //debug($insertTable); //debug($insertChamps); //debug($insertJoins); } error_reporting(E_ALL); //ini_set("display_errors", 1); if ($action == "update") { try { // on va executer la requete préparée, en y injectant les paramètres $pre = $this->db->prepare($sql); $pre->execute($resss); } catch (PDOException $e) { // 1.2 on lance un exception en cas d'erreur // il y a une double gestion de l'erreur // le mode debug et le mode enduser if (Config::$debug >= 1) { $error = 'Connexion à la base de donnée impossible.
Le serveur à renvoyé le message suivant :
<u><b>' . $e->getMessage() . '</b></u>
Cette erreur est survenur ligne : ' . $e->getLine() . '
' . $e->getCode(); debug($error); } else { $error = 'La base de données n\'est pas disponibles ! Veuillez réessayer dans quelques instants !'; debug($error); } } } elseif ($action == "insert") { try { $this->db->beginTransaction(); foreach ($insertGlobal as $ind => $val) { $pre = $this->db->prepare($val['sql']); /* foreach ($val['valeur-fusion'] as $kindex => $kval) { //debug($this->db->lastInsertId()); $pre->bindValue($kindex, $kval); debug("$kindex => $kval"); } $pre->execute(); */ $pre->execute($val['valeur-fusion']); //debug($pre->errorInfo()); //debug($pre); if (Config::$debug >= 1) { $test = $pre->errorInfo(); //$test['message'] = $pre->getMessage(); debug($test); } //$pre->debugDumpParams(); } $this->db->commit(); $this->id = $this->db->lastInsertId(); } catch (PDOException $e) { $this->db->rollBack(); // 1.2 on lance un exception en cas d'erreur // il y a une double gestion de l'erreur // le mode debug et le mode enduser if (Config::$debug >= 1) { $error = 'Connexion à la base de donnée impossible.
Le serveur à renvoyé le message suivant :
<u><b>' . $e->getMessage() . '</b></u>
Cette erreur est survenur ligne : ' . $e->getLine() . '
' . $e->getCode(); debug($error); } else { $error = 'La base de données n\'est pas disponibles ! Veuillez réessayer dans quelques instants !'; debug($error); } } } else { debug("Impossible de modifier la base", 1); } [/code] Et voici le array que je construis de tout ça [code] Array ( [p] => Array ( [champs] => Array ( [:p_id] => id=:p_id [:p_name] => name=:p_name [:p_sku] => sku=:p_sku [:p_shortcontent] => shortcontent=:p_shortcontent [:p_content] => content=:p_content [:p_online] => online=:p_online ) [valeurs] => Array ( [:p_id] => [:p_name] => titre test pour voir si ca marche [:p_sku] => test2b [:p_shortcontent] => test courte [:p_content] => test longue [:p_online] => 0 ) [quotes] => Array ( [:p_id] => NULL [:p_name] => 'titre test pour voir si ca marche' [:p_sku] => 'test2b' [:p_shortcontent] => 'test courte' [:p_content] => 'test longue' [:p_online] => 0 ) [valeur-fusion] => Array ( [:p_id] => NULL [:p_name] => 'titre test pour voir si ca marche' [:p_sku] => 'test2b' [:p_shortcontent] => 'test courte' [:p_content] => 'test longue' [:p_online] => 0 ) [sql] => INSERT INTO product SET id=:p_id,name=:p_name,sku=:p_sku,shortcontent=:p_shortcontent,content=:p_content,online=:p_online [valeur-fusion-debug] => Array ( [:p_id] => id=NULL [:p_name] => name='titre test pour voir si ca marche' [:p_sku] => sku='test2b' [:p_shortcontent] => shortcontent='test courte' [:p_content] => content='test longue' [:p_online] => online=0 ) [sql-debug] => INSERT INTO product SET id=NULL,name='titre test pour voir si ca marche',sku='test2b',shortcontent='test courte',content='test longue',online=0 ) [s] => Array ( [champs] => Array ( [:s_id] => id=:s_id [:s_title] => title=:s_title [:s_metadesc] => metadesc=:s_metadesc [:s_metakey] => metakey=:s_metakey [:s_slug] => slug=:s_slug [:s_product_id] => product_id=:s_product_id ) [valeurs] => Array ( [:s_id] => [:s_product_id] => [:s_title] => title test [:s_metakey] => key test [:s_metadesc] => desc test [:s_slug] => url-test ) [quotes] => Array ( [:s_id] => NULL [:s_product_id] => NULL [:s_title] => 'title test' [:s_metakey] => 'key test' [:s_metadesc] => 'desc test' [:s_slug] => 'url-test' ) [select] => Array ( [:s_product_id] => ( SELECT MAX(id) FROM product ) ) [valeur-fusion] => Array ( [:s_id] => NULL [:s_product_id] => ( SELECT MAX(id) FROM product ) [:s_title] => 'title test' [:s_metakey] => 'key test' [:s_metadesc] => 'desc test' [:s_slug] => 'url-test' ) [sql] => INSERT INTO product_seo SET id=:s_id,title=:s_title,metadesc=:s_metadesc,metakey=:s_metakey,slug=:s_slug,product_id=:s_product_id [valeur-fusion-debug] => Array ( [:s_id] => id=NULL [:s_product_id] => product_id=( SELECT MAX(id) FROM product ) [:s_title] => title='title test' [:s_metakey] => metakey='key test' [:s_metadesc] => metadesc='desc test' [:s_slug] => slug='url-test' ) [sql-debug] => INSERT INTO product_seo SET id=NULL,product_id=( SELECT MAX(id) FROM product ),title='title test',metakey='key test',metadesc='desc test',slug='url-test' ) [pac] => Array ( [champs] => Array ( [:pac_id] => id=:pac_id [:pac_category_id] => category_id=:pac_category_id [:pac_product_id] => product_id=:pac_product_id ) [valeurs] => Array ( [:pac_id] => [:pac_product_id] => [:pac_category_id] => 1 ) [quotes] => Array ( [:pac_id] => NULL [:pac_product_id] => NULL [:pac_category_id] => '1' ) [select] => Array ( [:pac_product_id] => ( SELECT MAX(id) FROM product ) ) [valeur-fusion] => Array ( [:pac_id] => NULL [:pac_product_id] => ( SELECT MAX(id) FROM product ) [:pac_category_id] => '1' ) [sql] => INSERT INTO product_associated_category SET id=:pac_id,category_id=:pac_category_id,product_id=:pac_product_id [valeur-fusion-debug] => Array ( [:pac_id] => id=NULL [:pac_product_id] => product_id=( SELECT MAX(id) FROM product ) [:pac_category_id] => category_id='1' ) [sql-debug] => INSERT INTO product_associated_category SET id=NULL,product_id=( SELECT MAX(id) FROM product ),category_id='1' ) [pai] => Array ( [champs] => Array ( [:pai_id] => id=:pai_id [:pai_product_id] => product_id=:pai_product_id [:pai_image_id] => image_id=:pai_image_id [:pai_online] => online=:pai_online [:pai_default_image] => default_image=:pai_default_image ) [valeurs] => Array ( [:pai_id] => [:pai_image_id] => [:pai_product_id] => [:pai_default_image] => 0 [:pai_online] => 0 ) [quotes] => Array ( [:pai_id] => NULL [:pai_image_id] => NULL [:pai_product_id] => NULL [:pai_default_image] => 0 [:pai_online] => 0 ) [select] => Array ( [:pai_product_id] => ( SELECT MAX(id) FROM product ) ) [valeur-fusion] => Array ( [:pai_id] => NULL [:pai_image_id] => NULL [:pai_product_id] => ( SELECT MAX(id) FROM product ) [:pai_default_image] => 0 [:pai_online] => 0 ) [sql] => INSERT INTO product_associated_image SET id=:pai_id,product_id=:pai_product_id,image_id=:pai_image_id,online=:pai_online,default_image=:pai_default_image [valeur-fusion-debug] => Array ( [:pai_id] => id=NULL [:pai_image_id] => image_id=NULL [:pai_product_id] => product_id=( SELECT MAX(id) FROM product ) [:pai_default_image] => default_image=0 [:pai_online] => online=0 ) [sql-debug] => INSERT INTO product_associated_image SET id=NULL,image_id=NULL,product_id=( SELECT MAX(id) FROM product ),default_image=0,online=0 ) * => Array ( [champs] => Array ( [:i_id] => id=:i_id [:i_file] => file=:i_file [:i_online] => online=:i_online [:i_name] => name=:i_name ) [valeurs] => Array ( [:i_id] => [:i_name] => [:i_file] => [:i_online] => 0 ) [quotes] => Array ( [:i_id] => NULL [:i_name] => NULL [:i_file] => NULL [:i_online] => 0 ) [select] => Array ( [:i_id] => ( SELECT MAX(image_id) FROM product_associated_image ) ) [valeur-fusion] => Array ( [:i_id] => ( SELECT MAX(image_id) FROM product_associated_image ) [:i_name] => NULL [:i_file] => NULL [:i_online] => 0 ) [sql] => INSERT INTO image SET id=:i_id,file=:i_file,online=:i_online,name=:i_name [valeur-fusion-debug] => Array ( [:i_id] => id=( SELECT MAX(image_id) FROM product_associated_image ) [:i_name] => name=NULL [:i_file] => file=NULL [:i_online] => online=0 ) [sql-debug] => INSERT INTO image SET id=( SELECT MAX(image_id) FROM product_associated_image ),name=NULL,file=NULL,online=0 ) ) [/code] Je suis désespéré. Si vous avez besoin des sources, je suis à votre dispo . Merci à tous Fabien

13 réponses


fabienc
Auteur
Réponse acceptée

Salut
J'y suis enfin arrivé après deux semaines à chercher comment faire.
Je vais pouvoir continuer les tutos maintenant.
J'ai suivi ton idée qui consistait à couper mes requêtes en 2, et j'ai mixé ça avec le fait de créer une entrée en base par défaut avec online=-1

Du coup, avec un seul formulaire, je peux gérer l'update et l'insert multiples. (le delete suivra)

Pour rappel, une fiche produit fait à appel à plus d'une dizaine de tables différentes dans ma BDD.
Maintenant, quand je mets à jour une fiche produit, cela modifie toutes les entrées qui vont bien, dans les tables qu'il faut.

Voici comment j'ai procédé pour ceux que ça intéresse: (je ne mets que le contenu du contrôler, car le code insert et update sont maxi longs)

// 2. si je n'ai pas d'id je vais créer un contenu à la volée
        if ($id === null) {
            $produit = $this->Products->findFirst(array(
                'conditions' => array('online' => -1)
                    ));
            if (!empty($produit)) {
                $id = $produit->id;
                debug('Nous sommes sur un contenu Ghost avec pour id : ' . $id);
            } else {
                $this->Products->save(array(
                    'conditions' => array('online' => -1)
                ));
                $id = Products::$lastId;

                $this->Products->save(array(
                    'tables' => 'product_seo',
                    'conditions' => array(
                        'product_id' => $id
                    )
                ));
                $this->Products->save(array(
                    'tables' => 'product_associated_category',
                    'conditions' => array(
                        'product_id' => $id
                    )
                ));
                // je mets un ghost dans la table image
                $this->Products->save(array(
                    'tables' => 'image',
                    'conditions' => array('online' => -1)
                ));
                // je n'oublie pas de récupérer le dernier id en base, qui en l'occurence sera celui du champ image
                $idImg = Products::$lastId;

                // je mets un ghost dans la table product_associated_image
                $this->Products->save(array(
                    'tables' => 'product_associated_image',
                    'conditions' => array(
                        'product_id' => $id,
                        'image_id'=>$idImg
                    )
                ));
                debug("La fiche produit existe déjà et a l'id : " . $id . "<br/> et l'id de la dernière image est : " . $idImg);
            }
        }

Juste, mon code n'est pas parfait et je ne maitrise pas toujours tout.
Je ne savais pas comment appeler une variable qui se trouve dans ma class Model, via mon contrôler ProductsController.
Du coup, j'ai faire de $lastId une variable statif.
Ainsi, après chaque insert en base, je récupère le dernier id inséré. Suffit de le stocker, et de le renvoyer à chaque étape de création des entrées dans la base.

Voila (je ne sais pas si c'est clair ce que je raconte, car là j'ai envie de dormir) :)

++

Fabien

Salut, il n'affiche pas le dernier id avec cette debug?

if ($this->nomController->data) {
    $this->Products->save($this->nomController->data, 'p_id', $tab);
    $id = $this->Products->id;
    debug($id);
}
fabienc
Auteur

Bonjour,
Le debug m'affiche '0'.
Par contre, si je mets dans ma boucle foreach $this->db->lastInsertId(); il me récupère bien le dernier id inscrit en base

Voici le code :

foreach ($insertGlobal as $ind => $val) {
                    $pre = $this->db->prepare($val'sql']);
                    /* foreach ($val'valeur-fusion'] as $kindex => $kval) {
                      //debug($this->db->lastInsertId());
                      $pre->bindValue($kindex, $kval);
                      debug("$kindex => $kval");
                      }
                      $pre->execute(); */
                    $pre->execute($val'valeur-fusion']);
                    $ida = $this->db->lastInsertId();
                    debug($ida);
                    //debug($pre->errorInfo());
                    //debug($pre);
                    if (Config::$debug >= 1) {
                        $test = $pre->errorInfo();
                        //$test'message'] = $pre->getMessage();
                        debug($test);
                    }
                    //$pre->debugDumpParams();
                }

et voici la tableau

/Applications/MAMP/htdocs/cms-heatmap/core/Model.php l.636
47 
 /Applications/MAMP/htdocs/cms-heatmap/core/Model.php l.636
99
 /Applications/MAMP/htdocs/cms-heatmap/core/Model.php l.636
88
 /Applications/MAMP/htdocs/cms-heatmap/core/Model.php l.636
112

 /Applications/MAMP/htdocs/cms-heatmap/core/Model.php l.636
101

 /Applications/MAMP/htdocs/cms-heatmap/controller/ProductsController.php l.287
0

Du coup, je n'arrive pas à comprendre pourquoi il ne veut pas me l'inscrire dans ma table à ce moment là !!
Est-ce qu'il faut que je modifie ma requête une fois qu'elle est exécutée, afin de faire un update des champs ????
Ca semble un peu idiot de le faire ainsi non?

Fabien

fabienc
Auteur

Dans ma table, la requete insert à chaque fois 0.
Je viens de tester le type de chaque lasinsertid() et au final, il s'agit d'un string et pas d'un int
Forcément, ça peut pas marcher (enfin je crois)
Mais du coup, je ne sais pas comment faire pour lui dire d'inscrire un int et pas un string !!
J'espère être sur la bonne piste cette fois ci !

Salut, je crois que le problème vient quand tu as désactivé le mode autocommit.
ce que je propose de réactiver l'autocommit et d'enlever les deux fonctions PDO beginTransaction(); et commit();

fabienc
Auteur

J'ai essayé mais cela n'a rien changé.
J'ai essayé de modifier le type de champ product_id pour le passer en varchar et j'ai refait un test !
Là, il m'inscrit la commande SQL au lieu de m'inscrire le résultat.
Du coup, il a inscrit dans le champ "product_id" la valeur :

CONVERT(SELECT id FROM product ORDER BY id DESC LIMIT 1),UNSIGNED INTEGER)

J'ai modifié la requête pour voir :

SELECT id FROM product ORDER BY id DESC LIMIT 1

non il ne l'interprete pas.
Ce que je ne comprends pas, c'est que la requête fonctionne correctement lorsque je suis dans phpmyadmin : exemple ci-dessous

INSERT INTO product_seo SET id=NULL,product_id=SELECT id FROM product ORDER BY id DESC LIMIT 1,title=NULL,metakey=NULL,metadesc=NULL,slug=NULL

Merci pour ton aide.
Je vais essayer de creuser la piste que j'évoquais plus haut, qui est la transformation du champ en entier.

J'ai vu qu'avec bindValue() on pouvait passer un troisième paramètre.
Sans doute vais-je devoir reconstruire mon tableau en entier, en y ajouter le paramètre à passer pour chacune des valeur !

Là encore, je ne suis pas sûr que cela résolve mon problème.

Je continue à chercher.

Fabien

ce que je propose encore, quand tu fusionnes les select avec les valeurs, tu prends la requête SQL et l'exécuter, après tu prend sa valeur et tu fusionnes après les valeurs:

if (!isset($insertGlobal$gindex]'select'])) {
        $insertGlobal$gindex]'valeur-fusion'] = $insertGlobal$gindex]'quotes'];
    } else {
        $r = array();
        foreach ($insertGlobal$gindex]'select'] as $key => $value) {
            $pre = $this->db->prepare($value);
            $pre->execute();
            $s_result = $pre->fetchColumn(); // la première résultat = ID
            if(!is_numeric( $s_result )){
                $s_result = $this->db->quote($s_result);
            }
            $r$key] = $s_result;
        }
        $insertGlobal$gindex]'valeur-fusion'] = array_merge($insertGlobal$gindex]'quotes'], $r);
    }

et n'oublies pas d'enlever les parenthèses de tes requêtes.

fabienc
Auteur

Salut
Enfin un début de quelque chose grâce à toi !
Je suis allé voir en base et maintenant je récupère bien un id.
Le problème, il me récupère l'id de l'enregistrement précédant.
Je n'ai pas encore étudié en profondeur le bout de code que tu m'as fourni, je l'ai testé direct.
Je vais essayer de comprendre ce que tu as proposé, et voir comment modifier cela pour que le dernier id enregistré soit le bon.
Merci pour ton aide

Ah oui, j'ai oublié ça.
je vais essayer de ma part :)

fabienc
Auteur

Du coup, j'essaie de mettre en place qui est dit dans le tuto jour 6 du mvc.
Lorsqu'on créé un nouveau formulaire, si aucun id n'est passé, on crée la fiche par défaut avec online = -1 et tous les champs à null
Ensuite, je suppose qu'il n'y aura plus qu'à exécuter la requête comme d'hab et ca devrait fonctionner.
Je te dis ça si j'ai assez de courage pour tout faire ce soir.
Fabien

je pense que si tu sépares l’exécution des requêtes sql, et de garder le changement que je fait:

function admin_edit($id = null) {
        $this->loadModel('Products');

        $first = array(
            'tables' => array(
              'product' => 'p'
            ),
            'fields' => array(
              'p' => 'id,name,sku,shortcontent,content,online'
            ),
            'conditions' => array(
              'p.id' => isset($id) ? $id : '1'
            )
        );
        $second = array(
            'tables' => array(
              'product' => 'p',
              'product_seo' => 's',
              'product_associated_category' => 'pac',
              'product_associated_image' => 'pai',
              'image' => 'i'
            ),
            'fields' => array(
              's' => 'id,title,metadesc,metakey,slug,product_id',
              'pac' => 'id,category_id,product_id',
              'pai' => 'id,product_id,image_id,online,default_image',
              'i' => 'id,file,online,name'
            ),
            'jointure' => array(
              's.product_id' => 'p.id',
              'pac.product_id' => 'p.id',
              'pai.product_id' => 'p.id',
              'i.id' => 'pai.image_id'
            ),
            'conditions' => array(
              'p.id' => isset($id) ? $id : '1'
            )
        );

        if ($this->nomController->data) {
            $this->Products->save($this->nomController->data, 'p_id', $first);
            $this->Products->save($this->nomController->data, 'p_id', $second);
            $id = $this->Products->id;
        }
        if ($id) {
            $d'products'] = $this->Products->findFirst($tab);
            $this->nomController->data = $d'products'];
            $this->set($d);
        }
    }

Je trouve pas a quoi sert le deuxième argument de la fonction save(); mais bon tu peux te sauver la vie.

et pour la création d'un nouveau formulaire, Grafikart a combiné les deux actions sur un ( la création, et le changement du contenu ).
Tu pourras créer une nouvelle action (admin_create) par exemple.
Bonne chance.

fabienc
Auteur

Salut
Je vais étudier ce que tu proposes.
Tout d'abord, je vais essayer de faire fonctionner correctement ta première proposition.
Concernant le deuxième argument de ma fonction save, oui en effte, je pourrai le ré intégrer dans mon array global.
Pour ce qui est des deux requêtes en une, moi je trouve ça pas mal, mais je garde en tête ta proposition.
Si j'ai le temps dans la journée, je teste ce que tu m'as founi.
Je te tiens au courant.
Merci
Fabien