Bonjour,
Je suis un peu étonné de cette erreur et je ne comprends pas pourquoi.
Dans ma page /view/Layout/default.ctp j'ai ceci

<?php echo $this->Form->create('Pave',array(
                                                          'url' => array(
                                                              'controller' => 'paves',
                                                              'action' => 'index',
                                                              'member' => false
                                                            ),
                                                          'class'=>'',
                                                          'novalidate')); ?>
                    <div class="grid_2 alpha">
                      <?php echo $this->Form->input('lastname',array('label'=>__("Nom"),'class'=>'')); ?>
                      <?php echo $this->Form->input('street',array('label'=>__("Rue"),'class'=>'')); ?>
                      <?php echo $this->Form->input('email',array('label'=>__('E-mail'),'class'=>'input-sm')); ?>
                    </div>
                    <div class="grid_2 omega">
                      <?php echo $this->Form->input('firstname',array('label'=>__("Prénom"),'class'=>'')); ?>
                      <?php echo $this->Form->input('city',array('label'=>__("Ville"),'class'=>'')); ?>
                      <?php echo $this->Form->input('job',array('label'=>__("Profession"),'class'=>'')); ?>
                      <?php echo $this->Form->input('newsletter',array('label'=>__(' Newsletter'),'class'=>'','value'=>1,'checked'=>"checked")); ?>
                    </div>
                    <br>
                    <?php echo $this->Form->input('captcha',array('label'=> array('text'=>__($this->Html->image('/users/captcha/').' = '),'style'=>'float:left'),'type'=>'number','style'=>'width:50px')); ?>
                      <?php echo $this->Form->End(array('label'=>__('Envoyer'),'class'=>'more_btn')); ?>

Donc quand je clique sur "envoyer", il va appelé le controller PavesController et l'action index
Apres avoir cliqué sur "envoyer" je suis aussi redirigé sur la page

http://localhost:8888/hallo-papa/paves

Dans mon ControllerPaves, j'ai ceci dans l'action index:

function index(){
        if($this->request->is('post')){ // || $this->request->is('put')
            // Check if password are egual
            $data = $this->request->data;
            debug($data);
            if($this->Session->read('Captcha') != $this->request->data'Pave']'captcha']){
                $this->Session->setFlash(__("Le calcul est faux"),'notif',array('type'=>'danger'));
            }elseif($this->Pave->save($data)){
                $this->Session->setFlash(__("Votre pavé a été envoyé"),'notif');
                unset($this->request->data);
                //$this->redirect(array('action'=>'index'));
            }else{
                $this->Session->setFlash(__("Votre pavé n'a pas pu être envoyé"),'notif',array('type'=>'danger'));
            }       
        }
    }

Je ne comprends pas pourquoi j'ai ce message d'erreur

Error: Call to a member function save() on a non-object
File: /Applications/MAMP/htdocs/hallo-papa/app/Controller/PavesController.php
Line: 13

à ce niveau

}elseif($this->Pave->save($data)){

J'ai controllé ma table 'paves' et j'ai bien les champs correspondant au debug($data)

array(
    'Pave' => array(
        'lastname' => '',
        'street' => '',
        'email' => '',
        'firstname' => '',
        'city' => '',
        'job' => '',
        'newsletter' => '1',
        'captcha' => '16'
    )
)

Es-ce que c'est parce que mon formulaire n'est pas dans /View/Paves/index.ctp ?

8 réponses


Ou es-ce que je dois mettre mon formulaire dans un Element?

Bonjour.
Pour commencer, si le formulaire n'est pas destiné pour le controller courant, il vaut mieux que tu fasse ton create comme ceci :

$this->Form->create(null, array(
    'url' => array('controller' => 'paves', 'action' => 'index', 'member' => false),  
    'inputDefaults' => array('class' => false), 
    'class' => false, 'novalidate' => true));

Ensuite, comme tu peux le constater ci-dessus, si tu ne veux pas de classe par défaut pour tes inputs, tu le précise dans les options du create avec un false, idem pour la class du formulaire.
Car préciser du 'vide' pour la classe du formulaire ça ne sert pas à grand chose et préciser du vide pour la classe à quasiment tous les inputs créés, c'est une perte de temps pour rien, surtout lorsque l'on utilise un helper de Framework qui permet de le préciser.
Si tu met novalidate sans préciser true , ça ne sert pas à grand chose de le mettre dans les options.
Il te faut mettre $this->Form->end() et non $this->Form->End() (cela m'étonne que tu n'ai pas eu d'erreur retournée par rapport à ce point là).
Pour qu'un élément de checkbox soit coché par défaut avec le helper Form, il faut mettre true et non checked , il est également inutile de mettre une valeur de 1 sur une checkbox, si elle est définie comme étant cochée par défaut.
Une fois arrangé, voici ton formulaire (j'ai précisé le modèle pour chaque champs, à toi de voir par la suite si c'est nécessaire ou non)

<?php echo $this->Form->create(null, array(
    'url' => array('controller' => 'paves', 'action' => 'index', 'member' => false), 
    'inputDefaults' => array('class' => false), 
    'class' => false, 'novalidate' => true)); ?>
    <div class="grid_2 alpha">
        <?php echo $this->Form->input('Pave.lastname', array('label' => __("Nom")));
        echo $this->Form->input('Pave.street', array('label' => __("Rue")));
        echo $this->Form->input('Pave.email', array('label' => __('E-mail'), 'class' => 'input-sm')); ?>
    </div>
    <div class="grid_2 omega">
        <?php echo $this->Form->input('Pave.firstname', array('label' => __("Prénom")));
        echo $this->Form->input('Pave.city', array('label' => __("Ville")));
        echo $this->Form->input('Pave.job', array('label'=>__("Profession")));
        echo $this->Form->input('Pave.newsletter', array('label' => __(' Newsletter'), 'checked' => true)); ?>
    </div><br>
    <?php echo $this->Form->input('Pave.captcha', array('label' => array('text' => __($this->Html->image('/users/captcha/').' = '), 'style' => 'float:left'), 'type' => 'number', 'style' => 'width:50px'));
echo $this->Form->end(array('label' =>__('Envoyer'), 'class' => 'more_btn')); ?>

Un dernier petit conseil, il est inutile d'ouvrir et de fermer tes balises PHP tant que tu n'as pas de code HTML entre tes echo.
Corriges ce que j'ai mis ci-dessus et reviens nous dire si ça change quelque chose.

Salut Lartak,

Merci pour cette belle explication. En premier temps (après avoir changé mon form->create de 'Pave' à null,

echo $this->Form->create(null, array(

mon debug($data) m'affichait un truc du genre

array(
    'Pafe' => array(
        'lastname' => '',
        'street' => '',
        'email' => '',
        'firstname' => '',
        'city' => '',
        'job' => '',
        'newsletter' => '1',
        'captcha' => '16'
    )
)

Le pafe m'a surpris car j'ai nullement ceci dans mon code. Mais mon erreur "Error: Call to a member function save()" a disparu

J'ai fais tous les changements suggérés

Mais depuis que j'ai ajouté le modele dans chaque champs, je retourve la même erreur. Voci mon code final

<?php echo $this->Form->create(null,array(
                                                          'url' => array(
                                                              'controller' => 'paves',
                                                              'action' => 'index',
                                                              'member' => false
                                                            ),
                                                          'inputDefaults' => array("class"=>false),
                                                          'class'=>false,
                                                          'novalidate' => true
                                                  )); ?>
                    <div class="grid_2 alpha">
                      <?php echo $this->Form->input('Pave.lastname',array('label'=>__("Nom"))); ?>
                      <?php echo $this->Form->input('Pave.street',array('label'=>__("Rue"))); ?>
                      <?php echo $this->Form->input('Pave.email',array('label'=>__('E-mail'))); ?>
                    </div>
                    <div class="grid_2 omega">
                      <?php echo $this->Form->input('Pave.firstname',array('label'=>__("Prénom"))); ?>
                      <?php echo $this->Form->input('Pave.city',array('label'=>__("Ville"))); ?>
                      <?php echo $this->Form->input('Pave.job',array('label'=>__("Profession"))); ?>
                      <?php echo $this->Form->input('Pave.newsletter',array('label'=>__(' Newsletter'),'value'=>1,'checked'=> true)); ?>
                    </div>
                    <br>
                    <?php echo $this->Form->input('Pave.captcha',array('label'=> array('text'=>__($this->Html->image('/users/captcha/').' = '),'style'=>'float:left'),'type'=>'number','style'=>'width:50px')); ?>
                      <?php echo $this->Form->end(array('label'=>__('Envoyer'),'class'=>'more_btn')); ?>

Je pense avoir fait toutes les corrections suggérées, si j'en ai pas loupée une...

Je n'ai jamais vu de formulaire qu'on initialisait en passant un model NULL.
J'utilise des tas de formulaires sur des controller qui ne sont pas ceux du model en question sans pour autant avoir d'erreur.
Et par sécurité autant que par convention, j'appelle toujours mes champs par "Model.field".

Ce qui ne fonctionne pas à mon avis dans ton script, c'est au niveau de ton controller.

Tu récupères les données, et tu cherches ensuite à enregistrer ton model, sauf que tu n'instancies pas le model en question et que tu ne lui passes pas non plus les données.

Donc avant de faire ton $this->Pave->save($data), il faut que tu fasses ces deux choses :

$this->Pave->create();
$this->Pave->set($data);

Et ensuite, tu auras simplement à faire un "$this->Pave->save()".

Niveau optimisation, tu pourrais également réorganiser tes conditions ou les modifier.
Par exemple ton "!= $this->request->data'Pave']'captcha']" n'as pas vraiment lieu d'être : si tu set ton model à partir de $data mais que le save renvoi false, alors c'est qu'il y avait une erreur, sinon il s'execute correctement.

Ok, j'ai trouvé.
(je crois)
J'ai renommé mon controller PavesController (Pave est un mot francais "pavé") en StonesController dont Stones est un mot anglais.
Je pense que le problème venais de la. Je dois pas utiliser des mot français, n'est-ce pas?

Si si, tu peux.

+1 avec pakito, la convention cakephp n'interdit pas les mots français, mais il faut juste respecter les pluriels.

Ok. Bon je voulais une table qui enregistre les pavés jetés.
Donc j ai appelé ma table paves sans l'accent. Donc peux être qu un mot avec accent cause problème?
Dans tous les cas, j ai utilise un mot en anglais "stones" et ça marche bien maintenant. Merci a vous pour vos conseils.