views:

836

answers:

10

Greetings everyone!

I have a strange problem with my cake (cake_1.2.0.7296-rc2). My start()-action runs twice, under certain circumstances, even though only one request is made.

The triggers seem to be : - loading an object like: $this->Questionnaire->read(null, $questionnaire_id); - accessing $this-data

If I disable the call to loadAvertisement() from the start()-action, this does not happen. If I disable the two calls inside loadAdvertisement(): $questionnaire = $this->Questionnaire->read(null, $questionnaire_id); $question = $this->Questionnaire->Question->read(null, $question_id); ... then it doesn't happen either.

Why?

See my code below, the Controller is "questionnaires_controller".

function checkValidQuestionnaire($id)
{
    $this->layout = 'questionnaire_frontend_layout';

    if (!$id)
    {
        $id = $this->Session->read('Questionnaire.id');        
    }

    if ($id) 
    {
        $this->data = $this->Questionnaire->read(null, $id);

        //echo "from ".$questionnaire['Questionnaire']['validFrom']." ".date("y.m.d");
        //echo " - to ".$questionnaire['Questionnaire']['validTo']." ".date("y.m.d");


        if ($this->data['Questionnaire']['isPublished'] != 1 
            //|| $this->data['Questionnaire']['validTo'] < date("y.m.d")
            //|| $this->data['Questionnaire']['validTo'] < date("y.m.d")
            )
        {
            $id = 0;
            $this->flash(__('Ungültiges Quiz. Weiter zum Archiv...', true), array('action'=>'archive'));
        }
    }
    else
    {
        $this->flash(__('Invalid Questionnaire', true), array('action'=>'intro'));
    }

    return $id;
}



function start($id = null) {
    $this->log("start");

    $id = $this->checkValidQuestionnaire($id);

    //$questionnaire = $this->Questionnaire->read(null, $id);
    $this->set('questionnaire', $this->data);

    // reset flow-controlling session vars
    $this->Session->write('Questionnaire',array('id' => $id));
    $this->Session->write('Questionnaire'.$id.'currQuestion', null);
    $this->Session->write('Questionnaire'.$id.'lastAnsweredQuestion', null);
    $this->Session->write('Questionnaire'.$id.'correctAnswersNum', null);

    $this->loadAdvertisement($id, 0);

    $this->Session->write('Questionnaire'.$id.'previewMode', $this->params['named']['preview_mode']);

    if (!$this->Session->read('Questionnaire'.$id.'previewMode'))
    {
        $questionnaire['Questionnaire']['participiantStartCount']++;
        $this->Questionnaire->save($questionnaire);
    }        

}




function loadAdvertisement($questionnaire_id, $question_id)
{

    //$questionnaire = array();
    $questionnaire = $this->Questionnaire->read(null, $questionnaire_id);

    //$question = array();
    $question = $this->Questionnaire->Question->read(null, $question_id);

    if (isset($question['Question']['advertisement_id']) && $question['Question']['advertisement_id'] > 0)
    {
        $this->set('advertisement', $this->Questionnaire->Question->Advertisement->read(null, $question['Question']['advertisement_id']));
    }
    else if (isset($questionnaire['Questionnaire']['advertisement_id']) && $questionnaire['Questionnaire']['advertisement_id'] > 0)
    {
        $this->set('advertisement', $this->Questionnaire->Question->Advertisement->read(null, $questionnaire['Questionnaire']['advertisement_id']));
    }

}

I really don't understand this... it don't think it's meant to be this way. Any help would be greatly appreciated! :)

Regards, Stu

+1  A: 

You might want to try and find out where it comes from using the debug_print_backtrace() function. (http://nl.php.net/manual/en/function.debug-print-backtrace.php

eelco
Hi!Thanks for the answer. However, it did not help, it just display two times exactly the same steps from the backtrace.This is a CakePHP specific problem, not just PHP.
+3  A: 

Check your layout for non-existent links, for example a misconfigured link to favicon.ico will cause the controller action to be triggered for a second time. Make sure favicon.ico points towards the webroot rather than the local directory, or else requests will be generated for /controller/action/favicon.ico rather than /favicon.ico - and thus trigger your action.

This can also happen with images, stylesheets and javascript includes.

To counter check the $id is an int, then check to ensure $id exists as a primary key in the database before progressing on to any functionality.

Martz
+1  A: 

Had the same problem, with a certain action randomly running 2-3 times. I tracked down two causes:

  • Firefox add-on Yslow was set to load automatically from it's Preferences, causing pages to reload when using F5 (not when loading the page from the browser's address bar and pressing Enter).

  • I had a faulty css style declaration within the options of a $html->link(); in some cases it would end up as background-image: url('');, which caused a rerun also. Setting the style for the link to background-image: none; when no image was available fixed things for me.

Hope this helps. I know this is quite an old post, but as it comes up pretty high in Google when searching for this problem, I thought it might help others by still posting.

Good luck

Jeroen den Haan

A: 

I had a problem like this last week.

Two possible reasons

  • Faulty routes (DO check your routes configuration)
  • Faulty AppController. I add loads of stuff into AppController, especially to beforeFilter() and beforeRender() so you might want to check those out also.

One more thing, are where are you setting the Questioneer.id in your Session? Perhaps that's the problem?

IvanBernat
A: 

THANKS GUYS. THIS TOTALLY SAVED MY LIFE!

A: 

I just experienced the same CakePHP + broken url in view = double action execution. Crazy. Is this a documented bug?

A: 

For me it was a JS issue. Take care of wrap function with jqyery that re-execue js in content wraped !!!

Thansk for your comments

Screu
A: 

I join the thanks, big comments to community JKTIC

JKTIC
A: 

Had the same problem, solved by disabling YSlow for firefox.

Thanks Jeroen den Haan.

Kalle
A: 

thx alot eelco.lempsink.nl

stroem