State Seems To Hold Onto Previously Set Value

Hopefully, someone will be able to answer this based on workflow vs showing the code. If it can’t be answered based on workflow, then I’ll have to figure out a way to reproduce the issue. Here goes…

  1. Initial page load (site/index/list/context1). Set value to ‘context1.’ Yii:app()->user->setState(‘context’,‘context1’);

  2. The user clicks on a link that reloads the page(site/index/list/context2). Change value of ‘context’ to ‘context2’. Set Yii:app()->user->setState(‘context’,‘context2’)

  3. Now the user is in ‘context2’. The user clicks on a ‘More’ button that is an ajax call to actionLoadMore(). Check ‘context’ in actionLoadMore(). Yii:app()->user->getState(‘context’) == ‘context1’

I’ve gone over this a dozen different ways to include using $_SESSION directly. Same result. Any ideas?

Mike

Can you are some more codes of those actions + excerpt from your config file containing specification of ‘user’ or ‘session’ component (of course if it’s specified).

I’ve isolated the problem but not sure why is it behaving as it is. Still looking. State/Session are working correctly.

Here’s a facsimile of the structure of actionIndex.




public function actionIndex($list='context1',$search='no')

    {

        if(Yii::app()->user->isGuest)

        {

            $this->layout = '//layouts/column1';

            $this->render('guest');

        }

        else

        {

            ...


            if($list == 'context2')

            {

                ...


                Yii::app()->user->setState('context','context2');

                

                $this->render('index', array('dataProvider'=>$dataProvider, 'list'=>$list,'myCount'=>$myCount));


            } //end if 

           


            if($list == 'context1')

            {

                ...


                Yii::app()->user->setState('context','context1');

                

                $this->render('index',array('dataProvider'=>$dataProvider, 'list'=>$list,'myCount'=>$myCount));

            }//end if


        }//end if


    }//end actionIndex




The above is accessed through two links on the site/index page. One link points to context1 (site/index/list/context1) and the other link points to context2 (site/indes/list/context2).




        echo "<ul><li><a href='".CController::createUrl('/site/index/list/context1')."' class='alllink'>All</a></li>";

        echo "<li><a style='text-decoration:underline' href='".CController::createUrl('/site/index/list/context2')."' class='friendslink'>My Friends</a></li></ul>";



As you can see, I’m passing parameters to actionIndex. The default value for $list is ‘context1’. When I pass ‘context2’ as a paramter (site/index/list/context2), the code in ‘context1’ executes, somehow. This is really hard to explain and probably won’t make a lot of sense but the ‘context2’ html is actually being rendered even though the block of code under ‘context1’ is entered and executed, at least to the point of setting the state value of ‘context’ to ‘context1.’ All of this happens before I make the ajax call. So, I was a bit mistaken about that.

Still not sure why is it behaving like this. I’m continuing to test.

Thanks Mike.

Hi Mike,

That is not a recommended way of creating links. It is assuming a certain kind of url manager rule and it will not work if the rule has been changed (or, if the rule has some error).

I guess ‘list’ parameter is not passed to your index controller correctly. I mean, it might be always empty and defaults to ‘context1’.

Try instead:




echo "<ul><li><a href='".CController::createUrl('site/index', array('list'=>'context1'))."' class='alllink'>All</a></li>";

echo "<li><a style='text-decoration:underline' href='".CController::createUrl('site/index', array('list'=>'context2'))."' class='friendslink'>My Friends</a></li>



Hi,

I did try that–same result. I have the url manager setup to accept the optional paths. This has worked correctly. It has been displaying the correct html for each context. The only reason I became aware of this issue is when I wanted to make an ajax call. In the ajax call, I test for the context. But, the problem is not in the ajax call, the problem is that both code blocks are being executed when I am in context2. I know this for a fact because if I add an exit statement in the code block for context1 prior to setting the context, if works as expected. I also send myself an email, for testing, when in context2. I receive the email and the correct html is displayed. If I add print statement in the context1 block, I’ll recieve the email but won’t see the print statement text.

Mike

So you suggest that generally it works OK, beside this testing email that is sent from context2 event if you are in context1 (and the only sympthom of execution context1 is sent mail)? Or perhaps I mistunderstood something?

Dear Friend

I do not know how far I have perceived your problem.

Anyway I am curious to test your code.

CONTROLLER.




class TrialController extends Controller

{

	public function actionContext($name)

	{	

		Yii::app()->user->setState('name',$name);

		$this->render('context');

	}


        public function actionAjax()

        {

		echo Yii::app()->user->getState('name');

	}




}



VIEW




echo CHtml::link("click",array('trial/context','name'=>"seenivasan"));


echo "<br>";


echo CHtml::ajaxLink("ajaxLink",array('trial/ajax'),array(

	'success'=>'js:function(data) {console.log(data)}'

));



After putting the following in URL bar,




http://localhost/sunlife/trial/context/michael



If I click ajaxLink I am getting "michael" in console.

Now if I click normal link, the page is reloaded.

Now if I click ajaxLink, I am getting "seenivasan" in console.

I am not seeing anything wrong.

Regards.

Hi,

Yeah, that’s basically what I’m saying. I created a test case and wasn’t able to reproduce the issue. Must be something in my actionIndex that is causing the issue. I’ll need to more testing. See in post below the test case.

Thanks, Mike

Hi,

I also created a test case trying to reproduce the issue. Looks like there is something in my project code that is causing the issue. The fact is I should refactor my code into two actions instead of what I have.

Thanks for taking the time to create the example. A facsimile of the structure causing the issue is below.

Mike

ACTION





    public function actionTest($list='context1')

    {

        if($list == 'context1')

        {

            Yii::app()->user->setState('ctx', 'context1');

            $this->render('test',array('list'=>$list));

        }

        else if($list == 'context2')

        {

            Yii::app()->user->setState('ctx', 'context2');

            $this->render('test',array('list'=>$list));

        }

    }




VIEW




if($list == 'context1')

{

    echo "<ul><li><a style='text-decoration:underline' href='".CController::createUrl('site/test/list/context1')."'>Context 1</a></li>";

    echo "<li><a  href='".CController::createUrl('site/test/list/context2')."'>Context 2</a></li></ul>";

}

else

{

    echo "<ul><li><a href='".CController::createUrl('site/test/list/context1')."'>Context 1</a></li>";

    echo "<li><a style='text-decoration:underline' href='".CController::createUrl('site/test/list/context2')."'>Context 2</a></li></ul>";

}




print Yii::app()->user->getState('ctx');



Dear Michael

I initially thought there is error in passing parameter to CController::createUrl method . But that is not the problem.

But I just copied your code with just change in Controller id.

That is also working.

I have just modified the code to my taste.

This is also working.

CONTROLLER




public function actionTest($list='context1')

	{

            Yii::app()->user->setState('ctx', $list);

            $this->render('context',array('list'=>$list));

	}



VIEW




echo "<ul><li><a href='".CController::createUrl('trial/test',array('list'=>'context1'))."'>Context 1</a></li>";

echo "<li><a style='text-decoration:underline' href='".CController::createUrl('trial/test',array('list'=>'context2'))."'>Context 2</a></li></ul>";

print Yii::app()->user->getState('ctx');



I finally found the problem.

All unhandled exceptions are handled at the application level. I create a log entry and redirect to the landing page of the site.

INDEX.PHP




try

{

    Yii::createWebApplication($config)->run();

}

catch (Exception $e)

{

    Yii::log($e->getMessage(),  CLogger::LEVEL_ERROR,'unhandled exception caught at index.php');


    Yii::app()->request->redirect(CController::createUrl('/site/index'));

}



The exception in this case was a missing image in a css file. You can see that the exception was occurring in context2 with a redirect to site/index. The redirect would then use the default value of $list (the param passed into actionIndex) causing context1’s code block to execute thus resetting the state value (ctx).

APPLICATION.LOG




$_SERVER=array (

  'REDIRECT_STATUS' => '200',

  'HTTP_ACCEPT' => 'image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5',

  'HTTP_REFERER' => 'http://.../site/index?list=friends',  //friends == context2 in the example

   ...

  'REDIRECT_URL' => '/css/images/ui-bg_flat_75_ffffff_40x100.png',

  'GATEWAY_INTERFACE' => 'CGI/1.1',

  'SERVER_PROTOCOL' => 'HTTP/1.1',

  'REQUEST_METHOD' => 'GET',

  'QUERY_STRING' => '',

  'REQUEST_URI' => '/css/images/ui-bg_flat_75_ffffff_40x100.png',

  'SCRIPT_NAME' => '/index.php',

  'PHP_SELF' => '/index.php',

  'REQUEST_TIME' => 1364369223,

)

2013/03/27 01:27:03 [error] [unhandled exception caught at index.php] Unable to resolve the request "css/images/ui-bg_flat_75_ffffff_40x100.png".

in /var/www/dkeidkd838dkckde32/index.php (34)



A couple things I don’t understand.

  1. Why would a missing image throw an exception?

2 Why context2 was rendered correctly, even though context1’s code block was also entered.

Thanks to all for your feedback, Mike

Ah, congrats!

I should have imagined that. Some browser repeats the same request for a page twice, when it failed to receive all the resources for the page. Missing images (sometimes "favicon.ico") will trigger this, and it will be a cause of the problems in session data.

Thanks. Persistence pays off once more.

I didn’t know that a missing image would result in a thrown exception? I’ve never seen that before. Is it just because it was in a css rule?

CSS EXAMPLE





.ui-widget-header .ui-state-active {

	border: 1px solid #aaaaaa;


        /****this image doesn't exist and this throws an exception...? that seems odd to me. ****/

	background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; 

	

        font-weight: normal;

	color: #212121;

}



Mike