Redirect loop problem s Response.redirect(url)
- Durisvk
- Member | 31
Ahojte,
tak mám tu ďalší problém.
Vytvoril som si triedu StateSaver, ktorá uloží do cookies momentálnu hodnotu
$value pod názvom $name. Ak je však
v cookies už uložená $old_value pod názvom
$name, porovná $value a $old
value a ak sa líšia, zavolá preddefinovaný callback. Trieda
vyzerá takto:
<?php
<?php
namespace Datagrid;
use Nette\Http\Request;
use Nette\Http\Response;
use Nette\InvalidStateException;
use Nette\Utils\Callback;
use Nette\Utils\DateTime;
class StateSaver extends \Nette\Object {
/**
* Time length to store values
*/
const STORE_TIME_IN_MINUTES = 20;
/** @var Request */
protected $httpRequest;
/** @var Response */
protected $httpResponse;
/** @var string */
protected $name;
/** @var mixed */
protected $value;
/** @var callable */
protected $onchange;
/**
* @param Request $httpRequest
* @param Response $httpResponse
* @param string $name
* @param mixed $value
*/
public function __construct(Request $httpRequest, Response $httpResponse, $name, $value)
{
$this->httpRequest = $httpRequest;
$this->httpResponse = $httpResponse;
$this->name = $name;
$this->value = $value;
}
/**
* Stores the value into Cookies under the parameter name and for
* STORE_TIME_IN_MINUTES
*
* @param null|mixed $value
* @return $this
*/
public function store($value = NULL)
{
if(!$value) {
$value = $this->value;
}
if(!$value) {
throw new InvalidStateException('Value must be set!');
}
$value = serialize($value);
if($this->name && is_string($this->name)) {
$this->httpResponse->setCookie($this->name,
$value,
new DateTime('+ ' . self::STORE_TIME_IN_MINUTES . ' minute'));
} else {
throw new InvalidStateException(sprintf('Name must be string, %s given', gettype($this->name)));
}
return $this;
}
/**
* Gets the stored value from the Cookies
*
* @return mixed|null
*/
protected function restore()
{
$value = $this->httpRequest->getCookie($this->name);
if($value) {
return unserialize($value);
} else {
return NULL;
}
}
/**
* Sets callback which will be called in checkState() if the stored value
* is different than the current one.
* As arguments should receive old stored value and the current value.
*
* @param $callback
* @return $this
*/
public function onChange($callback)
{
Callback::check($callback);
$this->onchange = $callback;
return $this;
}
/**
* Checks if value in cookies is set(if not it sets the value)
* and whether the stored value is different than the current one.
*/
public function checkState()
{
$old_value = $this->restore();
if ($old_value) {
if($old_value != $this->value && $this->onchange) {
Callback::invokeArgs($this->onchange, array($old_value, $this->value));
}
} else {
$this->store();
}
}
}
?>
Potom túto triedu používam, na uloženie URL do cookies, a ak sa stránka
znovu načíta bez akýchkoľvek $_GET[] parametrov tak ju chcem redirectnúť
na tú, ktorá je uložená v cookies. Ajaxovo to funguje skvele, ale keď
refreshnem stránku, vytvorí sa mi redirect loop, pritom ten Response.redirect
sa už po druhý krát nemá volať. Tu je kód kde používam StateSaver:
(Tu je problém)
<?php
public function attached($presenter)
{
parent::attached($presenter);
if($this->persistent) {
/** @var \Nette\Http\Request $request */
$request = $presenter->context->getByType('Nette\Http\Request');
/** @var \Nette\Http\Response $response */
$response = $presenter->context->getByType('Nette\Http\Response');
$stateSaver = new StateSaver($request, $response, $this->getParent()->getName(), (string)$request->getUrl());
$stateSaver->onChange(function($old_value, $new_value) use($request, $response, $stateSaver) {
$url = new Url($new_value);
if(!count($url->getQueryParameters())) {
$response->redirect($old_value);
} else {
$stateSaver->store($new_value);
}
});
ob_start();
$stateSaver->checkState();
}
}
?>
- amik
- Member | 118
Hi,
we'd like to help you, but are you sure all this code is relevant to your
problem?
It seems to me that the only place where you call redirect is the condition
if(!count($url->getQueryParameters())) { ...
, which probably
means that query parameters of the created URL are empty.
Please try to confirm my idea and find out more what is actually happening, not
just “it ends with loop somewhere”.
Also, please speak english there or use czech version of the forum.