Updated Symfony HttpFoundation to 2.1.6.
This commit is contained in:
parent
f754e1fa55
commit
cb567c5e4d
|
@ -0,0 +1,75 @@
|
||||||
|
CHANGELOG
|
||||||
|
=========
|
||||||
|
|
||||||
|
2.1.0
|
||||||
|
-----
|
||||||
|
|
||||||
|
* added Request::getSchemeAndHttpHost() and Request::getUserInfo()
|
||||||
|
* added a fluent interface to the Response class
|
||||||
|
* added Request::isProxyTrusted()
|
||||||
|
* added JsonResponse
|
||||||
|
* added a getTargetUrl method to RedirectResponse
|
||||||
|
* added support for streamed responses
|
||||||
|
* made Response::prepare() method the place to enforce HTTP specification
|
||||||
|
* [BC BREAK] moved management of the locale from the Session class to the Request class
|
||||||
|
* added a generic access to the PHP built-in filter mechanism: ParameterBag::filter()
|
||||||
|
* made FileBinaryMimeTypeGuesser command configurable
|
||||||
|
* added Request::getUser() and Request::getPassword()
|
||||||
|
* added support for the PATCH method in Request
|
||||||
|
* removed the ContentTypeMimeTypeGuesser class as it is deprecated and never used on PHP 5.3
|
||||||
|
* added ResponseHeaderBag::makeDisposition() (implements RFC 6266)
|
||||||
|
* made mimetype to extension conversion configurable
|
||||||
|
* [BC BREAK] Moved all session related classes and interfaces into own namespace, as
|
||||||
|
`Symfony\Component\HttpFoundation\Session` and renamed classes accordingly.
|
||||||
|
Session handlers are located in the subnamespace `Symfony\Component\HttpFoundation\Session\Handler`.
|
||||||
|
* SessionHandlers must implement `\SessionHandlerInterface` or extend from the
|
||||||
|
`Symfony\Component\HttpFoundation\Storage\Handler\NativeSessionHandler` base class.
|
||||||
|
* Added internal storage driver proxy mechanism for forward compatibility with
|
||||||
|
PHP 5.4 `\SessionHandler` class.
|
||||||
|
* Added session handlers for custom Memcache, Memcached and Null session save handlers.
|
||||||
|
* [BC BREAK] Removed `NativeSessionStorage` and replaced with `NativeFileSessionHandler`.
|
||||||
|
* [BC BREAK] `SessionStorageInterface` methods removed: `write()`, `read()` and
|
||||||
|
`remove()`. Added `getBag()`, `registerBag()`. The `NativeSessionStorage` class
|
||||||
|
is a mediator for the session storage internals including the session handlers
|
||||||
|
which do the real work of participating in the internal PHP session workflow.
|
||||||
|
* [BC BREAK] Introduced mock implementations of `SessionStorage` to enable unit
|
||||||
|
and functional testing without starting real PHP sessions. Removed
|
||||||
|
`ArraySessionStorage`, and replaced with `MockArraySessionStorage` for unit
|
||||||
|
tests; removed `FilesystemSessionStorage`, and replaced with`MockFileSessionStorage`
|
||||||
|
for functional tests. These do not interact with global session ini
|
||||||
|
configuration values, session functions or `$_SESSION` superglobal. This means
|
||||||
|
they can be configured directly allowing multiple instances to work without
|
||||||
|
conflicting in the same PHP process.
|
||||||
|
* [BC BREAK] Removed the `close()` method from the `Session` class, as this is
|
||||||
|
now redundant.
|
||||||
|
* Deprecated the following methods from the Session class: `setFlash()`, `setFlashes()`
|
||||||
|
`getFlash()`, `hasFlash()`, and `removeFlash()`. Use `getFlashBag()` instead
|
||||||
|
which returns a `FlashBagInterface`.
|
||||||
|
* `Session->clear()` now only clears session attributes as before it cleared
|
||||||
|
flash messages and attributes. `Session->getFlashBag()->all()` clears flashes now.
|
||||||
|
* Session data is now managed by `SessionBagInterface` to better encapsulate
|
||||||
|
session data.
|
||||||
|
* Refactored session attribute and flash messages system to their own
|
||||||
|
`SessionBagInterface` implementations.
|
||||||
|
* Added `FlashBag`. Flashes expire when retrieved by `get()` or `all()`. This
|
||||||
|
implementation is ESI compatible.
|
||||||
|
* Added `AutoExpireFlashBag` (default) to replicate Symfony 2.0.x auto expire
|
||||||
|
behaviour of messages auto expiring after one page page load. Messages must
|
||||||
|
be retrieved by `get()` or `all()`.
|
||||||
|
* Added `Symfony\Component\HttpFoundation\Attribute\AttributeBag` to replicate
|
||||||
|
attributes storage behaviour from 2.0.x (default).
|
||||||
|
* Added `Symfony\Component\HttpFoundation\Attribute\NamespacedAttributeBag` for
|
||||||
|
namespace session attributes.
|
||||||
|
* Flash API can stores messages in an array so there may be multiple messages
|
||||||
|
per flash type. The old `Session` class API remains without BC break as it
|
||||||
|
will allow single messages as before.
|
||||||
|
* Added basic session meta-data to the session to record session create time,
|
||||||
|
last updated time, and the lifetime of the session cookie that was provided
|
||||||
|
to the client.
|
||||||
|
* Request::getClientIp() method doesn't take a parameter anymore but bases
|
||||||
|
itself on the trustProxy parameter.
|
||||||
|
* Added isMethod() to Request object.
|
||||||
|
* [BC BREAK] The methods `getPathInfo()`, `getBaseUrl()` and `getBasePath()` of
|
||||||
|
a `Request` now all return a raw value (vs a urldecoded value before). Any call
|
||||||
|
to one of these methods must be checked and wrapped in a `rawurldecode()` if
|
||||||
|
needed.
|
|
@ -72,6 +72,11 @@ public function __construct($name, $value = null, $expire = 0, $path = '/', $dom
|
||||||
$this->httpOnly = (Boolean) $httpOnly;
|
$this->httpOnly = (Boolean) $httpOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the cookie as a string.
|
||||||
|
*
|
||||||
|
* @return string The cookie
|
||||||
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
$str = urlencode($this->getName()).'=';
|
$str = urlencode($this->getName()).'=';
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* Thrown when the access on a file was denied.
|
* Thrown when the access on a file was denied.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class AccessDeniedException extends FileException
|
class AccessDeniedException extends FileException
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* Thrown when an error occurred in the component File
|
* Thrown when an error occurred in the component File
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class FileException extends \RuntimeException
|
class FileException extends \RuntimeException
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* Thrown when a file was not found
|
* Thrown when a file was not found
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class FileNotFoundException extends FileException
|
class FileNotFoundException extends FileException
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* Thrown when an error occurred during file upload
|
* Thrown when an error occurred during file upload
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class UploadException extends FileException
|
class UploadException extends FileException
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
/**
|
/**
|
||||||
* A file in the file system.
|
* A file in the file system.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -106,6 +106,20 @@ public function getExtension()
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function move($directory, $name = null)
|
public function move($directory, $name = null)
|
||||||
|
{
|
||||||
|
$target = $this->getTargetFile($directory, $name);
|
||||||
|
|
||||||
|
if (!@rename($this->getPathname(), $target)) {
|
||||||
|
$error = error_get_last();
|
||||||
|
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
@chmod($target, 0666 & ~umask());
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTargetFile($directory, $name = null)
|
||||||
{
|
{
|
||||||
if (!is_dir($directory)) {
|
if (!is_dir($directory)) {
|
||||||
if (false === @mkdir($directory, 0777, true)) {
|
if (false === @mkdir($directory, 0777, true)) {
|
||||||
|
@ -115,15 +129,24 @@ public function move($directory, $name = null)
|
||||||
throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
|
throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
|
||||||
}
|
}
|
||||||
|
|
||||||
$target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : basename($name));
|
$target = $directory.DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name));
|
||||||
|
|
||||||
if (!@rename($this->getPathname(), $target)) {
|
return new File($target, false);
|
||||||
$error = error_get_last();
|
|
||||||
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chmod($target, 0666);
|
/**
|
||||||
|
* Returns locale independent base name of the given path.
|
||||||
|
*
|
||||||
|
* @param string $name The new file name
|
||||||
|
*
|
||||||
|
* @return string containing
|
||||||
|
*/
|
||||||
|
protected function getName($name)
|
||||||
|
{
|
||||||
|
$originalName = str_replace('\\', '/', $name);
|
||||||
|
$pos = strrpos($originalName, '/');
|
||||||
|
$originalName = false === $pos ? $originalName : substr($originalName, $pos + 1);
|
||||||
|
|
||||||
return new File($target);
|
return $originalName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,14 @@ class ExtensionGuesser implements ExtensionGuesserInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The singleton instance
|
* The singleton instance
|
||||||
|
*
|
||||||
* @var ExtensionGuesser
|
* @var ExtensionGuesser
|
||||||
*/
|
*/
|
||||||
static private $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All registered ExtensionGuesserInterface instances
|
* All registered ExtensionGuesserInterface instances
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guessers = array();
|
protected $guessers = array();
|
||||||
|
@ -45,7 +47,7 @@ class ExtensionGuesser implements ExtensionGuesserInterface
|
||||||
*
|
*
|
||||||
* @return ExtensionGuesser
|
* @return ExtensionGuesser
|
||||||
*/
|
*/
|
||||||
static public function getInstance()
|
public static function getInstance()
|
||||||
{
|
{
|
||||||
if (null === self::$instance) {
|
if (null === self::$instance) {
|
||||||
self::$instance = new self();
|
self::$instance = new self();
|
||||||
|
|
|
@ -22,5 +22,5 @@ interface ExtensionGuesserInterface
|
||||||
* @param string $mimeType The mime type
|
* @param string $mimeType The mime type
|
||||||
* @return string The guessed extension or NULL, if none could be guessed
|
* @return string The guessed extension or NULL, if none could be guessed
|
||||||
*/
|
*/
|
||||||
function guess($mimeType);
|
public function guess($mimeType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
/**
|
/**
|
||||||
* Guesses the mime type with the binary "file" (only available on *nix)
|
* Guesses the mime type with the binary "file" (only available on *nix)
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||||
{
|
{
|
||||||
|
@ -43,15 +43,13 @@ public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
|
||||||
*
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
static public function isSupported()
|
public static function isSupported()
|
||||||
{
|
{
|
||||||
return !defined('PHP_WINDOWS_VERSION_BUILD');
|
return !defined('PHP_WINDOWS_VERSION_BUILD');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guesses the mime type of the file with the given path
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @see MimeTypeGuesserInterface::guess()
|
|
||||||
*/
|
*/
|
||||||
public function guess($path)
|
public function guess($path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
/**
|
/**
|
||||||
* Guesses the mime type using the PECL extension FileInfo
|
* Guesses the mime type using the PECL extension FileInfo
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
|
class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||||
{
|
{
|
||||||
|
@ -26,15 +26,13 @@ class FileinfoMimeTypeGuesser implements MimeTypeGuesserInterface
|
||||||
*
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
static public function isSupported()
|
public static function isSupported()
|
||||||
{
|
{
|
||||||
return function_exists('finfo_open');
|
return function_exists('finfo_open');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guesses the mime type of the file with the given path
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @see MimeTypeGuesserInterface::guess()
|
|
||||||
*/
|
*/
|
||||||
public function guess($path)
|
public function guess($path)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\File\Mimetype;
|
namespace Symfony\Component\HttpFoundation\File\MimeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a best-guess mapping of mime type to file extension.
|
* Provides a best-guess mapping of mime type to file extension.
|
||||||
|
@ -542,6 +542,7 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
|
||||||
'application/x-pkcs7-certificates' => 'p7b',
|
'application/x-pkcs7-certificates' => 'p7b',
|
||||||
'application/x-pkcs7-certreqresp' => 'p7r',
|
'application/x-pkcs7-certreqresp' => 'p7r',
|
||||||
'application/x-rar-compressed' => 'rar',
|
'application/x-rar-compressed' => 'rar',
|
||||||
|
'application/x-rar' => 'rar',
|
||||||
'application/x-sh' => 'sh',
|
'application/x-sh' => 'sh',
|
||||||
'application/x-shar' => 'shar',
|
'application/x-shar' => 'shar',
|
||||||
'application/x-shockwave-flash' => 'swf',
|
'application/x-shockwave-flash' => 'swf',
|
||||||
|
@ -730,11 +731,7 @@ class MimeTypeExtensionGuesser implements ExtensionGuesserInterface
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the extension based on the mime type.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* If the mime type is unknown, returns null.
|
|
||||||
*
|
|
||||||
* @return string|null The guessed extension or null if it cannot be guessed
|
|
||||||
*/
|
*/
|
||||||
public function guess($mimeType)
|
public function guess($mimeType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\File\MimeType;
|
namespace Symfony\Component\HttpFoundation\File\MimeType;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||||
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||||
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
||||||
|
|
||||||
|
@ -28,18 +29,20 @@
|
||||||
*
|
*
|
||||||
* The last registered guesser is preferred over previously registered ones.
|
* The last registered guesser is preferred over previously registered ones.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class MimeTypeGuesser implements MimeTypeGuesserInterface
|
class MimeTypeGuesser implements MimeTypeGuesserInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The singleton instance
|
* The singleton instance
|
||||||
|
*
|
||||||
* @var MimeTypeGuesser
|
* @var MimeTypeGuesser
|
||||||
*/
|
*/
|
||||||
static private $instance = null;
|
private static $instance = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All registered MimeTypeGuesserInterface instances
|
* All registered MimeTypeGuesserInterface instances
|
||||||
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $guessers = array();
|
protected $guessers = array();
|
||||||
|
@ -49,7 +52,7 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface
|
||||||
*
|
*
|
||||||
* @return MimeTypeGuesser
|
* @return MimeTypeGuesser
|
||||||
*/
|
*/
|
||||||
static public function getInstance()
|
public static function getInstance()
|
||||||
{
|
{
|
||||||
if (null === self::$instance) {
|
if (null === self::$instance) {
|
||||||
self::$instance = new self();
|
self::$instance = new self();
|
||||||
|
|
|
@ -11,10 +11,13 @@
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\File\MimeType;
|
namespace Symfony\Component\HttpFoundation\File\MimeType;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
|
||||||
|
use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guesses the mime type of a file
|
* Guesses the mime type of a file
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
interface MimeTypeGuesserInterface
|
interface MimeTypeGuesserInterface
|
||||||
{
|
{
|
||||||
|
@ -28,5 +31,5 @@ interface MimeTypeGuesserInterface
|
||||||
* @throws FileNotFoundException If the file does not exist
|
* @throws FileNotFoundException If the file does not exist
|
||||||
* @throws AccessDeniedException If the file could not be read
|
* @throws AccessDeniedException If the file could not be read
|
||||||
*/
|
*/
|
||||||
function guess($path);
|
public function guess($path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
/**
|
/**
|
||||||
* A file uploaded through a form.
|
* A file uploaded through a form.
|
||||||
*
|
*
|
||||||
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
* @author Florian Eckerstorfer <florian@eckerstorfer.org>
|
* @author Florian Eckerstorfer <florian@eckerstorfer.org>
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*
|
*
|
||||||
|
@ -94,7 +94,7 @@ public function __construct($path, $originalName, $mimeType = null, $size = null
|
||||||
throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path')));
|
throw new FileException(sprintf('Unable to create UploadedFile because "file_uploads" is disabled in your php.ini file (%s)', get_cfg_var('cfg_file_path')));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->originalName = basename($originalName);
|
$this->originalName = $this->getName($originalName);
|
||||||
$this->mimeType = $mimeType ?: 'application/octet-stream';
|
$this->mimeType = $mimeType ?: 'application/octet-stream';
|
||||||
$this->size = $size;
|
$this->size = $size;
|
||||||
$this->error = $error ?: UPLOAD_ERR_OK;
|
$this->error = $error ?: UPLOAD_ERR_OK;
|
||||||
|
@ -189,8 +189,21 @@ public function isValid()
|
||||||
*/
|
*/
|
||||||
public function move($directory, $name = null)
|
public function move($directory, $name = null)
|
||||||
{
|
{
|
||||||
if ($this->isValid() && ($this->test || is_uploaded_file($this->getPathname()))) {
|
if ($this->isValid()) {
|
||||||
|
if ($this->test) {
|
||||||
return parent::move($directory, $name);
|
return parent::move($directory, $name);
|
||||||
|
} elseif (is_uploaded_file($this->getPathname())) {
|
||||||
|
$target = $this->getTargetFile($directory, $name);
|
||||||
|
|
||||||
|
if (!@move_uploaded_file($this->getPathname(), $target)) {
|
||||||
|
$error = error_get_last();
|
||||||
|
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error['message'])));
|
||||||
|
}
|
||||||
|
|
||||||
|
@chmod($target, 0666 & ~umask());
|
||||||
|
|
||||||
|
return $target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname()));
|
throw new FileException(sprintf('The file "%s" has not been uploaded via Http', $this->getPathname()));
|
||||||
|
@ -199,9 +212,9 @@ public function move($directory, $name = null)
|
||||||
/**
|
/**
|
||||||
* Returns the maximum size of an uploaded file as configured in php.ini
|
* Returns the maximum size of an uploaded file as configured in php.ini
|
||||||
*
|
*
|
||||||
* @return type The maximum size of an uploaded file in bytes
|
* @return int The maximum size of an uploaded file in bytes
|
||||||
*/
|
*/
|
||||||
static public function getMaxFilesize()
|
public static function getMaxFilesize()
|
||||||
{
|
{
|
||||||
$max = trim(ini_get('upload_max_filesize'));
|
$max = trim(ini_get('upload_max_filesize'));
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
class FileBag extends ParameterBag
|
class FileBag extends ParameterBag
|
||||||
{
|
{
|
||||||
static private $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
|
private static $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -38,8 +38,7 @@ public function __construct(array $parameters = array())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPdoc)
|
* {@inheritdoc}
|
||||||
* @see Symfony\Component\HttpFoundation\ParameterBag::replace()
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -50,23 +49,21 @@ public function replace(array $files = array())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPdoc)
|
* {@inheritdoc}
|
||||||
* @see Symfony\Component\HttpFoundation\ParameterBag::set()
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function set($key, $value)
|
public function set($key, $value)
|
||||||
{
|
{
|
||||||
if (is_array($value) || $value instanceof UploadedFile) {
|
if (!is_array($value) && !$value instanceof UploadedFile) {
|
||||||
parent::set($key, $this->convertFileInformation($value));
|
|
||||||
} else {
|
|
||||||
throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
|
throw new \InvalidArgumentException('An uploaded file must be an array or an instance of UploadedFile.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent::set($key, $this->convertFileInformation($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPdoc)
|
* {@inheritdoc}
|
||||||
* @see Symfony\Component\HttpFoundation\ParameterBag::add()
|
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class HeaderBag
|
class HeaderBag implements \IteratorAggregate, \Countable
|
||||||
{
|
{
|
||||||
protected $headers;
|
protected $headers;
|
||||||
protected $cacheControl;
|
protected $cacheControl;
|
||||||
|
@ -50,16 +50,13 @@ public function __toString()
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$beautifier = function ($name) {
|
|
||||||
return preg_replace_callback('/\-(.)/', function ($match) { return '-'.strtoupper($match[1]); }, ucfirst($name));
|
|
||||||
};
|
|
||||||
|
|
||||||
$max = max(array_map('strlen', array_keys($this->headers))) + 1;
|
$max = max(array_map('strlen', array_keys($this->headers))) + 1;
|
||||||
$content = '';
|
$content = '';
|
||||||
ksort($this->headers);
|
ksort($this->headers);
|
||||||
foreach ($this->headers as $name => $values) {
|
foreach ($this->headers as $name => $values) {
|
||||||
|
$name = implode('-', array_map('ucfirst', explode('-', $name)));
|
||||||
foreach ($values as $value) {
|
foreach ($values as $value) {
|
||||||
$content .= sprintf("%-{$max}s %s\r\n", $beautifier($name).':', $value);
|
$content .= sprintf("%-{$max}s %s\r\n", $name.':', $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +157,7 @@ public function set($key, $values, $replace = true)
|
||||||
{
|
{
|
||||||
$key = strtr(strtolower($key), '_', '-');
|
$key = strtr(strtolower($key), '_', '-');
|
||||||
|
|
||||||
$values = (array) $values;
|
$values = array_values((array) $values);
|
||||||
|
|
||||||
if (true === $replace || !isset($this->headers[$key])) {
|
if (true === $replace || !isset($this->headers[$key])) {
|
||||||
$this->headers[$key] = $values;
|
$this->headers[$key] = $values;
|
||||||
|
@ -226,7 +223,9 @@ public function remove($key)
|
||||||
* @param string $key The parameter key
|
* @param string $key The parameter key
|
||||||
* @param \DateTime $default The default value
|
* @param \DateTime $default The default value
|
||||||
*
|
*
|
||||||
* @return \DateTime The filtered value
|
* @return null|\DateTime The filtered value
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When the HTTP header is not parseable
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -267,6 +266,26 @@ public function removeCacheControlDirective($key)
|
||||||
$this->set('Cache-Control', $this->getCacheControlHeader());
|
$this->set('Cache-Control', $this->getCacheControlHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator for headers.
|
||||||
|
*
|
||||||
|
* @return \ArrayIterator An \ArrayIterator instance
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of headers.
|
||||||
|
*
|
||||||
|
* @return int The number of headers
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->headers);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getCacheControlHeader()
|
protected function getCacheControlHeader()
|
||||||
{
|
{
|
||||||
$parts = array();
|
$parts = array();
|
||||||
|
@ -298,7 +317,7 @@ protected function parseCacheControl($header)
|
||||||
$cacheControl = array();
|
$cacheControl = array();
|
||||||
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
preg_match_all('#([a-zA-Z][a-zA-Z_-]*)\s*(?:=(?:"([^"]*)"|([^ \t",;]*)))?#', $header, $matches, PREG_SET_ORDER);
|
||||||
foreach ($matches as $match) {
|
foreach ($matches as $match) {
|
||||||
$cacheControl[strtolower($match[1])] = isset($match[2]) && $match[2] ? $match[2] : (isset($match[3]) ? $match[3] : true);
|
$cacheControl[strtolower($match[1])] = isset($match[3]) ? $match[3] : (isset($match[2]) ? $match[2] : true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $cacheControl;
|
return $cacheControl;
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
*/
|
*/
|
||||||
class JsonResponse extends Response
|
class JsonResponse extends Response
|
||||||
{
|
{
|
||||||
|
protected $data;
|
||||||
|
protected $callback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
@ -27,23 +30,84 @@ class JsonResponse extends Response
|
||||||
*/
|
*/
|
||||||
public function __construct($data = array(), $status = 200, $headers = array())
|
public function __construct($data = array(), $status = 200, $headers = array())
|
||||||
{
|
{
|
||||||
// root should be JSON object, not array
|
parent::__construct('', $status, $headers);
|
||||||
if (is_array($data) && 0 === count($data)) {
|
|
||||||
$data = new \ArrayObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct(
|
$this->setData($data);
|
||||||
json_encode($data),
|
|
||||||
$status,
|
|
||||||
array_merge(array('Content-Type' => 'application/json'), $headers)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
static public function create($data = array(), $status = 200, $headers = array())
|
public static function create($data = array(), $status = 200, $headers = array())
|
||||||
{
|
{
|
||||||
return new static($data, $status, $headers);
|
return new static($data, $status, $headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the JSONP callback.
|
||||||
|
*
|
||||||
|
* @param string $callback
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function setCallback($callback = null)
|
||||||
|
{
|
||||||
|
if (null !== $callback) {
|
||||||
|
// taken from http://www.geekality.net/2011/08/03/valid-javascript-identifier/
|
||||||
|
$pattern = '/^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]*+$/u';
|
||||||
|
$parts = explode('.', $callback);
|
||||||
|
foreach ($parts as $part) {
|
||||||
|
if (!preg_match($pattern, $part)) {
|
||||||
|
throw new \InvalidArgumentException('The callback name is not valid.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->callback = $callback;
|
||||||
|
|
||||||
|
return $this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the data to be sent as json.
|
||||||
|
*
|
||||||
|
* @param mixed $data
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
public function setData($data = array())
|
||||||
|
{
|
||||||
|
// root should be JSON object, not array
|
||||||
|
if (is_array($data) && 0 === count($data)) {
|
||||||
|
$data = new \ArrayObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encode <, >, ', &, and " for RFC4627-compliant JSON, which may also be embedded into HTML.
|
||||||
|
$this->data = json_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);
|
||||||
|
|
||||||
|
return $this->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the content and headers according to the json data and callback.
|
||||||
|
*
|
||||||
|
* @return JsonResponse
|
||||||
|
*/
|
||||||
|
protected function update()
|
||||||
|
{
|
||||||
|
if (null !== $this->callback) {
|
||||||
|
// Not using application/javascript for compatibility reasons with older browsers.
|
||||||
|
$this->headers->set('Content-Type', 'text/javascript');
|
||||||
|
|
||||||
|
return $this->setContent(sprintf('%s(%s);', $this->callback, $this->data));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only set the header when there is none or when it equals 'text/javascript' (from a previous update with callback)
|
||||||
|
// in order to not overwrite a custom definition.
|
||||||
|
if (!$this->headers->has('Content-Type') || 'text/javascript' === $this->headers->get('Content-Type')) {
|
||||||
|
$this->headers->set('Content-Type', 'application/json');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->setContent($this->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class ParameterBag
|
class ParameterBag implements \IteratorAggregate, \Countable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Parameter storage.
|
* Parameter storage.
|
||||||
|
@ -94,6 +94,8 @@ public function add(array $parameters = array())
|
||||||
* @param mixed $default The default value if the parameter key does not exist
|
* @param mixed $default The default value if the parameter key does not exist
|
||||||
* @param boolean $deep If true, a path like foo[bar] will find deeper items
|
* @param boolean $deep If true, a path like foo[bar] will find deeper items
|
||||||
*
|
*
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function get($path, $default = null, $deep = false)
|
public function get($path, $default = null, $deep = false)
|
||||||
|
@ -109,7 +111,7 @@ public function get($path, $default = null, $deep = false)
|
||||||
|
|
||||||
$value = $this->parameters[$root];
|
$value = $this->parameters[$root];
|
||||||
$currentKey = null;
|
$currentKey = null;
|
||||||
for ($i=$pos,$c=strlen($path); $i<$c; $i++) {
|
for ($i = $pos, $c = strlen($path); $i < $c; $i++) {
|
||||||
$char = $path[$i];
|
$char = $path[$i];
|
||||||
|
|
||||||
if ('[' === $char) {
|
if ('[' === $char) {
|
||||||
|
@ -240,7 +242,7 @@ public function getDigits($key, $default = '', $deep = false)
|
||||||
* @param mixed $default The default value if the parameter key does not exist
|
* @param mixed $default The default value if the parameter key does not exist
|
||||||
* @param boolean $deep If true, a path like foo[bar] will find deeper items
|
* @param boolean $deep If true, a path like foo[bar] will find deeper items
|
||||||
*
|
*
|
||||||
* @return string The filtered value
|
* @return integer The filtered value
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -278,4 +280,24 @@ public function filter($key, $default = null, $deep = false, $filter=FILTER_DEFA
|
||||||
|
|
||||||
return filter_var($value, $filter, $options);
|
return filter_var($value, $filter, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator for parameters.
|
||||||
|
*
|
||||||
|
* @return \ArrayIterator An \ArrayIterator instance
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of parameters.
|
||||||
|
*
|
||||||
|
* @return int The number of parameters
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,9 @@
|
||||||
$loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
|
$loader->registerPrefixFallback(__DIR__.'/../vendor/symfony/src/Symfony/Component/HttpFoundation/Resources/stubs');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Resources
|
Resources
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Unit tests:
|
You can run the unit tests with the following command:
|
||||||
|
|
||||||
https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/HttpFoundation
|
phpunit
|
||||||
|
|
|
@ -39,24 +39,9 @@ public function __construct($url, $status = 302, $headers = array())
|
||||||
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->targetUrl = $url;
|
parent::__construct('', $status, $headers);
|
||||||
|
|
||||||
parent::__construct(
|
$this->setTargetUrl($url);
|
||||||
sprintf('<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
||||||
<meta http-equiv="refresh" content="1;url=%1$s" />
|
|
||||||
|
|
||||||
<title>Redirecting to %1$s</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Redirecting to <a href="%1$s">%1$s</a>.
|
|
||||||
</body>
|
|
||||||
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')),
|
|
||||||
$status,
|
|
||||||
array_merge($headers, array('Location' => $url))
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!$this->isRedirect()) {
|
if (!$this->isRedirect()) {
|
||||||
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
|
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
|
||||||
|
@ -66,7 +51,7 @@ public function __construct($url, $status = 302, $headers = array())
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
static public function create($url = '', $status = 302, $headers = array())
|
public static function create($url = '', $status = 302, $headers = array())
|
||||||
{
|
{
|
||||||
return new static($url, $status, $headers);
|
return new static($url, $status, $headers);
|
||||||
}
|
}
|
||||||
|
@ -80,4 +65,38 @@ public function getTargetUrl()
|
||||||
{
|
{
|
||||||
return $this->targetUrl;
|
return $this->targetUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the redirect target of this response.
|
||||||
|
*
|
||||||
|
* @param string $url The URL to redirect to
|
||||||
|
*
|
||||||
|
* @return RedirectResponse The current response.
|
||||||
|
*/
|
||||||
|
public function setTargetUrl($url)
|
||||||
|
{
|
||||||
|
if (empty($url)) {
|
||||||
|
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->targetUrl = $url;
|
||||||
|
|
||||||
|
$this->setContent(
|
||||||
|
sprintf('<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta http-equiv="refresh" content="1;url=%1$s" />
|
||||||
|
|
||||||
|
<title>Redirecting to %1$s</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Redirecting to <a href="%1$s">%1$s</a>.
|
||||||
|
</body>
|
||||||
|
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')));
|
||||||
|
|
||||||
|
$this->headers->set('Location', $url);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,13 +16,42 @@
|
||||||
/**
|
/**
|
||||||
* Request represents an HTTP request.
|
* Request represents an HTTP request.
|
||||||
*
|
*
|
||||||
|
* The methods dealing with URL accept / return a raw path (% encoded):
|
||||||
|
* * getBasePath
|
||||||
|
* * getBaseUrl
|
||||||
|
* * getPathInfo
|
||||||
|
* * getRequestUri
|
||||||
|
* * getUri
|
||||||
|
* * getUriForPath
|
||||||
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class Request
|
class Request
|
||||||
{
|
{
|
||||||
static protected $trustProxy = false;
|
const HEADER_CLIENT_IP = 'client_ip';
|
||||||
|
const HEADER_CLIENT_HOST = 'client_host';
|
||||||
|
const HEADER_CLIENT_PROTO = 'client_proto';
|
||||||
|
const HEADER_CLIENT_PORT = 'client_port';
|
||||||
|
|
||||||
|
protected static $trustProxy = false;
|
||||||
|
|
||||||
|
protected static $trustedProxies = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Names for headers that can be trusted when
|
||||||
|
* using trusted proxies.
|
||||||
|
*
|
||||||
|
* The default names are non-standard, but widely used
|
||||||
|
* by popular reverse proxies (like Apache mod_proxy or Amazon EC2).
|
||||||
|
*/
|
||||||
|
protected static $trustedHeaders = array(
|
||||||
|
self::HEADER_CLIENT_IP => 'X_FORWARDED_FOR',
|
||||||
|
self::HEADER_CLIENT_HOST => 'X_FORWARDED_HOST',
|
||||||
|
self::HEADER_CLIENT_PROTO => 'X_FORWARDED_PROTO',
|
||||||
|
self::HEADER_CLIENT_PORT => 'X_FORWARDED_PORT',
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \Symfony\Component\HttpFoundation\ParameterBag
|
* @var \Symfony\Component\HttpFoundation\ParameterBag
|
||||||
|
@ -79,17 +108,17 @@ class Request
|
||||||
protected $content;
|
protected $content;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $languages;
|
protected $languages;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $charsets;
|
protected $charsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $acceptableContentTypes;
|
protected $acceptableContentTypes;
|
||||||
|
|
||||||
|
@ -139,9 +168,9 @@ class Request
|
||||||
protected $defaultLocale = 'en';
|
protected $defaultLocale = 'en';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var array
|
||||||
*/
|
*/
|
||||||
static protected $formats;
|
protected static $formats;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
|
@ -205,11 +234,11 @@ public function initialize(array $query = array(), array $request = array(), arr
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
static public function createFromGlobals()
|
public static function createFromGlobals()
|
||||||
{
|
{
|
||||||
$request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
|
$request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);
|
||||||
|
|
||||||
if (0 === strpos($request->server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
|
if (0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
|
||||||
&& in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
|
&& in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE', 'PATCH'))
|
||||||
) {
|
) {
|
||||||
parse_str($request->getContent(), $data);
|
parse_str($request->getContent(), $data);
|
||||||
|
@ -224,7 +253,7 @@ static public function createFromGlobals()
|
||||||
*
|
*
|
||||||
* @param string $uri The URI
|
* @param string $uri The URI
|
||||||
* @param string $method The HTTP method
|
* @param string $method The HTTP method
|
||||||
* @param array $parameters The request (GET) or query (POST) parameters
|
* @param array $parameters The query (GET) or request (POST) parameters
|
||||||
* @param array $cookies The request cookies ($_COOKIE)
|
* @param array $cookies The request cookies ($_COOKIE)
|
||||||
* @param array $files The request files ($_FILES)
|
* @param array $files The request files ($_FILES)
|
||||||
* @param array $server The server parameters ($_SERVER)
|
* @param array $server The server parameters ($_SERVER)
|
||||||
|
@ -234,7 +263,7 @@ static public function createFromGlobals()
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
static public function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
|
public static function create($uri, $method = 'GET', $parameters = array(), $cookies = array(), $files = array(), $server = array(), $content = null)
|
||||||
{
|
{
|
||||||
$defaults = array(
|
$defaults = array(
|
||||||
'SERVER_NAME' => 'localhost',
|
'SERVER_NAME' => 'localhost',
|
||||||
|
@ -278,7 +307,7 @@ static public function create($uri, $method = 'GET', $parameters = array(), $coo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isset($components['path'])) {
|
if (!isset($components['path'])) {
|
||||||
$components['path'] = '';
|
$components['path'] = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (strtoupper($method)) {
|
switch (strtoupper($method)) {
|
||||||
|
@ -297,15 +326,12 @@ static public function create($uri, $method = 'GET', $parameters = array(), $coo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($components['query'])) {
|
if (isset($components['query'])) {
|
||||||
$queryString = html_entity_decode($components['query']);
|
parse_str(html_entity_decode($components['query']), $qs);
|
||||||
parse_str($queryString, $qs);
|
|
||||||
if (is_array($qs)) {
|
|
||||||
$query = array_replace($qs, $query);
|
$query = array_replace($qs, $query);
|
||||||
}
|
}
|
||||||
}
|
$queryString = http_build_query($query, '', '&');
|
||||||
$queryString = http_build_query($query);
|
|
||||||
|
|
||||||
$uri = $components['path'].($queryString ? '?'.$queryString : '');
|
$uri = $components['path'].('' !== $queryString ? '?'.$queryString : '');
|
||||||
|
|
||||||
$server = array_replace($defaults, $server, array(
|
$server = array_replace($defaults, $server, array(
|
||||||
'REQUEST_METHOD' => strtoupper($method),
|
'REQUEST_METHOD' => strtoupper($method),
|
||||||
|
@ -327,6 +353,8 @@ static public function create($uri, $method = 'GET', $parameters = array(), $coo
|
||||||
* @param array $files The FILES parameters
|
* @param array $files The FILES parameters
|
||||||
* @param array $server The SERVER parameters
|
* @param array $server The SERVER parameters
|
||||||
*
|
*
|
||||||
|
* @return Request The duplicated request
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
|
public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null)
|
||||||
|
@ -397,7 +425,8 @@ public function __toString()
|
||||||
/**
|
/**
|
||||||
* Overrides the PHP global variables according to this request instance.
|
* Overrides the PHP global variables according to this request instance.
|
||||||
*
|
*
|
||||||
* It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE, and $_FILES.
|
* It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
|
||||||
|
* $_FILES is never override, see rfc1867
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -407,7 +436,6 @@ public function overrideGlobals()
|
||||||
$_POST = $this->request->all();
|
$_POST = $this->request->all();
|
||||||
$_SERVER = $this->server->all();
|
$_SERVER = $this->server->all();
|
||||||
$_COOKIE = $this->cookies->all();
|
$_COOKIE = $this->cookies->all();
|
||||||
// FIXME: populate $_FILES
|
|
||||||
|
|
||||||
foreach ($this->headers->all() as $key => $value) {
|
foreach ($this->headers->all() as $key => $value) {
|
||||||
$key = strtoupper(str_replace('-', '_', $key));
|
$key = strtoupper(str_replace('-', '_', $key));
|
||||||
|
@ -418,22 +446,64 @@ public function overrideGlobals()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: should read variables_order and request_order
|
$request = array('g' => $_GET, 'p' => $_POST, 'c' => $_COOKIE);
|
||||||
// to know which globals to merge and in which order
|
|
||||||
$_REQUEST = array_merge($_GET, $_POST);
|
$requestOrder = ini_get('request_order') ?: ini_get('variable_order');
|
||||||
|
$requestOrder = preg_replace('#[^cgp]#', '', strtolower($requestOrder)) ?: 'gp';
|
||||||
|
|
||||||
|
$_REQUEST = array();
|
||||||
|
foreach (str_split($requestOrder) as $order) {
|
||||||
|
$_REQUEST = array_merge($_REQUEST, $request[$order]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trusts $_SERVER entries coming from proxies.
|
* Trusts $_SERVER entries coming from proxies.
|
||||||
*
|
*
|
||||||
* You should only call this method if your application
|
* @deprecated Deprecated since version 2.0, to be removed in 2.3. Use setTrustedProxies instead.
|
||||||
* is hosted behind a reverse proxy that you manage.
|
*/
|
||||||
|
public static function trustProxyData()
|
||||||
|
{
|
||||||
|
self::$trustProxy = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a list of trusted proxies.
|
||||||
|
*
|
||||||
|
* You should only list the reverse proxies that you manage directly.
|
||||||
|
*
|
||||||
|
* @param array $proxies A list of trusted proxies
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
static public function trustProxyData()
|
public static function setTrustedProxies(array $proxies)
|
||||||
{
|
{
|
||||||
self::$trustProxy = true;
|
self::$trustedProxies = $proxies;
|
||||||
|
self::$trustProxy = $proxies ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name for trusted headers.
|
||||||
|
*
|
||||||
|
* The following header keys are supported:
|
||||||
|
*
|
||||||
|
* * Request::HEADER_CLIENT_IP: defaults to X-Forwarded-For (see getClientIp())
|
||||||
|
* * Request::HEADER_CLIENT_HOST: defaults to X-Forwarded-Host (see getClientHost())
|
||||||
|
* * Request::HEADER_CLIENT_PORT: defaults to X-Forwarded-Port (see getClientPort())
|
||||||
|
* * Request::HEADER_CLIENT_PROTO: defaults to X-Forwarded-Proto (see getScheme() and isSecure())
|
||||||
|
*
|
||||||
|
* Setting an empty value allows to disable the trusted header for the given key.
|
||||||
|
*
|
||||||
|
* @param string $key The header key
|
||||||
|
* @param string $value The header name
|
||||||
|
*/
|
||||||
|
public static function setTrustedHeaderName($key, $value)
|
||||||
|
{
|
||||||
|
if (!array_key_exists($key, self::$trustedHeaders)) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Unable to set the trusted header name for key "%s".', $key));
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$trustedHeaders[$key] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -442,29 +512,72 @@ static public function trustProxyData()
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
static public function isProxyTrusted()
|
public static function isProxyTrusted()
|
||||||
{
|
{
|
||||||
return self::$trustProxy;
|
return self::$trustProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalizes a query string.
|
||||||
|
*
|
||||||
|
* It builds a normalized query string, where keys/value pairs are alphabetized,
|
||||||
|
* have consistent escaping and unneeded delimiters are removed.
|
||||||
|
*
|
||||||
|
* @param string $qs Query string
|
||||||
|
*
|
||||||
|
* @return string A normalized query string for the Request
|
||||||
|
*/
|
||||||
|
public static function normalizeQueryString($qs)
|
||||||
|
{
|
||||||
|
if ('' == $qs) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$parts = array();
|
||||||
|
$order = array();
|
||||||
|
|
||||||
|
foreach (explode('&', $qs) as $param) {
|
||||||
|
if ('' === $param || '=' === $param[0]) {
|
||||||
|
// Ignore useless delimiters, e.g. "x=y&".
|
||||||
|
// Also ignore pairs with empty key, even if there was a value, e.g. "=value", as such nameless values cannot be retrieved anyway.
|
||||||
|
// PHP also does not include them when building _GET.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$keyValuePair = explode('=', $param, 2);
|
||||||
|
|
||||||
|
// GET parameters, that are submitted from a HTML form, encode spaces as "+" by default (as defined in enctype application/x-www-form-urlencoded).
|
||||||
|
// PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str. This is why we use urldecode and then normalize to
|
||||||
|
// RFC 3986 with rawurlencode.
|
||||||
|
$parts[] = isset($keyValuePair[1]) ?
|
||||||
|
rawurlencode(urldecode($keyValuePair[0])).'='.rawurlencode(urldecode($keyValuePair[1])) :
|
||||||
|
rawurlencode(urldecode($keyValuePair[0]));
|
||||||
|
$order[] = urldecode($keyValuePair[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
array_multisort($order, SORT_ASC, $parts);
|
||||||
|
|
||||||
|
return implode('&', $parts);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a "parameter" value.
|
* Gets a "parameter" value.
|
||||||
*
|
*
|
||||||
* This method is mainly useful for libraries that want to provide some flexibility.
|
* This method is mainly useful for libraries that want to provide some flexibility.
|
||||||
*
|
*
|
||||||
* Order of precedence: GET, PATH, POST, COOKIE
|
* Order of precedence: GET, PATH, POST
|
||||||
*
|
*
|
||||||
* Avoid using this method in controllers:
|
* Avoid using this method in controllers:
|
||||||
*
|
*
|
||||||
* * slow
|
* * slow
|
||||||
* * prefer to get from a "named" source
|
* * prefer to get from a "named" source
|
||||||
*
|
*
|
||||||
* It is better to explicity get request parameters from the appropriate
|
* It is better to explicitly get request parameters from the appropriate
|
||||||
* public property instead (query, request, attributes, ...).
|
* public property instead (query, attributes, request).
|
||||||
*
|
*
|
||||||
* @param string $key the key
|
* @param string $key the key
|
||||||
* @param mixed $default the default value
|
* @param mixed $default the default value
|
||||||
* @param type $deep is parameter deep in multidimensional array
|
* @param Boolean $deep is parameter deep in multidimensional array
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
@ -489,22 +602,24 @@ public function getSession()
|
||||||
* Whether the request contains a Session which was started in one of the
|
* Whether the request contains a Session which was started in one of the
|
||||||
* previous requests.
|
* previous requests.
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return Boolean
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function hasPreviousSession()
|
public function hasPreviousSession()
|
||||||
{
|
{
|
||||||
// the check for $this->session avoids malicious users trying to fake a session cookie with proper name
|
// the check for $this->session avoids malicious users trying to fake a session cookie with proper name
|
||||||
$sessionName = $this->hasSession() ? $this->session->getName() : null;
|
return $this->hasSession() && $this->cookies->has($this->session->getName());
|
||||||
|
|
||||||
return $this->cookies->has($sessionName) && $this->hasSession();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the request contains a Session object.
|
* Whether the request contains a Session object.
|
||||||
*
|
*
|
||||||
* @return boolean
|
* This method does not give any information about the state of the session object,
|
||||||
|
* like whether the session is started or not. It is just a way to check if this Request
|
||||||
|
* is associated with a Session instance.
|
||||||
|
*
|
||||||
|
* @return Boolean true when the Request contains a Session object, false otherwise
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -528,23 +643,43 @@ public function setSession(SessionInterface $session)
|
||||||
/**
|
/**
|
||||||
* Returns the client IP address.
|
* Returns the client IP address.
|
||||||
*
|
*
|
||||||
|
* This method can read the client IP address from the "X-Forwarded-For" header
|
||||||
|
* when trusted proxies were set via "setTrustedProxies()". The "X-Forwarded-For"
|
||||||
|
* header value is a comma+space separated list of IP addresses, the left-most
|
||||||
|
* being the original client, and each successive proxy that passed the request
|
||||||
|
* adding the IP address where it received the request from.
|
||||||
|
*
|
||||||
|
* If your reverse proxy uses a different header name than "X-Forwarded-For",
|
||||||
|
* ("Client-Ip" for instance), configure it via "setTrustedHeaderName()" with
|
||||||
|
* the "client-ip" key.
|
||||||
|
*
|
||||||
* @return string The client IP address
|
* @return string The client IP address
|
||||||
*
|
*
|
||||||
|
* @see http://en.wikipedia.org/wiki/X-Forwarded-For
|
||||||
|
*
|
||||||
|
* @deprecated The proxy argument is deprecated since version 2.0 and will be removed in 2.3. Use setTrustedProxies instead.
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getClientIp()
|
public function getClientIp()
|
||||||
{
|
{
|
||||||
if (self::$trustProxy) {
|
$ip = $this->server->get('REMOTE_ADDR');
|
||||||
if ($this->server->has('HTTP_CLIENT_IP')) {
|
|
||||||
return $this->server->get('HTTP_CLIENT_IP');
|
|
||||||
} elseif ($this->server->has('HTTP_X_FORWARDED_FOR')) {
|
|
||||||
$clientIp = explode(',', $this->server->get('HTTP_X_FORWARDED_FOR'), 2);
|
|
||||||
|
|
||||||
return isset($clientIp[0]) ? trim($clientIp[0]) : '';
|
if (!self::$trustProxy) {
|
||||||
}
|
return $ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->server->get('REMOTE_ADDR');
|
if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) {
|
||||||
|
return $ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP])));
|
||||||
|
$clientIps[] = $ip;
|
||||||
|
|
||||||
|
$trustedProxies = self::$trustProxy && !self::$trustedProxies ? array($ip) : self::$trustedProxies;
|
||||||
|
$clientIps = array_diff($clientIps, $trustedProxies);
|
||||||
|
|
||||||
|
return array_pop($clientIps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -568,9 +703,10 @@ public function getScriptName()
|
||||||
*
|
*
|
||||||
* * http://localhost/mysite returns an empty string
|
* * http://localhost/mysite returns an empty string
|
||||||
* * http://localhost/mysite/about returns '/about'
|
* * http://localhost/mysite/about returns '/about'
|
||||||
|
* * htpp://localhost/mysite/enco%20ded returns '/enco%20ded'
|
||||||
* * http://localhost/mysite/about?var=1 returns '/about'
|
* * http://localhost/mysite/about?var=1 returns '/about'
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string The raw path (i.e. not urldecoded)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -590,9 +726,10 @@ public function getPathInfo()
|
||||||
*
|
*
|
||||||
* * http://localhost/index.php returns an empty string
|
* * http://localhost/index.php returns an empty string
|
||||||
* * http://localhost/index.php/page returns an empty string
|
* * http://localhost/index.php/page returns an empty string
|
||||||
* * http://localhost/web/index.php return '/web'
|
* * http://localhost/web/index.php returns '/web'
|
||||||
|
* * http://localhost/we%20b/index.php returns '/we%20b'
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string The raw path (i.e. not urldecoded)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -613,7 +750,7 @@ public function getBasePath()
|
||||||
* This is similar to getBasePath(), except that it also includes the
|
* This is similar to getBasePath(), except that it also includes the
|
||||||
* script filename (e.g. index.php) if one exists.
|
* script filename (e.g. index.php) if one exists.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string The raw url (i.e. not urldecoded)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -641,17 +778,25 @@ public function getScheme()
|
||||||
/**
|
/**
|
||||||
* Returns the port on which the request is made.
|
* Returns the port on which the request is made.
|
||||||
*
|
*
|
||||||
|
* This method can read the client port from the "X-Forwarded-Port" header
|
||||||
|
* when trusted proxies were set via "setTrustedProxies()".
|
||||||
|
*
|
||||||
|
* The "X-Forwarded-Port" header must contain the client port.
|
||||||
|
*
|
||||||
|
* If your reverse proxy uses a different header name than "X-Forwarded-Port",
|
||||||
|
* configure it via "setTrustedHeaderName()" with the "client-port" key.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getPort()
|
public function getPort()
|
||||||
{
|
{
|
||||||
if (self::$trustProxy && $this->headers->has('X-Forwarded-Port')) {
|
if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_PORT] && $port = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PORT])) {
|
||||||
return $this->headers->get('X-Forwarded-Port');
|
return $port;
|
||||||
} else {
|
|
||||||
return $this->server->get('SERVER_PORT');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->server->get('SERVER_PORT');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -674,6 +819,23 @@ public function getPassword()
|
||||||
return $this->server->get('PHP_AUTH_PW');
|
return $this->server->get('PHP_AUTH_PW');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the user info.
|
||||||
|
*
|
||||||
|
* @return string A user name and, optionally, scheme-specific information about how to gain authorization to access the server
|
||||||
|
*/
|
||||||
|
public function getUserInfo()
|
||||||
|
{
|
||||||
|
$userinfo = $this->getUser();
|
||||||
|
|
||||||
|
$pass = $this->getPassword();
|
||||||
|
if ('' != $pass) {
|
||||||
|
$userinfo .= ":$pass";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $userinfo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HTTP host being requested.
|
* Returns the HTTP host being requested.
|
||||||
*
|
*
|
||||||
|
@ -698,7 +860,7 @@ public function getHttpHost()
|
||||||
/**
|
/**
|
||||||
* Returns the requested URI.
|
* Returns the requested URI.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string The raw URI (i.e. not urldecoded)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -711,6 +873,19 @@ public function getRequestUri()
|
||||||
return $this->requestUri;
|
return $this->requestUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the scheme and HTTP host.
|
||||||
|
*
|
||||||
|
* If the URL was called with basic authentication, the user
|
||||||
|
* and the password are not added to the generated string.
|
||||||
|
*
|
||||||
|
* @return string The scheme and HTTP host
|
||||||
|
*/
|
||||||
|
public function getSchemeAndHttpHost()
|
||||||
|
{
|
||||||
|
return $this->getScheme().'://'.$this->getHttpHost();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a normalized URI for the Request.
|
* Generates a normalized URI for the Request.
|
||||||
*
|
*
|
||||||
|
@ -727,20 +902,7 @@ public function getUri()
|
||||||
$qs = '?'.$qs;
|
$qs = '?'.$qs;
|
||||||
}
|
}
|
||||||
|
|
||||||
$auth = '';
|
return $this->getSchemeAndHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
|
||||||
if ($user = $this->getUser()) {
|
|
||||||
$auth = $user;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pass = $this->getPassword()) {
|
|
||||||
$auth .= ":$pass";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('' !== $auth) {
|
|
||||||
$auth .= '@';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->getScheme().'://'.$auth.$this->getHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -754,7 +916,7 @@ public function getUri()
|
||||||
*/
|
*/
|
||||||
public function getUriForPath($path)
|
public function getUriForPath($path)
|
||||||
{
|
{
|
||||||
return $this->getScheme().'://'.$this->getHttpHost().$this->getBaseUrl().$path;
|
return $this->getSchemeAndHttpHost().$this->getBaseUrl().$path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -769,71 +931,76 @@ public function getUriForPath($path)
|
||||||
*/
|
*/
|
||||||
public function getQueryString()
|
public function getQueryString()
|
||||||
{
|
{
|
||||||
if (!$qs = $this->server->get('QUERY_STRING')) {
|
$qs = static::normalizeQueryString($this->server->get('QUERY_STRING'));
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$parts = array();
|
return '' === $qs ? null : $qs;
|
||||||
$order = array();
|
|
||||||
|
|
||||||
foreach (explode('&', $qs) as $segment) {
|
|
||||||
if (false === strpos($segment, '=')) {
|
|
||||||
$parts[] = $segment;
|
|
||||||
$order[] = $segment;
|
|
||||||
} else {
|
|
||||||
$tmp = explode('=', rawurldecode($segment), 2);
|
|
||||||
$parts[] = rawurlencode($tmp[0]).'='.rawurlencode($tmp[1]);
|
|
||||||
$order[] = $tmp[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
array_multisort($order, SORT_ASC, $parts);
|
|
||||||
|
|
||||||
return implode('&', $parts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the request is secure or not.
|
* Checks whether the request is secure or not.
|
||||||
*
|
*
|
||||||
|
* This method can read the client port from the "X-Forwarded-Proto" header
|
||||||
|
* when trusted proxies were set via "setTrustedProxies()".
|
||||||
|
*
|
||||||
|
* The "X-Forwarded-Proto" header must contain the protocol: "https" or "http".
|
||||||
|
*
|
||||||
|
* If your reverse proxy uses a different header name than "X-Forwarded-Proto"
|
||||||
|
* ("SSL_HTTPS" for instance), configure it via "setTrustedHeaderName()" with
|
||||||
|
* the "client-proto" key.
|
||||||
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function isSecure()
|
public function isSecure()
|
||||||
{
|
{
|
||||||
return (
|
if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_PROTO] && $proto = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_PROTO])) {
|
||||||
(strtolower($this->server->get('HTTPS')) == 'on' || $this->server->get('HTTPS') == 1)
|
return in_array(strtolower($proto), array('https', 'on', '1'));
|
||||||
||
|
}
|
||||||
(self::$trustProxy && strtolower($this->headers->get('SSL_HTTPS')) == 'on' || $this->headers->get('SSL_HTTPS') == 1)
|
|
||||||
||
|
return 'on' == strtolower($this->server->get('HTTPS')) || 1 == $this->server->get('HTTPS');
|
||||||
(self::$trustProxy && strtolower($this->headers->get('X_FORWARDED_PROTO')) == 'https')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the host name.
|
* Returns the host name.
|
||||||
*
|
*
|
||||||
|
* This method can read the client port from the "X-Forwarded-Host" header
|
||||||
|
* when trusted proxies were set via "setTrustedProxies()".
|
||||||
|
*
|
||||||
|
* The "X-Forwarded-Host" header must contain the client host name.
|
||||||
|
*
|
||||||
|
* If your reverse proxy uses a different header name than "X-Forwarded-Host",
|
||||||
|
* configure it via "setTrustedHeaderName()" with the "client-host" key.
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*
|
*
|
||||||
|
* @throws \UnexpectedValueException when the host name is invalid
|
||||||
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getHost()
|
public function getHost()
|
||||||
{
|
{
|
||||||
if (self::$trustProxy && $host = $this->headers->get('X_FORWARDED_HOST')) {
|
if (self::$trustProxy && self::$trustedHeaders[self::HEADER_CLIENT_HOST] && $host = $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_HOST])) {
|
||||||
$elements = explode(',', $host);
|
$elements = explode(',', $host);
|
||||||
|
|
||||||
$host = trim($elements[count($elements) - 1]);
|
$host = $elements[count($elements) - 1];
|
||||||
} else {
|
} elseif (!$host = $this->headers->get('HOST')) {
|
||||||
if (!$host = $this->headers->get('HOST')) {
|
|
||||||
if (!$host = $this->server->get('SERVER_NAME')) {
|
if (!$host = $this->server->get('SERVER_NAME')) {
|
||||||
$host = $this->server->get('SERVER_ADDR', '');
|
$host = $this->server->get('SERVER_ADDR', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim and remove port number from host
|
||||||
|
// host is lowercase as per RFC 952/2181
|
||||||
|
$host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
|
||||||
|
|
||||||
|
// as the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user)
|
||||||
|
// check that it does not contain forbidden characters (see RFC 952 and RFC 2181)
|
||||||
|
if ($host && !preg_match('/^\[?(?:[a-zA-Z0-9-:\]_]+\.?)+$/', $host)) {
|
||||||
|
throw new \UnexpectedValueException('Invalid Host');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove port number from host
|
return $host;
|
||||||
$host = preg_replace('/:\d+$/', '', $host);
|
|
||||||
|
|
||||||
return trim($host);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -863,7 +1030,7 @@ public function getMethod()
|
||||||
if (null === $this->method) {
|
if (null === $this->method) {
|
||||||
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
|
$this->method = strtoupper($this->server->get('REQUEST_METHOD', 'GET'));
|
||||||
if ('POST' === $this->method) {
|
if ('POST' === $this->method) {
|
||||||
$this->method = strtoupper($this->headers->get('X-HTTP-METHOD-OVERRIDE', $this->request->get('_method', 'POST')));
|
$this->method = strtoupper($this->headers->get('X-HTTP-METHOD-OVERRIDE', $this->request->get('_method', $this->query->get('_method', 'POST'))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,7 +1060,7 @@ public function getMimeType($format)
|
||||||
*
|
*
|
||||||
* @param string $mimeType The associated mime type
|
* @param string $mimeType The associated mime type
|
||||||
*
|
*
|
||||||
* @return string The format (null if not found)
|
* @return string|null The format (null if not found)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -972,13 +1139,13 @@ public function setRequestFormat($format)
|
||||||
/**
|
/**
|
||||||
* Gets the format associated with the request.
|
* Gets the format associated with the request.
|
||||||
*
|
*
|
||||||
* @return string The format (null if no content type is present)
|
* @return string|null The format (null if no content type is present)
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
public function getContentType()
|
public function getContentType()
|
||||||
{
|
{
|
||||||
return $this->getFormat($this->server->get('CONTENT_TYPE'));
|
return $this->getFormat($this->headers->get('CONTENT_TYPE'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -990,7 +1157,11 @@ public function getContentType()
|
||||||
*/
|
*/
|
||||||
public function setDefaultLocale($locale)
|
public function setDefaultLocale($locale)
|
||||||
{
|
{
|
||||||
$this->setPhpDefaultLocale($this->defaultLocale = $locale);
|
$this->defaultLocale = $locale;
|
||||||
|
|
||||||
|
if (null === $this->locale) {
|
||||||
|
$this->setPhpDefaultLocale($locale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1015,6 +1186,18 @@ public function getLocale()
|
||||||
return null === $this->locale ? $this->defaultLocale : $this->locale;
|
return null === $this->locale ? $this->defaultLocale : $this->locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the request method is of specified type.
|
||||||
|
*
|
||||||
|
* @param string $method Uppercase request method (GET, POST etc).
|
||||||
|
*
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public function isMethod($method)
|
||||||
|
{
|
||||||
|
return $this->getMethod() === strtoupper($method);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the method is safe or not.
|
* Checks whether the method is safe or not.
|
||||||
*
|
*
|
||||||
|
@ -1063,6 +1246,9 @@ public function getETags()
|
||||||
return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
|
return preg_split('/\s*,\s*/', $this->headers->get('if_none_match'), null, PREG_SPLIT_NO_EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
public function isNoCache()
|
public function isNoCache()
|
||||||
{
|
{
|
||||||
return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
|
return $this->headers->hasCacheControlDirective('no-cache') || 'no-cache' == $this->headers->get('Pragma');
|
||||||
|
@ -1197,22 +1383,30 @@ public function splitHttpAcceptHeader($header)
|
||||||
}
|
}
|
||||||
|
|
||||||
$values = array();
|
$values = array();
|
||||||
|
$groups = array();
|
||||||
foreach (array_filter(explode(',', $header)) as $value) {
|
foreach (array_filter(explode(',', $header)) as $value) {
|
||||||
// Cut off any q-value that might come after a semi-colon
|
// Cut off any q-value that might come after a semi-colon
|
||||||
if (preg_match('/;\s*(q=.*$)/', $value, $match)) {
|
if (preg_match('/;\s*(q=.*$)/', $value, $match)) {
|
||||||
$q = (float) substr(trim($match[1]), 2);
|
$q = substr(trim($match[1]), 2);
|
||||||
$value = trim(substr($value, 0, -strlen($match[0])));
|
$value = trim(substr($value, 0, -strlen($match[0])));
|
||||||
} else {
|
} else {
|
||||||
$q = 1;
|
$q = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$groups[$q][] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
krsort($groups);
|
||||||
|
|
||||||
|
foreach ($groups as $q => $items) {
|
||||||
|
$q = (float) $q;
|
||||||
|
|
||||||
if (0 < $q) {
|
if (0 < $q) {
|
||||||
|
foreach ($items as $value) {
|
||||||
$values[trim($value)] = $q;
|
$values[trim($value)] = $q;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
arsort($values);
|
|
||||||
reset($values);
|
|
||||||
|
|
||||||
return $values;
|
return $values;
|
||||||
}
|
}
|
||||||
|
@ -1229,8 +1423,11 @@ protected function prepareRequestUri()
|
||||||
{
|
{
|
||||||
$requestUri = '';
|
$requestUri = '';
|
||||||
|
|
||||||
if ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
if ($this->headers->has('X_ORIGINAL_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
||||||
// check this first so IIS will catch
|
// IIS with Microsoft Rewrite Module
|
||||||
|
$requestUri = $this->headers->get('X_ORIGINAL_URL');
|
||||||
|
} elseif ($this->headers->has('X_REWRITE_URL') && false !== stripos(PHP_OS, 'WIN')) {
|
||||||
|
// IIS with ISAPI_Rewrite
|
||||||
$requestUri = $this->headers->get('X_REWRITE_URL');
|
$requestUri = $this->headers->get('X_REWRITE_URL');
|
||||||
} elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
|
} elseif ($this->server->get('IIS_WasUrlRewritten') == '1' && $this->server->get('UNENCODED_URL') != '') {
|
||||||
// IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
|
// IIS7 with URL Rewrite: make sure we get the unencoded url (double slash problem)
|
||||||
|
@ -1238,14 +1435,14 @@ protected function prepareRequestUri()
|
||||||
} elseif ($this->server->has('REQUEST_URI')) {
|
} elseif ($this->server->has('REQUEST_URI')) {
|
||||||
$requestUri = $this->server->get('REQUEST_URI');
|
$requestUri = $this->server->get('REQUEST_URI');
|
||||||
// HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
|
// HTTP proxy reqs setup request uri with scheme and host [and port] + the url path, only use url path
|
||||||
$schemeAndHttpHost = $this->getScheme().'://'.$this->getHttpHost();
|
$schemeAndHttpHost = $this->getSchemeAndHttpHost();
|
||||||
if (strpos($requestUri, $schemeAndHttpHost) === 0) {
|
if (strpos($requestUri, $schemeAndHttpHost) === 0) {
|
||||||
$requestUri = substr($requestUri, strlen($schemeAndHttpHost));
|
$requestUri = substr($requestUri, strlen($schemeAndHttpHost));
|
||||||
}
|
}
|
||||||
} elseif ($this->server->has('ORIG_PATH_INFO')) {
|
} elseif ($this->server->has('ORIG_PATH_INFO')) {
|
||||||
// IIS 5.0, PHP as CGI
|
// IIS 5.0, PHP as CGI
|
||||||
$requestUri = $this->server->get('ORIG_PATH_INFO');
|
$requestUri = $this->server->get('ORIG_PATH_INFO');
|
||||||
if ($this->server->get('QUERY_STRING')) {
|
if ('' != $this->server->get('QUERY_STRING')) {
|
||||||
$requestUri .= '?'.$this->server->get('QUERY_STRING');
|
$requestUri .= '?'.$this->server->get('QUERY_STRING');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1288,14 +1485,14 @@ protected function prepareBaseUrl()
|
||||||
// Does the baseUrl have anything in common with the request_uri?
|
// Does the baseUrl have anything in common with the request_uri?
|
||||||
$requestUri = $this->getRequestUri();
|
$requestUri = $this->getRequestUri();
|
||||||
|
|
||||||
if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
|
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
|
||||||
// full $baseUrl matches
|
// full $baseUrl matches
|
||||||
return $baseUrl;
|
return $prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
|
if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, dirname($baseUrl))) {
|
||||||
// directory portion of $baseUrl matches
|
// directory portion of $baseUrl matches
|
||||||
return rtrim(dirname($baseUrl), '/');
|
return rtrim($prefix, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
$truncatedRequestUri = $requestUri;
|
$truncatedRequestUri = $requestUri;
|
||||||
|
@ -1304,7 +1501,7 @@ protected function prepareBaseUrl()
|
||||||
}
|
}
|
||||||
|
|
||||||
$basename = basename($baseUrl);
|
$basename = basename($baseUrl);
|
||||||
if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
|
if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
|
||||||
// no match whatsoever; set it blank
|
// no match whatsoever; set it blank
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
@ -1365,7 +1562,7 @@ protected function preparePathInfo()
|
||||||
$requestUri = substr($requestUri, 0, $pos);
|
$requestUri = substr($requestUri, 0, $pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((null !== $baseUrl) && (false === ($pathInfo = substr(urldecode($requestUri), strlen(urldecode($baseUrl)))))) {
|
if ((null !== $baseUrl) && (false === ($pathInfo = substr($requestUri, strlen($baseUrl))))) {
|
||||||
// If substr() returns false then PATH_INFO is set to an empty string
|
// If substr() returns false then PATH_INFO is set to an empty string
|
||||||
return '/';
|
return '/';
|
||||||
} elseif (null === $baseUrl) {
|
} elseif (null === $baseUrl) {
|
||||||
|
@ -1378,7 +1575,7 @@ protected function preparePathInfo()
|
||||||
/**
|
/**
|
||||||
* Initializes HTTP request formats.
|
* Initializes HTTP request formats.
|
||||||
*/
|
*/
|
||||||
static protected function initializeFormats()
|
protected static function initializeFormats()
|
||||||
{
|
{
|
||||||
static::$formats = array(
|
static::$formats = array(
|
||||||
'html' => array('text/html', 'application/xhtml+xml'),
|
'html' => array('text/html', 'application/xhtml+xml'),
|
||||||
|
@ -1410,4 +1607,28 @@ private function setPhpDefaultLocale($locale)
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the prefix as encoded in the string when the string starts with
|
||||||
|
* the given prefix, false otherwise.
|
||||||
|
*
|
||||||
|
* @param string $string The urlencoded string
|
||||||
|
* @param string $prefix The prefix not encoded
|
||||||
|
*
|
||||||
|
* @return string|false The prefix as it is encoded in $string, or false
|
||||||
|
*/
|
||||||
|
private function getUrlencodedPrefix($string, $prefix)
|
||||||
|
{
|
||||||
|
if (0 !== strpos(rawurldecode($string), $prefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$len = strlen($prefix);
|
||||||
|
|
||||||
|
if (preg_match("#^(%[[:xdigit:]]{2}|.){{$len}}#", $string, $match)) {
|
||||||
|
return $match[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ class RequestMatcher implements RequestMatcherInterface
|
||||||
private $host;
|
private $host;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $methods;
|
private $methods = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
|
@ -41,19 +41,26 @@ class RequestMatcher implements RequestMatcherInterface
|
||||||
private $ip;
|
private $ip;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attributes.
|
|
||||||
*
|
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
private $attributes;
|
private $attributes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $path
|
||||||
|
* @param string|null $host
|
||||||
|
* @param string|string[]|null $methods
|
||||||
|
* @param string|null $ip
|
||||||
|
* @param array $attributes
|
||||||
|
*/
|
||||||
public function __construct($path = null, $host = null, $methods = null, $ip = null, array $attributes = array())
|
public function __construct($path = null, $host = null, $methods = null, $ip = null, array $attributes = array())
|
||||||
{
|
{
|
||||||
$this->path = $path;
|
$this->matchPath($path);
|
||||||
$this->host = $host;
|
$this->matchHost($host);
|
||||||
$this->methods = $methods;
|
$this->matchMethod($methods);
|
||||||
$this->ip = $ip;
|
$this->matchIp($ip);
|
||||||
$this->attributes = $attributes;
|
foreach ($attributes as $k => $v) {
|
||||||
|
$this->matchAttribute($k, $v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,11 +96,11 @@ public function matchIp($ip)
|
||||||
/**
|
/**
|
||||||
* Adds a check for the HTTP method.
|
* Adds a check for the HTTP method.
|
||||||
*
|
*
|
||||||
* @param string|array $method An HTTP method or an array of HTTP methods
|
* @param string|string[]|null $method An HTTP method or an array of HTTP methods
|
||||||
*/
|
*/
|
||||||
public function matchMethod($method)
|
public function matchMethod($method)
|
||||||
{
|
{
|
||||||
$this->methods = array_map('strtoupper', is_array($method) ? $method : array($method));
|
$this->methods = array_map('strtoupper', (array) $method);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,7 +121,7 @@ public function matchAttribute($key, $regexp)
|
||||||
*/
|
*/
|
||||||
public function matches(Request $request)
|
public function matches(Request $request)
|
||||||
{
|
{
|
||||||
if (null !== $this->methods && !in_array($request->getMethod(), $this->methods)) {
|
if ($this->methods && !in_array($request->getMethod(), $this->methods)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +134,12 @@ public function matches(Request $request)
|
||||||
if (null !== $this->path) {
|
if (null !== $this->path) {
|
||||||
$path = str_replace('#', '\\#', $this->path);
|
$path = str_replace('#', '\\#', $this->path);
|
||||||
|
|
||||||
if (!preg_match('#'.$path.'#', $request->getPathInfo())) {
|
if (!preg_match('#'.$path.'#', rawurldecode($request->getPathInfo()))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $this->host && !preg_match('#'.str_replace('#', '\\#', $this->host).'#', $request->getHost())) {
|
if (null !== $this->host && !preg_match('#'.str_replace('#', '\\#', $this->host).'#i', $request->getHost())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,12 +205,21 @@ protected function checkIp4($requestIp, $ip)
|
||||||
*/
|
*/
|
||||||
protected function checkIp6($requestIp, $ip)
|
protected function checkIp6($requestIp, $ip)
|
||||||
{
|
{
|
||||||
if (!defined('AF_INET6')) {
|
if (!((extension_loaded('sockets') && defined('AF_INET6')) || @inet_pton('::1'))) {
|
||||||
throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
|
throw new \RuntimeException('Unable to check Ipv6. Check that PHP was not compiled with option "disable-ipv6".');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (false !== strpos($ip, '/')) {
|
||||||
list($address, $netmask) = explode('/', $ip, 2);
|
list($address, $netmask) = explode('/', $ip, 2);
|
||||||
|
|
||||||
|
if ($netmask < 1 || $netmask > 128) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$address = $ip;
|
||||||
|
$netmask = 128;
|
||||||
|
}
|
||||||
|
|
||||||
$bytesAddr = unpack("n*", inet_pton($address));
|
$bytesAddr = unpack("n*", inet_pton($address));
|
||||||
$bytesTest = unpack("n*", inet_pton($requestIp));
|
$bytesTest = unpack("n*", inet_pton($requestIp));
|
||||||
|
|
||||||
|
|
|
@ -29,5 +29,5 @@ interface RequestMatcherInterface
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function matches(Request $request);
|
public function matches(Request $request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
/**
|
/**
|
||||||
* SessionHandlerInterface
|
* SessionHandlerInterface
|
||||||
*
|
*
|
||||||
* Provides forward compatability with PHP 5.4
|
* Provides forward compatibility with PHP 5.4
|
||||||
*
|
*
|
||||||
* Extensive documentation can be found at php.net, see links:
|
* Extensive documentation can be found at php.net, see links:
|
||||||
*
|
*
|
||||||
|
@ -36,7 +36,7 @@ interface SessionHandlerInterface
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function open($savePath, $sessionName);
|
public function open($savePath, $sessionName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close session.
|
* Close session.
|
||||||
|
@ -45,18 +45,20 @@ function open($savePath, $sessionName);
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function close();
|
public function close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read session.
|
* Read session.
|
||||||
*
|
*
|
||||||
|
* @param string $sessionId
|
||||||
|
*
|
||||||
* @see http://php.net/sessionhandlerinterface.read
|
* @see http://php.net/sessionhandlerinterface.read
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException On fatal error but not "record not found".
|
* @throws \RuntimeException On fatal error but not "record not found".
|
||||||
*
|
*
|
||||||
* @return string String as stored in persistent storage or empty string in all other cases.
|
* @return string String as stored in persistent storage or empty string in all other cases.
|
||||||
*/
|
*/
|
||||||
function read($sessionId);
|
public function read($sessionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Commit session to storage.
|
* Commit session to storage.
|
||||||
|
@ -68,7 +70,7 @@ function read($sessionId);
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function write($sessionId, $data);
|
public function write($sessionId, $data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys this session.
|
* Destroys this session.
|
||||||
|
@ -81,7 +83,7 @@ function write($sessionId, $data);
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function destroy($sessionId);
|
public function destroy($sessionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Garbage collection for storage.
|
* Garbage collection for storage.
|
||||||
|
@ -94,5 +96,5 @@ function destroy($sessionId);
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function gc($lifetime);
|
public function gc($lifetime);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ class Response
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
static public $statusTexts = array(
|
public static $statusTexts = array(
|
||||||
100 => 'Continue',
|
100 => 'Continue',
|
||||||
101 => 'Switching Protocols',
|
101 => 'Switching Protocols',
|
||||||
102 => 'Processing', // RFC2518
|
102 => 'Processing', // RFC2518
|
||||||
|
@ -83,6 +83,7 @@ class Response
|
||||||
305 => 'Use Proxy',
|
305 => 'Use Proxy',
|
||||||
306 => 'Reserved',
|
306 => 'Reserved',
|
||||||
307 => 'Temporary Redirect',
|
307 => 'Temporary Redirect',
|
||||||
|
308 => 'Permanent Redirect', // RFC-reschke-http-status-308-07
|
||||||
400 => 'Bad Request',
|
400 => 'Bad Request',
|
||||||
401 => 'Unauthorized',
|
401 => 'Unauthorized',
|
||||||
402 => 'Payment Required',
|
402 => 'Payment Required',
|
||||||
|
@ -101,26 +102,26 @@ class Response
|
||||||
415 => 'Unsupported Media Type',
|
415 => 'Unsupported Media Type',
|
||||||
416 => 'Requested Range Not Satisfiable',
|
416 => 'Requested Range Not Satisfiable',
|
||||||
417 => 'Expectation Failed',
|
417 => 'Expectation Failed',
|
||||||
418 => 'I\'m a teapot',
|
418 => 'I\'m a teapot', // RFC2324
|
||||||
422 => 'Unprocessable Entity', // RFC4918
|
422 => 'Unprocessable Entity', // RFC4918
|
||||||
423 => 'Locked', // RFC4918
|
423 => 'Locked', // RFC4918
|
||||||
424 => 'Failed Dependency', // RFC4918
|
424 => 'Failed Dependency', // RFC4918
|
||||||
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
|
425 => 'Reserved for WebDAV advanced collections expired proposal', // RFC2817
|
||||||
426 => 'Upgrade Required', // RFC2817
|
426 => 'Upgrade Required', // RFC2817
|
||||||
428 => 'Precondition Required', // RFC-nottingham-http-new-status-04
|
428 => 'Precondition Required', // RFC6585
|
||||||
429 => 'Too Many Requests', // RFC-nottingham-http-new-status-04
|
429 => 'Too Many Requests', // RFC6585
|
||||||
431 => 'Request Header Fields Too Large', // RFC-nottingham-http-new-status-04
|
431 => 'Request Header Fields Too Large', // RFC6585
|
||||||
500 => 'Internal Server Error',
|
500 => 'Internal Server Error',
|
||||||
501 => 'Not Implemented',
|
501 => 'Not Implemented',
|
||||||
502 => 'Bad Gateway',
|
502 => 'Bad Gateway',
|
||||||
503 => 'Service Unavailable',
|
503 => 'Service Unavailable',
|
||||||
504 => 'Gateway Timeout',
|
504 => 'Gateway Timeout',
|
||||||
505 => 'HTTP Version Not Supported',
|
505 => 'HTTP Version Not Supported',
|
||||||
506 => 'Variant Also Negotiates (Experimental)', // [RFC2295]
|
506 => 'Variant Also Negotiates (Experimental)', // RFC2295
|
||||||
507 => 'Insufficient Storage', // RFC4918
|
507 => 'Insufficient Storage', // RFC4918
|
||||||
508 => 'Loop Detected', // RFC5842
|
508 => 'Loop Detected', // RFC5842
|
||||||
510 => 'Not Extended', // RFC2774
|
510 => 'Not Extended', // RFC2774
|
||||||
511 => 'Network Authentication Required', // RFC-nottingham-http-new-status-04
|
511 => 'Network Authentication Required', // RFC6585
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,7 +158,7 @@ public function __construct($content = '', $status = 200, $headers = array())
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*/
|
*/
|
||||||
static public function create($content = '', $status = 200, $headers = array())
|
public static function create($content = '', $status = 200, $headers = array())
|
||||||
{
|
{
|
||||||
return new static($content, $status, $headers);
|
return new static($content, $status, $headers);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +166,7 @@ static public function create($content = '', $status = 200, $headers = array())
|
||||||
/**
|
/**
|
||||||
* Returns the Response as an HTTP string.
|
* Returns the Response as an HTTP string.
|
||||||
*
|
*
|
||||||
* The string representation of the Resonse is the same as the
|
* The string representation of the Response is the same as the
|
||||||
* one that will be sent to the client only if the prepare() method
|
* one that will be sent to the client only if the prepare() method
|
||||||
* has been called before.
|
* has been called before.
|
||||||
*
|
*
|
||||||
|
@ -197,13 +198,15 @@ public function __clone()
|
||||||
* the Request that is "associated" with this Response.
|
* the Request that is "associated" with this Response.
|
||||||
*
|
*
|
||||||
* @param Request $request A Request instance
|
* @param Request $request A Request instance
|
||||||
|
*
|
||||||
|
* @return Response The current response.
|
||||||
*/
|
*/
|
||||||
public function prepare(Request $request)
|
public function prepare(Request $request)
|
||||||
{
|
{
|
||||||
$headers = $this->headers;
|
$headers = $this->headers;
|
||||||
|
|
||||||
if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
|
if ($this->isInformational() || in_array($this->statusCode, array(204, 304))) {
|
||||||
$this->setContent('');
|
$this->setContent(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Content-type based on the Request
|
// Content-type based on the Request
|
||||||
|
@ -231,11 +234,24 @@ public function prepare(Request $request)
|
||||||
if ('HEAD' === $request->getMethod()) {
|
if ('HEAD' === $request->getMethod()) {
|
||||||
// cf. RFC2616 14.13
|
// cf. RFC2616 14.13
|
||||||
$length = $headers->get('Content-Length');
|
$length = $headers->get('Content-Length');
|
||||||
$this->setContent('');
|
$this->setContent(null);
|
||||||
if ($length) {
|
if ($length) {
|
||||||
$headers->set('Content-Length', $length);
|
$headers->set('Content-Length', $length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix protocol
|
||||||
|
if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {
|
||||||
|
$this->setProtocolVersion('1.1');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we need to send extra expire info headers
|
||||||
|
if ('1.0' == $this->getProtocolVersion() && 'no-cache' == $this->headers->get('Cache-Control')) {
|
||||||
|
$this->headers->set('pragma', 'no-cache');
|
||||||
|
$this->headers->set('expires', -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -294,6 +310,18 @@ public function send()
|
||||||
|
|
||||||
if (function_exists('fastcgi_finish_request')) {
|
if (function_exists('fastcgi_finish_request')) {
|
||||||
fastcgi_finish_request();
|
fastcgi_finish_request();
|
||||||
|
} elseif ('cli' !== PHP_SAPI) {
|
||||||
|
// ob_get_level() never returns 0 on some Windows configurations, so if
|
||||||
|
// the level is the same two times in a row, the loop should be stopped.
|
||||||
|
$previous = null;
|
||||||
|
$obStatus = ob_get_status(1);
|
||||||
|
while (($level = ob_get_level()) > 0 && $level !== $previous) {
|
||||||
|
$previous = $level;
|
||||||
|
if ($obStatus[$level - 1] && isset($obStatus[$level - 1]['del']) && $obStatus[$level - 1]['del']) {
|
||||||
|
ob_end_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -365,7 +393,10 @@ public function getProtocolVersion()
|
||||||
* Sets the response status code.
|
* Sets the response status code.
|
||||||
*
|
*
|
||||||
* @param integer $code HTTP status code
|
* @param integer $code HTTP status code
|
||||||
* @param string $text HTTP status text
|
* @param mixed $text HTTP status text
|
||||||
|
*
|
||||||
|
* If the status text is null it will be automatically populated for the known
|
||||||
|
* status codes and left empty otherwise.
|
||||||
*
|
*
|
||||||
* @return Response
|
* @return Response
|
||||||
*
|
*
|
||||||
|
@ -375,12 +406,24 @@ public function getProtocolVersion()
|
||||||
*/
|
*/
|
||||||
public function setStatusCode($code, $text = null)
|
public function setStatusCode($code, $text = null)
|
||||||
{
|
{
|
||||||
$this->statusCode = (int) $code;
|
$this->statusCode = $code = (int) $code;
|
||||||
if ($this->isInvalid()) {
|
if ($this->isInvalid()) {
|
||||||
throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
|
throw new \InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->statusText = false === $text ? '' : (null === $text ? self::$statusTexts[$this->statusCode] : $text);
|
if (null === $text) {
|
||||||
|
$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $text) {
|
||||||
|
$this->statusText = '';
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->statusText = $text;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +571,7 @@ public function setPublic()
|
||||||
*/
|
*/
|
||||||
public function mustRevalidate()
|
public function mustRevalidate()
|
||||||
{
|
{
|
||||||
return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('must-proxy-revalidate');
|
return $this->headers->hasCacheControlDirective('must-revalidate') || $this->headers->has('proxy-revalidate');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,7 +585,7 @@ public function mustRevalidate()
|
||||||
*/
|
*/
|
||||||
public function getDate()
|
public function getDate()
|
||||||
{
|
{
|
||||||
return $this->headers->getDate('Date');
|
return $this->headers->getDate('Date', new \DateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -701,7 +744,7 @@ public function setSharedMaxAge($value)
|
||||||
* When the responses TTL is <= 0, the response may not be served from cache without first
|
* When the responses TTL is <= 0, the response may not be served from cache without first
|
||||||
* revalidating with the origin.
|
* revalidating with the origin.
|
||||||
*
|
*
|
||||||
* @return integer The TTL in seconds
|
* @return integer|null The TTL in seconds
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -960,6 +1003,10 @@ public function setVary($headers, $replace = true)
|
||||||
*/
|
*/
|
||||||
public function isNotModified(Request $request)
|
public function isNotModified(Request $request)
|
||||||
{
|
{
|
||||||
|
if (!$request->isMethodSafe()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$lastModified = $request->headers->get('If-Modified-Since');
|
$lastModified = $request->headers->get('If-Modified-Since');
|
||||||
$notModified = false;
|
$notModified = false;
|
||||||
if ($etags = $request->getEtags()) {
|
if ($etags = $request->getEtags()) {
|
||||||
|
@ -1095,7 +1142,7 @@ public function isNotFound()
|
||||||
*/
|
*/
|
||||||
public function isRedirect($location = null)
|
public function isRedirect($location = null)
|
||||||
{
|
{
|
||||||
return in_array($this->statusCode, array(201, 301, 302, 303, 307)) && (null === $location ?: $location == $this->headers->get('Location'));
|
return in_array($this->statusCode, array(201, 301, 302, 303, 307, 308)) && (null === $location ?: $location == $this->headers->get('Location'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -231,7 +231,7 @@ public function makeDisposition($disposition, $filename, $filenameFallback = '')
|
||||||
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
|
throw new \InvalidArgumentException(sprintf('The disposition must be either "%s" or "%s".', self::DISPOSITION_ATTACHMENT, self::DISPOSITION_INLINE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$filenameFallback) {
|
if ('' == $filenameFallback) {
|
||||||
$filenameFallback = $filename;
|
$filenameFallback = $filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,14 +246,14 @@ public function makeDisposition($disposition, $filename, $filenameFallback = '')
|
||||||
}
|
}
|
||||||
|
|
||||||
// path separators aren't allowed in either.
|
// path separators aren't allowed in either.
|
||||||
if (preg_match('#[/\\\\]#', $filename) || preg_match('#[/\\\\]#', $filenameFallback)) {
|
if (false !== strpos($filename, '/') || false !== strpos($filename, '\\') || false !== strpos($filenameFallback, '/') || false !== strpos($filenameFallback, '\\')) {
|
||||||
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
|
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = sprintf('%s; filename="%s"', $disposition, str_replace(array('\\', '"'), array('\\\\', '\\"'), $filenameFallback));
|
$output = sprintf('%s; filename="%s"', $disposition, str_replace('"', '\\"', $filenameFallback));
|
||||||
|
|
||||||
if ($filename != $filenameFallback) {
|
if ($filename !== $filenameFallback) {
|
||||||
$output .= sprintf("; filename*=utf-8''%s", str_replace(array("'", '(', ')', '*'), array('%27', '%28', '%29', '%2A'), urlencode($filename)));
|
$output .= sprintf("; filename*=utf-8''%s", rawurlencode($filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||||
|
* @author Robert Kiss <kepten@gmail.com>
|
||||||
*/
|
*/
|
||||||
class ServerBag extends ParameterBag
|
class ServerBag extends ParameterBag
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Gets the HTTP headers.
|
* Gets the HTTP headers.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getHeaders()
|
public function getHeaders()
|
||||||
{
|
{
|
||||||
|
@ -33,14 +34,47 @@ public function getHeaders()
|
||||||
}
|
}
|
||||||
// CONTENT_* are not prefixed with HTTP_
|
// CONTENT_* are not prefixed with HTTP_
|
||||||
elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) {
|
elseif (in_array($key, array('CONTENT_LENGTH', 'CONTENT_MD5', 'CONTENT_TYPE'))) {
|
||||||
$headers[$key] = $this->parameters[$key];
|
$headers[$key] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->parameters['PHP_AUTH_USER'])) {
|
||||||
|
$headers['PHP_AUTH_USER'] = $this->parameters['PHP_AUTH_USER'];
|
||||||
|
$headers['PHP_AUTH_PW'] = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* php-cgi under Apache does not pass HTTP Basic user/pass to PHP by default
|
||||||
|
* For this workaround to work, add these lines to your .htaccess file:
|
||||||
|
* RewriteCond %{HTTP:Authorization} ^(.+)$
|
||||||
|
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||||
|
*
|
||||||
|
* A sample .htaccess file:
|
||||||
|
* RewriteEngine On
|
||||||
|
* RewriteCond %{HTTP:Authorization} ^(.+)$
|
||||||
|
* RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||||
|
* RewriteCond %{REQUEST_FILENAME} !-f
|
||||||
|
* RewriteRule ^(.*)$ app.php [QSA,L]
|
||||||
|
*/
|
||||||
|
|
||||||
|
$authorizationHeader = null;
|
||||||
|
if (isset($this->parameters['HTTP_AUTHORIZATION'])) {
|
||||||
|
$authorizationHeader = $this->parameters['HTTP_AUTHORIZATION'];
|
||||||
|
} elseif (isset($this->parameters['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||||
|
$authorizationHeader = $this->parameters['REDIRECT_HTTP_AUTHORIZATION'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode AUTHORIZATION header into PHP_AUTH_USER and PHP_AUTH_PW when authorization header is basic
|
||||||
|
if ((null !== $authorizationHeader) && (0 === stripos($authorizationHeader, 'basic'))) {
|
||||||
|
$exploded = explode(':', base64_decode(substr($authorizationHeader, 6)));
|
||||||
|
if (count($exploded) == 2) {
|
||||||
|
list($headers['PHP_AUTH_USER'], $headers['PHP_AUTH_PW']) = $exploded;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHP_AUTH_USER/PHP_AUTH_PW
|
// PHP_AUTH_USER/PHP_AUTH_PW
|
||||||
if (isset($this->parameters['PHP_AUTH_USER'])) {
|
if (isset($headers['PHP_AUTH_USER'])) {
|
||||||
$pass = isset($this->parameters['PHP_AUTH_PW']) ? $this->parameters['PHP_AUTH_PW'] : '';
|
$headers['AUTHORIZATION'] = 'Basic '.base64_encode($headers['PHP_AUTH_USER'].':'.$headers['PHP_AUTH_PW']);
|
||||||
$headers['AUTHORIZATION'] = 'Basic '.base64_encode($this->parameters['PHP_AUTH_USER'].':'.$pass);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $headers;
|
return $headers;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* This class relates to session attribute storage
|
* This class relates to session attribute storage
|
||||||
*/
|
*/
|
||||||
class AttributeBag implements AttributeBagInterface
|
class AttributeBag implements AttributeBagInterface, \IteratorAggregate, \Countable
|
||||||
{
|
{
|
||||||
private $name = 'attributes';
|
private $name = 'attributes';
|
||||||
|
|
||||||
|
@ -134,4 +134,24 @@ public function clear()
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator for attributes.
|
||||||
|
*
|
||||||
|
* @return \ArrayIterator An \ArrayIterator instance
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of attributes.
|
||||||
|
*
|
||||||
|
* @return int The number of attributes
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ interface AttributeBagInterface extends SessionBagInterface
|
||||||
*
|
*
|
||||||
* @return Boolean true if the attribute is defined, false otherwise
|
* @return Boolean true if the attribute is defined, false otherwise
|
||||||
*/
|
*/
|
||||||
function has($name);
|
public function has($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an attribute.
|
* Returns an attribute.
|
||||||
|
@ -37,7 +37,7 @@ function has($name);
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
function get($name, $default = null);
|
public function get($name, $default = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an attribute.
|
* Sets an attribute.
|
||||||
|
@ -45,21 +45,21 @@ function get($name, $default = null);
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*/
|
*/
|
||||||
function set($name, $value);
|
public function set($name, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns attributes.
|
* Returns attributes.
|
||||||
*
|
*
|
||||||
* @return array Attributes
|
* @return array Attributes
|
||||||
*/
|
*/
|
||||||
function all();
|
public function all();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets attributes.
|
* Sets attributes.
|
||||||
*
|
*
|
||||||
* @param array $attributes Attributes
|
* @param array $attributes Attributes
|
||||||
*/
|
*/
|
||||||
function replace(array $attributes);
|
public function replace(array $attributes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an attribute.
|
* Removes an attribute.
|
||||||
|
@ -68,5 +68,5 @@ function replace(array $attributes);
|
||||||
*
|
*
|
||||||
* @return mixed The removed value
|
* @return mixed The removed value
|
||||||
*/
|
*/
|
||||||
function remove($name);
|
public function remove($name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,15 @@ public function initialize(array &$flashes)
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function peek($type, $default = null)
|
public function add($type, $message)
|
||||||
|
{
|
||||||
|
$this->flashes['new'][$type][] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function peek($type, array $default = array())
|
||||||
{
|
{
|
||||||
return $this->has($type) ? $this->flashes['display'][$type] : $default;
|
return $this->has($type) ? $this->flashes['display'][$type] : $default;
|
||||||
}
|
}
|
||||||
|
@ -85,13 +93,13 @@ public function peek($type, $default = null)
|
||||||
*/
|
*/
|
||||||
public function peekAll()
|
public function peekAll()
|
||||||
{
|
{
|
||||||
return array_key_exists('display', $this->flashes) ? (array)$this->flashes['display'] : array();
|
return array_key_exists('display', $this->flashes) ? (array) $this->flashes['display'] : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function get($type, $default = null)
|
public function get($type, array $default = array())
|
||||||
{
|
{
|
||||||
$return = $default;
|
$return = $default;
|
||||||
|
|
||||||
|
@ -129,9 +137,9 @@ public function setAll(array $messages)
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function set($type, $message)
|
public function set($type, $messages)
|
||||||
{
|
{
|
||||||
$this->flashes['new'][$type] = $message;
|
$this->flashes['new'][$type] = (array) $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -139,7 +147,7 @@ public function set($type, $message)
|
||||||
*/
|
*/
|
||||||
public function has($type)
|
public function has($type)
|
||||||
{
|
{
|
||||||
return array_key_exists($type, $this->flashes['display']);
|
return array_key_exists($type, $this->flashes['display']) && $this->flashes['display'][$type];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,9 +171,6 @@ public function getStorageKey()
|
||||||
*/
|
*/
|
||||||
public function clear()
|
public function clear()
|
||||||
{
|
{
|
||||||
$return = $this->all();
|
return $this->all();
|
||||||
$this->flashes = array('display' => array(), 'new' => array());
|
|
||||||
|
|
||||||
return $return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* @author Drak <drak@zikula.org>
|
* @author Drak <drak@zikula.org>
|
||||||
*/
|
*/
|
||||||
class FlashBag implements FlashBagInterface
|
class FlashBag implements FlashBagInterface, \IteratorAggregate, \Countable
|
||||||
{
|
{
|
||||||
private $name = 'flashes';
|
private $name = 'flashes';
|
||||||
|
|
||||||
|
@ -68,7 +68,15 @@ public function initialize(array &$flashes)
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function peek($type, $default = null)
|
public function add($type, $message)
|
||||||
|
{
|
||||||
|
$this->flashes[$type][] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function peek($type, array $default =array())
|
||||||
{
|
{
|
||||||
return $this->has($type) ? $this->flashes[$type] : $default;
|
return $this->has($type) ? $this->flashes[$type] : $default;
|
||||||
}
|
}
|
||||||
|
@ -84,7 +92,7 @@ public function peekAll()
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function get($type, $default = null)
|
public function get($type, array $default = array())
|
||||||
{
|
{
|
||||||
if (!$this->has($type)) {
|
if (!$this->has($type)) {
|
||||||
return $default;
|
return $default;
|
||||||
|
@ -111,9 +119,9 @@ public function all()
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function set($type, $message)
|
public function set($type, $messages)
|
||||||
{
|
{
|
||||||
$this->flashes[$type] = $message;
|
$this->flashes[$type] = (array) $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,7 +137,7 @@ public function setAll(array $messages)
|
||||||
*/
|
*/
|
||||||
public function has($type)
|
public function has($type)
|
||||||
{
|
{
|
||||||
return array_key_exists($type, $this->flashes);
|
return array_key_exists($type, $this->flashes) && $this->flashes[$type];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,4 +163,24 @@ public function clear()
|
||||||
{
|
{
|
||||||
return $this->all();
|
return $this->all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator for flashes.
|
||||||
|
*
|
||||||
|
* @return \ArrayIterator An \ArrayIterator instance
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->all());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of flashes.
|
||||||
|
*
|
||||||
|
* @return int The number of flashes
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->flashes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,51 +21,59 @@
|
||||||
interface FlashBagInterface extends SessionBagInterface
|
interface FlashBagInterface extends SessionBagInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Registers a message for a given type.
|
* Adds a flash message for type.
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $message
|
* @param string $message
|
||||||
*/
|
*/
|
||||||
function set($type, $message);
|
public function add($type, $message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets flash message for a given type.
|
* Registers a message for a given type.
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @param string|array $message
|
||||||
|
*/
|
||||||
|
public function set($type, $message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets flash messages for a given type.
|
||||||
*
|
*
|
||||||
* @param string $type Message category type.
|
* @param string $type Message category type.
|
||||||
* @param string $default Default value if $type doee not exist.
|
* @param array $default Default value if $type does not exist.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
function peek($type, $default = null);
|
public function peek($type, array $default = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets all flash messages.
|
* Gets all flash messages.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function peekAll();
|
public function peekAll();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets and clears flash from the stack.
|
* Gets and clears flash from the stack.
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @param string $default Default value if $type doee not exist.
|
* @param array $default Default value if $type does not exist.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
function get($type, $default = null);
|
public function get($type, array $default = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets and clears flashes from the stack.
|
* Gets and clears flashes from the stack.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function all();
|
public function all();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets all flash messages.
|
* Sets all flash messages.
|
||||||
*/
|
*/
|
||||||
function setAll(array $messages);
|
public function setAll(array $messages);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has flash messages for a given type?
|
* Has flash messages for a given type?
|
||||||
|
@ -74,12 +82,12 @@ function setAll(array $messages);
|
||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*/
|
*/
|
||||||
function has($type);
|
public function has($type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all defined types.
|
* Returns a list of all defined types.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
function keys();
|
public function keys();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class Session implements SessionInterface
|
class Session implements SessionInterface, \IteratorAggregate, \Countable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Storage driver.
|
* Storage driver.
|
||||||
|
@ -57,13 +57,13 @@ public function __construct(SessionStorageInterface $storage = null, AttributeBa
|
||||||
{
|
{
|
||||||
$this->storage = $storage ?: new NativeSessionStorage();
|
$this->storage = $storage ?: new NativeSessionStorage();
|
||||||
|
|
||||||
$attributeBag = $attributes ?: new AttributeBag();
|
$attributes = $attributes ?: new AttributeBag();
|
||||||
$this->attributeName = $attributeBag->getName();
|
$this->attributeName = $attributes->getName();
|
||||||
$this->registerBag($attributeBag);
|
$this->registerBag($attributes);
|
||||||
|
|
||||||
$flashBag = $flashes ?: new FlashBag();
|
$flashes = $flashes ?: new FlashBag();
|
||||||
$this->flashName = $flashBag->getName();
|
$this->flashName = $flashes->getName();
|
||||||
$this->registerBag($flashBag);
|
$this->registerBag($flashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,19 +133,47 @@ public function clear()
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function invalidate()
|
public function isStarted()
|
||||||
{
|
{
|
||||||
$this->storage->clear();
|
return $this->storage->isStarted();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->storage->regenerate(true);
|
/**
|
||||||
|
* Returns an iterator for attributes.
|
||||||
|
*
|
||||||
|
* @return \ArrayIterator An \ArrayIterator instance
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \ArrayIterator($this->storage->getBag($this->attributeName)->all());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of attributes.
|
||||||
|
*
|
||||||
|
* @return int The number of attributes
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return count($this->storage->getBag($this->attributeName)->all());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function migrate($destroy = false)
|
public function invalidate($lifetime = null)
|
||||||
{
|
{
|
||||||
return $this->storage->regenerate($destroy);
|
$this->storage->clear();
|
||||||
|
|
||||||
|
return $this->migrate(true, $lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function migrate($destroy = false, $lifetime = null)
|
||||||
|
{
|
||||||
|
return $this->storage->regenerate($destroy, $lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,9 +217,15 @@ public function setName($name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a SessionBagInterface with the session.
|
* {@inheritdoc}
|
||||||
*
|
*/
|
||||||
* @param SessionBagInterface $bag
|
public function getMetadataBag()
|
||||||
|
{
|
||||||
|
return $this->storage->getMetadataBag();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function registerBag(SessionBagInterface $bag)
|
public function registerBag(SessionBagInterface $bag)
|
||||||
{
|
{
|
||||||
|
@ -199,11 +233,7 @@ public function registerBag(SessionBagInterface $bag)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get's a bag instance.
|
* {@inheritdoc}
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
*
|
|
||||||
* @return SessionBagInterface
|
|
||||||
*/
|
*/
|
||||||
public function getBag($name)
|
public function getBag($name)
|
||||||
{
|
{
|
||||||
|
@ -229,7 +259,20 @@ public function getFlashBag()
|
||||||
*/
|
*/
|
||||||
public function getFlashes()
|
public function getFlashes()
|
||||||
{
|
{
|
||||||
return $this->getBag('flashes')->all();
|
$all = $this->getBag($this->flashName)->all();
|
||||||
|
|
||||||
|
$return = array();
|
||||||
|
if ($all) {
|
||||||
|
foreach ($all as $name => $array) {
|
||||||
|
if (is_numeric(key($array))) {
|
||||||
|
$return[$name] = reset($array);
|
||||||
|
} else {
|
||||||
|
$return[$name] = $array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -239,7 +282,9 @@ public function getFlashes()
|
||||||
*/
|
*/
|
||||||
public function setFlashes($values)
|
public function setFlashes($values)
|
||||||
{
|
{
|
||||||
$this->getBag('flashes')->setAll($values);
|
foreach ($values as $name => $value) {
|
||||||
|
$this->getBag($this->flashName)->set($name, $value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,7 +297,9 @@ public function setFlashes($values)
|
||||||
*/
|
*/
|
||||||
public function getFlash($name, $default = null)
|
public function getFlash($name, $default = null)
|
||||||
{
|
{
|
||||||
return $this->getBag('flashes')->get($name, $default);
|
$return = $this->getBag($this->flashName)->get($name);
|
||||||
|
|
||||||
|
return empty($return) ? $default : reset($return);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,7 +310,7 @@ public function getFlash($name, $default = null)
|
||||||
*/
|
*/
|
||||||
public function setFlash($name, $value)
|
public function setFlash($name, $value)
|
||||||
{
|
{
|
||||||
$this->getBag('flashes')->set($name, $value);
|
$this->getBag($this->flashName)->set($name, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,7 +322,7 @@ public function setFlash($name, $value)
|
||||||
*/
|
*/
|
||||||
public function hasFlash($name)
|
public function hasFlash($name)
|
||||||
{
|
{
|
||||||
return $this->getBag('flashes')->has($name);
|
return $this->getBag($this->flashName)->has($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,7 +332,7 @@ public function hasFlash($name)
|
||||||
*/
|
*/
|
||||||
public function removeFlash($name)
|
public function removeFlash($name)
|
||||||
{
|
{
|
||||||
$this->getBag('flashes')->get($name);
|
$this->getBag($this->flashName)->get($name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,6 +342,6 @@ public function removeFlash($name)
|
||||||
*/
|
*/
|
||||||
public function clearFlashes()
|
public function clearFlashes()
|
||||||
{
|
{
|
||||||
return $this->getBag('flashes')->clear();
|
return $this->getBag($this->flashName)->clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,26 +23,26 @@ interface SessionBagInterface
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function getName();
|
public function getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the Bag
|
* Initializes the Bag
|
||||||
*
|
*
|
||||||
* @param array $array
|
* @param array $array
|
||||||
*/
|
*/
|
||||||
function initialize(array &$array);
|
public function initialize(array &$array);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the storage key for this bag.
|
* Gets the storage key for this bag.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function getStorageKey();
|
public function getStorageKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears out data from bag.
|
* Clears out data from bag.
|
||||||
*
|
*
|
||||||
* @return mixed Whatever data was contained.
|
* @return mixed Whatever data was contained.
|
||||||
*/
|
*/
|
||||||
function clear();
|
public function clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\Session;
|
namespace Symfony\Component\HttpFoundation\Session;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for the session.
|
* Interface for the session.
|
||||||
*
|
*
|
||||||
|
@ -27,7 +29,7 @@ interface SessionInterface
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function start();
|
public function start();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session ID.
|
* Returns the session ID.
|
||||||
|
@ -36,7 +38,7 @@ function start();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function getId();
|
public function getId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the session ID
|
* Sets the session ID
|
||||||
|
@ -45,7 +47,7 @@ function getId();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function setId($id);
|
public function setId($id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session name.
|
* Returns the session name.
|
||||||
|
@ -54,7 +56,7 @@ function setId($id);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function getName();
|
public function getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the session name.
|
* Sets the session name.
|
||||||
|
@ -63,7 +65,7 @@ function getName();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function setName($name);
|
public function setName($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalidates the current session.
|
* Invalidates the current session.
|
||||||
|
@ -71,23 +73,32 @@ function setName($name);
|
||||||
* Clears all session attributes and flashes and regenerates the
|
* Clears all session attributes and flashes and regenerates the
|
||||||
* session and deletes the old session from persistence.
|
* session and deletes the old session from persistence.
|
||||||
*
|
*
|
||||||
|
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||||
|
* will leave the system settings unchanged, 0 sets the cookie
|
||||||
|
* to expire with browser session. Time is in seconds, and is
|
||||||
|
* not a Unix timestamp.
|
||||||
|
*
|
||||||
* @return Boolean True if session invalidated, false if error.
|
* @return Boolean True if session invalidated, false if error.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function invalidate();
|
public function invalidate($lifetime = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrates the current session to a new session id while maintaining all
|
* Migrates the current session to a new session id while maintaining all
|
||||||
* session attributes.
|
* session attributes.
|
||||||
*
|
*
|
||||||
* @param Boolean $destroy Whether to delete the old session or leave it to garbage collection.
|
* @param Boolean $destroy Whether to delete the old session or leave it to garbage collection.
|
||||||
|
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||||
|
* will leave the system settings unchanged, 0 sets the cookie
|
||||||
|
* to expire with browser session. Time is in seconds, and is
|
||||||
|
* not a Unix timestamp.
|
||||||
*
|
*
|
||||||
* @return Boolean True if session migrated, false if error.
|
* @return Boolean True if session migrated, false if error.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function migrate($destroy = false);
|
public function migrate($destroy = false, $lifetime = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force the session to be saved and closed.
|
* Force the session to be saved and closed.
|
||||||
|
@ -96,7 +107,7 @@ function migrate($destroy = false);
|
||||||
* the session will be automatically saved at the end of
|
* the session will be automatically saved at the end of
|
||||||
* code execution.
|
* code execution.
|
||||||
*/
|
*/
|
||||||
function save();
|
public function save();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if an attribute is defined.
|
* Checks if an attribute is defined.
|
||||||
|
@ -107,7 +118,7 @@ function save();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function has($name);
|
public function has($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an attribute.
|
* Returns an attribute.
|
||||||
|
@ -119,7 +130,7 @@ function has($name);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function get($name, $default = null);
|
public function get($name, $default = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an attribute.
|
* Sets an attribute.
|
||||||
|
@ -129,7 +140,7 @@ function get($name, $default = null);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function set($name, $value);
|
public function set($name, $value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns attributes.
|
* Returns attributes.
|
||||||
|
@ -138,14 +149,14 @@ function set($name, $value);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function all();
|
public function all();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets attributes.
|
* Sets attributes.
|
||||||
*
|
*
|
||||||
* @param array $attributes Attributes
|
* @param array $attributes Attributes
|
||||||
*/
|
*/
|
||||||
function replace(array $attributes);
|
public function replace(array $attributes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes an attribute.
|
* Removes an attribute.
|
||||||
|
@ -156,12 +167,42 @@ function replace(array $attributes);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function remove($name);
|
public function remove($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all attributes.
|
* Clears all attributes.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function clear();
|
public function clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the session was started.
|
||||||
|
*
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public function isStarted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a SessionBagInterface with the session.
|
||||||
|
*
|
||||||
|
* @param SessionBagInterface $bag
|
||||||
|
*/
|
||||||
|
public function registerBag(SessionBagInterface $bag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a bag instance by name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return SessionBagInterface
|
||||||
|
*/
|
||||||
|
public function getBag($name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets session meta.
|
||||||
|
*
|
||||||
|
* @return MetadataBag
|
||||||
|
*/
|
||||||
|
public function getMetadataBag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,85 +19,55 @@
|
||||||
class MemcacheSessionHandler implements \SessionHandlerInterface
|
class MemcacheSessionHandler implements \SessionHandlerInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Memcache driver.
|
* @var \Memcache Memcache driver.
|
||||||
*
|
|
||||||
* @var \Memcache
|
|
||||||
*/
|
*/
|
||||||
private $memcache;
|
private $memcache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* @var integer Time to live in seconds
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
*/
|
||||||
private $memcacheOptions;
|
private $ttl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key prefix for shared environments.
|
* @var string Key prefix for shared environments.
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
*/
|
||||||
private $prefix;
|
private $prefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* List of available options:
|
||||||
|
* * prefix: The prefix to use for the memcache keys in order to avoid collision
|
||||||
|
* * expiretime: The time to live in seconds
|
||||||
|
*
|
||||||
* @param \Memcache $memcache A \Memcache instance
|
* @param \Memcache $memcache A \Memcache instance
|
||||||
* @param array $memcacheOptions An associative array of Memcache options
|
* @param array $options An associative array of Memcache options
|
||||||
* @param array $options Session configuration options.
|
*
|
||||||
|
* @throws \InvalidArgumentException When unsupported options are passed
|
||||||
*/
|
*/
|
||||||
public function __construct(\Memcache $memcache, array $memcacheOptions = array(), array $options = array())
|
public function __construct(\Memcache $memcache, array $options = array())
|
||||||
{
|
{
|
||||||
$this->memcache = $memcache;
|
if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
|
||||||
|
throw new \InvalidArgumentException(sprintf(
|
||||||
// defaults
|
'The following options are not supported "%s"', implode(', ', $diff)
|
||||||
if (!isset($memcacheOptions['serverpool'])) {
|
|
||||||
$memcacheOptions['serverpool'] = array(array(
|
|
||||||
'host' => '127.0.0.1',
|
|
||||||
'port' => 11211,
|
|
||||||
'timeout' => 1,
|
|
||||||
'persistent' => false,
|
|
||||||
'weight' => 1,
|
|
||||||
'retry_interval' => 15,
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$memcacheOptions['expiretime'] = isset($memcacheOptions['expiretime']) ? (int)$memcacheOptions['expiretime'] : 86400;
|
$this->memcache = $memcache;
|
||||||
$this->prefix = isset($memcacheOptions['prefix']) ? $memcacheOptions['prefix'] : 'sf2s';
|
$this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
|
||||||
|
$this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
|
||||||
$this->memcacheOptions = $memcacheOptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function addServer(array $server)
|
|
||||||
{
|
|
||||||
if (!array_key_exists('host', $server)) {
|
|
||||||
throw new \InvalidArgumentException('host key must be set');
|
|
||||||
}
|
|
||||||
|
|
||||||
$server['port'] = isset($server['port']) ? (int)$server['port'] : 11211;
|
|
||||||
$server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1;
|
|
||||||
$server['persistent'] = isset($server['persistent']) ? (bool)$server['persistent'] : false;
|
|
||||||
$server['weight'] = isset($server['weight']) ? (int)$server['weight'] : 1;
|
|
||||||
$server['retry_interval'] = isset($server['retry_interval']) ? (int)$server['retry_interval'] : 15;
|
|
||||||
|
|
||||||
$this->memcache->addserver($server['host'], $server['port'], $server['persistent'],$server['weight'],$server['timeout'],$server['retry_interval']);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function open($savePath, $sessionName)
|
public function open($savePath, $sessionName)
|
||||||
{
|
{
|
||||||
foreach ($this->memcacheOptions['serverpool'] as $server) {
|
|
||||||
$this->addServer($server);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
|
@ -105,7 +75,7 @@ public function close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function read($sessionId)
|
public function read($sessionId)
|
||||||
{
|
{
|
||||||
|
@ -113,15 +83,15 @@ public function read($sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function write($sessionId, $data)
|
public function write($sessionId, $data)
|
||||||
{
|
{
|
||||||
return $this->memcache->set($this->prefix.$sessionId, $data, 0, $this->memcacheOptions['expiretime']);
|
return $this->memcache->set($this->prefix.$sessionId, $data, 0, time() + $this->ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function destroy($sessionId)
|
public function destroy($sessionId)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +99,7 @@ public function destroy($sessionId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function gc($lifetime)
|
public function gc($lifetime)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,55 +24,56 @@
|
||||||
class MemcachedSessionHandler implements \SessionHandlerInterface
|
class MemcachedSessionHandler implements \SessionHandlerInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Memcached driver.
|
* @var \Memcached Memcached driver.
|
||||||
*
|
|
||||||
* @var \Memcached
|
|
||||||
*/
|
*/
|
||||||
private $memcached;
|
private $memcached;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options.
|
* @var integer Time to live in seconds
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
*/
|
||||||
private $memcachedOptions;
|
private $ttl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string Key prefix for shared environments.
|
||||||
|
*/
|
||||||
|
private $prefix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* List of available options:
|
||||||
|
* * prefix: The prefix to use for the memcached keys in order to avoid collision
|
||||||
|
* * expiretime: The time to live in seconds
|
||||||
|
*
|
||||||
* @param \Memcached $memcached A \Memcached instance
|
* @param \Memcached $memcached A \Memcached instance
|
||||||
* @param array $memcachedOptions An associative array of Memcached options
|
* @param array $options An associative array of Memcached options
|
||||||
* @param array $options Session configuration options.
|
*
|
||||||
|
* @throws \InvalidArgumentException When unsupported options are passed
|
||||||
*/
|
*/
|
||||||
public function __construct(\Memcached $memcached, array $memcachedOptions = array(), array $options = array())
|
public function __construct(\Memcached $memcached, array $options = array())
|
||||||
{
|
{
|
||||||
$this->memcached = $memcached;
|
$this->memcached = $memcached;
|
||||||
|
|
||||||
// defaults
|
if ($diff = array_diff(array_keys($options), array('prefix', 'expiretime'))) {
|
||||||
if (!isset($memcachedOptions['serverpool'])) {
|
throw new \InvalidArgumentException(sprintf(
|
||||||
$memcachedOptions['serverpool'][] = array(
|
'The following options are not supported "%s"', implode(', ', $diff)
|
||||||
'host' => '127.0.0.1',
|
));
|
||||||
'port' => 11211,
|
|
||||||
'weight' => 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$memcachedOptions['expiretime'] = isset($memcachedOptions['expiretime']) ? (int)$memcachedOptions['expiretime'] : 86400;
|
$this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;
|
||||||
|
$this->prefix = isset($options['prefix']) ? $options['prefix'] : 'sf2s';
|
||||||
$this->memcached->setOption(\Memcached::OPT_PREFIX_KEY, isset($memcachedOptions['prefix']) ? $memcachedOptions['prefix'] : 'sf2s');
|
|
||||||
|
|
||||||
$this->memcachedOptions = $memcachedOptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function open($savePath, $sessionName)
|
public function open($savePath, $sessionName)
|
||||||
{
|
{
|
||||||
return $this->memcached->addServers($this->memcachedOptions['serverpool']);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
|
@ -80,51 +81,35 @@ public function close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function read($sessionId)
|
public function read($sessionId)
|
||||||
{
|
{
|
||||||
return $this->memcached->get($sessionId) ?: '';
|
return $this->memcached->get($this->prefix.$sessionId) ?: '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function write($sessionId, $data)
|
public function write($sessionId, $data)
|
||||||
{
|
{
|
||||||
return $this->memcached->set($sessionId, $data, $this->memcachedOptions['expiretime']);
|
return $this->memcached->set($this->prefix.$sessionId, $data, time() + $this->ttl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function destroy($sessionId)
|
public function destroy($sessionId)
|
||||||
{
|
{
|
||||||
return $this->memcached->delete($sessionId);
|
return $this->memcached->delete($this->prefix.$sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function gc($lifetime)
|
public function gc($lifetime)
|
||||||
{
|
{
|
||||||
// not required here because memcached will auto expire the records anyhow.
|
// not required here because memcached will auto expire the records anyhow.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a server to the memcached handler.
|
|
||||||
*
|
|
||||||
* @param array $server
|
|
||||||
*/
|
|
||||||
protected function addServer(array $server)
|
|
||||||
{
|
|
||||||
if (array_key_exists('host', $server)) {
|
|
||||||
throw new \InvalidArgumentException('host key must be set');
|
|
||||||
}
|
|
||||||
$server['port'] = isset($server['port']) ? (int)$server['port'] : 11211;
|
|
||||||
$server['timeout'] = isset($server['timeout']) ? (int)$server['timeout'] : 1;
|
|
||||||
$server['presistent'] = isset($server['presistent']) ? (bool)$server['presistent'] : false;
|
|
||||||
$server['weight'] = isset($server['weight']) ? (bool)$server['weight'] : 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
150
laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php
vendored
Executable file
150
laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/Handler/MongoDbSessionHandler.php
vendored
Executable file
|
@ -0,0 +1,150 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MongoDB session handler
|
||||||
|
*
|
||||||
|
* @author Markus Bachmann <markus.bachmann@bachi.biz>
|
||||||
|
*/
|
||||||
|
class MongoDbSessionHandler implements \SessionHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Mongo
|
||||||
|
*/
|
||||||
|
private $mongo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \MongoCollection
|
||||||
|
*/
|
||||||
|
private $collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param \Mongo|\MongoClient $mongo A MongoClient or Mongo instance
|
||||||
|
* @param array $options An associative array of field options
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
|
||||||
|
* @throws \InvalidArgumentException When "database" or "collection" not provided
|
||||||
|
*/
|
||||||
|
public function __construct($mongo, array $options)
|
||||||
|
{
|
||||||
|
if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
|
||||||
|
throw new \InvalidArgumentException('MongoClient or Mongo instance required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($options['database']) || !isset($options['collection'])) {
|
||||||
|
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->mongo = $mongo;
|
||||||
|
|
||||||
|
$this->options = array_merge(array(
|
||||||
|
'id_field' => 'sess_id',
|
||||||
|
'data_field' => 'sess_data',
|
||||||
|
'time_field' => 'sess_time',
|
||||||
|
), $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function open($savePath, $sessionName)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function close()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function destroy($sessionId)
|
||||||
|
{
|
||||||
|
$this->getCollection()->remove(
|
||||||
|
array($this->options['id_field'] => $sessionId),
|
||||||
|
array('justOne' => true)
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function gc($lifetime)
|
||||||
|
{
|
||||||
|
$time = new \MongoTimestamp(time() - $lifetime);
|
||||||
|
|
||||||
|
$this->getCollection()->remove(array(
|
||||||
|
$this->options['time_field'] => array('$lt' => $time),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc]
|
||||||
|
*/
|
||||||
|
public function write($sessionId, $data)
|
||||||
|
{
|
||||||
|
$data = array(
|
||||||
|
$this->options['id_field'] => $sessionId,
|
||||||
|
$this->options['data_field'] => new \MongoBinData($data, \MongoBinData::BYTE_ARRAY),
|
||||||
|
$this->options['time_field'] => new \MongoTimestamp()
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->getCollection()->update(
|
||||||
|
array($this->options['id_field'] => $sessionId),
|
||||||
|
array('$set' => $data),
|
||||||
|
array('upsert' => true)
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public function read($sessionId)
|
||||||
|
{
|
||||||
|
$dbData = $this->getCollection()->findOne(array(
|
||||||
|
$this->options['id_field'] => $sessionId,
|
||||||
|
));
|
||||||
|
|
||||||
|
return null === $dbData ? '' : $dbData[$this->options['data_field']]->bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a "MongoCollection" instance
|
||||||
|
*
|
||||||
|
* @return \MongoCollection
|
||||||
|
*/
|
||||||
|
private function getCollection()
|
||||||
|
{
|
||||||
|
if (null === $this->collection) {
|
||||||
|
$this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->collection;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,13 @@ class NativeFileSessionHandler extends NativeSessionHandler
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string $savePath Path of directory to save session files. Default null will leave setting as defined by PHP.
|
* @param string $savePath Path of directory to save session files.
|
||||||
|
* Default null will leave setting as defined by PHP.
|
||||||
|
* '/path', 'N;/path', or 'N;octal-mode;/path
|
||||||
|
*
|
||||||
|
* @see http://php.net/session.configuration.php#ini.session.save-path for further details.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException On invalid $savePath
|
||||||
*/
|
*/
|
||||||
public function __construct($savePath = null)
|
public function __construct($savePath = null)
|
||||||
{
|
{
|
||||||
|
@ -31,11 +37,22 @@ public function __construct($savePath = null)
|
||||||
$savePath = ini_get('session.save_path');
|
$savePath = ini_get('session.save_path');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($savePath && !is_dir($savePath)) {
|
$baseDir = $savePath;
|
||||||
mkdir($savePath, 0777, true);
|
|
||||||
|
if ($count = substr_count($savePath, ';')) {
|
||||||
|
if ($count > 2) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// characters after last ';' are the path
|
||||||
|
$baseDir = ltrim(strrchr($savePath, ';'), ';');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($baseDir && !is_dir($baseDir)) {
|
||||||
|
mkdir($baseDir, 0777, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ini_set('session.save_handler', 'files');
|
|
||||||
ini_set('session.save_path', $savePath);
|
ini_set('session.save_path', $savePath);
|
||||||
|
ini_set('session.save_handler', 'files');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NativeMemcacheSessionHandler.
|
|
||||||
*
|
|
||||||
* Driver for the memcache session save hadlers provided by the memcache PHP extension.
|
|
||||||
*
|
|
||||||
* @see http://php.net/memcache
|
|
||||||
*
|
|
||||||
* @author Drak <drak@zikula.org>
|
|
||||||
*/
|
|
||||||
class NativeMemcacheSessionHandler extends NativeSessionHandler
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $savePath Path of memcache server.
|
|
||||||
* @param array $options Session configuration options.
|
|
||||||
*/
|
|
||||||
public function __construct($savePath = 'tcp://127.0.0.1:11211?persistent=0', array $options = array())
|
|
||||||
{
|
|
||||||
if (!extension_loaded('memcache')) {
|
|
||||||
throw new \RuntimeException('PHP does not have "memcache" session module registered');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $savePath) {
|
|
||||||
$savePath = ini_get('session.save_path');
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set('session.save_handler', 'memcache');
|
|
||||||
ini_set('session.save_path', $savePath);
|
|
||||||
|
|
||||||
$this->setOptions($options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set any memcached ini values.
|
|
||||||
*
|
|
||||||
* @see http://php.net/memcache.ini
|
|
||||||
*/
|
|
||||||
protected function setOptions(array $options)
|
|
||||||
{
|
|
||||||
foreach ($options as $key => $value) {
|
|
||||||
if (in_array($key, array(
|
|
||||||
'memcache.allow_failover', 'memcache.max_failover_attempts',
|
|
||||||
'memcache.chunk_size', 'memcache.default_port', 'memcache.hash_strategy',
|
|
||||||
'memcache.hash_function', 'memcache.protocol', 'memcache.redundancy',
|
|
||||||
'memcache.session_redundancy', 'memcache.compress_threshold',
|
|
||||||
'memcache.lock_timeout'))) {
|
|
||||||
ini_set($key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NativeMemcachedSessionHandler.
|
|
||||||
*
|
|
||||||
* Driver for the memcached session save hadlers provided by the memcached PHP extension.
|
|
||||||
*
|
|
||||||
* @see http://php.net/memcached.sessions
|
|
||||||
*
|
|
||||||
* @author Drak <drak@zikula.org>
|
|
||||||
*/
|
|
||||||
class NativeMemcachedSessionHandler extends NativeSessionHandler
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $savePath Comma separated list of servers: e.g. memcache1.example.com:11211,memcache2.example.com:11211
|
|
||||||
* @param array $options Session configuration options.
|
|
||||||
*/
|
|
||||||
public function __construct($savePath = '127.0.0.1:11211', array $options = array())
|
|
||||||
{
|
|
||||||
if (!extension_loaded('memcached')) {
|
|
||||||
throw new \RuntimeException('PHP does not have "memcached" session module registered');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $savePath) {
|
|
||||||
$savePath = ini_get('session.save_path');
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set('session.save_handler', 'memcached');
|
|
||||||
ini_set('session.save_path', $savePath);
|
|
||||||
|
|
||||||
$this->setOptions($options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set any memcached ini values.
|
|
||||||
*
|
|
||||||
* @see https://github.com/php-memcached-dev/php-memcached/blob/master/memcached.ini
|
|
||||||
*/
|
|
||||||
protected function setOptions(array $options)
|
|
||||||
{
|
|
||||||
foreach ($options as $key => $value) {
|
|
||||||
if (in_array($key, array(
|
|
||||||
'memcached.sess_locking', 'memcached.sess_lock_wait',
|
|
||||||
'memcached.sess_prefix', 'memcached.compression_type',
|
|
||||||
'memcached.compression_factor', 'memcached.compression_threshold',
|
|
||||||
'memcached.serializer'))) {
|
|
||||||
ini_set($key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of the Symfony package.
|
|
||||||
*
|
|
||||||
* (c) Fabien Potencier <fabien@symfony.com>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* NativeSqliteSessionHandler.
|
|
||||||
*
|
|
||||||
* Driver for the sqlite session save hadlers provided by the SQLite PHP extension.
|
|
||||||
*
|
|
||||||
* @author Drak <drak@zikula.org>
|
|
||||||
*/
|
|
||||||
class NativeSqliteSessionHandler extends NativeSessionHandler
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $savePath Path to SQLite database file itself.
|
|
||||||
* @param array $options Session configuration options.
|
|
||||||
*/
|
|
||||||
public function __construct($savePath, array $options = array())
|
|
||||||
{
|
|
||||||
if (!extension_loaded('sqlite')) {
|
|
||||||
throw new \RuntimeException('PHP does not have "sqlite" session module registered');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $savePath) {
|
|
||||||
$savePath = ini_get('session.save_path');
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set('session.save_handler', 'sqlite');
|
|
||||||
ini_set('session.save_path', $savePath);
|
|
||||||
|
|
||||||
$this->setOptions($options);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set any sqlite ini values.
|
|
||||||
*
|
|
||||||
* @see http://php.net/sqlite.configuration
|
|
||||||
*/
|
|
||||||
protected function setOptions(array $options)
|
|
||||||
{
|
|
||||||
foreach ($options as $key => $value) {
|
|
||||||
if (in_array($key, array('sqlite.assoc_case'))) {
|
|
||||||
ini_set($key, $value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,7 @@
|
||||||
/**
|
/**
|
||||||
* NullSessionHandler.
|
* NullSessionHandler.
|
||||||
*
|
*
|
||||||
* Can be used in unit testing or in a sitation where persisted sessions are not desired.
|
* Can be used in unit testing or in a situations where persisted sessions are not desired.
|
||||||
*
|
*
|
||||||
* @author Drak <drak@zikula.org>
|
* @author Drak <drak@zikula.org>
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,30 +20,30 @@
|
||||||
class PdoSessionHandler implements \SessionHandlerInterface
|
class PdoSessionHandler implements \SessionHandlerInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* PDO instance.
|
* @var \PDO PDO instance.
|
||||||
*
|
|
||||||
* @var \PDO
|
|
||||||
*/
|
*/
|
||||||
private $pdo;
|
private $pdo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database options.
|
* @var array Database options.
|
||||||
*
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
*/
|
||||||
private $dbOptions;
|
private $dbOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
|
* List of available options:
|
||||||
|
* * db_table: The name of the table [required]
|
||||||
|
* * db_id_col: The column where to store the session id [default: sess_id]
|
||||||
|
* * db_data_col: The column where to store the session data [default: sess_data]
|
||||||
|
* * db_time_col: The column where to store the timestamp [default: sess_time]
|
||||||
|
*
|
||||||
* @param \PDO $pdo A \PDO instance
|
* @param \PDO $pdo A \PDO instance
|
||||||
* @param array $dbOptions An associative array of DB options
|
* @param array $dbOptions An associative array of DB options
|
||||||
* @param array $options Session configuration options
|
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException When "db_table" option is not provided
|
* @throws \InvalidArgumentException When "db_table" option is not provided
|
||||||
*/
|
*/
|
||||||
public function __construct(\PDO $pdo, array $dbOptions = array(), array $options = array())
|
public function __construct(\PDO $pdo, array $dbOptions = array())
|
||||||
{
|
{
|
||||||
if (!array_key_exists('db_table', $dbOptions)) {
|
if (!array_key_exists('db_table', $dbOptions)) {
|
||||||
throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.');
|
throw new \InvalidArgumentException('You must provide the "db_table" option for a PdoSessionStorage.');
|
||||||
|
@ -58,7 +58,7 @@ public function __construct(\PDO $pdo, array $dbOptions = array(), array $option
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function open($path, $name)
|
public function open($path, $name)
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ public function open($path, $name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function close()
|
public function close()
|
||||||
{
|
{
|
||||||
|
@ -74,7 +74,7 @@ public function close()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function destroy($id)
|
public function destroy($id)
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ public function destroy($id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function gc($lifetime)
|
public function gc($lifetime)
|
||||||
{
|
{
|
||||||
|
@ -106,11 +106,11 @@ public function gc($lifetime)
|
||||||
$dbTimeCol = $this->dbOptions['db_time_col'];
|
$dbTimeCol = $this->dbOptions['db_time_col'];
|
||||||
|
|
||||||
// delete the session records that have expired
|
// delete the session records that have expired
|
||||||
$sql = "DELETE FROM $dbTable WHERE $dbTimeCol < (:time - $lifetime)";
|
$sql = "DELETE FROM $dbTable WHERE $dbTimeCol < :time";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$stmt = $this->pdo->prepare($sql);
|
$stmt = $this->pdo->prepare($sql);
|
||||||
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
|
$stmt->bindValue(':time', time() - $lifetime, \PDO::PARAM_INT);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
|
throw new \RuntimeException(sprintf('PDOException was thrown when trying to manipulate session data: %s', $e->getMessage()), 0, $e);
|
||||||
|
@ -120,7 +120,7 @@ public function gc($lifetime)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function read($id)
|
public function read($id)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +154,7 @@ public function read($id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function write($id, $data)
|
public function write($id, $data)
|
||||||
{
|
{
|
||||||
|
@ -164,15 +164,34 @@ public function write($id, $data)
|
||||||
$dbIdCol = $this->dbOptions['db_id_col'];
|
$dbIdCol = $this->dbOptions['db_id_col'];
|
||||||
$dbTimeCol = $this->dbOptions['db_time_col'];
|
$dbTimeCol = $this->dbOptions['db_time_col'];
|
||||||
|
|
||||||
$sql = ('mysql' === $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME))
|
|
||||||
? "INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time) "
|
|
||||||
."ON DUPLICATE KEY UPDATE $dbDataCol = VALUES($dbDataCol), $dbTimeCol = CASE WHEN $dbTimeCol = :time THEN (VALUES($dbTimeCol) + 1) ELSE VALUES($dbTimeCol) END"
|
|
||||||
: "UPDATE $dbTable SET $dbDataCol = :data, $dbTimeCol = :time WHERE $dbIdCol = :id";
|
|
||||||
|
|
||||||
try {
|
|
||||||
//session data can contain non binary safe characters so we need to encode it
|
//session data can contain non binary safe characters so we need to encode it
|
||||||
$encoded = base64_encode($data);
|
$encoded = base64_encode($data);
|
||||||
$stmt = $this->pdo->prepare($sql);
|
|
||||||
|
try {
|
||||||
|
$driver = $this->pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||||
|
|
||||||
|
if ('mysql' === $driver) {
|
||||||
|
// MySQL would report $stmt->rowCount() = 0 on UPDATE when the data is left unchanged
|
||||||
|
// it could result in calling createNewSession() whereas the session already exists in
|
||||||
|
// the DB which would fail as the id is unique
|
||||||
|
$stmt = $this->pdo->prepare(
|
||||||
|
"INSERT INTO $dbTable ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, :time) " .
|
||||||
|
"ON DUPLICATE KEY UPDATE $dbDataCol = VALUES($dbDataCol), $dbTimeCol = VALUES($dbTimeCol)"
|
||||||
|
);
|
||||||
|
$stmt->bindParam(':id', $id, \PDO::PARAM_STR);
|
||||||
|
$stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
|
||||||
|
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
|
||||||
|
$stmt->execute();
|
||||||
|
} elseif ('oci' === $driver) {
|
||||||
|
$stmt = $this->pdo->prepare("MERGE INTO $dbTable USING DUAL ON($dbIdCol = :id) ".
|
||||||
|
"WHEN NOT MATCHED THEN INSERT ($dbIdCol, $dbDataCol, $dbTimeCol) VALUES (:id, :data, sysdate) " .
|
||||||
|
"WHEN MATCHED THEN UPDATE SET $dbDataCol = :data WHERE $dbIdCol = :id");
|
||||||
|
|
||||||
|
$stmt->bindParam(':id', $id, \PDO::PARAM_STR);
|
||||||
|
$stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
|
||||||
|
$stmt->execute();
|
||||||
|
} else {
|
||||||
|
$stmt = $this->pdo->prepare("UPDATE $dbTable SET $dbDataCol = :data, $dbTimeCol = :time WHERE $dbIdCol = :id");
|
||||||
$stmt->bindParam(':id', $id, \PDO::PARAM_STR);
|
$stmt->bindParam(':id', $id, \PDO::PARAM_STR);
|
||||||
$stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
|
$stmt->bindParam(':data', $encoded, \PDO::PARAM_STR);
|
||||||
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
|
$stmt->bindValue(':time', time(), \PDO::PARAM_INT);
|
||||||
|
@ -183,6 +202,7 @@ public function write($id, $data)
|
||||||
// session_regenerate_id()
|
// session_regenerate_id()
|
||||||
$this->createNewSession($id, $data);
|
$this->createNewSession($id, $data);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (\PDOException $e) {
|
} catch (\PDOException $e) {
|
||||||
throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
|
throw new \RuntimeException(sprintf('PDOException was thrown when trying to write the session data: %s', $e->getMessage()), 0, $e);
|
||||||
}
|
}
|
||||||
|
|
160
laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MetadataBag.php
vendored
Executable file
160
laravel/vendor/Symfony/Component/HttpFoundation/Session/Storage/MetadataBag.php
vendored
Executable file
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata container.
|
||||||
|
*
|
||||||
|
* Adds metadata to the session.
|
||||||
|
*
|
||||||
|
* @author Drak <drak@zikula.org>
|
||||||
|
*/
|
||||||
|
class MetadataBag implements SessionBagInterface
|
||||||
|
{
|
||||||
|
const CREATED = 'c';
|
||||||
|
const UPDATED = 'u';
|
||||||
|
const LIFETIME = 'l';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name = '__metadata';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $storageKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $meta = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unix timestamp.
|
||||||
|
*
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private $lastUsed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param string $storageKey The key used to store bag in the session.
|
||||||
|
*/
|
||||||
|
public function __construct($storageKey = '_sf2_meta')
|
||||||
|
{
|
||||||
|
$this->storageKey = $storageKey;
|
||||||
|
$this->meta = array(self::CREATED => 0, self::UPDATED => 0, self::LIFETIME => 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function initialize(array &$array)
|
||||||
|
{
|
||||||
|
$this->meta = &$array;
|
||||||
|
|
||||||
|
if (isset($array[self::CREATED])) {
|
||||||
|
$this->lastUsed = $this->meta[self::UPDATED];
|
||||||
|
$this->meta[self::UPDATED] = time();
|
||||||
|
} else {
|
||||||
|
$this->stampCreated();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the lifetime that the session cookie was set with.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getLifetime()
|
||||||
|
{
|
||||||
|
return $this->meta[self::LIFETIME];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stamps a new session's metadata.
|
||||||
|
*
|
||||||
|
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||||
|
* will leave the system settings unchanged, 0 sets the cookie
|
||||||
|
* to expire with browser session. Time is in seconds, and is
|
||||||
|
* not a Unix timestamp.
|
||||||
|
*/
|
||||||
|
public function stampNew($lifetime = null)
|
||||||
|
{
|
||||||
|
$this->stampCreated($lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getStorageKey()
|
||||||
|
{
|
||||||
|
return $this->storageKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the created timestamp metadata.
|
||||||
|
*
|
||||||
|
* @return integer Unix timestamp
|
||||||
|
*/
|
||||||
|
public function getCreated()
|
||||||
|
{
|
||||||
|
return $this->meta[self::CREATED];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last used metadata.
|
||||||
|
*
|
||||||
|
* @return integer Unix timestamp
|
||||||
|
*/
|
||||||
|
public function getLastUsed()
|
||||||
|
{
|
||||||
|
return $this->lastUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function clear()
|
||||||
|
{
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets name.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*/
|
||||||
|
public function setName($name)
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function stampCreated($lifetime = null)
|
||||||
|
{
|
||||||
|
$timeStamp = time();
|
||||||
|
$this->meta[self::CREATED] = $this->meta[self::UPDATED] = $this->lastUsed = $timeStamp;
|
||||||
|
$this->meta[self::LIFETIME] = (null === $lifetime) ? ini_get('session.cookie_lifetime') : $lifetime;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MockArraySessionStorage mocks the session for unit tests.
|
* MockArraySessionStorage mocks the session for unit tests.
|
||||||
|
@ -52,14 +53,26 @@ class MockArraySessionStorage implements SessionStorageInterface
|
||||||
*/
|
*/
|
||||||
protected $data = array();
|
protected $data = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MetadataBag
|
||||||
|
*/
|
||||||
|
protected $metadataBag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $bags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string $name Session name
|
* @param string $name Session name
|
||||||
|
* @param MetadataBag $metaBag MetadataBag instance.
|
||||||
*/
|
*/
|
||||||
public function __construct($name = 'MOCKSESSID')
|
public function __construct($name = 'MOCKSESSID', MetadataBag $metaBag = null)
|
||||||
{
|
{
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
|
$this->setMetadataBag($metaBag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,16 +103,16 @@ public function start()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function regenerate($destroy = false)
|
public function regenerate($destroy = false, $lifetime = null)
|
||||||
{
|
{
|
||||||
if (!$this->started) {
|
if (!$this->started) {
|
||||||
$this->start();
|
$this->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->metadataBag->stampNew($lifetime);
|
||||||
$this->id = $this->generateId();
|
$this->id = $this->generateId();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -146,6 +159,9 @@ public function setName($name)
|
||||||
*/
|
*/
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
|
if (!$this->started || $this->closed) {
|
||||||
|
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed");
|
||||||
|
}
|
||||||
// nothing to do since we don't persist the session data
|
// nothing to do since we don't persist the session data
|
||||||
$this->closed = false;
|
$this->closed = false;
|
||||||
}
|
}
|
||||||
|
@ -191,6 +207,38 @@ public function getBag($name)
|
||||||
return $this->bags[$name];
|
return $this->bags[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isStarted()
|
||||||
|
{
|
||||||
|
return $this->started;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MetadataBag.
|
||||||
|
*
|
||||||
|
* @param MetadataBag $bag
|
||||||
|
*/
|
||||||
|
public function setMetadataBag(MetadataBag $bag = null)
|
||||||
|
{
|
||||||
|
if (null === $bag) {
|
||||||
|
$bag = new MetadataBag();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->metadataBag = $bag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MetadataBag.
|
||||||
|
*
|
||||||
|
* @return MetadataBag
|
||||||
|
*/
|
||||||
|
public function getMetadataBag()
|
||||||
|
{
|
||||||
|
return $this->metadataBag;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a session ID.
|
* Generates a session ID.
|
||||||
*
|
*
|
||||||
|
@ -206,7 +254,9 @@ protected function generateId()
|
||||||
|
|
||||||
protected function loadSession()
|
protected function loadSession()
|
||||||
{
|
{
|
||||||
foreach ($this->bags as $bag) {
|
$bags = array_merge($this->bags, array($this->metadataBag));
|
||||||
|
|
||||||
|
foreach ($bags as $bag) {
|
||||||
$key = $bag->getStorageKey();
|
$key = $bag->getStorageKey();
|
||||||
$this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array();
|
$this->data[$key] = isset($this->data[$key]) ? $this->data[$key] : array();
|
||||||
$bag->initialize($this->data[$key]);
|
$bag->initialize($this->data[$key]);
|
||||||
|
|
|
@ -29,13 +29,19 @@ class MockFileSessionStorage extends MockArraySessionStorage
|
||||||
*/
|
*/
|
||||||
private $savePath;
|
private $savePath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $sessionData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param string $savePath Path of directory to save session files.
|
* @param string $savePath Path of directory to save session files.
|
||||||
* @param string $name Session name.
|
* @param string $name Session name.
|
||||||
|
* @param MetadataBag $metaBag MetadataBag instance.
|
||||||
*/
|
*/
|
||||||
public function __construct($savePath = null, $name = 'MOCKSESSID')
|
public function __construct($savePath = null, $name = 'MOCKSESSID', MetadataBag $metaBag = null)
|
||||||
{
|
{
|
||||||
if (null === $savePath) {
|
if (null === $savePath) {
|
||||||
$savePath = sys_get_temp_dir();
|
$savePath = sys_get_temp_dir();
|
||||||
|
@ -47,7 +53,7 @@ public function __construct($savePath = null, $name = 'MOCKSESSID')
|
||||||
|
|
||||||
$this->savePath = $savePath;
|
$this->savePath = $savePath;
|
||||||
|
|
||||||
parent::__construct($name);
|
parent::__construct($name, $metaBag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,15 +79,17 @@ public function start()
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function regenerate($destroy = false)
|
public function regenerate($destroy = false, $lifetime = null)
|
||||||
{
|
{
|
||||||
|
if (!$this->started) {
|
||||||
|
$this->start();
|
||||||
|
}
|
||||||
|
|
||||||
if ($destroy) {
|
if ($destroy) {
|
||||||
$this->destroy();
|
$this->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->id = $this->generateId();
|
return parent::regenerate($destroy, $lifetime);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,7 +97,16 @@ public function regenerate($destroy = false)
|
||||||
*/
|
*/
|
||||||
public function save()
|
public function save()
|
||||||
{
|
{
|
||||||
|
if (!$this->started) {
|
||||||
|
throw new \RuntimeException("Trying to save a session that was not started yet or was already closed");
|
||||||
|
}
|
||||||
|
|
||||||
file_put_contents($this->getFilePath(), serialize($this->data));
|
file_put_contents($this->getFilePath(), serialize($this->data));
|
||||||
|
|
||||||
|
// this is needed for Silex, where the session object is re-used across requests
|
||||||
|
// in functional tests. In Symfony, the container is rebooted, so we don't have
|
||||||
|
// this issue
|
||||||
|
$this->started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
|
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy;
|
||||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
|
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
|
||||||
|
@ -45,17 +46,24 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||||
*/
|
*/
|
||||||
protected $saveHandler;
|
protected $saveHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var MetadataBag
|
||||||
|
*/
|
||||||
|
protected $metadataBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* Depending on how you want the storage driver to behave you probably
|
* Depending on how you want the storage driver to behave you probably
|
||||||
* want top override this constructor entirely.
|
* want to override this constructor entirely.
|
||||||
*
|
*
|
||||||
* List of options for $options array with their defaults.
|
* List of options for $options array with their defaults.
|
||||||
* @see http://php.net/session.configuration for options
|
* @see http://php.net/session.configuration for options
|
||||||
* but we omit 'session.' from the beginning of the keys for convenience.
|
* but we omit 'session.' from the beginning of the keys for convenience.
|
||||||
*
|
*
|
||||||
* auto_start, "0"
|
* ("auto_start", is not supported as it tells PHP to start a session before
|
||||||
|
* PHP starts to execute user-land code. Setting during runtime has no effect).
|
||||||
|
*
|
||||||
* cache_limiter, "nocache" (use "0" to prevent headers from being sent entirely).
|
* cache_limiter, "nocache" (use "0" to prevent headers from being sent entirely).
|
||||||
* cookie_domain, ""
|
* cookie_domain, ""
|
||||||
* cookie_httponly, ""
|
* cookie_httponly, ""
|
||||||
|
@ -85,11 +93,10 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||||
*
|
*
|
||||||
* @param array $options Session configuration options.
|
* @param array $options Session configuration options.
|
||||||
* @param object $handler SessionHandlerInterface.
|
* @param object $handler SessionHandlerInterface.
|
||||||
|
* @param MetadataBag $metaBag MetadataBag.
|
||||||
*/
|
*/
|
||||||
public function __construct(array $options = array(), $handler = null)
|
public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null)
|
||||||
{
|
{
|
||||||
// sensible defaults
|
|
||||||
ini_set('session.auto_start', 0); // by default we prefer to explicitly start the session using the class.
|
|
||||||
ini_set('session.cache_limiter', ''); // disable by default because it's managed by HeaderBag (if used)
|
ini_set('session.cache_limiter', ''); // disable by default because it's managed by HeaderBag (if used)
|
||||||
ini_set('session.use_cookies', 1);
|
ini_set('session.use_cookies', 1);
|
||||||
|
|
||||||
|
@ -99,6 +106,7 @@ public function __construct(array $options = array(), $handler = null)
|
||||||
register_shutdown_function('session_write_close');
|
register_shutdown_function('session_write_close');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->setMetadataBag($metaBag);
|
||||||
$this->setOptions($options);
|
$this->setOptions($options);
|
||||||
$this->setSaveHandler($handler);
|
$this->setSaveHandler($handler);
|
||||||
}
|
}
|
||||||
|
@ -165,7 +173,7 @@ public function getId()
|
||||||
*/
|
*/
|
||||||
public function setId($id)
|
public function setId($id)
|
||||||
{
|
{
|
||||||
return $this->saveHandler->setId($id);
|
$this->saveHandler->setId($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,8 +195,16 @@ public function setName($name)
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function regenerate($destroy = false)
|
public function regenerate($destroy = false, $lifetime = null)
|
||||||
{
|
{
|
||||||
|
if (null !== $lifetime) {
|
||||||
|
ini_set('session.cookie_lifetime', $lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($destroy) {
|
||||||
|
$this->metadataBag->stampNew();
|
||||||
|
}
|
||||||
|
|
||||||
return session_regenerate_id($destroy);
|
return session_regenerate_id($destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,15 +256,47 @@ public function getBag($name)
|
||||||
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
|
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ini_get('session.auto_start') && !$this->started) {
|
if ($this->saveHandler->isActive() && !$this->started) {
|
||||||
$this->start();
|
|
||||||
} elseif ($this->saveHandler->isActive() && !$this->started) {
|
|
||||||
$this->loadSession();
|
$this->loadSession();
|
||||||
|
} elseif (!$this->started) {
|
||||||
|
$this->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->bags[$name];
|
return $this->bags[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the MetadataBag.
|
||||||
|
*
|
||||||
|
* @param MetadataBag $metaBag
|
||||||
|
*/
|
||||||
|
public function setMetadataBag(MetadataBag $metaBag = null)
|
||||||
|
{
|
||||||
|
if (null === $metaBag) {
|
||||||
|
$metaBag = new MetadataBag();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->metadataBag = $metaBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the MetadataBag.
|
||||||
|
*
|
||||||
|
* @return MetadataBag
|
||||||
|
*/
|
||||||
|
public function getMetadataBag()
|
||||||
|
{
|
||||||
|
return $this->metadataBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isStarted()
|
||||||
|
{
|
||||||
|
return $this->started;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets session.* ini variables.
|
* Sets session.* ini variables.
|
||||||
*
|
*
|
||||||
|
@ -261,9 +309,8 @@ public function getBag($name)
|
||||||
*/
|
*/
|
||||||
public function setOptions(array $options)
|
public function setOptions(array $options)
|
||||||
{
|
{
|
||||||
foreach ($options as $key => $value) {
|
$validOptions = array_flip(array(
|
||||||
if (in_array($key, array(
|
'cache_limiter', 'cookie_domain', 'cookie_httponly',
|
||||||
'auto_start', 'cache_limiter', 'cookie_domain', 'cookie_httponly',
|
|
||||||
'cookie_lifetime', 'cookie_path', 'cookie_secure',
|
'cookie_lifetime', 'cookie_path', 'cookie_secure',
|
||||||
'entropy_file', 'entropy_length', 'gc_divisor',
|
'entropy_file', 'entropy_length', 'gc_divisor',
|
||||||
'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
|
'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character',
|
||||||
|
@ -271,7 +318,11 @@ public function setOptions(array $options)
|
||||||
'serialize_handler', 'use_cookies',
|
'serialize_handler', 'use_cookies',
|
||||||
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
|
'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled',
|
||||||
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
|
'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name',
|
||||||
'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags'))) {
|
'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags',
|
||||||
|
));
|
||||||
|
|
||||||
|
foreach ($options as $key => $value) {
|
||||||
|
if (isset($validOptions[$key])) {
|
||||||
ini_set('session.'.$key, $value);
|
ini_set('session.'.$key, $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +349,7 @@ public function setSaveHandler($saveHandler = null)
|
||||||
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
|
if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) {
|
||||||
$saveHandler = new SessionHandlerProxy($saveHandler);
|
$saveHandler = new SessionHandlerProxy($saveHandler);
|
||||||
} elseif (!$saveHandler instanceof AbstractProxy) {
|
} elseif (!$saveHandler instanceof AbstractProxy) {
|
||||||
$saveHandler = new NativeProxy($saveHandler);
|
$saveHandler = new NativeProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->saveHandler = $saveHandler;
|
$this->saveHandler = $saveHandler;
|
||||||
|
@ -335,7 +386,9 @@ protected function loadSession(array &$session = null)
|
||||||
$session = &$_SESSION;
|
$session = &$_SESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->bags as $bag) {
|
$bags = array_merge($this->bags, array($this->metadataBag));
|
||||||
|
|
||||||
|
foreach ($bags as $bag) {
|
||||||
$key = $bag->getStorageKey();
|
$key = $bag->getStorageKey();
|
||||||
$session[$key] = isset($session[$key]) ? $session[$key] : array();
|
$session[$key] = isset($session[$key]) ? $session[$key] : array();
|
||||||
$bag->initialize($session[$key]);
|
$bag->initialize($session[$key]);
|
||||||
|
|
|
@ -58,7 +58,7 @@ public function isSessionHandlerInterface()
|
||||||
/**
|
/**
|
||||||
* Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
|
* Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
public function isWrapper()
|
public function isWrapper()
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ public function isWrapper()
|
||||||
/**
|
/**
|
||||||
* Has a session started?
|
* Has a session started?
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return Boolean
|
||||||
*/
|
*/
|
||||||
public function isActive()
|
public function isActive()
|
||||||
{
|
{
|
||||||
|
@ -78,7 +78,7 @@ public function isActive()
|
||||||
/**
|
/**
|
||||||
* Sets the active flag.
|
* Sets the active flag.
|
||||||
*
|
*
|
||||||
* @param bool $flag
|
* @param Boolean $flag
|
||||||
*/
|
*/
|
||||||
public function setActive($flag)
|
public function setActive($flag)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ public function __construct()
|
||||||
/**
|
/**
|
||||||
* Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
|
* Returns true if this handler wraps an internal PHP session save handler using \SessionHandler.
|
||||||
*
|
*
|
||||||
* @return bool False.
|
* @return Boolean False.
|
||||||
*/
|
*/
|
||||||
public function isWrapper()
|
public function isWrapper()
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ public function __construct(\SessionHandlerInterface $handler)
|
||||||
*/
|
*/
|
||||||
public function open($savePath, $sessionName)
|
public function open($savePath, $sessionName)
|
||||||
{
|
{
|
||||||
$return = (bool)$this->handler->open($savePath, $sessionName);
|
$return = (bool) $this->handler->open($savePath, $sessionName);
|
||||||
|
|
||||||
if (true === $return) {
|
if (true === $return) {
|
||||||
$this->active = true;
|
$this->active = true;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
namespace Symfony\Component\HttpFoundation\Session\Storage;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
use Symfony\Component\HttpFoundation\Session\SessionBagInterface;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\Storage\MetadataBag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* StorageInterface.
|
* StorageInterface.
|
||||||
|
@ -32,7 +33,14 @@ interface SessionStorageInterface
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function start();
|
public function start();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the session is started.
|
||||||
|
*
|
||||||
|
* @return boolean True if started, false otherwise.
|
||||||
|
*/
|
||||||
|
public function isStarted();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session ID
|
* Returns the session ID
|
||||||
|
@ -41,7 +49,7 @@ function start();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function getId();
|
public function getId();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the session ID
|
* Sets the session ID
|
||||||
|
@ -50,7 +58,7 @@ function getId();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function setId($id);
|
public function setId($id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the session name
|
* Returns the session name
|
||||||
|
@ -59,7 +67,7 @@ function setId($id);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function getName();
|
public function getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the session name
|
* Sets the session name
|
||||||
|
@ -68,7 +76,7 @@ function getName();
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function setName($name);
|
public function setName($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regenerates id that represents this storage.
|
* Regenerates id that represents this storage.
|
||||||
|
@ -82,6 +90,10 @@ function setName($name);
|
||||||
* only delete the session data from persistent storage.
|
* only delete the session data from persistent storage.
|
||||||
*
|
*
|
||||||
* @param Boolean $destroy Destroy session when regenerating?
|
* @param Boolean $destroy Destroy session when regenerating?
|
||||||
|
* @param integer $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||||
|
* will leave the system settings unchanged, 0 sets the cookie
|
||||||
|
* to expire with browser session. Time is in seconds, and is
|
||||||
|
* not a Unix timestamp.
|
||||||
*
|
*
|
||||||
* @return Boolean True if session regenerated, false if error
|
* @return Boolean True if session regenerated, false if error
|
||||||
*
|
*
|
||||||
|
@ -89,7 +101,7 @@ function setName($name);
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
function regenerate($destroy = false);
|
public function regenerate($destroy = false, $lifetime = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Force the session to be saved and closed.
|
* Force the session to be saved and closed.
|
||||||
|
@ -98,13 +110,16 @@ function regenerate($destroy = false);
|
||||||
* used for a storage object design for unit or functional testing where
|
* used for a storage object design for unit or functional testing where
|
||||||
* a real PHP session would interfere with testing, in which case it
|
* a real PHP session would interfere with testing, in which case it
|
||||||
* it should actually persist the session data if required.
|
* it should actually persist the session data if required.
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException If the session is saved without being started, or if the session
|
||||||
|
* is already closed.
|
||||||
*/
|
*/
|
||||||
function save();
|
public function save();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all session data in memory.
|
* Clear all session data in memory.
|
||||||
*/
|
*/
|
||||||
function clear();
|
public function clear();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a SessionBagInterface by name.
|
* Gets a SessionBagInterface by name.
|
||||||
|
@ -115,12 +130,17 @@ function clear();
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException If the bag does not exist
|
* @throws \InvalidArgumentException If the bag does not exist
|
||||||
*/
|
*/
|
||||||
function getBag($name);
|
public function getBag($name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a SessionBagInterface for use.
|
* Registers a SessionBagInterface for use.
|
||||||
*
|
*
|
||||||
* @param SessionBagInterface $bag
|
* @param SessionBagInterface $bag
|
||||||
*/
|
*/
|
||||||
function registerBag(SessionBagInterface $bag);
|
public function registerBag(SessionBagInterface $bag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return MetadataBag
|
||||||
|
*/
|
||||||
|
public function getMetadataBag();
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,21 +72,17 @@ public function setCallback($callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @{inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function prepare(Request $request)
|
public function prepare(Request $request)
|
||||||
{
|
{
|
||||||
if ('1.0' != $request->server->get('SERVER_PROTOCOL')) {
|
|
||||||
$this->setProtocolVersion('1.1');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->headers->set('Cache-Control', 'no-cache');
|
$this->headers->set('Cache-Control', 'no-cache');
|
||||||
|
|
||||||
parent::prepare($request);
|
return parent::prepare($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @{inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* This method only sends the content once.
|
* This method only sends the content once.
|
||||||
*/
|
*/
|
||||||
|
@ -106,7 +102,7 @@ public function sendContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @{inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @throws \LogicException when the content is not null
|
* @throws \LogicException when the content is not null
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +114,7 @@ public function setContent($content)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @{inheritdoc}
|
* {@inheritdoc}
|
||||||
*
|
*
|
||||||
* @return false
|
* @return false
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.2"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-0": {
|
"psr-0": {
|
||||||
|
@ -25,9 +25,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"target-dir": "Symfony/Component/HttpFoundation",
|
"target-dir": "Symfony/Component/HttpFoundation",
|
||||||
"extra": {
|
"minimum-stability": "dev"
|
||||||
"branch-alias": {
|
|
||||||
"dev-master": "2.1-dev"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue