View Issue Details

IDProjectCategoryView StatusLast Update
16386Bug reportsOtherpublic2020-07-09 22:51
ReporterChristin8 Assigned To 
PrioritynoneSeverityblock 
Status newResolutionopen 
Product Version3.22.19 
Summary16386: Token-based persistence produces weird results when switching devices, browsers, and in incognito browsers to continue survey.
Description

Participant beings survey with token, answeres few a question groups (all groups in the survey are mandatory) and then closes web-browser. When they return to the survey on another device, another browser, or even in incognito/private browsing mode in the same browser they come back to the survey on another state then they left it. It seems like it is working only when they start the survey, leave the browser and come back to it with the token on exactly the same device in the same (not incognito/private) browser.

It almost seems that the browser is storing information about the surveys state - which can only be accessed within the same browser and not on another browser / device / between different incognito browser windows.

Additionally, some participants told us that they make it e.g. halfway through the survey, then they take a break and want to come back and can't proceed even on the same browser. They can't see the questions inside the group, only the description of the question group. Some also get the following error message: "One or more mandatory questions have not been answered. You cannot proceed until these have been completed.” Disabling "mandatory" only achieves that the error message is not displayed, but the questions inside the group are not displayed still.

Steps To Reproduce

Survey structure:
A) The survey basically starts with a view pages, in the beginning, to display information and gather details from all participants.
B) Then, a question group with a hidden question, that selects 40 out of 123 subquestions. Implemented by this approach basically: https://manual.limesurvey.org/Workarounds:_Survey_behaviour#Randomly_show_X_out_of_Y_question_groups
C) Then, 123 question groups with 3 subquestions each. The question groups have a relevance equation to get only displayed on step B, and are in the same randomization group to get shuffled through.

Reproduce the unwanted behavior:
1) Open survey in browser (normal mode): go through the first static pages each participant gets.
2) Continue to an arbitrary point while answering some of the 40 selected question groups.
3) Exit the survey. Return in a new window (normal mode) with the token link, everything works fine and you can continue where you stopped.
4) Return in a new browser / device / incognito window with the token link. You get redirected to another (random?) question group and only the question group description is shown, and no questions.

I was told that it shouldn't make a difference which browser or device participants are using, but it seems like it makes a huge difference. I tried the described test in different browsers and in normal mode/private/incognito mode and there is no recognizable pattern for the buggy behavior.

I updated to Version 3.22.19+200605 as the bug described here (https://bugs.limesurvey.org/view.php?id=16354) should be fixed. Nevertheless, our problem still exists.

Additional Information

The issues were also described and discused here already https://forums.limesurvey.org/forum/installation-a-update-issues/121416-resume-later-problem?start=15#200641

TagsNo tags attached.
Complete LimeSurvey version number (& build)Version 3.22.19+200605
I will donate to the project if issue is resolvedNo
BrowserSafari, Firefox, Chrome
Database & DB-VersionDo not know
Server OS (if known)
Webserver software & version (if known)
PHP VersionDo not know

Activities

Christin8

Christin8

2020-06-13 14:23

reporter  

limesurvey_survey_587283.lss (2,033,863 bytes)
DenisChenu

DenisChenu

2020-06-15 08:10

developer   ~58278

Can not reproduce …

DenisChenu

DenisChenu

2020-06-15 08:15

developer   ~58279

Oh, not reltead to token answer persistence .

You have an issue in your script, seem not closed.

Then broke something else when reloaded.

PHP notice.html (17,040 bytes)   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>PHP notice</title>

<style type="text/css">
/*<![CDATA[*/
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0;}
body{line-height:1;}
ol,ul{list-style:none;}
blockquote,q{quotes:none;}
blockquote:before,blockquote:after,q:before,q:after{content:none;}
:focus{outline:0;}
ins{text-decoration:none;}
del{text-decoration:line-through;}
table{border-collapse:collapse;border-spacing:0;}

body {
	font: normal 9pt "Verdana";
	color: #000;
	background: #fff;
}

h1 {
	font: normal 18pt "Verdana";
	color: #f00;
	margin-bottom: .5em;
}

h2 {
	font: normal 14pt "Verdana";
	color: #800000;
	margin-bottom: .5em;
}

h3 {
	font: bold 11pt "Verdana";
}

pre {
	font: normal 11pt Menlo, Consolas, "Lucida Console", Monospace;
}

pre span.error {
	display: block;
	background: #fce3e3;
}

pre span.ln {
	color: #999;
	padding-right: 0.5em;
	border-right: 1px solid #ccc;
}

pre span.error-ln {
	font-weight: bold;
}

.container {
	margin: 1em 4em;
}

.version {
	color: gray;
	font-size: 8pt;
	border-top: 1px solid #aaa;
	padding-top: 1em;
	margin-bottom: 1em;
}

.message {
	color: #000;
	padding: 1em;
	font-size: 11pt;
	background: #f3f3f3;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	margin-bottom: 1em;
	line-height: 160%;
}

.source {
	margin-bottom: 1em;
}

.code pre {
	background-color: #ffe;
	margin: 0.5em 0;
	padding: 0.5em;
	line-height: 125%;
	border: 1px solid #eee;
}

.source .file {
	margin-bottom: 1em;
	font-weight: bold;
}

.traces {
	margin: 2em 0;
}

.trace {
	margin: 0.5em 0;
	padding: 0.5em;
}

.trace.app {
	border: 1px dashed #c00;
}

.trace .number {
	text-align: right;
	width: 2em;
	padding: 0.5em;
}

.trace .content {
	padding: 0.5em;
}

.trace .plus,
.trace .minus {
	display:inline;
	vertical-align:middle;
	text-align:center;
	border:1px solid #000;
	color:#000;
	font-size:10px;
	line-height:10px;
	margin:0;
	padding:0 1px;
	width:10px;
	height:10px;
}

.trace.collapsed .minus,
.trace.expanded .plus,
.trace.collapsed pre {
	display: none;
}

.trace-file {
	cursor: pointer;
	padding: 0.2em;
}

.trace-file:hover {
	background: #f0ffff;
}
/*]]>*/
</style>
</head>

<body>
<div class="container">
	<h1>PHP notice</h1>

	<p class="message">
		Trying to access array offset on value of type bool	</p>

	<div class="source">
		<p class="file">/mnt/data/shnoulle/nginx/www/3LTS/application/helpers/frontend_helper.php(2144)</p>
		<div class="code"><pre><span class="ln">2132</span>     /* @deprecated since we use button and not input with different value. */
<span class="ln">2133</span>     foreach ($aAcceptedMove as $sAccepteMove) {
<span class="ln">2134</span>         if (Yii::app()-&gt;request-&gt;getParam($sAccepteMove)) {
<span class="ln">2135</span>                     $move = $sAccepteMove;
<span class="ln">2136</span>         }
<span class="ln">2137</span>     }
<span class="ln">2138</span>     /* default move (user don't click on a button, but use enter in a input:text or a select */
<span class="ln">2139</span>     if ($move == 'default') {
<span class="ln">2140</span>         $surveyid = Yii::app()-&gt;getConfig('surveyID');
<span class="ln">2141</span>         $thissurvey = getsurveyinfo($surveyid);
<span class="ln">2142</span>         $iSessionStep = (isset($_SESSION['survey_'.$surveyid]['step'])) ? $_SESSION['survey_'.$surveyid]['step'] : false;
<span class="ln">2143</span>         $iSessionTotalSteps = (isset($_SESSION['survey_'.$surveyid]['totalsteps'])) ? $_SESSION['survey_'.$surveyid]['totalsteps'] : false;
<span class="error"><span class="ln error-ln">2144</span>         if ($iSessionStep &amp;&amp; ($iSessionStep == $iSessionTotalSteps) || $thissurvey['format'] == 'A') {
</span><span class="ln">2145</span>             $move = "movesubmit";
<span class="ln">2146</span>         } else {
<span class="ln">2147</span>             $move = "movenext";
<span class="ln">2148</span>         }
<span class="ln">2149</span>     }
<span class="ln">2150</span>     return $move;
<span class="ln">2151</span> }
<span class="ln">2152</span> 
<span class="ln">2153</span> /**
<span class="ln">2154</span>  * Get the margin class for side-body div depending
<span class="ln">2155</span>  * on side-menu behaviour config and page (edit or not
<span class="ln">2156</span>  * etc).
</pre></div>	</div>

	<div class="traces">
		<h2>Stack Trace</h2>
				<table style="width:100%;">
						<tbody><tr class="trace app expanded">
			<td class="number">
				#0			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/application/controllers/survey/index.php(37): <strong>getMove</strong>()				</div>

				<div class="code"><pre><span class="ln">32</span> 
<span class="ln">33</span>         $this-&gt;_loadRequiredHelpersAndLibraries();
<span class="ln">34</span>         $param       = $this-&gt;_getParameters(func_get_args(), $_POST);
<span class="ln">35</span>         $surveyid    = $param['sid'];
<span class="ln">36</span>         $thisstep    = $param['thisstep'];
<span class="error"><span class="ln error-ln">37</span>         $move        = getMove();
</span><span class="ln">38</span>         $clienttoken = trim($param['token']);
<span class="ln">39</span> 
<span class="ln">40</span>         $oSurvey = Survey::model()-&gt;findByPk($surveyid);
<span class="ln">41</span> 
<span class="ln">42</span>         if(empty($oSurvey)) {
</pre></div>			</td>
		</tr>
						<tr class="trace app expanded">
			<td class="number">
				#1			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/application/controllers/survey/index.php(24): <strong>index</strong>-&gt;<strong>action</strong>()				</div>

				<div class="code"><pre><span class="ln">19</span>     public $oTemplate;
<span class="ln">20</span> 
<span class="ln">21</span>     public function run()
<span class="ln">22</span>     {
<span class="ln">23</span>         useFirebug();
<span class="error"><span class="ln error-ln">24</span>         $this-&gt;action();
</span><span class="ln">25</span>     }
<span class="ln">26</span> 
<span class="ln">27</span>     public function action()
<span class="ln">28</span>     {
<span class="ln">29</span>         global $surveyid;
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#2			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/actions/CAction.php(76): <strong>index</strong>-&gt;<strong>run</strong>()				</div>

				<div class="code"><pre><span class="ln">71</span>     {
<span class="ln">72</span>         $method=new ReflectionMethod($this, 'run');
<span class="ln">73</span>         if($method-&gt;getNumberOfParameters()&gt;0)
<span class="ln">74</span>             return $this-&gt;runWithParamsInternal($this, $method, $params);
<span class="ln">75</span> 
<span class="error"><span class="ln error-ln">76</span>         $this-&gt;run();
</span><span class="ln">77</span>         return true;
<span class="ln">78</span>     }
<span class="ln">79</span> 
<span class="ln">80</span>     /**
<span class="ln">81</span>      * Executes a method of an object with the supplied named parameters.
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#3			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/CController.php(308): <strong>CAction</strong>-&gt;<strong>runWithParams</strong>(array("r" =&gt; "survey/index", "sid" =&gt; "587283"))				</div>

				<div class="code"><pre><span class="ln">303</span>     {
<span class="ln">304</span>         $priorAction=$this-&gt;_action;
<span class="ln">305</span>         $this-&gt;_action=$action;
<span class="ln">306</span>         if($this-&gt;beforeAction($action))
<span class="ln">307</span>         {
<span class="error"><span class="ln error-ln">308</span>             if($action-&gt;runWithParams($this-&gt;getActionParams())===false)
</span><span class="ln">309</span>                 $this-&gt;invalidActionParams($action);
<span class="ln">310</span>             else
<span class="ln">311</span>                 $this-&gt;afterAction($action);
<span class="ln">312</span>         }
<span class="ln">313</span>         $this-&gt;_action=$priorAction;
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#4			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/CController.php(286): <strong>CController</strong>-&gt;<strong>runAction</strong>(index)				</div>

				<div class="code"><pre><span class="ln">281</span>      * @see runAction
<span class="ln">282</span>      */
<span class="ln">283</span>     public function runActionWithFilters($action,$filters)
<span class="ln">284</span>     {
<span class="ln">285</span>         if(empty($filters))
<span class="error"><span class="ln error-ln">286</span>             $this-&gt;runAction($action);
</span><span class="ln">287</span>         else
<span class="ln">288</span>         {
<span class="ln">289</span>             $priorAction=$this-&gt;_action;
<span class="ln">290</span>             $this-&gt;_action=$action;
<span class="ln">291</span>             CFilterChain::create($this,$action,$filters)-&gt;run();
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#5			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/CController.php(265): <strong>CController</strong>-&gt;<strong>runActionWithFilters</strong>(index, array())				</div>

				<div class="code"><pre><span class="ln">260</span>         {
<span class="ln">261</span>             if(($parent=$this-&gt;getModule())===null)
<span class="ln">262</span>                 $parent=Yii::app();
<span class="ln">263</span>             if($parent-&gt;beforeControllerAction($this,$action))
<span class="ln">264</span>             {
<span class="error"><span class="ln error-ln">265</span>                 $this-&gt;runActionWithFilters($action,$this-&gt;filters());
</span><span class="ln">266</span>                 $parent-&gt;afterControllerAction($this,$action);
<span class="ln">267</span>             }
<span class="ln">268</span>         }
<span class="ln">269</span>         else
<span class="ln">270</span>             $this-&gt;missingAction($actionID);
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#6			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/CWebApplication.php(282): <strong>CController</strong>-&gt;<strong>run</strong>("index")				</div>

				<div class="code"><pre><span class="ln">277</span>         {
<span class="ln">278</span>             list($controller,$actionID)=$ca;
<span class="ln">279</span>             $oldController=$this-&gt;_controller;
<span class="ln">280</span>             $this-&gt;_controller=$controller;
<span class="ln">281</span>             $controller-&gt;init();
<span class="error"><span class="ln error-ln">282</span>             $controller-&gt;run($actionID);
</span><span class="ln">283</span>             $this-&gt;_controller=$oldController;
<span class="ln">284</span>         }
<span class="ln">285</span>         else
<span class="ln">286</span>             throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
<span class="ln">287</span>                 array('{route}'=&gt;$route===''?$this-&gt;defaultController:$route)));
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#7			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/web/CWebApplication.php(141): <strong>CWebApplication</strong>-&gt;<strong>runController</strong>("survey/index")				</div>

				<div class="code"><pre><span class="ln">136</span>             foreach(array_splice($this-&gt;catchAllRequest,1) as $name=&gt;$value)
<span class="ln">137</span>                 $_GET[$name]=$value;
<span class="ln">138</span>         }
<span class="ln">139</span>         else
<span class="ln">140</span>             $route=$this-&gt;getUrlManager()-&gt;parseUrl($this-&gt;getRequest());
<span class="error"><span class="ln error-ln">141</span>         $this-&gt;runController($route);
</span><span class="ln">142</span>     }
<span class="ln">143</span> 
<span class="ln">144</span>     /**
<span class="ln">145</span>      * Registers the core application components.
<span class="ln">146</span>      * This method overrides the parent implementation by registering additional core components.
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#8			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/framework/base/CApplication.php(185): <strong>CWebApplication</strong>-&gt;<strong>processRequest</strong>()				</div>

				<div class="code"><pre><span class="ln">180</span>     public function run()
<span class="ln">181</span>     {
<span class="ln">182</span>         if($this-&gt;hasEventHandler('onBeginRequest'))
<span class="ln">183</span>             $this-&gt;onBeginRequest(new CEvent($this));
<span class="ln">184</span>         register_shutdown_function(array($this,'end'),0,false);
<span class="error"><span class="ln error-ln">185</span>         $this-&gt;processRequest();
</span><span class="ln">186</span>         if($this-&gt;hasEventHandler('onEndRequest'))
<span class="ln">187</span>             $this-&gt;onEndRequest(new CEvent($this));
<span class="ln">188</span>     }
<span class="ln">189</span> 
<span class="ln">190</span>     /**
</pre></div>			</td>
		</tr>
						<tr class="trace app expanded">
			<td class="number">
				#9			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/mnt/data/shnoulle/nginx/www/3LTS/index.php(194): <strong>CApplication</strong>-&gt;<strong>run</strong>()				</div>

				<div class="code"><pre><span class="ln">189</span> require_once APPPATH . 'core/LSYii_Application' . EXT;
<span class="ln">190</span> 
<span class="ln">191</span> $config = require_once(APPPATH . 'config/internal' . EXT);
<span class="ln">192</span> 
<span class="ln">193</span> Yii::$enableIncludePath = false;
<span class="error"><span class="ln error-ln">194</span> Yii::createApplication('LSYii_Application', $config)-&gt;run();
</span><span class="ln">195</span> 
<span class="ln">196</span> /* End of file index.php */
<span class="ln">197</span> /* Location: ./index.php */
</pre></div>			</td>
		</tr>
				</tbody></table>
	</div>

	<div class="version">
		2020-06-15 06:11:28 nginx/1.18.0 <a href="http://www.yiiframework.com/">Yii Framework</a>/1.1.22-dev	</div>
</div>

<script type="text/javascript">
/*<![CDATA[*/
var traceReg = new RegExp("(^|\\s)trace-file(\\s|$)");
var collapsedReg = new RegExp("(^|\\s)collapsed(\\s|$)");

var e = document.getElementsByTagName("div");
for(var j=0,len=e.length;j<len;j++){
	if(traceReg.test(e[j].className)){
		e[j].onclick = function(){
			var trace = this.parentNode.parentNode;
			if(collapsedReg.test(trace.className))
				trace.className = trace.className.replace("collapsed", "expanded");
			else
				trace.className = trace.className.replace("expanded", "collapsed");
		}
	}
}
/*]]>*/
</script>



<div id="grammalecte_menu_main_button_shadow_host" style="width: 0px; height: 0px;"></div></body><script src="PHP%20notice_fichiers/api.js"></script></html>
PHP notice.html (17,040 bytes)   
Peek 15-06-2020 08-15.gif (786,841 bytes)
Christin8

Christin8

2020-06-15 09:35

reporter   ~58280

Thanks for your quick reply and your effort! Do you have a recommendation on how to fix this?

DenisChenu

DenisChenu

2020-06-15 09:52

developer   ~58281

Fix the scripot,

Try to remove it for starting …

It's not a a support system here …

Christin8

Christin8

2020-06-16 13:11

reporter   ~58302

test.mov (1,979,933 bytes)   
cdorin

cdorin

2020-07-09 22:51

manager   ~58883

Leaving a comment to bump it

Issue History

Date Modified Username Field Change
2020-06-13 14:23 Christin8 New Issue
2020-06-13 14:23 Christin8 File Added: limesurvey_survey_587283.lss
2020-06-15 08:07 DenisChenu Assigned To => DenisChenu
2020-06-15 08:07 DenisChenu Status new => assigned
2020-06-15 08:10 DenisChenu Assigned To DenisChenu => cdorin
2020-06-15 08:10 DenisChenu Note Added: 58278
2020-06-15 08:15 DenisChenu Note Added: 58279
2020-06-15 08:15 DenisChenu File Added: Capture d’écran du 2020-06-15 08-12-56.png
2020-06-15 08:15 DenisChenu File Added: PHP notice.html
2020-06-15 08:15 DenisChenu File Added: Peek 15-06-2020 08-15.gif
2020-06-15 09:35 Christin8 Note Added: 58280
2020-06-15 09:52 DenisChenu Note Added: 58281
2020-06-16 13:11 Christin8 Note Added: 58302
2020-06-16 13:11 Christin8 File Added: test.mov
2020-07-09 22:50 cdorin Assigned To cdorin =>
2020-07-09 22:50 cdorin Status assigned => new
2020-07-09 22:51 cdorin Note Added: 58883