Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MessagesStorage & RequestStorage #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/Application/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,17 @@ class Application extends Nette\Object
/** @var IRouter */
private $router;

/** @var IRequestStorage */
private $requestStorage;

public function __construct(IPresenterFactory $presenterFactory, IRouter $router, Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse)

public function __construct(IPresenterFactory $presenterFactory, IRouter $router, Nette\Http\IRequest $httpRequest, Nette\Http\IResponse $httpResponse, IRequestStorage $requestStorage)
{
$this->httpRequest = $httpRequest;
$this->httpResponse = $httpResponse;
$this->presenterFactory = $presenterFactory;
$this->router = $router;
$this->requestStorage = $requestStorage;
}


Expand Down Expand Up @@ -111,7 +115,7 @@ public function run()
*/
public function createInitialRequest()
{
$request = $this->router->match($this->httpRequest);
$request = $this->requestStorage->getRequest($this->httpRequest) ?: $this->router->match($this->httpRequest);

if (!$request instanceof Request) {
throw new BadRequestException('No route for HTTP request.');
Expand Down
65 changes: 65 additions & 0 deletions src/Application/IMessageStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

use Nette;


/**
* @author Filip Procházka
*/
interface IMessageStorage
{

const FLASH_KEY = '_fid';

/**
* @param string
*/
function setId($id);


/**
* @return string
*/
function getId();


/**
* Checks if a storage contains messages.
* @return bool
*/
function hasMessages();


/**
* Stores flash message for given component path and returns it's value object for further modifications.
* @param string
* @param string
* @param string
* @return object
*/
function addMessage($message, $type = 'info', $id = 'flash');


/**
* Returns array of stored flash messages for given component path.
* @param string
* @return object[]
*/
function getMessages($id = NULL);


/**
* Sets expiration for currently opened messages
* @param string
* @return void
*/
function setExpiration($expiration);

}
45 changes: 45 additions & 0 deletions src/Application/IRequestStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

use Nette;


/**
* Interface for storing and restoring requests.
*
* @author Martin Major
*/
interface IRequestStorage
{

/**
* Stores current request and returns key.
* @param Request application request
* @param string expiration time
* @return string key
*/
function storeRequest(Request $request, $expiration = '+ 10 minutes');


/**
* Restores request by its key.
* @param string key
* @return Responses\RedirectResponse|NULL
*/
function restoreRequest($key);


/**
* Returns stored request.
* @param \Nette\Http\IRequest
* @return Request|NULL
*/
function getRequest(Nette\Http\IRequest $httpRequest);

}
121 changes: 121 additions & 0 deletions src/Application/MessageStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

use Nette;


/**
* @author Filip Procházka
*/
class MessageStorage extends Nette\Object implements IMessageStorage
{
/** @var Nette\Http\Session */
private $session;

/** @var string */
private $id;



/**
* @param Nette\Http\Session
*/
public function __construct(Nette\Http\Session $session)
{
$this->session = $session;
}


/**
* @param string
*/
public function setId($id)
{
$this->id = $id;
}


/**
* @return string
*/
public function getId()
{
return $this->id;
}


/**
* Checks if a storage contains messages.
* @return bool
*/
public function hasMessages()
{
return $this->id && $this->session->hasSection('Nette.Application.Flash/' . $this->id);
}


/**
* Stores flash message for given component path and returns it's value object for further modifications.
* @param string
* @param string
* @param string
* @return object
*/
public function addMessage($message, $type = 'info', $id = 'flash')
{
$messages = $this->getSession()->$id;
$messages[] = $flash = (object) array(
'message' => $message,
'type' => $type,
);
$this->getSession()->$id = $messages;

return $flash;
}


/**
* Returns array of stored flash messages for given component path.
* @param string
* @return object[]
*/
public function getMessages($id = NULL)
{
return $this->getSession()->$id;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably here should by (array)

}


/**
* Returns session namespace provided to pass temporary data between redirects.
* @internal
* @return Nette\Http\SessionSection
*/
public function getSession()
{
if (!$this->id) {
$this->id = Nette\Utils\Random::generate(4);
}
return $this->session->getSection('Nette.Application.Flash/' . $this->id);
}



/**
* Sets expiration for currently opened messages
* @param string
* @return void
*/
public function setExpiration($expiration)
{
if ($this->hasMessages()) {
$this->getSession()->setExpiration($expiration);
}
}

}
133 changes: 133 additions & 0 deletions src/Application/RequestStorage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php

/**
* This file is part of the Nette Framework (http://nette.org)
* Copyright (c) 2004 David Grudl (http://davidgrudl.com)
*/

namespace Nette\Application;

use Nette;


/**
* Service for storing and restoring requests from session.
*
* @author Martin Major
*/
class RequestStorage extends Nette\Object implements IRequestStorage
{
/** URL parameter key */
const REQUEST_KEY = '_rid';

/** @var Nette\Http\IRequest */
private $httpRequest;

/** @var Nette\Http\Session */
private $session;

/** @var Nette\Security\User */
private $user;

/** @var Nette\Application\IMessageStorage */
private $flashStorage;



public function __construct(Nette\Http\IRequest $httpRequest, Nette\Http\Session $session, Nette\Security\User $user, IMessageStorage $flashStorage)
{
$this->httpRequest = $httpRequest;
$this->session = $session;
$this->user = $user;
$this->flashStorage = $flashStorage;
}


/**
* Stores current request to session.
* @param Request application request
* @param string expiration time
* @return string key
*/
public function storeRequest(Request $request, $expiration = '+ 10 minutes')
{
$session = $this->session->getSection('Nette.Application/requests');
do {
$key = Nette\Utils\Random::generate(5);
} while (isset($session[$key]));

$url = clone $this->httpRequest->getUrl();

$session[$key] = array(
'user' => $this->user->getId(),
'url' => $url->appendQuery(array(static::REQUEST_KEY => $key))->getAbsoluteUrl(),
'request' => $request,
);
$session->setExpiration($expiration, $key);
return $key;
}


/**
* Restores request from session.
* @param string key
* @return Responses\RedirectResponse|NULL
*/
public function restoreRequest($key)
{
list($request, $url) = $this->loadRequestFromSession($key);
if ($request === NULL) {
return NULL;
}

if ($this->flashStorage->hasMessages()) {
$url .= '&' . IMessageStorage::FLASH_KEY . '=' . $this->flashStorage->getId();
}

return new Responses\RedirectResponse($url);
}


/**
* Returns stored request.
* @param \Nette\Http\IRequest
* @return Request|NULL
*/
public function getRequest(Nette\Http\IRequest $httpRequest)
{
$key = $httpRequest->getQuery(static::REQUEST_KEY);

list($request, $url) = $this->loadRequestFromSession($key);
if ($request === NULL) {
return NULL;
}

$flash = $this->httpRequest->getUrl()->getQueryParameter(IMessageStorage::FLASH_KEY);
if ($flash !== NULL) {
$parameters = $request->getParameters();
$request->setParameters($parameters + array(IMessageStorage::FLASH_KEY => $flash));
}

return $request;
}


/**
* Loads request from session by its key.
* @param string key
* @return array(Request, string)
*/
protected function loadRequestFromSession($key)
{
$session = $this->session->getSection('Nette.Application/requests');
if (!isset($session[$key]) || ($session[$key]['user'] !== NULL && $session[$key]['user'] !== $this->user->getId())) {
return array(NULL, NULL);
}

$request = clone $session[$key]['request'];
$request->setFlag(Request::RESTORED, TRUE);

return array($request, $session[$key]['url']);
}

}