2

first some background information:

A user can fill out some input text boxes and upload multiple images (in one upload field). After the form is submitted, the text from the text fields is saved in the DB with $this->XXX->save(). Additionally the data (in particular the images from the file upload) is processed in the callback function afterSave(). So far so good.

Now to the problem:

It seems that the callback function is called multiple times (1 time for each uploaded image). So the problem is, the first time is everything fine, but after that the $this->data array is basically empty (all text fields are = '') so the callback function throws some exceptions because there is no data. I solved the problem by just checking with isset() and so on but I think that is not solving the problem.

So my question is, why is the callback function called multiple times and how can I prevent that?

Edit: Following some relevant code snippets:

Controller:

      if ($this->request->is('post') || $this->request->is('put')) {

        if($aid==null) $this->Article->create();
        if ($this->Article->save($this->data)) {
            $this->Session->setFlash(__('The article has been saved'), 'flash_custom');
            return $this->redirect(array('controller' => 'articles', 'action' => 'view', $this->id));
        } ...

Model:

I think most of that is not relevant here.. In general I send data to other Models where this data is saved in other db tables like this for pictures

 if ($this->data['Article']['picture']) {
   foreach ($this->data['Article']['picture'] as $picture) {
       if (is_uploaded_file($picture['tmp_name']) && (substr($picture['type'], 0, 5) == "image") && $numberOfPictures < $pictures_allowed) {
           $this->Picture->addPicture($picture, $this->id);
       }
       $numberOfPictures++;
   }

Error Dump:

I think a Dump of the $this->data array is quite interesting here (explanation below)

array(
'Article' => array(
    'pictures' => '0',
    'title' => 'Error Test',
    'abstract' => 'Test abstract',
    'body' => 'Testtext',
    'picture' => array(
        (int) 0 => array(
            [maximum depth reached]
        ),
        (int) 1 => array(
            [maximum depth reached]
        ),
        (int) 2 => array(
            [maximum depth reached]
        )
    ),
    'modified' => '2015-04-13 22:00:09',
    'created' => '2015-04-13 22:00:09',
    'id' => '294'
))


Notice (8): Undefined index: title [APP/Model/Article.php, line 723]
Notice (8): Undefined index: body [APP/Model/Article.php, line 724]
Notice (8): Undefined index: abstract [APP/Model/Article.php, line 725]

array(
    'Article' => array(
        'id' => '294',
        'pictures' => (int) 1,
        'modified' => '2015-04-13 22:00:09',
        'title' => '',
        'body' => '',
        'abstract' => '',
    )
)

Notice (8): Undefined index: picture [APP/Model/Article.php, line 777]

Notice (8): Undefined index: title [APP/Model/Article.php, line 723]

Notice (8): Undefined index: body [APP/Model/Article.php, line 724]

Notice (8): Undefined index: abstract [APP/Model/Article.php, line 725]

array(
    'Article' => array(
        'id' => '294',
        'pictures' => (int) 2,
        'modified' => '2015-04-13 22:00:10',
        'title' => '',
        'body' => '',
        'abstract' => '',
    )
)

Notice (8): Undefined index: picture [APP/Model/Article.php, line 777]

Notice (8): Undefined index: title [APP/Model/Article.php, line 723]

Notice (8): Undefined index: body [APP/Model/Article.php, line 724]

Notice (8): Undefined index: abstract [APP/Model/Article.php, line 725]

array(
    'Article' => array(
        'id' => '294',
        'pictures' => (int) 3,
        'modified' => '2015-04-13 22:00:10',
        'title' => '',
        'body' => '',
        'abstract' => '',
    )
)

Notice (8): Undefined index: picture [APP/Model/Article.php, line 777]

Explanation:

I just dumped $this->data once but like you see I've uploaded 3 pictures and I got 3 afterSave calls and so 3 $this->data dumps. The first time everything is fine, but after that some warnings are thrown because the array is not filled anymore.

I hope this additional information may help you

tobysas
  • 308
  • 5
  • 18

1 Answers1

2

If you're calling Model::save via the aftersave callback for the same model, then it will be a recursively saving, as the aftersave will call the save, which will trigger the aftersave again..

Disable callbacks in save method you're using in the aftersave

$this->save($data, array('callbacks' => false));

Documentation

Colonel Mustard
  • 1,482
  • 2
  • 17
  • 42
  • good approach, but i don't call Model::save via the afterSave callback.. But nevertheless thank you! – tobysas Apr 13 '15 at 14:33
  • so how are you saving data from a callback then? Post some code – Colonel Mustard Apr 13 '15 at 15:13
  • okay i went step for step through the code and actually your advise was quite right! I found a save() in a callback function of a complete different model but initiated in the posted article model.. so thank you – tobysas Apr 14 '15 at 16:06