Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 22-01-2009 15:27:16

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Problème save($data); bloque sur la fonction _refresh

Bonjour,

Je suis actuellement en train de réalisé mon premier projet avec le framework de zend et je suis bloqué sur le problème suivant:

Code:

<?php

require_once ('Zend/Db/Table/Row/Abstract.php');

class Rem_Db_Row extends Zend_Db_Table_Row_Abstract {

    public function toStdClass()
    {
        return (object)$this->toArray();
    }
    
    public function save($srcData = null)
    {
        if ($srcData) {
            $this->_cleanData = $srcData;
        }
        return parent::save();
    }
    
    protected function _refresh(){
        
        
    }
}

?>

Si je ne surcharge pas _refresh, l'erreure suivante m'est renvoyée:

Code:

Cannot refresh row as parent is missing

Je ne sais pas trop d'où cela peut provenir.


Merci

Hors ligne

 

#2 22-01-2009 15:48:46

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1176
Site web

Re: Problème save($data); bloque sur la fonction _refresh

Hello,

Un trigger ou une séquence ou un champs auto-incrémenté ?

A+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#3 22-01-2009 16:03:01

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

Un champs auto-incrémenté,
je joins par la même occasion la méthode _refresh()

Code:

/**
     * Constructs where statement for retrieving row(s).
     *
     * @param bool $useDirty
     * @return array
     */
    protected function _getWhereQuery($useDirty = true)
    {
        $where = array();
        $db = $this->_getTable()->getAdapter();
        $primaryKey = $this->_getPrimaryKey($useDirty);
        $info = $this->_getTable()->info();
        $metadata = $info[Zend_Db_Table_Abstract::METADATA];

        // retrieve recently updated row using primary keys
        $where = array();
        foreach ($primaryKey as $column => $value) {
            $tableName = $db->quoteIdentifier($info[Zend_Db_Table_Abstract::NAME]);
            $type = $metadata[$column]['DATA_TYPE'];
            $columnName = $db->quoteIdentifier($column, true);
            $where[] = $db->quoteInto("{$tableName}.{$columnName} = ?", $value, $type);
        }
        return $where;
    }

/**
     * Refreshes properties from the database.
     *
     * @return void
     */
    protected function _refresh()
    {
        $where = $this->_getWhereQuery();
        $row = $this->_getTable()->fetchRow($where);

        if (null === $row) {
            require_once 'Zend/Db/Table/Row/Exception.php';
            throw new Zend_Db_Table_Row_Exception('Cannot refresh row as parent is missing');
        }

        $this->_data = $row->toArray();
        $this->_cleanData = $this->_data;
        $this->_modifiedFields = array();
    }

Dernière modification par squall6969 (22-01-2009 16:04:35)

Hors ligne

 

#4 22-01-2009 16:42:34

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1176
Site web

Re: Problème save($data); bloque sur la fonction _refresh

Hello,

Je dirais donc que tu n'as pas déclaré :

Code:

protected $_sequence = true;

dans la définition de ta Zend_Db_Table associée.

A+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#5 22-01-2009 17:42:13

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

mikaelkael a écrit:

Hello,

Je dirais donc que tu n'as pas déclaré :

Code:

protected $_sequence = true;

dans la définition de ta Zend_Db_Table associée.

A+

J'ai essayé de rajouter ce que tu m'as dis mais le problème persiste, d'autant plus que $_sequence = true par défault.

En fait j'ai l'impression qu'il n'arrive pas à retrouver la clé primaire de la table... et que du coups il ne retrouve pas le row inséré.

Ma clé primaire est pourtant bien déclarée et est un première position de colonne, donc $_identity n'a pas besoin d'être touché.

Voici mon modèle

Code:

<?php

class Model_Client {
    
    private $_db;

    public function __construct()
    {
        $this->_db = Zend_Registry::get('dbAdapter');
    }
    
    public function getClientList(){
        $client = new Model_Client_Table;
        return $client->getList();
    }
    
    public function getClientById($id){
        $client = new Model_Client_Table;
        return $client->getById($id);
    }
    
    public function newClient($Client=null){
        $client = new Model_Client_Table;
        return $client->newRow($Client);
    }
    
    public function saveClient($Client=null){
        $client = new Model_Client_Table;
        return $client->save($Client);
    }
    
    public function deleteClientById($id){
        $client = new Model_Client_Table;
        return $client->deleteById($id);
    }
}

?>

Ma table/row associée

Code:

<?php

require_once ('Rem/Db/Table.php');

class Model_Client_Table extends Rem_Db_Table{

    protected $_name = 'client';
    protected $_primary = 'cli_id';
    protected $_rowClass = 'Model_Client_Row';
    protected $_rowsetClass = 'Model_Client_Rowset';
    
}

?>

<?php

//require_once ('Rem/Db/Row.php');

class Model_Client_Row extends Rem_Db_Row{
    
}

?>

J'espère que avec cela vous pourrez m'aider plus facilement.


Je vous remercie !!!

Hors ligne

 

#6 22-01-2009 18:31:00

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

J'ai résolu mon problème de la manière suivante:

Code:

<?php

require_once ('Zend/Db/Table/Row/Abstract.php');

class Rem_Db_Row extends Zend_Db_Table_Row_Abstract {
    
    public function toStdClass()
    {
        return (object)$this->toArray();
    }
    
    public function save($srcData = null)
    {
        $this->_primary = array($srcData[0]);//J'ai du rajouter cette ligne, je pense initialiser cette propriété dans la classe fille Model_Client_Table_Row, à voir...
        
        if ($srcData) { 
            $this->_cleanData = $srcData;
        }
        return parent::save();
    }
    
}

?>

Hors ligne

 

#7 22-01-2009 19:58:35

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: Problème save($data); bloque sur la fonction _refresh

squall6969 a écrit:

Bonjour,

Je suis actuellement en train de réalisé mon premier projet avec le framework de zend et je suis bloqué sur le problème suivant:

Code:

<?php

require_once ('Zend/Db/Table/Row/Abstract.php');

class Rem_Db_Row extends Zend_Db_Table_Row_Abstract {

    public function toStdClass()
    {
        return (object)$this->toArray();
    }
    
    public function save($srcData = null)
    {
        if ($srcData) {
            $this->_cleanData = $srcData;
        }
        return parent::save();
    }
    
    protected function _refresh(){
        
        
    }
}

?>

Si je ne surcharge pas _refresh, l'erreure suivante m'est renvoyée:

Code:

Cannot refresh row as parent is missing

Je ne sais pas trop d'où cela peut provenir.


Merci

il ne faut pas modifier _cleanData
mais _data

Fait par Zend
le processus est le suivant lecture des données dans la base
Données placées dans _cleanData et _data

Puis par toi
Travail sur les données dans _data

puis lorsque tu sauve par Zend
comparaison des donnée de _clean_Data et _Data
mise à jour des données de _data qui ne sont pas identique à celle de _cleanData dans la base

donc si tu touche à _cleanData Zend ne saura plus ce qu'il faut faire et tu vas dans le mur
A+JYT

Hors ligne

 

#8 22-01-2009 20:43:15

keilnoth
Membre
Date d'inscription: 30-08-2008
Messages: 128
Site web

Re: Problème save($data); bloque sur la fonction _refresh

Exact, ton problème c'est ça :

$this->_cleanData = $srcData;

Il y a une méthode setFromArray() qui permet de définir les valeurs d'une ligne dans l'objet. Toucher aux membres protégés, c'est très dangereux, surtout quand on ne maîtrise pas la totalité du code de Zend. smile

Normalement, Zend est assez bien fait pour que tu n'ai jamais à le faire.

Quand tu sauves ta ligne, Zend fait ça :

    public function save()
    {
        /**
         * If the _cleanData array is empty,
         * this is an INSERT of a new row.
         * Otherwise it is an UPDATE.
         */
        if (empty($this->_cleanData)) {
            return $this->_doInsert();
        } else {
            return $this->_doUpdate();
        }
    }

Donc en fait, tu fais un update, Zend tente ensuite de récupérer la ligne mais ne la trouve pas vu que la ligne n'existe pas. Et il renvoi cette erreur.


Quelques tutoriaux Zend Framework !

Hors ligne

 

#9 23-01-2009 10:01:45

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

keilnoth a écrit:

Il y a une méthode setFromArray() qui permet de définir les valeurs d'une ligne dans l'objet. Toucher aux membres protégés, c'est très dangereux, surtout quand on ne maîtrise pas la totalité du code de Zend. smile

Je n'arrives pas à faire fonctionner ce "é'&('" _doUpdate !!!!!

Je vous donnes ce que j'ai fais d'après vos conseils:

Code:

<?php

require_once ('Zend/Db/Table/Row/Abstract.php');

class Rem_Db_Row extends Zend_Db_Table_Row_Abstract {
    
    public function toStdClass()
    {
        return (object)$this->toArray();
    }
    
    public function save($srcData = null)
    {
        //print_r($srcData);exit();
        if ($srcData) { 
        
            
            $this->setFromArray($srcData);
           
        }
        return parent::save();
    }
    
}

?>

Mais cela me dit que sa créer un duplicata de ma clé primaire, il essaye de faire un insert au lieu d'un update.
Comment initialiser correectement le tout.

Merci.


PS: je me suis pas mal servi des source de lesauf, que je remercie au passage.
Seulement je n'ais pas voulu faire un copié collé tout bête et j'ai donc tout repris à la base

Hors ligne

 

#10 23-01-2009 12:40:50

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: Problème save($data); bloque sur la fonction _refresh

d'abord un find depuis ta table
ainsi tu récupère un Zend_Db_Table_Row avec le _clean en état
ensuite le setFromArray et enfin le save

si tu ne veux pas devoir refaire le find lors de la mise à jour
lorsque la première fois tu récupère ton objet tu le mets en session (enfin ses données clean et data)

puis lorsque tu reviens tu recrée un row avec et tu fais le setFromArray puis le save

A+JYT

Hors ligne

 

#11 23-01-2009 13:23:02

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

J'ai un soucis:
La méthode setFromArray me récupère aussi les champs submit et effacer de mon formulaire, et donc cela lève une exception en me disant que le champs "submit n'existe pas dans ma bdd".

Code:

public function saveAction($perform = true) 
    {
        $this->_linkContext();
  
        $srcData = $this->model->{$this->_getItemById}($this->context->id);
            
        echo "<pre>";
        print_r($this->context->formData);exit();
        echo "</pre>";
        
        // lecture du row  dans le rowset
        $srcData = $srcData->current();
        
        $srcData->setFromArray($this->context->formData);
        
        $id = $srcData->save();
        
        if ($id) {
            $this->_messenger->addOk($this->_messages['saved']);
               $redirect = $this->_to('show-list');
        } else {
            $this->_messenger->addError($this->_messages['unsaved']);
            $redirect = $this->_to('show-form');
        }
        if ($perform) {
            $this->_redirect($redirect);
        } else {
            return $redirect;
        }
    }

Je galère vraiment, je sais pas pourquoi, il doit y avoir quelque chose que j'ai mal saisie...


Merci sekajin tu m'es d'une aide précieuse.

Hors ligne

 

#12 23-01-2009 14:43:33

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

Re,

Voila la méthode de travail adopté pour résoudre le problème, tout détruire pour reconstruire, ET SA MARCHE !!!

Voici saveAction:

Code:

public function saveAction($perform = true) 
    {
        //récupération du contexte
        $this->_linkContext();
        
        //stockage de la méthode d'enregistrement
        $saveMethod = $this->context->saveMethod;
          
        
        if ("edit" == $saveMethod){
        //update
            //récupération de l'objet en cours d'edition
            $dataRowset = $this->model->{$this->_getItemById}($this->context->id);
                
            // lecture du row  dans le rowset
            $dataRow = $dataRowset->current();
        }else{
        //insert
            $dataRow = $this->model->{$this->_newItem}();
        }
            
        //selection des champs à mettre à jour
        $this->context->formData = array_intersect_key( $this->context->formData, $dataRow->toArray());
        
        //mise à jour du row
        $dataRow->setFromArray($this->context->formData);
            
        //sauvegarde de la mise à jour
        $id = $dataRow->save();
        
        //gestion des redirections en fonction de la réussite de l'enregistrement/mise à jour
        if ($id) {
            //succès
               $redirect = $this->_to('show-list');
        } else { 
            //échec
            $redirect = $this->_to('show-form');
        }
        
        //validation
        if ($perform) {
            $this->_redirect($redirect);
        } else {
            return $redirect;
        }
    }

Mon problème venait du fait que lorsqu l'on sérialise un objet de type row, celui ci perd la connection de la base de donnée pour des raisons de sécurité.
J'ai donc contourné le problème en communiquant l'id, puis refais un find() comme sekajin me l'a conseillé.

Je comprends mieu pourquoi lesauf surchargeait sa méthode save()...
Mais on m'a conseillé de ne jamais agir directement sur les propriétées protégé de zend sans en avoir l'expérience, et je suis plutôt pour cette idéologie.

Je vais maintenant continuer à avancer et essayer d'obtenir les résultats que je souhaites.


Je vous tiens au courant.


Merci encore pour votre aide, super forum !

Hors ligne

 

#13 23-01-2009 15:52:31

keilnoth
Membre
Date d'inscription: 30-08-2008
Messages: 128
Site web

Re: Problème save($data); bloque sur la fonction _refresh

Pour virer les champs qui n'existent pas dans ta table, dans ton modèle :

    $fields = $this->info(Zend_Db_Table_Abstract::COLS);

    /* getting only the related fields */
    foreach ($data as $field => $value) {
        if (!in_array($field, $fields)) {
            unset($data[$field]);
        }
    }

Il me semble que tu te compliques énormément la vie. Chez moi, ce genre d'action se résume à :

$request = $this->getRequest() ;
$db_table = new Db_Table_Model() ;
$db_table->save($request->getParams()) ;

Bien entendu, c'est grossièrement résumé... smile

La différence entre un update et un insert c'est la présence de la clé primaire dans ton tableau de données. Si tu fais un update, la clé primaire se trouve dans la requête GET ou POST que tu as réalisé.


Quelques tutoriaux Zend Framework !

Hors ligne

 

#14 23-01-2009 16:11:47

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

keilnoth a écrit:

Il me semble que tu te compliques énormément la vie. Chez moi, ce genre d'action se résume à :

$request = $this->getRequest() ;
$db_table = new Db_Table_Model() ;
$db_table->save($request->getParams()) ;

j'avais au début un fonctionnement similaire à cela mais je rencontrais des soucis par ci par là.
En tant que novice dans le framework j'ai préféré décomposer dans un premier temps pour comprendre la logique de base.

Par la suite je fournirais mes sources afin que je sois exposer à toutes les critiques qui pourrons me faire progresser.


Merci pour cette astuce, j'ai moi préféré passer par un array_intersect_key(), mais je devrais peut être me fier à ta méthode qui est plus sûre.

keilnoth a écrit:

$fields = $this->info(Zend_Db_Table_Abstract::COLS);

    /* getting only the related fields */
    foreach ($data as $field => $value) {
        if (!in_array($field, $fields)) {
            unset($data[$field]);
        }
    }

Je vous tiens au jus, merci de votre aide !

Hors ligne

 

#15 23-01-2009 16:34:48

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1176
Site web

Re: Problème save($data); bloque sur la fonction _refresh

keilnoth a écrit:

Pour virer les champs qui n'existent pas dans ta table, dans ton modèle :

    $fields = $this->info(Zend_Db_Table_Abstract::COLS);

    /* getting only the related fields */
    foreach ($data as $field => $value) {
        if (!in_array($field, $fields)) {
            unset($data[$field]);
        }
    }

Soit vous utilisez une ancienne version du ZF, soit vous avez pas vu le changement mais c'est corriger depuis ZF 1.7.0 (issue de référence : http://framework.zend.com/issues/browse/ZF-2243)

A+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#16 23-01-2009 20:12:11

keilnoth
Membre
Date d'inscription: 30-08-2008
Messages: 128
Site web

Re: Problème save($data); bloque sur la fonction _refresh

Possible, ça fait un bail que je l'utilise... Je crois que je l'avais trouvée dans un tutorial ou qqch comme ça.


Quelques tutoriaux Zend Framework !

Hors ligne

 

#17 23-01-2009 20:16:00

squall6969
Membre
Date d'inscription: 14-09-2008
Messages: 90

Re: Problème save($data); bloque sur la fonction _refresh

mikaelkael a écrit:

Soit vous utilisez une ancienne version du ZF, soit vous avez pas vu le changement mais c'est corriger depuis ZF 1.7.0 (issue de référence : http://framework.zend.com/issues/browse/ZF-2243)

A+

Effectivement, merci pour l'info !

Je vais mettre à jour mon framework et tester tout sa ^^

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages