Merge branch '2.3' into 2.5
* 2.3: added missing files [TwigBundle] added a test Indicate which file was being parsed if an exception is thrown while running translation:debug [ClassLoader] Cast $useIncludePath property to boolean [HttpFoundation] Minor spelling fix in PHPDocs improve error message for multiple documents [Session] remove invalid workaround in session regenerate [Kernel] ensure session is saved before sending response [Routing] serialize the compiled route to speed things up [Validator] Fixed Regex::getHtmlPattern() to work with complex and negated patterns [DependencyInjection] use inheritdoc for loaders [Config] fix filelocator with empty name [Form] fix form handling with unconventional request methods like OPTIONS CSRF warning docs on Request::enableHttpMethodParameterOverride() Conflicts: src/Symfony/Component/Routing/Route.php
This commit is contained in:
commit
14c417a391
@ -0,0 +1 @@
|
||||
{% syntax error
|
@ -70,4 +70,17 @@ class TwigExtractorTest extends \PHPUnit_Framework_TestCase
|
||||
array('{{ "new key" | transchoice(domain="domain", count=1) }}', array('new key' => 'domain')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Twig_Error
|
||||
* @expectedExceptionMessage Unclosed "block" in "extractor/syntax_error.twig" at line 1
|
||||
*/
|
||||
public function testExtractSyntaxError()
|
||||
{
|
||||
$twig = new \Twig_Environment(new \Twig_Loader_Array(array()));
|
||||
$twig->addExtension(new TranslationExtension($this->getMock('Symfony\Component\Translation\TranslatorInterface')));
|
||||
|
||||
$extractor = new TwigExtractor($twig);
|
||||
$extractor->extract(__DIR__.'/../Fixtures', new MessageCatalogue('en'));
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,13 @@ class TwigExtractor implements ExtractorInterface
|
||||
$finder = new Finder();
|
||||
$files = $finder->files()->name('*.twig')->sortByName()->in($directory);
|
||||
foreach ($files as $file) {
|
||||
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
|
||||
try {
|
||||
$this->extractTemplate(file_get_contents($file->getPathname()), $catalogue);
|
||||
} catch (\Twig_Error $e) {
|
||||
$e->setTemplateFile($file->getRelativePathname());
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,10 @@
|
||||
<argument type="service" id="service_container" />
|
||||
</service>
|
||||
|
||||
<service id="session.save_listener" class="Symfony\Component\HttpKernel\EventListener\SaveSessionListener">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
</service>
|
||||
|
||||
<!-- for BC -->
|
||||
<service id="session.storage.filesystem" alias="session.storage.mock_file" />
|
||||
</services>
|
||||
|
@ -107,7 +107,7 @@ class ClassLoader
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
$this->useIncludePath = (bool) $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ class UniversalClassLoader
|
||||
*/
|
||||
public function useIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
$this->useIncludePath = (bool) $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -31,18 +31,14 @@ class FileLocator implements FileLocatorInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a full path for a given file name.
|
||||
*
|
||||
* @param mixed $name The file name to locate
|
||||
* @param string $currentPath The current path
|
||||
* @param bool $first Whether to return the first occurrence or an array of filenames
|
||||
*
|
||||
* @return string|array The full path to the file|An array of file paths
|
||||
*
|
||||
* @throws \InvalidArgumentException When file is not found
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function locate($name, $currentPath = null, $first = true)
|
||||
{
|
||||
if ('' == $name) {
|
||||
throw new \InvalidArgumentException('An empty file name is not valid to be located.');
|
||||
}
|
||||
|
||||
if ($this->isAbsolutePath($name)) {
|
||||
if (!file_exists($name)) {
|
||||
throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
|
||||
@ -84,10 +80,10 @@ class FileLocator implements FileLocatorInterface
|
||||
*/
|
||||
private function isAbsolutePath($file)
|
||||
{
|
||||
if ($file[0] == '/' || $file[0] == '\\'
|
||||
if ($file[0] === '/' || $file[0] === '\\'
|
||||
|| (strlen($file) > 3 && ctype_alpha($file[0])
|
||||
&& $file[1] == ':'
|
||||
&& ($file[2] == '\\' || $file[2] == '/')
|
||||
&& $file[1] === ':'
|
||||
&& ($file[2] === '\\' || $file[2] === '/')
|
||||
)
|
||||
|| null !== parse_url($file, PHP_URL_SCHEME)
|
||||
) {
|
||||
|
@ -19,11 +19,11 @@ interface FileLocatorInterface
|
||||
/**
|
||||
* Returns a full path for a given file name.
|
||||
*
|
||||
* @param mixed $name The file name to locate
|
||||
* @param string $currentPath The current path
|
||||
* @param bool $first Whether to return the first occurrence or an array of filenames
|
||||
* @param string $name The file name to locate
|
||||
* @param string|null $currentPath The current path
|
||||
* @param bool $first Whether to return the first occurrence or an array of filenames
|
||||
*
|
||||
* @return string|array The full path to the file|An array of file paths
|
||||
* @return string|array The full path to the file or an array of file paths
|
||||
*
|
||||
* @throws \InvalidArgumentException When file is not found
|
||||
*/
|
||||
|
@ -34,14 +34,7 @@ class DelegatingLoader extends Loader
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws FileLoaderLoadException if no loader is found.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
|
@ -22,8 +22,14 @@ use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceExceptio
|
||||
*/
|
||||
abstract class FileLoader extends Loader
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $loading = array();
|
||||
|
||||
/**
|
||||
* @var FileLocatorInterface
|
||||
*/
|
||||
protected $locator;
|
||||
|
||||
private $currentDir;
|
||||
@ -38,11 +44,21 @@ abstract class FileLoader extends Loader
|
||||
$this->locator = $locator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current directory.
|
||||
*
|
||||
* @param string $dir
|
||||
*/
|
||||
public function setCurrentDir($dir)
|
||||
{
|
||||
$this->currentDir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file locator used by this loader.
|
||||
*
|
||||
* @return FileLocatorInterface
|
||||
*/
|
||||
public function getLocator()
|
||||
{
|
||||
return $this->locator;
|
||||
@ -51,10 +67,10 @@ abstract class FileLoader extends Loader
|
||||
/**
|
||||
* Imports a resource.
|
||||
*
|
||||
* @param mixed $resource A Resource
|
||||
* @param string $type The resource type
|
||||
* @param bool $ignoreErrors Whether to ignore import errors or not
|
||||
* @param string $sourceResource The original resource importing the new resource
|
||||
* @param mixed $resource A Resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
* @param bool $ignoreErrors Whether to ignore import errors or not
|
||||
* @param string|null $sourceResource The original resource importing the new resource
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
|
@ -23,9 +23,7 @@ abstract class Loader implements LoaderInterface
|
||||
protected $resolver;
|
||||
|
||||
/**
|
||||
* Gets the loader resolver.
|
||||
*
|
||||
* @return LoaderResolverInterface A LoaderResolverInterface instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResolver()
|
||||
{
|
||||
@ -33,9 +31,7 @@ abstract class Loader implements LoaderInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the loader resolver.
|
||||
*
|
||||
* @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setResolver(LoaderResolverInterface $resolver)
|
||||
{
|
||||
@ -45,8 +41,8 @@ abstract class Loader implements LoaderInterface
|
||||
/**
|
||||
* Imports a resource.
|
||||
*
|
||||
* @param mixed $resource A Resource
|
||||
* @param string $type The resource type
|
||||
* @param mixed $resource A resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@ -58,12 +54,12 @@ abstract class Loader implements LoaderInterface
|
||||
/**
|
||||
* Finds a loader able to load an imported resource.
|
||||
*
|
||||
* @param mixed $resource A Resource
|
||||
* @param string $type The resource type
|
||||
* @param mixed $resource A resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @return LoaderInterface A LoaderInterface instance
|
||||
*
|
||||
* @throws FileLoaderLoadException if no loader is found
|
||||
* @throws FileLoaderLoadException If no loader is found
|
||||
*/
|
||||
public function resolve($resource, $type = null)
|
||||
{
|
||||
|
@ -21,18 +21,20 @@ interface LoaderInterface
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @param mixed $resource The resource
|
||||
* @param string $type The resource type
|
||||
* @param mixed $resource The resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @throws \Exception If something went wrong
|
||||
*/
|
||||
public function load($resource, $type = null);
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
* Returns whether this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
* @param mixed $resource A resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* @return bool True if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null);
|
||||
|
||||
|
@ -39,12 +39,7 @@ class LoaderResolver implements LoaderResolverInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a loader able to load the resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return LoaderInterface|false A LoaderInterface instance
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve($resource, $type = null)
|
||||
{
|
||||
|
@ -21,10 +21,10 @@ interface LoaderResolverInterface
|
||||
/**
|
||||
* Returns a loader able to load the resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
* @param mixed $resource A resource
|
||||
* @param string|null $type The resource type or null if unknown
|
||||
*
|
||||
* @return LoaderInterface A LoaderInterface instance
|
||||
* @return LoaderInterface|false The loader or false if none is able to load the resource
|
||||
*/
|
||||
public function resolve($resource, $type = null);
|
||||
}
|
||||
|
@ -24,8 +24,8 @@ class DirectoryResource implements ResourceInterface, \Serializable
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $resource The file path to the resource
|
||||
* @param string $pattern A pattern to restrict monitored files
|
||||
* @param string $resource The file path to the resource
|
||||
* @param string|null $pattern A pattern to restrict monitored files
|
||||
*/
|
||||
public function __construct($resource, $pattern = null)
|
||||
{
|
||||
@ -34,9 +34,7 @@ class DirectoryResource implements ResourceInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the Resource.
|
||||
*
|
||||
* @return string A string representation of the Resource
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
@ -44,26 +42,25 @@ class DirectoryResource implements ResourceInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource tied to this Resource.
|
||||
*
|
||||
* @return mixed The resource
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pattern to restrict monitored files
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the resource has not been updated since the given timestamp.
|
||||
*
|
||||
* @param int $timestamp The last time the resource was loaded
|
||||
*
|
||||
* @return bool true if the resource has not been updated, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFresh($timestamp)
|
||||
{
|
||||
|
@ -20,6 +20,9 @@ namespace Symfony\Component\Config\Resource;
|
||||
*/
|
||||
class FileResource implements ResourceInterface, \Serializable
|
||||
{
|
||||
/**
|
||||
* @var string|false
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
@ -33,9 +36,7 @@ class FileResource implements ResourceInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the Resource.
|
||||
*
|
||||
* @return string A string representation of the Resource
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
@ -43,9 +44,7 @@ class FileResource implements ResourceInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the resource tied to this Resource.
|
||||
*
|
||||
* @return mixed The resource
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
@ -53,15 +52,11 @@ class FileResource implements ResourceInterface, \Serializable
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the resource has not been updated since the given timestamp.
|
||||
*
|
||||
* @param int $timestamp The last time the resource was loaded
|
||||
*
|
||||
* @return bool true if the resource has not been updated, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFresh($timestamp)
|
||||
{
|
||||
if (!file_exists($this->resource)) {
|
||||
if (false === $this->resource || !file_exists($this->resource)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -28,14 +28,14 @@ interface ResourceInterface
|
||||
/**
|
||||
* Returns true if the resource has not been updated since the given timestamp.
|
||||
*
|
||||
* @param int $timestamp The last time the resource was loaded
|
||||
* @param int $timestamp The last time the resource was loaded
|
||||
*
|
||||
* @return bool true if the resource has not been updated, false otherwise
|
||||
* @return bool True if the resource has not been updated, false otherwise
|
||||
*/
|
||||
public function isFresh($timestamp);
|
||||
|
||||
/**
|
||||
* Returns the resource tied to this Resource.
|
||||
* Returns the tied resource.
|
||||
*
|
||||
* @return mixed The resource
|
||||
*/
|
||||
|
@ -87,6 +87,7 @@ class FileLocatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage The file "foobar.xml" does not exist
|
||||
*/
|
||||
public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
|
||||
{
|
||||
@ -104,4 +105,15 @@ class FileLocatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage An empty file name is not valid to be located.
|
||||
*/
|
||||
public function testLocateEmpty()
|
||||
{
|
||||
$loader = new FileLocator(array(__DIR__.'/Fixtures'));
|
||||
|
||||
$loader->locate(null, __DIR__);
|
||||
}
|
||||
}
|
||||
|
@ -36,23 +36,15 @@ class ClosureLoader extends Loader
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Closure.
|
||||
*
|
||||
* @param \Closure $closure The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($closure, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
call_user_func($closure, $this->container);
|
||||
call_user_func($resource, $this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
@ -27,8 +27,8 @@ abstract class FileLoader extends BaseFileLoader
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
* @param FileLocatorInterface $locator A FileLocator instance
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
* @param FileLocatorInterface $locator A FileLocator instance
|
||||
*/
|
||||
public function __construct(ContainerBuilder $container, FileLocatorInterface $locator)
|
||||
{
|
||||
|
@ -22,22 +22,17 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
class IniFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @throws InvalidArgumentException When ini file is not valid
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
$result = parse_ini_file($path, true);
|
||||
if (false === $result || array() === $result) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $file));
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $resource));
|
||||
}
|
||||
|
||||
if (isset($result['parameters']) && is_array($result['parameters'])) {
|
||||
@ -48,12 +43,7 @@ class IniFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
@ -24,18 +24,15 @@ use Symfony\Component\Config\Resource\FileResource;
|
||||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a PHP file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
// the container and loader variables are exposed to the included file below
|
||||
$container = $this->container;
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
@ -43,12 +40,7 @@ class PhpFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
@ -32,14 +32,11 @@ class XmlFileLoader extends FileLoader
|
||||
const NS = 'http://symfony.com/schema/dic/services';
|
||||
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$xml = $this->parseFileToDOM($path);
|
||||
|
||||
@ -62,12 +59,7 @@ class XmlFileLoader extends FileLoader
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
@ -33,14 +33,11 @@ class YamlFileLoader extends FileLoader
|
||||
private $yamlParser;
|
||||
|
||||
/**
|
||||
* Loads a Yaml file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
public function load($resource, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
$path = $this->locator->locate($resource);
|
||||
|
||||
$content = $this->loadFile($path);
|
||||
|
||||
@ -57,7 +54,7 @@ class YamlFileLoader extends FileLoader
|
||||
// parameters
|
||||
if (isset($content['parameters'])) {
|
||||
if (!is_array($content['parameters'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
throw new InvalidArgumentException(sprintf('The "parameters" key should contain an array in %s. Check your YAML syntax.', $resource));
|
||||
}
|
||||
|
||||
foreach ($content['parameters'] as $key => $value) {
|
||||
@ -69,16 +66,11 @@ class YamlFileLoader extends FileLoader
|
||||
$this->loadFromExtensions($content);
|
||||
|
||||
// services
|
||||
$this->parseDefinitions($content, $file);
|
||||
$this->parseDefinitions($content, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return bool true if this class supports the given resource, false otherwise
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\HttpFoundation\EventListener;
|
||||
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\Exception\LogicException;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
@ -49,12 +48,19 @@ class BindRequestListener implements EventSubscriberInterface
|
||||
$name = $form->getConfig()->getName();
|
||||
$default = $form->getConfig()->getCompound() ? array() : null;
|
||||
|
||||
// Store the bound data in case of a post request
|
||||
// For request methods that must not have a request body we fetch data
|
||||
// from the query string. Otherwise we look for data in the request body.
|
||||
switch ($request->getMethod()) {
|
||||
case 'POST':
|
||||
case 'PUT':
|
||||
case 'DELETE':
|
||||
case 'PATCH':
|
||||
case 'GET':
|
||||
case 'HEAD':
|
||||
case 'TRACE':
|
||||
$data = '' === $name
|
||||
? $request->query->all()
|
||||
: $request->query->get($name, $default);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
if ('' === $name) {
|
||||
// Form bound without name
|
||||
$params = $request->request->all();
|
||||
@ -71,19 +77,6 @@ class BindRequestListener implements EventSubscriberInterface
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'GET':
|
||||
$data = '' === $name
|
||||
? $request->query->all()
|
||||
: $request->query->get($name, $default);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new LogicException(sprintf(
|
||||
'The request method "%s" is not supported',
|
||||
$request->getMethod()
|
||||
));
|
||||
}
|
||||
|
||||
$event->setData($data);
|
||||
|
@ -55,7 +55,9 @@ class HttpFoundationRequestHandler implements RequestHandlerInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if ('GET' === $method) {
|
||||
// For request methods that must not have a request body we fetch data
|
||||
// from the query string. Otherwise we look for data in the request body.
|
||||
if ('GET' === $method || 'HEAD' === $method || 'TRACE' === $method) {
|
||||
if ('' === $name) {
|
||||
$data = $request->query->all();
|
||||
} else {
|
||||
|
@ -63,7 +63,9 @@ class NativeRequestHandler implements RequestHandlerInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if ('GET' === $method) {
|
||||
// For request methods that must not have a request body we fetch data
|
||||
// from the query string. Otherwise we look for data in the request body.
|
||||
if ('GET' === $method || 'HEAD' === $method || 'TRACE' === $method) {
|
||||
if ('' === $name) {
|
||||
$data = $_GET;
|
||||
} else {
|
||||
|
@ -496,7 +496,7 @@ class Request
|
||||
* Overrides the PHP global variables according to this request instance.
|
||||
*
|
||||
* It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
|
||||
* $_FILES is never override, see rfc1867
|
||||
* $_FILES is never overridden, see rfc1867
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
@ -671,6 +671,9 @@ class Request
|
||||
*
|
||||
* Be warned that enabling this feature might lead to CSRF issues in your code.
|
||||
* Check that you are using CSRF tokens when required.
|
||||
* If the HTTP method parameter override is enabled, an html-form with method "POST" can be altered
|
||||
* and used to send a "PUT" or "DELETE" request via the _method request parameter.
|
||||
* If these methods are not protected against CSRF, this presents a possible vulnerability.
|
||||
*
|
||||
* The HTTP method can only be overridden when the real HTTP method is POST.
|
||||
*/
|
||||
@ -1612,7 +1615,7 @@ class Request
|
||||
/**
|
||||
* Returns true if the request is a XMLHttpRequest.
|
||||
*
|
||||
* It works if your JavaScript library set an X-Requested-With HTTP header.
|
||||
* It works if your JavaScript library sets an X-Requested-With HTTP header.
|
||||
* It is known to work with common JavaScript frameworks:
|
||||
* @link http://en.wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript
|
||||
*
|
||||
|
@ -206,23 +206,7 @@ class NativeSessionStorage implements SessionStorageInterface
|
||||
$this->metadataBag->stampNew();
|
||||
}
|
||||
|
||||
$ret = session_regenerate_id($destroy);
|
||||
|
||||
// workaround for https://bugs.php.net/bug.php?id=61470 as suggested by David Grudl
|
||||
if ('files' === $this->getSaveHandler()->getSaveHandlerName()) {
|
||||
session_write_close();
|
||||
if (isset($_SESSION)) {
|
||||
$backup = $_SESSION;
|
||||
session_start();
|
||||
$_SESSION = $backup;
|
||||
} else {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$this->loadSession();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return session_regenerate_id($destroy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,6 +88,14 @@ interface SessionStorageInterface
|
||||
* Note regenerate+destroy should not clear the session data in memory
|
||||
* only delete the session data from persistent storage.
|
||||
*
|
||||
* Care: When regenerating the session ID no locking is involved in PHPs
|
||||
* session design. See https://bugs.php.net/bug.php?id=61470 for a discussion.
|
||||
* So you must make sure the regenerated session is saved BEFORE sending the
|
||||
* headers with the new ID. Symfonys HttpKernel offers a listener for this.
|
||||
* See Symfony\Component\HttpKernel\EventListener\SaveSessionListener.
|
||||
* Otherwise session data could get lost again for concurrent requests with the
|
||||
* new ID. One result could be that you get logged out after just logging in.
|
||||
*
|
||||
* @param bool $destroy Destroy session when regenerating?
|
||||
* @param int $lifetime Sets the cookie lifetime for the session cookie. A null value
|
||||
* will leave the system settings unchanged, 0 sets the cookie
|
||||
|
@ -47,7 +47,7 @@ class FileLocator extends BaseFileLocator
|
||||
*/
|
||||
public function locate($file, $currentPath = null, $first = true)
|
||||
{
|
||||
if ('@' === $file[0]) {
|
||||
if (isset($file[0]) && '@' === $file[0]) {
|
||||
return $this->kernel->locateResource($file, $this->path, $first);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,67 @@
|
||||
<?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\HttpKernel\EventListener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Saves the session, in case it is still open, before sending the response/headers.
|
||||
*
|
||||
* This ensures several things in case the developer did not save the session explicitly:
|
||||
*
|
||||
* * If a session save handler without locking is used, it ensures the data is available
|
||||
* on the next request, e.g. after a redirect. PHPs auto-save at script end via
|
||||
* session_register_shutdown is executed after fastcgi_finish_request. So in this case
|
||||
* the data could be missing the next request because it might not be saved the moment
|
||||
* the new request is processed.
|
||||
* * A locking save handler (e.g. the native 'files') circumvents concurrency problems like
|
||||
* the one above. But by saving the session before long-running things in the terminate event,
|
||||
* we ensure the session is not blocked longer than needed.
|
||||
* * When regenerating the session ID no locking is involved in PHPs session design. See
|
||||
* https://bugs.php.net/bug.php?id=61470 for a discussion. So in this case, the session must
|
||||
* be saved anyway before sending the headers with the new session ID. Otherwise session
|
||||
* data could get lost again for concurrent requests with the new ID. One result could be
|
||||
* that you get logged out after just logging in.
|
||||
*
|
||||
* This listener should be executed as one of the last listeners, so that previous listeners
|
||||
* can still operate on the open session. This prevents the overhead of restarting it.
|
||||
* Listeners after closing the session can still work with the session as usual because
|
||||
* Symfonys session implementation starts the session on demand. So writing to it after
|
||||
* it is saved will just restart it.
|
||||
*
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class SaveSessionListener implements EventSubscriberInterface
|
||||
{
|
||||
public function onKernelResponse(FilterResponseEvent $event)
|
||||
{
|
||||
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$session = $event->getRequest()->getSession();
|
||||
if ($session && $session->isStarted()) {
|
||||
$session->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
// low priority but higher than StreamedResponseListener
|
||||
KernelEvents::RESPONSE => array(array('onKernelResponse', -1000)),
|
||||
);
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Routing;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CompiledRoute
|
||||
class CompiledRoute implements \Serializable
|
||||
{
|
||||
private $variables;
|
||||
private $tokens;
|
||||
@ -51,6 +51,39 @@ class CompiledRoute
|
||||
$this->variables = $variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
'vars' => $this->variables,
|
||||
'path_prefix' => $this->staticPrefix,
|
||||
'path_regex' => $this->regex,
|
||||
'path_tokens' => $this->tokens,
|
||||
'path_vars' => $this->pathVariables,
|
||||
'host_regex' => $this->hostRegex,
|
||||
'host_tokens' => $this->hostTokens,
|
||||
'host_vars' => $this->hostVariables,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($serialized);
|
||||
$this->variables = $data['vars'];
|
||||
$this->staticPrefix = $data['path_prefix'];
|
||||
$this->regex = $data['path_regex'];
|
||||
$this->tokens = $data['path_tokens'];
|
||||
$this->pathVariables = $data['path_vars'];
|
||||
$this->hostRegex = $data['host_regex'];
|
||||
$this->hostTokens = $data['host_tokens'];
|
||||
$this->hostVariables = $data['host_vars'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the static prefix.
|
||||
*
|
||||
|
@ -99,6 +99,9 @@ class Route implements \Serializable
|
||||
$this->setCondition($condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array(
|
||||
@ -110,12 +113,16 @@ class Route implements \Serializable
|
||||
'schemes' => $this->schemes,
|
||||
'methods' => $this->methods,
|
||||
'condition' => $this->condition,
|
||||
'compiled' => $this->compiled,
|
||||
));
|
||||
}
|
||||
|
||||
public function unserialize($data)
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = unserialize($data);
|
||||
$data = unserialize($serialized);
|
||||
$this->path = $data['path'];
|
||||
$this->host = $data['host'];
|
||||
$this->defaults = $data['defaults'];
|
||||
@ -123,7 +130,13 @@ class Route implements \Serializable
|
||||
$this->options = $data['options'];
|
||||
$this->schemes = $data['schemes'];
|
||||
$this->methods = $data['methods'];
|
||||
<<<<<<< HEAD
|
||||
$this->condition = $data['condition'];
|
||||
=======
|
||||
if (isset($data['compiled'])) {
|
||||
$this->compiled = $data['compiled'];
|
||||
}
|
||||
>>>>>>> 2.3
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,7 +229,7 @@ class RouteTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testSerialize()
|
||||
{
|
||||
$route = new Route('/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
|
||||
$route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
|
||||
|
||||
$serialized = serialize($route);
|
||||
$unserialized = unserialize($serialized);
|
||||
@ -237,4 +237,39 @@ class RouteTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals($route, $unserialized);
|
||||
$this->assertNotSame($route, $unserialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the compiled version is also serialized to prevent the overhead
|
||||
* of compiling it again after unserialize.
|
||||
*/
|
||||
public function testSerializeWhenCompiled()
|
||||
{
|
||||
$route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
|
||||
$route->setHost('{locale}.example.net');
|
||||
$route->compile();
|
||||
|
||||
$serialized = serialize($route);
|
||||
$unserialized = unserialize($serialized);
|
||||
|
||||
$this->assertEquals($route, $unserialized);
|
||||
$this->assertNotSame($route, $unserialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the serialized representation of a route in one symfony version
|
||||
* also works in later symfony versions, i.e. the unserialized route is in the
|
||||
* same state as another, semantically equivalent, route.
|
||||
*/
|
||||
public function testSerializedRepresentationKeepsWorking()
|
||||
{
|
||||
$serialized = 'C:31:"Symfony\Component\Routing\Route":933:{a:8:{s:4:"path";s:13:"/prefix/{foo}";s:4:"host";s:20:"{locale}.example.net";s:8:"defaults";a:1:{s:3:"foo";s:7:"default";}s:12:"requirements";a:1:{s:3:"foo";s:3:"\d+";}s:7:"options";a:1:{s:14:"compiler_class";s:39:"Symfony\Component\Routing\RouteCompiler";}s:7:"schemes";a:0:{}s:7:"methods";a:0:{}s:8:"compiled";C:39:"Symfony\Component\Routing\CompiledRoute":568:{a:8:{s:4:"vars";a:2:{i:0;s:6:"locale";i:1;s:3:"foo";}s:11:"path_prefix";s:7:"/prefix";s:10:"path_regex";s:30:"#^/prefix(?:/(?P<foo>\d+))?$#s";s:11:"path_tokens";a:2:{i:0;a:4:{i:0;s:8:"variable";i:1;s:1:"/";i:2;s:3:"\d+";i:3;s:3:"foo";}i:1;a:2:{i:0;s:4:"text";i:1;s:7:"/prefix";}}s:9:"path_vars";a:1:{i:0;s:3:"foo";}s:10:"host_regex";s:38:"#^(?P<locale>[^\.]++)\.example\.net$#s";s:11:"host_tokens";a:2:{i:0;a:2:{i:0;s:4:"text";i:1;s:12:".example.net";}i:1;a:4:{i:0;s:8:"variable";i:1;s:0:"";i:2;s:7:"[^\.]++";i:3;s:6:"locale";}}s:9:"host_vars";a:1:{i:0;s:6:"locale";}}}}}';
|
||||
$unserialized = unserialize($serialized);
|
||||
|
||||
$route = new Route('/prefix/{foo}', array('foo' => 'default'), array('foo' => '\d+'));
|
||||
$route->setHost('{locale}.example.net');
|
||||
$route->compile();
|
||||
|
||||
$this->assertEquals($route, $unserialized);
|
||||
$this->assertNotSame($route, $unserialized);
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,14 @@ class Regex extends Constraint
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns htmlPattern if exists or pattern is convertible.
|
||||
* Converts the htmlPattern to a suitable format for HTML5 pattern.
|
||||
* Example: /^[a-z]+$/ would be converted to [a-z]+
|
||||
* However, if options are specified, it cannot be converted
|
||||
*
|
||||
* Pattern is also ignored if match=false since the pattern should
|
||||
* then be reversed before application.
|
||||
*
|
||||
* @link http://dev.w3.org/html5/spec/single-page.html#the-pattern-attribute
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
@ -58,40 +65,34 @@ class Regex extends Constraint
|
||||
: $this->htmlPattern;
|
||||
}
|
||||
|
||||
return $this->getNonDelimitedPattern();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the htmlPattern to a suitable format for HTML5 pattern.
|
||||
* Example: /^[a-z]+$/ would be converted to [a-z]+
|
||||
* However, if options are specified, it cannot be converted
|
||||
*
|
||||
* Pattern is also ignored if match=false since the pattern should
|
||||
* then be reversed before application.
|
||||
*
|
||||
* @todo reverse pattern in case match=false as per issue #5307
|
||||
*
|
||||
* @link http://dev.w3.org/html5/spec/single-page.html#the-pattern-attribute
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function getNonDelimitedPattern()
|
||||
{
|
||||
// If match = false, pattern should not be added to HTML5 validation
|
||||
if (!$this->match) {
|
||||
// Quit if delimiters not at very beginning/end (e.g. when options are passed)
|
||||
if ($this->pattern[0] !== $this->pattern[strlen($this->pattern) - 1]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (preg_match('/^(.)(\^?)(.*?)(\$?)\1$/', $this->pattern, $matches)) {
|
||||
$delimiter = $matches[1];
|
||||
$start = empty($matches[2]) ? '.*' : '';
|
||||
$pattern = $matches[3];
|
||||
$end = empty($matches[4]) ? '.*' : '';
|
||||
$delimiter = $this->pattern[0];
|
||||
|
||||
// Unescape the delimiter in pattern
|
||||
$pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
|
||||
// Unescape the delimiter
|
||||
$pattern = str_replace('\\'.$delimiter, $delimiter, substr($this->pattern, 1, -1));
|
||||
|
||||
return $start.$pattern.$end;
|
||||
// If the pattern is inverted, we can simply wrap it in
|
||||
// ((?!pattern).)*
|
||||
if (!$this->match) {
|
||||
return '((?!'.$pattern.').)*';
|
||||
}
|
||||
|
||||
// If the pattern contains an or statement, wrap the pattern in
|
||||
// .*(pattern).* and quit. Otherwise we'd need to parse the pattern
|
||||
if (false !== strpos($pattern, '|')) {
|
||||
return '.*('.$pattern.').*';
|
||||
}
|
||||
|
||||
// Trim leading ^, otherwise prepend .*
|
||||
$pattern = '^' === $pattern[0] ? substr($pattern, 1) : '.*'.$pattern;
|
||||
|
||||
// Trim trailing $, otherwise append .*
|
||||
$pattern = '$' === $pattern[strlen($pattern) - 1] ? substr($pattern, 0, -1) : $pattern.'.*';
|
||||
|
||||
return $pattern;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
<?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 Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraints\Regex;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class RegexTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstraintGetDefaultOption()
|
||||
{
|
||||
$constraint = new Regex('/^[0-9]+$/');
|
||||
|
||||
$this->assertSame('/^[0-9]+$/', $constraint->pattern);
|
||||
}
|
||||
|
||||
public function provideHtmlPatterns()
|
||||
{
|
||||
return array(
|
||||
// HTML5 wraps the pattern in ^(?:pattern)$
|
||||
array('/^[0-9]+$/', '[0-9]+'),
|
||||
array('/[0-9]+$/', '.*[0-9]+'),
|
||||
array('/^[0-9]+/', '[0-9]+.*'),
|
||||
array('/[0-9]+/', '.*[0-9]+.*'),
|
||||
// We need a smart way to allow matching of patterns that contain
|
||||
// ^ and $ at various sub-clauses of an or-clause
|
||||
// .*(pattern).* seems to work correctly
|
||||
array('/[0-9]$|[a-z]+/', '.*([0-9]$|[a-z]+).*'),
|
||||
array('/[0-9]$|^[a-z]+/', '.*([0-9]$|^[a-z]+).*'),
|
||||
array('/^[0-9]|[a-z]+$/', '.*(^[0-9]|[a-z]+$).*'),
|
||||
// Unescape escaped delimiters
|
||||
array('/^[0-9]+\/$/', '[0-9]+/'),
|
||||
array('#^[0-9]+\#$#', '[0-9]+#'),
|
||||
// Cannot be converted
|
||||
array('/^[0-9]+$/i', null),
|
||||
|
||||
// Inverse matches are simple, just wrap in
|
||||
// ((?!pattern).)*
|
||||
array('/^[0-9]+$/', '((?!^[0-9]+$).)*', false),
|
||||
array('/[0-9]+$/', '((?![0-9]+$).)*', false),
|
||||
array('/^[0-9]+/', '((?!^[0-9]+).)*', false),
|
||||
array('/[0-9]+/', '((?![0-9]+).)*', false),
|
||||
array('/[0-9]$|[a-z]+/', '((?![0-9]$|[a-z]+).)*', false),
|
||||
array('/[0-9]$|^[a-z]+/', '((?![0-9]$|^[a-z]+).)*', false),
|
||||
array('/^[0-9]|[a-z]+$/', '((?!^[0-9]|[a-z]+$).)*', false),
|
||||
array('/^[0-9]+\/$/', '((?!^[0-9]+/$).)*', false),
|
||||
array('#^[0-9]+\#$#', '((?!^[0-9]+#$).)*', false),
|
||||
array('/^[0-9]+$/i', null, false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideHtmlPatterns
|
||||
*/
|
||||
public function testGetHtmlPattern($pattern, $htmlPattern, $match = true)
|
||||
{
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => $pattern,
|
||||
'match' => $match,
|
||||
));
|
||||
|
||||
$this->assertSame($pattern, $constraint->pattern);
|
||||
$this->assertSame($htmlPattern, $constraint->getHtmlPattern());
|
||||
}
|
||||
|
||||
public function testGetCustomHtmlPattern()
|
||||
{
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '((?![0-9]$|[a-z]+).)*',
|
||||
'htmlPattern' => 'foobar',
|
||||
));
|
||||
|
||||
$this->assertSame('((?![0-9]$|[a-z]+).)*', $constraint->pattern);
|
||||
$this->assertSame('foobar', $constraint->getHtmlPattern());
|
||||
}
|
||||
}
|
@ -94,70 +94,4 @@ class RegexValidatorTest extends AbstractConstraintValidatorTest
|
||||
array('090foo'),
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstraintGetDefaultOption()
|
||||
{
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[0-9]+$/',
|
||||
));
|
||||
|
||||
$this->assertEquals('pattern', $constraint->getDefaultOption());
|
||||
}
|
||||
|
||||
public function testHtmlPatternEscaping()
|
||||
{
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[0-9]+\/$/',
|
||||
));
|
||||
|
||||
$this->assertEquals('[0-9]+/', $constraint->getHtmlPattern());
|
||||
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '#^[0-9]+\#$#',
|
||||
));
|
||||
|
||||
$this->assertEquals('[0-9]+#', $constraint->getHtmlPattern());
|
||||
}
|
||||
|
||||
public function testHtmlPattern()
|
||||
{
|
||||
// Specified htmlPattern
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[a-z]+$/i',
|
||||
'htmlPattern' => '[a-zA-Z]+',
|
||||
));
|
||||
$this->assertEquals('[a-zA-Z]+', $constraint->getHtmlPattern());
|
||||
|
||||
// Disabled htmlPattern
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[a-z]+$/i',
|
||||
'htmlPattern' => false,
|
||||
));
|
||||
$this->assertNull($constraint->getHtmlPattern());
|
||||
|
||||
// Cannot be converted
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[a-z]+$/i',
|
||||
));
|
||||
$this->assertNull($constraint->getHtmlPattern());
|
||||
|
||||
// Automatically converted
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/^[a-z]+$/',
|
||||
));
|
||||
$this->assertEquals('[a-z]+', $constraint->getHtmlPattern());
|
||||
|
||||
// Automatically converted, adds .*
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/[a-z]+/',
|
||||
));
|
||||
$this->assertEquals('.*[a-z]+.*', $constraint->getHtmlPattern());
|
||||
|
||||
// Dropped because of match=false
|
||||
$constraint = new Regex(array(
|
||||
'pattern' => '/[a-z]+/',
|
||||
'match' => false,
|
||||
));
|
||||
$this->assertNull($constraint->getHtmlPattern());
|
||||
}
|
||||
}
|
||||
|
@ -228,6 +228,11 @@ class Parser
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// multiple documents are not supported
|
||||
if ('---' === $this->currentLine) {
|
||||
throw new ParseException('Multiple documents are not supported.');
|
||||
}
|
||||
|
||||
// 1-liner optionally followed by newline
|
||||
$lineCount = count($this->lines);
|
||||
if (1 === $lineCount || (2 === $lineCount && empty($this->lines[1]))) {
|
||||
|
@ -482,6 +482,27 @@ EOF;
|
||||
$this->parser->parse($yaml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
||||
* @expectedExceptionMessage Multiple documents are not supported.
|
||||
*/
|
||||
public function testMultipleDocumentsNotSupportedException()
|
||||
{
|
||||
Yaml::parse(<<<EOL
|
||||
# Ranking of 1998 home runs
|
||||
---
|
||||
- Mark McGwire
|
||||
- Sammy Sosa
|
||||
- Ken Griffey
|
||||
|
||||
# Team ranking
|
||||
---
|
||||
- Chicago Cubs
|
||||
- St Louis Cardinals
|
||||
EOL
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
|
||||
*/
|
||||
|
Reference in New Issue
Block a user