diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000000000..b739519fc0d9c
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+ ./tests/Symfony/
+ ./src/Symfony/Framework/
+
+
+
+
+
+ ./src/Symfony/
+
+ ./src/Symfony/Framework/DoctrineBundle
+ ./src/Symfony/Framework/ZendBundle
+
+ ./src/Symfony/Framework/*/Resources
+
+ ./src/Symfony/Foundation/bootstrap.php
+ ./src/Symfony/Foundation/packager.php
+
+
+
+
diff --git a/src/Symfony/Components/Console/Application.php b/src/Symfony/Components/Console/Application.php
index e26319be75aec..0c93c814d8f23 100644
--- a/src/Symfony/Components/Console/Application.php
+++ b/src/Symfony/Components/Console/Application.php
@@ -19,7 +19,7 @@
use Symfony\Components\Console\Helper\DialogHelper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -40,8 +40,8 @@
* $app->addCommand(new SimpleCommand());
* $app->run();
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class Application
@@ -99,6 +99,8 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
* @param OutputInterface $output An Output instance
*
* @return integer 0 if everything went fine, or an error code
+ *
+ * @throws \Exception When doRun returns Exception
*/
public function run(InputInterface $input = null, OutputInterface $output = null)
{
@@ -396,6 +398,8 @@ public function addCommand(Command $command)
* @param string $name The command name or alias
*
* @return Command A Command object
+ *
+ * @throws \InvalidArgumentException When command name given does not exist
*/
public function getCommand($name)
{
@@ -456,6 +460,8 @@ public function getNamespaces()
* Finds a registered namespace by a name or an abbreviation.
*
* @return string A registered namespace
+ *
+ * @throws \InvalidArgumentException When namespace is incorrect or ambiguous
*/
public function findNamespace($namespace)
{
@@ -483,6 +489,8 @@ public function findNamespace($namespace)
* @param string $name A command name or a command alias
*
* @return Command A Command instance
+ *
+ * @throws \InvalidArgumentException When command name is incorrect or ambiguous
*/
public function findCommand($name)
{
diff --git a/src/Symfony/Components/Console/Command/Command.php b/src/Symfony/Components/Console/Command/Command.php
index bbde5f94e0831..25b2a0091df81 100644
--- a/src/Symfony/Components/Console/Command/Command.php
+++ b/src/Symfony/Components/Console/Command/Command.php
@@ -10,7 +10,7 @@
use Symfony\Components\Console\Application;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -21,8 +21,8 @@
/**
* Base class for all commands.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class Command
@@ -43,6 +43,8 @@ class Command
* Constructor.
*
* @param string $name The name of the command
+ *
+ * @throws \LogicException When the command name is empty
*/
public function __construct($name = null)
{
@@ -88,6 +90,8 @@ protected function configure()
* @param OutputInterface $output An OutputInterface instance
*
* @return integer 0 if everything went fine, or an error code
+ *
+ * @throws \LogicException When this abstrass class is not implemented
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
@@ -273,6 +277,8 @@ public function addOption($name, $shortcut = null, $mode = null, $description =
* @param string $name The command name
*
* @return Command The current instance
+ *
+ * @throws \InvalidArgumentException When command name given is empty
*/
public function setName($name)
{
diff --git a/src/Symfony/Components/Console/Command/HelpCommand.php b/src/Symfony/Components/Console/Command/HelpCommand.php
index 8258c5c182905..537de5a84eae0 100644
--- a/src/Symfony/Components/Console/Command/HelpCommand.php
+++ b/src/Symfony/Components/Console/Command/HelpCommand.php
@@ -10,7 +10,7 @@
use Symfony\Components\Console\Command\Command;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -21,8 +21,8 @@
/**
* HelpCommand displays the help for a given command.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class HelpCommand extends Command
diff --git a/src/Symfony/Components/Console/Command/ListCommand.php b/src/Symfony/Components/Console/Command/ListCommand.php
index 3fddbc224c5a9..6e05b5f04f276 100644
--- a/src/Symfony/Components/Console/Command/ListCommand.php
+++ b/src/Symfony/Components/Console/Command/ListCommand.php
@@ -10,7 +10,7 @@
use Symfony\Components\Console\Command\Command;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -21,8 +21,8 @@
/**
* ListCommand displays the list of all available commands for the application.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class ListCommand extends Command
diff --git a/src/Symfony/Components/Console/Helper/DialogHelper.php b/src/Symfony/Components/Console/Helper/DialogHelper.php
index a19c3d949a5e0..31c3d820f61a8 100644
--- a/src/Symfony/Components/Console/Helper/DialogHelper.php
+++ b/src/Symfony/Components/Console/Helper/DialogHelper.php
@@ -5,7 +5,7 @@
use Symfony\Components\Console\Output\OutputInterface;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* The Dialog class provides helpers to interact with the user.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class DialogHelper extends Helper
@@ -82,6 +82,8 @@ public function askConfirmation(OutputInterface $output, $question, $default = t
* @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite)
*
* @return mixed
+ *
+ * @throws \Exception When any of the validator returns an error
*/
public function askAndValidate(OutputInterface $output, $question, \Closure $validator, $attempts = false)
{
diff --git a/src/Symfony/Components/Console/Helper/FormatterHelper.php b/src/Symfony/Components/Console/Helper/FormatterHelper.php
index 6eedca733a935..2d1c5fb52c5f2 100644
--- a/src/Symfony/Components/Console/Helper/FormatterHelper.php
+++ b/src/Symfony/Components/Console/Helper/FormatterHelper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Helper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* The Formatter class provides helpers to format messages.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class FormatterHelper extends Helper
diff --git a/src/Symfony/Components/Console/Helper/Helper.php b/src/Symfony/Components/Console/Helper/Helper.php
index f083b47abe952..0a99683f72b9e 100644
--- a/src/Symfony/Components/Console/Helper/Helper.php
+++ b/src/Symfony/Components/Console/Helper/Helper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Helper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Helper is the base class for all helper classes.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
abstract class Helper implements HelperInterface
diff --git a/src/Symfony/Components/Console/Helper/HelperInterface.php b/src/Symfony/Components/Console/Helper/HelperInterface.php
index f3de9aa65ea04..3d220bfea26cc 100644
--- a/src/Symfony/Components/Console/Helper/HelperInterface.php
+++ b/src/Symfony/Components/Console/Helper/HelperInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Helper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* HelperInterface is the interface all helpers must implement.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
interface HelperInterface
diff --git a/src/Symfony/Components/Console/Helper/HelperSet.php b/src/Symfony/Components/Console/Helper/HelperSet.php
index 67d764f52e343..d6b5ca4bcbd40 100644
--- a/src/Symfony/Components/Console/Helper/HelperSet.php
+++ b/src/Symfony/Components/Console/Helper/HelperSet.php
@@ -5,7 +5,7 @@
use Symfony\Components\Console\Command\Command;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* HelperSet represents a set of helpers to be used with a command.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class HelperSet
diff --git a/src/Symfony/Components/Console/Input/ArgvInput.php b/src/Symfony/Components/Console/Input/ArgvInput.php
index a140219bfdebf..0d19942240fb8 100644
--- a/src/Symfony/Components/Console/Input/ArgvInput.php
+++ b/src/Symfony/Components/Console/Input/ArgvInput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -20,7 +20,7 @@
*
* By default, the `$_SERVER['argv']` array is used for the input values.
*
- * This can be overriden by explicitly passing the input values in the constructor:
+ * This can be overridden by explicitly passing the input values in the constructor:
*
* $input = new ArgvInput($_SERVER['argv']);
*
@@ -31,8 +31,8 @@
* the same rules as the argv one. It's almost always better to use the
* `StringInput` when you want to provide your own input.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*
* @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
@@ -46,7 +46,7 @@ class ArgvInput extends Input
/**
* Constructor.
*
- * @param array $argv An array of parameters from the CLI (in the argv format)
+ * @param array $argv An array of parameters from the CLI (in the argv format)
* @param InputDefinition $definition A InputDefinition instance
*/
public function __construct(array $argv = null, InputDefinition $definition = null)
@@ -118,6 +118,8 @@ protected function parseShortOption($token)
* Parses a short option set.
*
* @param string $token The current token
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function parseShortOptionSet($name)
{
@@ -166,6 +168,8 @@ protected function parseLongOption($token)
* Parses an argument.
*
* @param string $token The current token
+ *
+ * @throws \RuntimeException When too many arguments are given
*/
protected function parseArgument($token)
{
@@ -182,6 +186,8 @@ protected function parseArgument($token)
*
* @param string $shortcut The short option key
* @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function addShortOption($shortcut, $value)
{
@@ -198,6 +204,8 @@ protected function addShortOption($shortcut, $value)
*
* @param string $name The long option key
* @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function addLongOption($name, $value)
{
diff --git a/src/Symfony/Components/Console/Input/ArrayInput.php b/src/Symfony/Components/Console/Input/ArrayInput.php
index 3ae6154d30900..71cdefc36fe28 100644
--- a/src/Symfony/Components/Console/Input/ArrayInput.php
+++ b/src/Symfony/Components/Console/Input/ArrayInput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
*
* $input = new ArrayInput(array('name' => 'foo', '--bar' => 'foobar'));
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class ArrayInput extends Input
@@ -29,7 +29,7 @@ class ArrayInput extends Input
/**
* Constructor.
*
- * @param array $param An array of parameters
+ * @param array $param An array of parameters
* @param InputDefinition $definition A InputDefinition instance
*/
public function __construct(array $parameters, InputDefinition $definition = null)
@@ -117,6 +117,8 @@ protected function parse()
*
* @param string $shortcut The short option key
* @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function addShortOption($shortcut, $value)
{
@@ -133,6 +135,8 @@ protected function addShortOption($shortcut, $value)
*
* @param string $name The long option key
* @param mixed $value The value for the option
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function addLongOption($name, $value)
{
@@ -161,6 +165,8 @@ protected function addLongOption($name, $value)
*
* @param string $name The argument name
* @param mixed $value The value for the argument
+ *
+ * @throws \RuntimeException When option given doesn't exist
*/
protected function addArgument($name, $value)
{
diff --git a/src/Symfony/Components/Console/Input/Input.php b/src/Symfony/Components/Console/Input/Input.php
index 9e9e5f48263cd..a5a4f1ec07ac5 100644
--- a/src/Symfony/Components/Console/Input/Input.php
+++ b/src/Symfony/Components/Console/Input/Input.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -20,8 +20,8 @@
* * `StringInput`: The input is provided as a string
* * `ArrayInput`: The input is provided as an array
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
abstract class Input implements InputInterface
@@ -68,6 +68,9 @@ public function bind(InputDefinition $definition)
*/
abstract protected function parse();
+ /**
+ * @throws \RuntimeException When not enough arguments are given
+ */
public function validate()
{
if (count($this->arguments) < $this->definition->getArgumentRequiredCount())
@@ -102,6 +105,8 @@ public function getArguments()
* @param string $name The argument name
*
* @return mixed The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
*/
public function getArgument($name)
{
@@ -118,6 +123,8 @@ public function getArgument($name)
*
* @param string $name The argument name
* @param string $value The argument value
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
*/
public function setArgument($name, $value)
{
@@ -157,6 +164,8 @@ public function getOptions()
* @param string $name The option name
*
* @return mixed The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
*/
public function getOption($name)
{
@@ -173,6 +182,8 @@ public function getOption($name)
*
* @param string $name The option name
* @param string $value The option value
+ *
+ * @throws \InvalidArgumentException When option given doesn't exist
*/
public function setOption($name, $value)
{
diff --git a/src/Symfony/Components/Console/Input/InputArgument.php b/src/Symfony/Components/Console/Input/InputArgument.php
index 9b5925b4bfaf8..aada8b6281798 100644
--- a/src/Symfony/Components/Console/Input/InputArgument.php
+++ b/src/Symfony/Components/Console/Input/InputArgument.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Represents a command line argument.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class InputArgument
@@ -36,6 +36,8 @@ class InputArgument
* @param integer $mode The argument mode: self::REQUIRED or self::OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (for self::OPTIONAL mode only)
+ *
+ * @throws \InvalidArgumentException When argument mode is not valid
*/
public function __construct($name, $mode = null, $description = '', $default = null)
{
@@ -89,6 +91,8 @@ public function isArray()
* Sets the default value.
*
* @param mixed $default The default value
+ *
+ * @throws \LogicException When incorrect default value is given
*/
public function setDefault($default = null)
{
diff --git a/src/Symfony/Components/Console/Input/InputDefinition.php b/src/Symfony/Components/Console/Input/InputDefinition.php
index 2977e7fd6d427..3c3a69123f713 100644
--- a/src/Symfony/Components/Console/Input/InputDefinition.php
+++ b/src/Symfony/Components/Console/Input/InputDefinition.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -21,8 +21,8 @@
* new InputOption('foo', 'f', InputOption::PARAMETER_REQUIRED),
* ));
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class InputDefinition
@@ -97,6 +97,8 @@ public function addArguments($arguments = array())
* Add an InputArgument object.
*
* @param InputArgument $argument An InputArgument object
+ *
+ * @throws \LogicException When incorrect argument is given
*/
public function addArgument(InputArgument $argument)
{
@@ -138,6 +140,8 @@ public function addArgument(InputArgument $argument)
* @param string|integer $name The InputArgument name or position
*
* @return InputArgument An InputArgument object
+ *
+ * @throws \InvalidArgumentException When argument given doesn't exist
*/
public function getArgument($name)
{
@@ -240,6 +244,8 @@ public function addOptions($options = array())
* Add an InputOption object.
*
* @param InputOption $option An InputOption object
+ *
+ * @throws \LogicException When option given already exist
*/
public function addOption(InputOption $option)
{
@@ -342,6 +348,8 @@ public function getOptionDefaults()
* @param string $shortcut The shortcut
*
* @return string The InputOption name
+ *
+ * @throws \InvalidArgumentException When option given does not exist
*/
protected function shortcutToName($shortcut)
{
diff --git a/src/Symfony/Components/Console/Input/InputInterface.php b/src/Symfony/Components/Console/Input/InputInterface.php
index 953553e7805aa..8367c9123b6f9 100644
--- a/src/Symfony/Components/Console/Input/InputInterface.php
+++ b/src/Symfony/Components/Console/Input/InputInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* InputInterface is the interface implemented by all input classes.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
interface InputInterface
diff --git a/src/Symfony/Components/Console/Input/InputOption.php b/src/Symfony/Components/Console/Input/InputOption.php
index 46a47d0d5720e..a547968d331c3 100644
--- a/src/Symfony/Components/Console/Input/InputOption.php
+++ b/src/Symfony/Components/Console/Input/InputOption.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Represents a command line option.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class InputOption
@@ -39,6 +39,8 @@ class InputOption
* @param integer $mode The option mode: self::PARAMETER_REQUIRED, self::PARAMETER_NONE or self::PARAMETER_OPTIONAL
* @param string $description A description text
* @param mixed $default The default value (must be null for self::PARAMETER_REQUIRED or self::PARAMETER_NONE)
+ *
+ * @throws \InvalidArgumentException If option mode is invalid or incompatible
*/
public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)
{
diff --git a/src/Symfony/Components/Console/Input/StringInput.php b/src/Symfony/Components/Console/Input/StringInput.php
index c66f7b9dc4b39..6b3668dedfa0b 100644
--- a/src/Symfony/Components/Console/Input/StringInput.php
+++ b/src/Symfony/Components/Console/Input/StringInput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Input;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
*
* $input = new StringInput('foo --bar="foobar"');
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class StringInput extends ArgvInput
@@ -40,6 +40,9 @@ public function __construct($input, InputDefinition $definition = null)
$this->tokens = $this->tokenize($input);
}
+ /**
+ * @throws \InvalidArgumentException When unable to parse input (should never happen)
+ */
protected function tokenize($input)
{
$input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input);
diff --git a/src/Symfony/Components/Console/Output/ConsoleOutput.php b/src/Symfony/Components/Console/Output/ConsoleOutput.php
index 7950c25ec02df..94c132daa9d7a 100644
--- a/src/Symfony/Components/Console/Output/ConsoleOutput.php
+++ b/src/Symfony/Components/Console/Output/ConsoleOutput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Output;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -22,8 +22,8 @@
*
* $output = new StreamOutput(fopen('php://stdout', 'w'));
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class ConsoleOutput extends StreamOutput
diff --git a/src/Symfony/Components/Console/Output/NullOutput.php b/src/Symfony/Components/Console/Output/NullOutput.php
index 86e2c326f8e01..5ef678a24bcf1 100644
--- a/src/Symfony/Components/Console/Output/NullOutput.php
+++ b/src/Symfony/Components/Console/Output/NullOutput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Output;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
*
* $output = new NullOutput();
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class NullOutput extends Output
diff --git a/src/Symfony/Components/Console/Output/Output.php b/src/Symfony/Components/Console/Output/Output.php
index 7bfa8bf012290..20a39f1c75892 100644
--- a/src/Symfony/Components/Console/Output/Output.php
+++ b/src/Symfony/Components/Console/Output/Output.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Output;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -20,8 +20,8 @@
* * verbose: -v (more output - debug)
* * quiet: -q (no output)
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
abstract class Output implements OutputInterface
@@ -127,6 +127,8 @@ public function writeln($messages, $type = 0)
* @param string|array $messages The message as an array of lines of a single string
* @param Boolean $newline Whether to add a newline or not
* @param integer $type The type of output
+ *
+ * @throws \InvalidArgumentException When unknown output type is given
*/
public function write($messages, $newline = false, $type = 0)
{
@@ -182,6 +184,9 @@ protected function format($message)
return preg_replace_callback('#([a-z][a-z0-9\-_]+)>#i', array($this, 'replaceEndStyle'), $message);
}
+ /**
+ * @throws \InvalidArgumentException When style is unknown
+ */
protected function replaceStartStyle($match)
{
if (!$this->decorated)
diff --git a/src/Symfony/Components/Console/Output/OutputInterface.php b/src/Symfony/Components/Console/Output/OutputInterface.php
index 26bc6b76ef72b..6e93b78d5c6d3 100644
--- a/src/Symfony/Components/Console/Output/OutputInterface.php
+++ b/src/Symfony/Components/Console/Output/OutputInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Output;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* OutputInterface is the interface implemented by all Output classes.
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
interface OutputInterface
diff --git a/src/Symfony/Components/Console/Output/StreamOutput.php b/src/Symfony/Components/Console/Output/StreamOutput.php
index fdb74debedff6..dfff19107366d 100644
--- a/src/Symfony/Components/Console/Output/StreamOutput.php
+++ b/src/Symfony/Components/Console/Output/StreamOutput.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Console\Output;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -22,8 +22,8 @@
*
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
*
- * @package symfony
- * @subpackage console
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class StreamOutput extends Output
@@ -36,6 +36,8 @@ class StreamOutput extends Output
* @param mixed $stream A stream resource
* @param integer $verbosity The verbosity level (self::VERBOSITY_QUIET, self::VERBOSITY_NORMAL, self::VERBOSITY_VERBOSE)
* @param Boolean $decorated Whether to decorate messages or not (null for auto-guessing)
+ *
+ * @throws \InvalidArgumentException When first argument is not a real stream
*/
public function __construct($stream, $verbosity = self::VERBOSITY_NORMAL, $decorated = null)
{
@@ -69,6 +71,8 @@ public function getStream()
*
* @param string $message A message to write to the output
* @param Boolean $newline Whether to add a newline or not
+ *
+ * @throws \RuntimeException When unable to write output (should never happen)
*/
public function doWrite($message, $newline)
{
diff --git a/src/Symfony/Components/Console/Shell.php b/src/Symfony/Components/Console/Shell.php
index f91965c0bd402..d62d8db97eeb6 100644
--- a/src/Symfony/Components/Console/Shell.php
+++ b/src/Symfony/Components/Console/Shell.php
@@ -7,7 +7,7 @@
use Symfony\Components\Console\Output\ConsoleOutput;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -21,8 +21,8 @@
* This class only works with a PHP compiled with readline support
* (either --with-readline or --with-libedit)
*
- * @package symfony
- * @subpackage cli
+ * @package Symfony
+ * @subpackage Components_Console
* @author Fabien Potencier
*/
class Shell
@@ -38,6 +38,8 @@ class Shell
* a \RuntimeException exception is thrown.
*
* @param Application $application An application instance
+ *
+ * @throws \RuntimeException When Readline extension is not enabled
*/
public function __construct(Application $application)
{
diff --git a/src/Symfony/Components/Console/Tester/ApplicationTester.php b/src/Symfony/Components/Console/Tester/ApplicationTester.php
index aa31f71cb4c8c..dc8501856f427 100644
--- a/src/Symfony/Components/Console/Tester/ApplicationTester.php
+++ b/src/Symfony/Components/Console/Tester/ApplicationTester.php
@@ -6,6 +6,20 @@
use Symfony\Components\Console\Input\ArrayInput;
use Symfony\Components\Console\Output\StreamOutput;
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * @package Symfony
+ * @subpackage Components_Console
+ * @author Fabien Potencier
+ */
class ApplicationTester
{
protected $application;
diff --git a/src/Symfony/Components/Console/Tester/CommandTester.php b/src/Symfony/Components/Console/Tester/CommandTester.php
index bc0ee8879ed3c..d7a8b813d1b68 100644
--- a/src/Symfony/Components/Console/Tester/CommandTester.php
+++ b/src/Symfony/Components/Console/Tester/CommandTester.php
@@ -6,6 +6,20 @@
use Symfony\Components\Console\Input\ArrayInput;
use Symfony\Components\Console\Output\StreamOutput;
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/**
+ * @package Symfony
+ * @subpackage Components_Console
+ * @author Fabien Potencier
+ */
class CommandTester
{
protected $command;
diff --git a/src/Symfony/Components/CssSelector/Node/AttribNode.php b/src/Symfony/Components/CssSelector/Node/AttribNode.php
new file mode 100644
index 0000000000000..5b7a8a1b80051
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/AttribNode.php
@@ -0,0 +1,136 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * AttribNode represents a "selector[namespace|attrib operator value]" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class AttribNode implements NodeInterface
+{
+ protected $selector;
+ protected $namespace;
+ protected $attrib;
+ protected $operator;
+ protected $value;
+
+ public function __construct($selector, $namespace, $attrib, $operator, $value)
+ {
+ $this->selector = $selector;
+ $this->namespace = $namespace;
+ $this->attrib = $attrib;
+ $this->operator = $operator;
+ $this->value = $value;
+ }
+
+ public function __toString()
+ {
+ if ($this->operator == 'exists')
+ {
+ return sprintf('%s[%s[%s]]', __CLASS__, $this->selector, $this->formatAttrib());
+ }
+ else
+ {
+ return sprintf('%s[%s[%s %s %s]]', __CLASS__, $this->selector, $this->formatAttrib(), $this->operator, $this->value);
+ }
+ }
+
+ /**
+ * @throws SyntaxError When unknown operator is found
+ */
+ public function toXpath()
+ {
+ $path = $this->selector->toXpath();
+ $attrib = $this->xpathAttrib();
+ $value = $this->value;
+ if ($this->operator == 'exists')
+ {
+ $path->addCondition($attrib);
+ }
+ elseif ($this->operator == '=')
+ {
+ $path->addCondition(sprintf('%s = %s', $attrib, XPathExpr::xpathLiteral($value)));
+ }
+ elseif ($this->operator == '!=')
+ {
+ // FIXME: this seems like a weird hack...
+ if ($value)
+ {
+ $path->addCondition(sprintf('not(%s) or %s != %s', $attrib, $attrib, XPathExpr::xpathLiteral($value)));
+ }
+ else
+ {
+ $path->addCondition(sprintf('%s != %s', $attrib, XPathExpr::xpathLiteral($value)));
+ }
+ // path.addCondition('%s != %s' % (attrib, xpathLiteral(value)))
+ }
+ elseif ($this->operator == '~=')
+ {
+ $path->addCondition(sprintf("contains(concat(' ', normalize-space(%s), ' '), %s)", $attrib, XPathExpr::xpathLiteral(' '.$value.' ')));
+ }
+ elseif ($this->operator == '|=')
+ {
+ // Weird, but true...
+ $path->addCondition(sprintf('%s = %s or starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value), $attrib, XPathExpr::xpathLiteral($value.'-')));
+ }
+ elseif ($this->operator == '^=')
+ {
+ $path->addCondition(sprintf('starts-with(%s, %s)', $attrib, XPathExpr::xpathLiteral($value)));
+ }
+ elseif ($this->operator == '$=')
+ {
+ // Oddly there is a starts-with in XPath 1.0, but not ends-with
+ $path->addCondition(sprintf('substring(%s, string-length(%s)-%s) = %s', $attrib, $attrib, strlen($value) - 1, XPathExpr::xpathLiteral($value)));
+ }
+ elseif ($this->operator == '*=')
+ {
+ // FIXME: case sensitive?
+ $path->addCondition(sprintf('contains(%s, %s)', $attrib, XPathExpr::xpathLiteral($value)));
+ }
+ else
+ {
+ throw new SyntaxError(sprintf("Unknown operator: %s", $this->operator));
+ }
+
+ return $path;
+ }
+
+ protected function xpathAttrib()
+ {
+ // FIXME: if attrib is *?
+ if ($this->namespace == '*')
+ {
+ return '@'.$this->attrib;
+ }
+
+ return sprintf('@%s:%s', $this->namespace, $this->attrib);
+ }
+
+ protected function formatAttrib()
+ {
+ if ($this->namespace == '*')
+ {
+ return $this->attrib;
+ }
+
+ return sprintf('%s|%s', $this->namespace, $this->attrib);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/ClassNode.php b/src/Symfony/Components/CssSelector/Node/ClassNode.php
new file mode 100644
index 0000000000000..729ee1f223800
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/ClassNode.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * ClassNode represents a "selector.className" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class ClassNode implements NodeInterface
+{
+ protected $selector;
+ protected $className;
+
+ public function __construct($selector, $className)
+ {
+ $this->selector = $selector;
+ $this->className = $className;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s[%s.%s]', __CLASS__, $this->selector, $this->className);
+ }
+
+ public function toXpath()
+ {
+ $selXpath = $this->selector->toXpath();
+ $selXpath->addCondition(sprintf("contains(concat(' ', normalize-space(@class), ' '), %s)", XPathExpr::xpathLiteral(' '.$this->className.' ')));
+
+ return $selXpath;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/CombinedSelectorNode.php b/src/Symfony/Components/CssSelector/Node/CombinedSelectorNode.php
new file mode 100644
index 0000000000000..0a5914d52fcba
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/CombinedSelectorNode.php
@@ -0,0 +1,102 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * CombinedSelectorNode represents a combinator node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class CombinedSelectorNode implements NodeInterface
+{
+ static protected $_method_mapping = array(
+ ' ' => 'descendant',
+ '>' => 'child',
+ '+' => 'direct_adjacent',
+ '~' => 'indirect_adjacent',
+ );
+
+ protected $selector;
+ protected $combinator;
+ protected $subselector;
+
+ public function __construct($selector, $combinator, $subselector)
+ {
+ $this->selector = $selector;
+ $this->combinator = $combinator;
+ $this->subselector = $subselector;
+ }
+
+ public function __toString()
+ {
+ $comb = $this->combinator == ' ' ? '' : $this->combinator;
+
+ return sprintf('%s[%s %s %s]', __CLASS__, $this->selector, $comb, $this->subselector);
+ }
+
+ /**
+ * @throws SyntaxError When unknown combinator is found
+ */
+ public function toXpath()
+ {
+ if (!isset(self::$_method_mapping[$this->combinator]))
+ {
+ throw new SyntaxError(sprintf("Unknown combinator: %s", $this->combinator));
+ }
+
+ $method = '_xpath_'.self::$_method_mapping[$this->combinator];
+ $path = $this->selector->toXpath();
+
+ return $this->$method($path, $this->subselector);
+ }
+
+ protected function _xpath_descendant($xpath, $sub)
+ {
+ // when sub is a descendant in any way of xpath
+ $xpath->join('/descendant::', $sub->toXpath());
+
+ return $xpath;
+ }
+
+ protected function _xpath_child($xpath, $sub)
+ {
+ // when sub is an immediate child of xpath
+ $xpath->join('/', $sub->toXpath());
+
+ return $xpath;
+ }
+
+ protected function _xpath_direct_adjacent($xpath, $sub)
+ {
+ // when sub immediately follows xpath
+ $xpath->join('/following-sibling::', $sub->toXpath());
+ $xpath->addNameTest();
+ $xpath->addCondition('position() = 1');
+
+ return $xpath;
+ }
+
+ protected function _xpath_indirect_adjacent($xpath, $sub)
+ {
+ // when sub comes somewhere after xpath as a sibling
+ $xpath->join('/following-sibling::', $sub->toXpath());
+
+ return $xpath;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/ElementNode.php b/src/Symfony/Components/CssSelector/Node/ElementNode.php
new file mode 100644
index 0000000000000..ad76ffbac83d9
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/ElementNode.php
@@ -0,0 +1,66 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * ElementNode represents a "namespace|element" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class ElementNode implements NodeInterface
+{
+ protected $namespace;
+ protected $element;
+
+ public function __construct($namespace, $element)
+ {
+ $this->namespace = $namespace;
+ $this->element = $element;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s[%s]', __CLASS__, $this->formatElement());
+ }
+
+ public function formatElement()
+ {
+ if ($this->namespace == '*')
+ {
+ return $this->element;
+ }
+
+ return sprintf('%s|%s', $this->namespace, $this->element);
+ }
+
+ public function toXpath()
+ {
+ if ($this->namespace == '*')
+ {
+ $el = strtolower($this->element);
+ }
+ else
+ {
+ // FIXME: Should we lowercase here?
+ $el = sprintf('%s:%s', $this->namespace, $this->element);
+ }
+
+ return new XPathExpr(null, null, $el);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/FunctionNode.php b/src/Symfony/Components/CssSelector/Node/FunctionNode.php
new file mode 100644
index 0000000000000..ceb78e28ed5e9
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/FunctionNode.php
@@ -0,0 +1,265 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * FunctionNode represents a "selector:name(expr)" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class FunctionNode implements NodeInterface
+{
+ static protected $unsupported = array('target', 'lang', 'enabled', 'disabled');
+
+ protected $selector;
+ protected $type;
+ protected $name;
+ protected $expr;
+
+ public function __construct($selector, $type, $name, $expr)
+ {
+ $this->selector = $selector;
+ $this->type = $type;
+ $this->name = $name;
+ $this->expr = $expr;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s[%s%s%s(%s)]', __CLASS__, $this->selector, $this->type, $this->name, $this->expr);
+ }
+
+ /**
+ * @throws SyntaxError When unsupported or unknown pseudo-class is found
+ */
+ public function toXpath()
+ {
+ $sel_path = $this->selector->toXpath();
+ if (in_array($this->name, self::$unsupported))
+ {
+ throw new SyntaxError(sprintf("The pseudo-class %s is not supported", $this->name));
+ }
+ $method = '_xpath_'.str_replace('-', '_', $this->name);
+ if (!method_exists($this, $method))
+ {
+ throw new SyntaxError(sprintf("The pseudo-class %s is unknown", $this->name));
+ }
+
+ return $this->$method($sel_path, $this->expr);
+ }
+
+ protected function _xpath_nth_child($xpath, $expr, $last = false, $addNameTest = true)
+ {
+ list($a, $b) = $this->parseSeries($expr);
+ if (!$a && !$b && !$last)
+ {
+ // a=0 means nothing is returned...
+ $xpath->addCondition('false() and position() = 0');
+
+ return $xpath;
+ }
+
+ if ($addNameTest)
+ {
+ $xpath->addNameTest();
+ }
+
+ $xpath->addStarPrefix();
+ if ($a == 0)
+ {
+ if ($last)
+ {
+ $b = sprintf('last() - %s', $b);
+ }
+ $xpath->addCondition(sprintf('position() = %s', $b));
+
+ return $xpath;
+ }
+
+ if ($last)
+ {
+ // FIXME: I'm not sure if this is right
+ $a = -$a;
+ $b = -$b;
+ }
+
+ if ($b > 0)
+ {
+ $b_neg = -$b;
+ }
+ else
+ {
+ $b_neg = sprintf('+%s', -$b);
+ }
+
+ if ($a != 1)
+ {
+ $expr = array(sprintf('(position() %s) mod %s = 0', $b_neg, $a));
+ }
+ else
+ {
+ $expr = array();
+ }
+
+ if ($b >= 0)
+ {
+ $expr[] = sprintf('position() >= %s', $b);
+ }
+ elseif ($b < 0 && $last)
+ {
+ $expr[] = sprintf('position() < (last() %s)', $b);
+ }
+ $expr = implode($expr, ' and ');
+
+ if ($expr)
+ {
+ $xpath->addCondition($expr);
+ }
+
+ return $xpath;
+ /* FIXME: handle an+b, odd, even
+ an+b means every-a, plus b, e.g., 2n+1 means odd
+ 0n+b means b
+ n+0 means a=1, i.e., all elements
+ an means every a elements, i.e., 2n means even
+ -n means -1n
+ -1n+6 means elements 6 and previous */
+ }
+
+ protected function _xpath_nth_last_child($xpath, $expr)
+ {
+ return $this->_xpath_nth_child($xpath, $expr, true);
+ }
+
+ protected function _xpath_nth_of_type($xpath, $expr)
+ {
+ if ($xpath->getElement() == '*')
+ {
+ throw new SyntaxError("*:nth-of-type() is not implemented");
+ }
+
+ return $this->_xpath_nth_child($xpath, $expr, false, false);
+ }
+
+ protected function _xpath_nth_last_of_type($xpath, $expr)
+ {
+ return $this->_xpath_nth_child($xpath, $expr, true, false);
+ }
+
+ protected function _xpath_contains($xpath, $expr)
+ {
+ // text content, minus tags, must contain expr
+ if ($expr instanceof ElementNode)
+ {
+ $expr = $expr->formatElement();
+ }
+
+ // FIXME: lower-case is only available with XPath 2
+ //$xpath->addCondition(sprintf('contains(lower-case(string(.)), %s)', XPathExpr::xpathLiteral(strtolower($expr))));
+ $xpath->addCondition(sprintf('contains(string(.), %s)', XPathExpr::xpathLiteral($expr)));
+
+ // FIXME: Currently case insensitive matching doesn't seem to be happening
+
+ return $xpath;
+ }
+
+ protected function _xpath_not($xpath, $expr)
+ {
+ // everything for which not expr applies
+ $expr = $expr->toXpath();
+ $cond = $expr->getCondition();
+ // FIXME: should I do something about element_path?
+ $xpath->addCondition(sprintf('not(%s)', $cond));
+
+ return $xpath;
+ }
+
+ // Parses things like '1n+2', or 'an+b' generally, returning (a, b)
+ protected function parseSeries($s)
+ {
+ if ($s instanceof ElementNode)
+ {
+ $s = $s->formatElement();
+ }
+
+ if (!$s || $s == '*')
+ {
+ // Happens when there's nothing, which the CSS parser thinks of as *
+ return array(0, 0);
+ }
+
+ if (is_string($s))
+ {
+ // Happens when you just get a number
+ return array(0, $s);
+ }
+
+ if ($s == 'odd')
+ {
+ return array(2, 1);
+ }
+
+ if ($s == 'even')
+ {
+ return array(2, 0);
+ }
+
+ if ($s == 'n')
+ {
+ return array(1, 0);
+ }
+
+ if (false === strpos($s, 'n'))
+ {
+ // Just a b
+
+ return array(0, intval((string) $s));
+ }
+
+ list($a, $b) = explode('n', $s);
+ if (!$a)
+ {
+ $a = 1;
+ }
+ elseif ($a == '-' || $a == '+')
+ {
+ $a = intval($a.'1');
+ }
+ else
+ {
+ $a = intval($a);
+ }
+
+ if (!$b)
+ {
+ $b = 0;
+ }
+ elseif ($b == '-' || $b == '+')
+ {
+ $b = intval($b.'1');
+ }
+ else
+ {
+ $b = intval($b);
+ }
+
+ return array($a, $b);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/HashNode.php b/src/Symfony/Components/CssSelector/Node/HashNode.php
new file mode 100644
index 0000000000000..207cb2f5c0553
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/HashNode.php
@@ -0,0 +1,49 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * HashNode represents a "selector#id" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class HashNode implements NodeInterface
+{
+ protected $selector;
+ protected $id;
+
+ public function __construct($selector, $id)
+ {
+ $this->selector = $selector;
+ $this->id = $id;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s[%s#%s]', __CLASS__, $this->selector, $this->id);
+ }
+
+ public function toXpath()
+ {
+ $path = $this->selector->toXpath();
+ $path->addCondition(sprintf('@id = %s', XPathExpr::xpathLiteral($this->id)));
+
+ return $path;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/NodeInterface.php b/src/Symfony/Components/CssSelector/Node/NodeInterface.php
new file mode 100644
index 0000000000000..9f818cd274a72
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/NodeInterface.php
@@ -0,0 +1,29 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * ClassNode represents a "selector.className" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+interface NodeInterface
+{
+ public function __toString();
+
+ public function toXpath();
+}
diff --git a/src/Symfony/Components/CssSelector/Node/OrNode.php b/src/Symfony/Components/CssSelector/Node/OrNode.php
new file mode 100644
index 0000000000000..fb4026e6ea326
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/OrNode.php
@@ -0,0 +1,50 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * OrNode represents a "Or" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class OrNode implements NodeInterface
+{
+ protected $items;
+
+ public function __construct($items)
+ {
+ $this->items = $items;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s(%s)', __CLASS__, $this->items);
+ }
+
+ public function toXpath()
+ {
+ $paths = array();
+ foreach ($this->items as $item)
+ {
+ $paths[] = $item->toXpath();
+ }
+
+ return new XPathExprOr($paths);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Node/PseudoNode.php b/src/Symfony/Components/CssSelector/Node/PseudoNode.php
new file mode 100644
index 0000000000000..9b6ed800e4023
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Node/PseudoNode.php
@@ -0,0 +1,170 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * PseudoNode represents a "selector:ident" node.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class PseudoNode implements NodeInterface
+{
+ static protected $unsupported = array(
+ 'indeterminate', 'first-line', 'first-letter',
+ 'selection', 'before', 'after', 'link', 'visited',
+ 'active', 'focus', 'hover',
+ );
+
+ protected $element;
+ protected $type;
+ protected $ident;
+
+ /**
+ * @throws SyntaxError When incorrect PseudoNode type is given
+ */
+ public function __construct($element, $type, $ident)
+ {
+ $this->element = $element;
+
+ if (!in_array($type, array(':', '::')))
+ {
+ throw new SyntaxError(sprintf('The PseudoNode type can only be : or :: (%s given).', $type));
+ }
+
+ $this->type = $type;
+ $this->ident = $ident;
+ }
+
+ public function __toString()
+ {
+ return sprintf('%s[%s%s%s]', __CLASS__, $this->element, $this->type, $this->ident);
+ }
+
+ /**
+ * @throws SyntaxError When unsupported or unknown pseudo-class is found
+ */
+ public function toXpath()
+ {
+ $el_xpath = $this->element->toXpath();
+
+ if (in_array($this->ident, self::$unsupported))
+ {
+ throw new SyntaxError(sprintf("The pseudo-class %s is unsupported", $this->ident));
+ }
+ $method = 'xpath_'.str_replace('-', '_', $this->ident);
+ if (!method_exists($this, $method))
+ {
+ throw new SyntaxError(sprintf("The pseudo-class %s is unknown", $this->ident));
+ }
+
+ return $this->$method($el_xpath);
+ }
+
+ protected function xpath_checked($xpath)
+ {
+ // FIXME: is this really all the elements?
+ $xpath->addCondition("(@selected or @checked) and (name(.) = 'input' or name(.) = 'option')");
+
+ return $xpath;
+ }
+
+ /**
+ * @throws SyntaxError If this element is the root element
+ */
+ protected function xpath_root($xpath)
+ {
+ // if this element is the root element
+ throw new SyntaxError();
+ }
+
+ protected function xpath_first_child($xpath)
+ {
+ $xpath->addStarPrefix();
+ $xpath->addNameTest();
+ $xpath->addCondition('position() = 1');
+
+ return $xpath;
+ }
+
+ protected function xpath_last_child($xpath)
+ {
+ $xpath->addStarPrefix();
+ $xpath->addNameTest();
+ $xpath->addCondition('position() = last()');
+
+ return $xpath;
+ }
+
+ protected function xpath_first_of_type($xpath)
+ {
+ if ($xpath->getElement() == '*')
+ {
+ throw new SyntaxError("*:first-of-type is not implemented");
+ }
+ $xpath->addStarPrefix();
+ $xpath->addCondition('position() = 1');
+
+ return $xpath;
+ }
+
+ /**
+ * @throws SyntaxError Because *:last-of-type is not implemented
+ */
+ protected function xpath_last_of_type($xpath)
+ {
+ if ($xpath->getElement() == '*')
+ {
+ throw new SyntaxError("*:last-of-type is not implemented");
+ }
+ $xpath->addStarPrefix();
+ $xpath->addCondition('position() = last()');
+
+ return $xpath;
+ }
+
+ protected function xpath_only_child($xpath)
+ {
+ $xpath->addNameTest();
+ $xpath->addStarPrefix();
+ $xpath->addCondition('last() = 1');
+
+ return $xpath;
+ }
+
+ /**
+ * @throws SyntaxError Because *:only-of-type is not implemented
+ */
+ protected function xpath_only_of_type($xpath)
+ {
+ if ($xpath->getElement() == '*')
+ {
+ throw new SyntaxError("*:only-of-type is not implemented");
+ }
+ $xpath->addCondition('last() = 1');
+
+ return $xpath;
+ }
+
+ protected function xpath_empty($xpath)
+ {
+ $xpath->addCondition("not(*) and not(normalize-space())");
+
+ return $xpath;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Parser.php b/src/Symfony/Components/CssSelector/Parser.php
new file mode 100644
index 0000000000000..929fa808a6eca
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Parser.php
@@ -0,0 +1,320 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Parser is the main entry point of the component and can convert CSS
+ * selectors to XPath expressions.
+ *
+ * $xpath = Parser::cssToXpath('h1.foo');
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class Parser
+{
+ /**
+ * @throws SyntaxError When got None for xpath expression
+ */
+ static public function cssToXpath($cssExpr, $prefix = 'descendant-or-self::')
+ {
+ if (is_string($cssExpr))
+ {
+ if (preg_match('#^\w+\s*$#u', $cssExpr, $match))
+ {
+ return $prefix.trim($match[0]);
+ }
+
+ if (preg_match('~^(\w*)#(\w+)\s*$~u', $cssExpr, $match))
+ {
+ return sprintf("%s%s[@id = '%s']", $prefix, $match[1] ? $match[1] : '*', $match[2]);
+ }
+
+ if (preg_match('#^(\w*)\.(\w+)\s*$#u', $cssExpr, $match))
+ {
+ return sprintf("%s%s[contains(concat(' ', normalize-space(@class), ' '), ' %s ')]", $prefix, $match[1] ? $match[1] : '*', $match[2]);
+ }
+
+ $parser = new self();
+ $cssExpr = $parser->parse($cssExpr);
+ }
+
+ $expr = $cssExpr->toXpath();
+
+ // @codeCoverageIgnoreStart
+ if (!$expr)
+ {
+ throw new SyntaxError(sprintf("Got None for xpath expression from %s.", $cssExpr));
+ }
+ // @codeCoverageIgnoreEnd
+
+ if ($prefix)
+ {
+ $expr->addPrefix($prefix);
+ }
+
+ return (string) $expr;
+ }
+
+ /**
+ * @throws \Exception When tokenizer throws it while parsing
+ */
+ public function parse($string)
+ {
+ $tokenizer = new Tokenizer();
+
+ $stream = new TokenStream($tokenizer->tokenize($string), $string);
+
+ try
+ {
+ return $this->parseSelectorGroup($stream);
+ }
+ catch (\Exception $e)
+ {
+ $class = get_class($e);
+
+ throw new $class(sprintf("%s at %s -> %s", $e->getMessage(), implode($stream->getUsed(), ''), $stream->peek()));
+ }
+ }
+
+ protected function parseSelectorGroup($stream)
+ {
+ $result = array();
+ while (1)
+ {
+ $result[] = $this->parseSelector($stream);
+ if ($stream->peek() == ',')
+ {
+ $stream->next();
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (count($result) == 1)
+ {
+ return $result[0];
+ }
+
+ return new Node\OrNode($result);
+ }
+
+ /**
+ * @throws SyntaxError When expected selector but got something else
+ */
+ protected function parseSelector($stream)
+ {
+ $result = $this->parseSimpleSelector($stream);
+
+ while (1)
+ {
+ $peek = $stream->peek();
+ if ($peek == ',' || $peek === null)
+ {
+ return $result;
+ }
+ elseif (in_array($peek, array('+', '>', '~')))
+ {
+ // A combinator
+ $combinator = (string) $stream->next();
+ }
+ else
+ {
+ $combinator = ' ';
+ }
+ $consumed = count($stream->getUsed());
+ $next_selector = $this->parseSimpleSelector($stream);
+ if ($consumed == count($stream->getUsed()))
+ {
+ throw new SyntaxError(sprintf("Expected selector, got '%s'", $stream->peek()));
+ }
+
+ $result = new Node\CombinedSelectorNode($result, $combinator, $next_selector);
+ }
+
+ return $result;
+ }
+
+ /**
+ * @throws SyntaxError When expected symbol but got something else
+ */
+ protected function parseSimpleSelector($stream)
+ {
+ $peek = $stream->peek();
+ if ($peek != '*' && !$peek->isType('Symbol'))
+ {
+ $element = $namespace = '*';
+ }
+ else
+ {
+ $next = $stream->next();
+ if ($next != '*' && !$next->isType('Symbol'))
+ {
+ throw new SyntaxError(sprintf("Expected symbol, got '%s'", $next));
+ }
+
+ if ($stream->peek() == '|')
+ {
+ $namespace = $next;
+ $stream->next();
+ $element = $stream->next();
+ if ($element != '*' && !$next->isType('Symbol'))
+ {
+ throw new SyntaxError(sprintf("Expected symbol, got '%s'", $next));
+ }
+ }
+ else
+ {
+ $namespace = '*';
+ $element = $next;
+ }
+ }
+
+ $result = new Node\ElementNode($namespace, $element);
+ $has_hash = false;
+ while (1)
+ {
+ $peek = $stream->peek();
+ if ($peek == '#')
+ {
+ if ($has_hash)
+ {
+ /* You can't have two hashes
+ (FIXME: is there some more general rule I'm missing?) */
+ // @codeCoverageIgnoreStart
+ break;
+ // @codeCoverageIgnoreEnd
+ }
+ $stream->next();
+ $result = new Node\HashNode($result, $stream->next());
+ $has_hash = true;
+
+ continue;
+ }
+ elseif ($peek == '.')
+ {
+ $stream->next();
+ $result = new Node\ClassNode($result, $stream->next());
+
+ continue;
+ }
+ elseif ($peek == '[')
+ {
+ $stream->next();
+ $result = $this->parseAttrib($result, $stream);
+ $next = $stream->next();
+ if ($next != ']')
+ {
+ throw new SyntaxError(sprintf("] expected, got '%s'", $next));
+ }
+
+ continue;
+ }
+ elseif ($peek == ':' || $peek == '::')
+ {
+ $type = $stream->next();
+ $ident = $stream->next();
+ if (!$ident || !$ident->isType('Symbol'))
+ {
+ throw new SyntaxError(sprintf("Expected symbol, got '%s'", $ident));
+ }
+
+ if ($stream->peek() == '(')
+ {
+ $stream->next();
+ $peek = $stream->peek();
+ if ($peek->isType('String'))
+ {
+ $selector = $stream->next();
+ }
+ elseif ($peek->isType('Symbol') && is_int($peek))
+ {
+ $selector = intval($stream->next());
+ }
+ else
+ {
+ // FIXME: parseSimpleSelector, or selector, or...?
+ $selector = $this->parseSimpleSelector($stream);
+ }
+ $next = $stream->next();
+ if ($next != ')')
+ {
+ throw new SyntaxError(sprintf("Expected ')', got '%s' and '%s'", $next, $selector));
+ }
+
+ $result = new Node\FunctionNode($result, $type, $ident, $selector);
+ }
+ else
+ {
+ $result = new Node\PseudoNode($result, $type, $ident);
+ }
+
+ continue;
+ }
+ else
+ {
+ if ($peek == ' ')
+ {
+ $stream->next();
+ }
+
+ break;
+ }
+ // FIXME: not sure what "negation" is
+ }
+
+ return $result;
+ }
+
+ /**
+ * @throws SyntaxError When encountered unexpected selector
+ */
+ protected function parseAttrib($selector, $stream)
+ {
+ $attrib = $stream->next();
+ if ($stream->peek() == '|')
+ {
+ $namespace = $attrib;
+ $stream->next();
+ $attrib = $stream->next();
+ }
+ else
+ {
+ $namespace = '*';
+ }
+
+ if ($stream->peek() == ']')
+ {
+ return new Node\AttribNode($selector, $namespace, $attrib, 'exists', null);
+ }
+
+ $op = $stream->next();
+ if (!in_array($op, array('^=', '$=', '*=', '=', '~=', '|=', '!=')))
+ {
+ throw new SyntaxError(sprintf("Operator expected, got '%s'", $op));
+ }
+
+ $value = $stream->next();
+ if (!$value->isType('Symbol') && !$value->isType('String'))
+ {
+ throw new SyntaxError(sprintf("Expected string or symbol, got '%s'", $value));
+ }
+
+ return new Node\AttribNode($selector, $namespace, $attrib, $op, $value);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/README b/src/Symfony/Components/CssSelector/README
new file mode 100644
index 0000000000000..9a52f5637460a
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/README
@@ -0,0 +1,4 @@
+This component is a port of the Python lxml library,
+which is copyright Infrae and distributed under the BSD license.
+
+Current code is a port of http://codespeak.net/svn/lxml/trunk/src/lxml/cssselect.py@71545
diff --git a/src/Symfony/Components/CssSelector/SyntaxError.php b/src/Symfony/Components/CssSelector/SyntaxError.php
new file mode 100644
index 0000000000000..3be18b519936b
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/SyntaxError.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * SyntaxError is thrown when a CSS selector syntax is not valid.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class SyntaxError extends \LogicException
+{
+}
diff --git a/src/Symfony/Components/CssSelector/Token.php b/src/Symfony/Components/CssSelector/Token.php
new file mode 100644
index 0000000000000..c4489b9e2e7ca
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Token.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Token represents a CSS Selector token.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class Token
+{
+ protected $type;
+ protected $value;
+ protected $position;
+
+ public function __construct($type, $value, $position)
+ {
+ $this->type = $type;
+ $this->value = $value;
+ $this->position = $position;
+ }
+
+ public function __toString()
+ {
+ return (string) $this->value;
+ }
+
+ public function isType($type)
+ {
+ return $this->type == $type;
+ }
+
+ public function getPosition()
+ {
+ return $this->position;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/TokenStream.php b/src/Symfony/Components/CssSelector/TokenStream.php
new file mode 100644
index 0000000000000..7f6402e74a8bf
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/TokenStream.php
@@ -0,0 +1,83 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * TokenStream represents a stream of CSS Selector tokens.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class TokenStream
+{
+ protected $used;
+ protected $tokens;
+ protected $source;
+ protected $peeked;
+ protected $peeking;
+
+ public function __construct($tokens, $source = null)
+ {
+ $this->used = array();
+ $this->tokens = $tokens;
+ $this->source = $source;
+ $this->peeked = null;
+ $this->peeking = false;
+ }
+
+ public function getUsed()
+ {
+ return $this->used;
+ }
+
+ public function next()
+ {
+ if ($this->peeking)
+ {
+ $this->peeking = false;
+ $this->used[] = $this->peeked;
+
+ return $this->peeked;
+ }
+
+ if (!count($this->tokens))
+ {
+ return null;
+ }
+
+ $next = array_shift($this->tokens);
+ $this->used[] = $next;
+
+ return $next;
+ }
+
+ public function peek()
+ {
+ if (!$this->peeking)
+ {
+ if (!count($this->tokens))
+ {
+ return null;
+ }
+
+ $this->peeked = array_shift($this->tokens);
+
+ $this->peeking = true;
+ }
+
+ return $this->peeked;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/Tokenizer.php b/src/Symfony/Components/CssSelector/Tokenizer.php
new file mode 100644
index 0000000000000..15acf8a56e273
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/Tokenizer.php
@@ -0,0 +1,192 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * Tokenizer lexes a CSS Selector to tokens.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class Tokenizer
+{
+ public function tokenize($s)
+ {
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
+ {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
+ $tokens = array();
+ $pos = 0;
+ $s = preg_replace('#/\*.*?\*/#s', '', $s);
+
+ while (1)
+ {
+ if (preg_match('#\s+#A', $s, $match, 0, $pos))
+ {
+ $preceding_whitespace_pos = $pos;
+ $pos += strlen($match[0]);
+ }
+ else
+ {
+ $preceding_whitespace_pos = 0;
+ }
+
+ if ($pos >= strlen($s))
+ {
+ if (isset($mbEncoding))
+ {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return $tokens;
+ }
+
+ if (preg_match('#[+-]?\d*n(?:[+-]\d+)?#A', $s, $match, 0, $pos) && 'n' !== $match[0])
+ {
+ $sym = substr($s, $pos, strlen($match[0]));
+ $tokens[] = new Token('Symbol', $sym, $pos);
+ $pos += strlen($match[0]);
+
+ continue;
+ }
+
+ $c = $s[$pos];
+ $c2 = substr($s, $pos, 2);
+ if (in_array($c2, array('~=', '|=', '^=', '$=', '*=', '::', '!=')))
+ {
+ $tokens[] = new Token('Token', $c2, $pos);
+ $pos += 2;
+
+ continue;
+ }
+
+ if (in_array($c, array('>', '+', '~', ',', '.', '*', '=', '[', ']', '(', ')', '|', ':', '#')))
+ {
+ if (in_array($c, array('.', '#', '[')) && $preceding_whitespace_pos > 0)
+ {
+ $tokens[] = new Token('Token', ' ', $preceding_whitespace_pos);
+ }
+ $tokens[] = new Token('Token', $c, $pos);
+ ++$pos;
+
+ continue;
+ }
+
+ if ($c === '"' || $c === "'")
+ {
+ // Quoted string
+ $old_pos = $pos;
+ list($sym, $pos) = $this->tokenizeEscapedString($s, $pos);
+
+ $tokens[] = new Token('String', $sym, $old_pos);
+
+ continue;
+ }
+
+ $old_pos = $pos;
+ list($sym, $pos) = $this->tokenizeSymbol($s, $pos);
+
+ $tokens[] = new Token('Symbol', $sym, $old_pos);
+
+ continue;
+ }
+ }
+
+ /**
+ * @throws SyntaxError When expected closing is not found
+ */
+ protected function tokenizeEscapedString($s, $pos)
+ {
+ $quote = $s[$pos];
+
+ $pos = $pos + 1;
+ $start = $pos;
+ while (1)
+ {
+ $next = strpos($s, $quote, $pos);
+ if (false === $next)
+ {
+ throw new SyntaxError(sprintf("Expected closing %s for string in: %s", $quote, substr($s, $start)));
+ }
+
+ $result = substr($s, $start, $next - $start);
+ if ('\\' === $result[strlen($result) - 1])
+ {
+ // next quote character is escaped
+ $pos = $next + 1;
+ $continue;
+ }
+
+ if (false !== strpos($result, '\\'))
+ {
+ $result = $this->unescapeStringLiteral($result);
+ }
+
+ return array($result, $next + 1);
+ }
+ }
+
+ /**
+ * @throws SyntaxError When invalid escape sequence is found
+ */
+ protected function unescapeStringLiteral($literal)
+ {
+ return preg_replace_callback('#(\\\\(?:[A-Fa-f0-9]{1,6}(?:\r\n|\s)?|[^A-Fa-f0-9]))#', function ($matches) use ($literal)
+ {
+ if ($matches[0][0] == '\\' && strlen($matches[0]) > 1)
+ {
+ $matches[0] = substr($matches[0], 1);
+ if (in_array($matches[0][0], array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f')))
+ {
+ return chr(trim($matches[0]));
+ }
+ }
+ else
+ {
+ throw new SyntaxError(sprintf("Invalid escape sequence %s in string %s", $matches[0], $literal));
+ }
+ }, $literal);
+ }
+
+ /**
+ * @throws SyntaxError When Unexpected symbol is found
+ */
+ protected function tokenizeSymbol($s, $pos)
+ {
+ $start = $pos;
+
+ if (!preg_match('#[^\w\-]#', $s, $match, PREG_OFFSET_CAPTURE, $pos))
+ {
+ // Goes to end of s
+ return array(substr($s, $start), strlen($s));
+ }
+
+ $matchStart = $match[0][1];
+
+ if ($matchStart == $pos)
+ {
+ throw new SyntaxError(sprintf("Unexpected symbol: %s at %s", $s[$pos], $pos));
+ }
+
+ $result = substr($s, $start, $matchStart - $start);
+ $pos = $matchStart;
+
+ return array($result, $pos);
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/XPathExpr.php b/src/Symfony/Components/CssSelector/XPathExpr.php
new file mode 100644
index 0000000000000..c358289d07cf3
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/XPathExpr.php
@@ -0,0 +1,185 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * XPathExpr represents an XPath expression.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class XPathExpr
+{
+ protected $prefix;
+ protected $path;
+ protected $element;
+ protected $condition;
+ protected $starPrefix;
+
+ public function __construct($prefix = null, $path = null, $element = '*', $condition = null, $starPrefix = false)
+ {
+ $this->prefix = $prefix;
+ $this->path = $path;
+ $this->element = $element;
+ $this->condition = $condition;
+ $this->starPrefix = $starPrefix;
+ }
+
+ public function getElement()
+ {
+ return $this->element;
+ }
+
+ public function getCondition()
+ {
+ return $this->condition;
+ }
+
+ public function __toString()
+ {
+ $path = '';
+ if (null !== $this->prefix)
+ {
+ $path .= $this->prefix;
+ }
+
+ if (null !== $this->path)
+ {
+ $path .= $this->path;
+ }
+
+ $path .= $this->element;
+
+ if ($this->condition)
+ {
+ $path .= sprintf('[%s]', $this->condition);
+ }
+
+ return $path;
+ }
+
+ public function addCondition($condition)
+ {
+ if ($this->condition)
+ {
+ $this->condition = sprintf('%s and (%s)', $this->condition, $condition);
+ }
+ else
+ {
+ $this->condition = $condition;
+ }
+ }
+
+ public function addPrefix($prefix)
+ {
+ if ($this->prefix)
+ {
+ $this->prefix = $prefix.$this->prefix;
+ }
+ else
+ {
+ $this->prefix = $prefix;
+ }
+ }
+
+ public function addNameTest()
+ {
+ if ($this->element == '*')
+ {
+ // We weren't doing a test anyway
+ return;
+ }
+
+ $this->addCondition(sprintf("name() = %s", XPathExpr::xpathLiteral($this->element)));
+ $this->element = '*';
+ }
+
+ public function addStarPrefix()
+ {
+ /*
+ Adds a /* prefix if there is no prefix. This is when you need
+ to keep context's constrained to a single parent.
+ */
+ if ($this->path)
+ {
+ $this->path .= '*/';
+ }
+ else
+ {
+ $this->path = '*/';
+ }
+
+ $this->starPrefix = true;
+ }
+
+ public function join($combiner, $other)
+ {
+ $prefix = (string) $this;
+
+ $prefix .= $combiner;
+ $path = $other->prefix.$other->path;
+
+ /* We don't need a star prefix if we are joining to this other
+ prefix; so we'll get rid of it */
+ if ($other->starPrefix && $path == '*/')
+ {
+ $path = '';
+ }
+ $this->prefix = $prefix;
+ $this->path = $path;
+ $this->element = $other->element;
+ $this->condition = $other->condition;
+ }
+
+ static public function xpathLiteral($s)
+ {
+ if ($s instanceof Node\ElementNode)
+ {
+ // This is probably a symbol that looks like an expression...
+ $s = $s->formatElement();
+ }
+ else
+ {
+ $s = (string) $s;
+ }
+
+ if (false === strpos($s, "'"))
+ {
+ $s = sprintf("'%s'", $s);
+ }
+ elseif (false === strpos($s, '"'))
+ {
+ $s = sprintf('"%s"', $s);
+ }
+ else
+ {
+ $tmp = array();
+ foreach (preg_split("#('+)#", $s) as $part)
+ {
+ if (!$part)
+ {
+ continue;
+ }
+
+ $tmp[] = sprintf(false !== strpos($part, "'") ? '"%s"' : "'%s'", $part);
+ }
+
+ $s = sprintf("concat(%s)", implode($tmp, ','));
+ }
+
+ return $s;
+ }
+}
diff --git a/src/Symfony/Components/CssSelector/XPathExprOr.php b/src/Symfony/Components/CssSelector/XPathExprOr.php
new file mode 100644
index 0000000000000..04804dee42d15
--- /dev/null
+++ b/src/Symfony/Components/CssSelector/XPathExprOr.php
@@ -0,0 +1,46 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * XPathExprOr represents XPath |'d expressions.
+ *
+ * Note that unfortunately it isn't the union, it's the sum, so duplicate elements will appear.
+ *
+ * This component is a port of the Python lxml library,
+ * which is copyright Infrae and distributed under the BSD license.
+ *
+ * @package Symfony
+ * @subpackage Components_CssSelector
+ * @author Fabien Potencier
+ */
+class XPathExprOr extends XPathExpr
+{
+ public function __construct($items, $prefix = null)
+ {
+ $this->items = $items;
+ $this->prefix = $prefix;
+ }
+
+ public function __toString()
+ {
+ $prefix = $this->prefix;
+
+ $tmp = array();
+ foreach ($this->items as $i)
+ {
+ $tmp[] = sprintf("%s%s", $prefix, $i);
+ }
+
+ return implode($tmp, ' | ');
+ }
+}
diff --git a/src/Symfony/Components/DependencyInjection/AnnotatedContainerInterface.php b/src/Symfony/Components/DependencyInjection/AnnotatedContainerInterface.php
index 4946123e7efad..147300b820d07 100644
--- a/src/Symfony/Components/DependencyInjection/AnnotatedContainerInterface.php
+++ b/src/Symfony/Components/DependencyInjection/AnnotatedContainerInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* AnnotatedContainerInterface is the interface implemented when a container knows how to deals with annotations.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface AnnotatedContainerInterface
diff --git a/src/Symfony/Components/DependencyInjection/Builder.php b/src/Symfony/Components/DependencyInjection/Builder.php
index 65ee52894f000..5027552697788 100644
--- a/src/Symfony/Components/DependencyInjection/Builder.php
+++ b/src/Symfony/Components/DependencyInjection/Builder.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Builder is a DI container that provides an interface to build the services.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class Builder extends Container implements AnnotatedContainerInterface
@@ -335,6 +335,8 @@ public function getDefinition($id)
* @param string $id The service identifier
*
* @return object The service described by the service definition
+ *
+ * @throws \InvalidArgumentException When configure callable is not callable
*/
protected function createService(Definition $definition, $id)
{
diff --git a/src/Symfony/Components/DependencyInjection/BuilderConfiguration.php b/src/Symfony/Components/DependencyInjection/BuilderConfiguration.php
index 512f76849aef3..6b11a989c01cf 100644
--- a/src/Symfony/Components/DependencyInjection/BuilderConfiguration.php
+++ b/src/Symfony/Components/DependencyInjection/BuilderConfiguration.php
@@ -5,7 +5,7 @@
use Symfony\Components\DependencyInjection\Loader\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* A BuilderConfiguration is a consistent set of definitions and parameters.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class BuilderConfiguration
@@ -277,7 +277,7 @@ public function setDefinition($id, Definition $definition)
{
unset($this->aliases[$id]);
- return $this->definitions[$id] = $definition;
+ $this->definitions[$id] = $definition;
return $this;
}
diff --git a/src/Symfony/Components/DependencyInjection/Container.php b/src/Symfony/Components/DependencyInjection/Container.php
index 95ec4118214d6..e403657353398 100644
--- a/src/Symfony/Components/DependencyInjection/Container.php
+++ b/src/Symfony/Components/DependencyInjection/Container.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -46,8 +46,8 @@
* * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
* (for instance, ignore a setter if the service does not exist)
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class Container implements ContainerInterface, \ArrayAccess
@@ -193,7 +193,7 @@ public function getService($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_RE
throw new \InvalidArgumentException(sprintf('A service id should be a string (%s given).', str_replace("\n", '', var_export($id, true))));
}
- if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service'))
+ if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service') && 'getService' !== $method)
{
return $this->$method();
}
@@ -317,6 +317,8 @@ public function __set($id, $service)
* Removes a service by identifier.
*
* @param string The service identifier
+ *
+ * @throws LogicException When trying to unset a service
*/
public function __unset($id)
{
@@ -330,12 +332,14 @@ public function __unset($id)
* @param array $arguments The method arguments
*
* @return mixed
+ *
+ * @throws \BadMethodCallException When calling to an undefined method
*/
public function __call($method, $arguments)
{
if (!preg_match('/^get(.+)Service$/', $method, $match))
{
- throw new \RuntimeException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
+ throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
}
return $this->getService(self::underscore($match[1]));
diff --git a/src/Symfony/Components/DependencyInjection/ContainerInterface.php b/src/Symfony/Components/DependencyInjection/ContainerInterface.php
index 5fce378cf8845..149a0cacf4de5 100644
--- a/src/Symfony/Components/DependencyInjection/ContainerInterface.php
+++ b/src/Symfony/Components/DependencyInjection/ContainerInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* ContainerInterface is the interface implemented by service container classes.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface ContainerInterface
diff --git a/src/Symfony/Components/DependencyInjection/Definition.php b/src/Symfony/Components/DependencyInjection/Definition.php
index f624203478918..6f2911dda8208 100644
--- a/src/Symfony/Components/DependencyInjection/Definition.php
+++ b/src/Symfony/Components/DependencyInjection/Definition.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Definition represents a service definition.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class Definition
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/Dumper.php b/src/Symfony/Components/DependencyInjection/Dumper/Dumper.php
index 4e75f00cf424e..65212d51f5a66 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/Dumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/Dumper.php
@@ -5,7 +5,7 @@
use Symfony\Components\DependencyInjection\Builder;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* Dumper is the abstract class for all built-in dumpers.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
abstract class Dumper implements DumperInterface
@@ -40,6 +40,8 @@ public function __construct(Builder $container)
* @param array $options An array of options
*
* @return string The representation of the service container
+ *
+ * @throws \LogicException When this abstrass class is not implemented
*/
public function dump(array $options = array())
{
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/DumperInterface.php b/src/Symfony/Components/DependencyInjection/Dumper/DumperInterface.php
index 964a6052425de..f1ac040e64e23 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/DumperInterface.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/DumperInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Dumper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* DumperInterface is the interface implemented by service container dumper classes.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface DumperInterface
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/GraphvizDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/GraphvizDumper.php
index 37db58750e3de..1edea7f04de54 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/GraphvizDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/GraphvizDumper.php
@@ -8,7 +8,7 @@
use Symfony\Components\DependencyInjection\Builder;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -23,8 +23,8 @@
*
* dot -Tpng container.dot > foo.png
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class GraphvizDumper extends Dumper
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php
index 5202c5f261c94..14c80e942d02c 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php
@@ -8,7 +8,7 @@
use Symfony\Components\DependencyInjection\Parameter;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -19,8 +19,8 @@
/**
* PhpDumper dumps a service container as a PHP class.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class PhpDumper extends Dumper
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
index a91e0b6908531..0c0e975b647a3 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
@@ -7,7 +7,7 @@
use Symfony\Components\DependencyInjection\Reference;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
/**
* XmlDumper dumps a service container as an XML string.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class XmlDumper extends Dumper
@@ -227,6 +227,9 @@ protected function escape($arguments)
return $args;
}
+ /**
+ * @throws \RuntimeException When trying to dump object or ressource
+ */
static public function phpToXml($value)
{
switch (true)
diff --git a/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php b/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
index 78365864968bb..136784ad54dff 100644
--- a/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
+++ b/src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
@@ -8,7 +8,7 @@
use Symfony\Components\DependencyInjection\Reference;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -19,8 +19,8 @@
/**
* YamlDumper dumps a service container as a YAML string.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class YamlDumper extends Dumper
@@ -143,6 +143,9 @@ protected function addParameters()
return Yaml::dump(array('parameters' => $this->prepareParameters($this->container->getParameters())), 2);
}
+ /**
+ * @throws \RuntimeException When trying to dump object or resource
+ */
protected function dumpValue($value)
{
if (is_array($value))
diff --git a/src/Symfony/Components/DependencyInjection/FileResource.php b/src/Symfony/Components/DependencyInjection/FileResource.php
index 24e1e0d5ffe14..bf1c578787c2b 100644
--- a/src/Symfony/Components/DependencyInjection/FileResource.php
+++ b/src/Symfony/Components/DependencyInjection/FileResource.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* FileResource represents a resource stored on the filesystem.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class FileResource implements ResourceInterface
diff --git a/src/Symfony/Components/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Components/DependencyInjection/Loader/FileLoader.php
index bd65728b0a846..60b66d10f5d60 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/FileLoader.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/FileLoader.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* FileLoader is the abstract class used by all built-in loaders that are file based.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
abstract class FileLoader extends Loader
@@ -37,6 +37,9 @@ public function __construct($paths = array())
$this->paths = $paths;
}
+ /**
+ * @throws \InvalidArgumentException When provided file does not exist
+ */
protected function findFile($file)
{
$path = $this->getAbsolutePath($file);
diff --git a/src/Symfony/Components/DependencyInjection/Loader/IniFileLoader.php b/src/Symfony/Components/DependencyInjection/Loader/IniFileLoader.php
index 6df27729fba73..1c69fdce10a10 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/IniFileLoader.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/IniFileLoader.php
@@ -6,7 +6,7 @@
use Symfony\Components\DependencyInjection\FileResource;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* IniFileLoader loads parameters from INI files.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class IniFileLoader extends FileLoader
@@ -29,6 +29,8 @@ class IniFileLoader extends FileLoader
* @param string $file An INI file path
*
* @return BuilderConfiguration A BuilderConfiguration instance
+ *
+ * @throws \InvalidArgumentException When ini file is not valid
*/
public function load($file)
{
diff --git a/src/Symfony/Components/DependencyInjection/Loader/Loader.php b/src/Symfony/Components/DependencyInjection/Loader/Loader.php
index aff4c24efccc9..97f30719c6ef7 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/Loader.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/Loader.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Loader is the abstract class used by all built-in loaders.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
abstract class Loader implements LoaderInterface
diff --git a/src/Symfony/Components/DependencyInjection/Loader/LoaderExtension.php b/src/Symfony/Components/DependencyInjection/Loader/LoaderExtension.php
index 23f7e0298552e..1a2b1ce94ccb2 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/LoaderExtension.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/LoaderExtension.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* LoaderExtension is a helper class that helps organize extensions better.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
abstract class LoaderExtension implements LoaderExtensionInterface
@@ -40,6 +40,8 @@ public function setConfiguration($name, $resource)
* @param array An array of configuration values
*
* @return BuilderConfiguration A BuilderConfiguration instance
+ *
+ * @throws \InvalidArgumentException When provided tag is not defined in this extension
*/
public function load($tag, array $config)
{
diff --git a/src/Symfony/Components/DependencyInjection/Loader/LoaderExtensionInterface.php b/src/Symfony/Components/DependencyInjection/Loader/LoaderExtensionInterface.php
index cd94acfb5678e..98b62c13243ca 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/LoaderExtensionInterface.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/LoaderExtensionInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* LoaderExtensionInterface is the interface implemented by loader extension classes.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface LoaderExtensionInterface
@@ -53,7 +53,7 @@ public function getNamespace();
public function getXsdValidationBasePath();
/**
- * Returns the recommanded alias to use in XML.
+ * Returns the recommended alias to use in XML.
*
* This alias is also the mandatory prefix to use when using YAML.
*
diff --git a/src/Symfony/Components/DependencyInjection/Loader/LoaderInterface.php b/src/Symfony/Components/DependencyInjection/Loader/LoaderInterface.php
index e55e7a6d6b536..85dce17915dbb 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/LoaderInterface.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/LoaderInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -20,8 +20,8 @@
* $container = new Builder();
* $container->merge($config);
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface LoaderInterface
diff --git a/src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php
index 35b5d4a0432ab..69fef75f8c4c6 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/XmlFileLoader.php
@@ -9,7 +9,7 @@
use Symfony\Components\DependencyInjection\FileResource;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -20,8 +20,8 @@
/**
* XmlFileLoader loads XML files service definitions.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class XmlFileLoader extends FileLoader
@@ -197,6 +197,9 @@ protected function parseDefinition(BuilderConfiguration $configuration, $id, $se
$configuration->setDefinition($id, $definition);
}
+ /**
+ * @throws \InvalidArgumentException When loading of XML file returns error
+ */
protected function parseFile($file)
{
$dom = new \DOMDocument();
@@ -249,6 +252,10 @@ protected function validate($dom, $file)
$this->validateExtensions($dom, $file);
}
+ /**
+ * @throws \RuntimeException When extension references a non-existent XSD file
+ * @throws \InvalidArgumentException When xml doesn't validate its xsd schema
+ */
protected function validateSchema($dom, $file)
{
$schemaLocations = array('http://www.symfony-project.org/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd'));
@@ -299,6 +306,9 @@ protected function validateSchema($dom, $file)
libxml_use_internal_errors(false);
}
+ /**
+ * @throws \InvalidArgumentException When non valid tag are found or no extension are found
+ */
protected function validateExtensions($dom, $file)
{
foreach ($dom->documentElement->childNodes as $node)
diff --git a/src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php
index 1926ce7e3d89a..3c3cf80cfd3c7 100644
--- a/src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Components/DependencyInjection/Loader/YamlFileLoader.php
@@ -10,7 +10,7 @@
use Symfony\Components\Yaml\Yaml;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -23,8 +23,8 @@
*
* The YAML format does not support anonymous services (cf. the XML loader).
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class YamlFileLoader extends FileLoader
@@ -196,6 +196,9 @@ protected function loadFile($file)
return $this->validate(Yaml::load($file), $file);
}
+ /**
+ * @throws \InvalidArgumentException When service file is not valid
+ */
protected function validate($content, $file)
{
if (null === $content)
diff --git a/src/Symfony/Components/DependencyInjection/Parameter.php b/src/Symfony/Components/DependencyInjection/Parameter.php
index 1e33454c9a278..0556d3800390d 100644
--- a/src/Symfony/Components/DependencyInjection/Parameter.php
+++ b/src/Symfony/Components/DependencyInjection/Parameter.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Parameter represents a parameter reference.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class Parameter
diff --git a/src/Symfony/Components/DependencyInjection/Reference.php b/src/Symfony/Components/DependencyInjection/Reference.php
index 099c91ebb4319..414c6389670c6 100644
--- a/src/Symfony/Components/DependencyInjection/Reference.php
+++ b/src/Symfony/Components/DependencyInjection/Reference.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Reference represents a service reference.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
class Reference
diff --git a/src/Symfony/Components/DependencyInjection/ResourceInterface.php b/src/Symfony/Components/DependencyInjection/ResourceInterface.php
index fc940164d8739..64f359b6b2165 100644
--- a/src/Symfony/Components/DependencyInjection/ResourceInterface.php
+++ b/src/Symfony/Components/DependencyInjection/ResourceInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* ResourceInterface is the interface that must be implemented by all Resource classes.
*
- * @package symfony
- * @subpackage dependency_injection
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
* @author Fabien Potencier
*/
interface ResourceInterface
diff --git a/src/Symfony/Components/DependencyInjection/SimpleXMLElement.php b/src/Symfony/Components/DependencyInjection/SimpleXMLElement.php
index 41700111e4bf4..66d02a12c411b 100644
--- a/src/Symfony/Components/DependencyInjection/SimpleXMLElement.php
+++ b/src/Symfony/Components/DependencyInjection/SimpleXMLElement.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\DependencyInjection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -11,6 +11,13 @@
* with this source code in the file LICENSE.
*/
+/**
+ * SimpleXMLElement class.
+ *
+ * @package Symfony
+ * @subpackage Components_DependencyInjection
+ * @author Fabien Potencier
+ */
class SimpleXMLElement extends \SimpleXMLElement
{
public function getAttributeAsPhp($name)
diff --git a/src/Symfony/Components/EventDispatcher/Event.php b/src/Symfony/Components/EventDispatcher/Event.php
index 21c79d1fd5dee..a2319805f76e3 100644
--- a/src/Symfony/Components/EventDispatcher/Event.php
+++ b/src/Symfony/Components/EventDispatcher/Event.php
@@ -3,9 +3,9 @@
namespace Symfony\Components\EventDispatcher;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
* (c) Fabien Potencier
- *
+ *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@@ -13,8 +13,8 @@
/**
* Event.
*
- * @package symfony
- * @subpackage event_dispatcher
+ * @package Symfony
+ * @subpackage Components_EventDispatcher
* @author Fabien Potencier
*/
class Event implements \ArrayAccess
@@ -127,6 +127,8 @@ public function hasParameter($name)
* @param string $name The parameter name
*
* @return mixed The parameter value
+ *
+ * @throws \InvalidArgumentException When parameter doesn't exists for this event
*/
public function getParameter($name)
{
diff --git a/src/Symfony/Components/EventDispatcher/EventDispatcher.php b/src/Symfony/Components/EventDispatcher/EventDispatcher.php
index 604516c87ec6a..ff5cc500ee2e7 100644
--- a/src/Symfony/Components/EventDispatcher/EventDispatcher.php
+++ b/src/Symfony/Components/EventDispatcher/EventDispatcher.php
@@ -3,9 +3,9 @@
namespace Symfony\Components\EventDispatcher;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
* (c) Fabien Potencier
- *
+ *
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@@ -15,8 +15,8 @@
*
* @see http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/index.html Apple's Cocoa framework
*
- * @package symfony
- * @subpackage event_dispatcher
+ * @package Symfony
+ * @subpackage Components_EventDispatcher
* @author Fabien Potencier
*/
class EventDispatcher
diff --git a/src/Symfony/Components/OutputEscaper/ArrayDecorator.php b/src/Symfony/Components/OutputEscaper/ArrayDecorator.php
index c0752f4ffd645..ecf5f2a452c32 100644
--- a/src/Symfony/Components/OutputEscaper/ArrayDecorator.php
+++ b/src/Symfony/Components/OutputEscaper/ArrayDecorator.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -15,8 +15,8 @@
* Output escaping decorator class for arrays.
*
* @see Escaper
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
* @author Mike Squire
*/
@@ -89,7 +89,7 @@ public function valid()
/**
* Returns true if the supplied offset isset in the array (as required by the ArrayAccess interface).
*
- * @param string $offset The offset of the value to check existance of
+ * @param string $offset The offset of the value to check existence of
*
* @return bool true if the offset isset; false otherwise
*/
@@ -120,7 +120,7 @@ public function offsetGet($offset)
* @param string $offset (ignored)
* @param string $value (ignored)
*
- * @throws \LogicException
+ * @throws \LogicException When trying to set values
*/
public function offsetSet($offset, $value)
{
@@ -136,7 +136,7 @@ public function offsetSet($offset, $value)
*
* @param string $offset (ignored)
*
- * @throws LogicException
+ * @throws \LogicException When trying to unset values
*/
public function offsetUnset($offset)
{
diff --git a/src/Symfony/Components/OutputEscaper/Escaper.php b/src/Symfony/Components/OutputEscaper/Escaper.php
index 19d0440a36dfb..3cec532cfd973 100644
--- a/src/Symfony/Components/OutputEscaper/Escaper.php
+++ b/src/Symfony/Components/OutputEscaper/Escaper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Abstract class that provides an interface for escaping of output.
*
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
* @author Mike Squire
*/
@@ -127,26 +127,28 @@ static public function escape($escaper, $value)
return $copy;
}
- elseif (self::isClassMarkedAsSafe(get_class($value)))
+
+ if (self::isClassMarkedAsSafe(get_class($value)))
{
// the class or one of its children is marked as safe
// return the unescaped object
return $value;
}
- elseif ($value instanceof SafeDecorator)
+
+ if ($value instanceof SafeDecorator)
{
// do not escape objects marked as safe
// return the original object
return $value->getValue();
}
- elseif ($value instanceof \Traversable)
+
+ if ($value instanceof \Traversable)
{
return new IteratorDecorator($escaper, $value);
}
- else
- {
- return new ObjectDecorator($escaper, $value);
- }
+
+ return new ObjectDecorator($escaper, $value);
+
}
// it must be a resource; cannot escape that.
@@ -173,7 +175,8 @@ static public function unescape($value)
{
return html_entity_decode($value, ENT_QUOTES, self::$charset);
}
- elseif (is_array($value))
+
+ if (is_array($value))
{
foreach ($value as $name => $v)
{
@@ -182,7 +185,8 @@ static public function unescape($value)
return $value;
}
- elseif (is_object($value))
+
+ if (is_object($value))
{
return $value instanceof Escaper ? $value->getRawValue() : $value;
}
@@ -348,7 +352,10 @@ function ($value)
* @param string $value the value to escape
* @return string the escaped value
*/
- function ($value) { return $value; },
+ function ($value)
+ {
+ return $value;
+ },
'js' =>
/**
@@ -363,7 +370,10 @@ function ($value) { return $value; },
* @param string $value the value to escape
* @return string the escaped value
*/
- function ($value) { return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), (is_string($value) ? htmlentities($value, ENT_QUOTES, Escaper::getCharset()) : $value)); },
+ function ($value)
+ {
+ return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), (is_string($value) ? htmlentities($value, ENT_QUOTES, Escaper::getCharset()) : $value));
+ },
'js_no_entities' =>
/**
@@ -373,7 +383,10 @@ function ($value) { return str_replace(array("\\" , "\n" , "\r" , "\"" , "'"
* @param string $value the value to escape
* @return string the escaped value
*/
- function ($value) { return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), $value); },
+ function ($value)
+ {
+ return str_replace(array("\\" , "\n" , "\r" , "\"" , "'" ), array("\\\\", "\\n" , "\\r", "\\\"", "\\'"), $value);
+ },
);
}
}
diff --git a/src/Symfony/Components/OutputEscaper/GetterDecorator.php b/src/Symfony/Components/OutputEscaper/GetterDecorator.php
index 1cfc175fff1fe..48f48ece66d9e 100644
--- a/src/Symfony/Components/OutputEscaper/GetterDecorator.php
+++ b/src/Symfony/Components/OutputEscaper/GetterDecorator.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -15,8 +15,8 @@
* Abstract output escaping decorator class for "getter" objects.
*
* @see Escaper
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
* @author Mike Squire
*/
@@ -25,7 +25,7 @@ abstract class GetterDecorator extends Escaper
/**
* Returns the raw, unescaped value associated with the key supplied.
*
- * The key might be an index into an array or a value to be passed to the
+ * The key might be an index into an array or a value to be passed to the
* decorated object's get() method.
*
* @param string $key The key to retrieve
diff --git a/src/Symfony/Components/OutputEscaper/IteratorDecorator.php b/src/Symfony/Components/OutputEscaper/IteratorDecorator.php
index cd70dd8bbfda4..d367e69631f55 100644
--- a/src/Symfony/Components/OutputEscaper/IteratorDecorator.php
+++ b/src/Symfony/Components/OutputEscaper/IteratorDecorator.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
* into an iterator with each value escaped.
*
* @see Escaper
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
* @author Mike Squire
*/
@@ -33,7 +33,7 @@ class IteratorDecorator extends ObjectDecorator implements \Iterator, \Countable
private $iterator;
/**
- * Constructs a new escaping iteratoror using the escaping method and value supplied.
+ * Constructs a new escaping iterator using the escaping method and value supplied.
*
* @param string $escaper The escaping method to use
* @param \Traversable $value The iterator to escape
@@ -100,7 +100,7 @@ public function valid()
/**
* Returns true if the supplied offset isset in the array (as required by the ArrayAccess interface).
*
- * @param string $offset The offset of the value to check existance of
+ * @param string $offset The offset of the value to check existence of
*
* @return bool true if the offset isset; false otherwise
*/
@@ -131,7 +131,7 @@ public function offsetGet($offset)
* @param string $offset (ignored)
* @param string $value (ignored)
*
- * @throws \LogicException
+ * @throws \LogicException When trying to set values
*/
public function offsetSet($offset, $value)
{
@@ -147,7 +147,7 @@ public function offsetSet($offset, $value)
*
* @param string $offset (ignored)
*
- * @throws \LogicException
+ * @throws \LogicException When trying to unset values
*/
public function offsetUnset($offset)
{
diff --git a/src/Symfony/Components/OutputEscaper/ObjectDecorator.php b/src/Symfony/Components/OutputEscaper/ObjectDecorator.php
index 77e49369b82e6..0dd1d96754a0a 100644
--- a/src/Symfony/Components/OutputEscaper/ObjectDecorator.php
+++ b/src/Symfony/Components/OutputEscaper/ObjectDecorator.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
* their return values.
*
* @see Escaper
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
* @author Mike Squire
*/
diff --git a/src/Symfony/Components/OutputEscaper/SafeDecorator.php b/src/Symfony/Components/OutputEscaper/SafeDecorator.php
index 75ac82d6e2e27..f2525ba5820dd 100644
--- a/src/Symfony/Components/OutputEscaper/SafeDecorator.php
+++ b/src/Symfony/Components/OutputEscaper/SafeDecorator.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\OutputEscaper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Marks a variable as being safe for output.
*
- * @package symfony
- * @subpackage output_escaper
+ * @package Symfony
+ * @subpackage Components_OutputEscaper
* @author Fabien Potencier
*/
class SafeDecorator extends \ArrayIterator
diff --git a/src/Symfony/Components/RequestHandler/Exception/ForbiddenHttpException.php b/src/Symfony/Components/RequestHandler/Exception/ForbiddenHttpException.php
index 96a1ff057a9d2..cabf2ccf72671 100644
--- a/src/Symfony/Components/RequestHandler/Exception/ForbiddenHttpException.php
+++ b/src/Symfony/Components/RequestHandler/Exception/ForbiddenHttpException.php
@@ -2,6 +2,22 @@
namespace Symfony\Components\RequestHandler\Exception;
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * ForbiddenHttpException.
+ *
+ * @package Symfony
+ * @subpackage Components_RequestHandler
+ * @author Fabien Potencier
+ */
class ForbiddenHttpException extends HttpException
{
public function __construct($message = '')
diff --git a/src/Symfony/Components/RequestHandler/Exception/HttpException.php b/src/Symfony/Components/RequestHandler/Exception/HttpException.php
index 077563e46420a..6622d295f12a8 100644
--- a/src/Symfony/Components/RequestHandler/Exception/HttpException.php
+++ b/src/Symfony/Components/RequestHandler/Exception/HttpException.php
@@ -2,7 +2,24 @@
namespace Symfony\Components\RequestHandler\Exception;
-// by convention, exception code == response status code
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * HttpException.
+ *
+ * By convention, exception code == response status code.
+ *
+ * @package Symfony
+ * @subpackage Components_RequestHandler
+ * @author Fabien Potencier
+ */
class HttpException extends \Exception
{
}
diff --git a/src/Symfony/Components/RequestHandler/Exception/NotFoundHttpException.php b/src/Symfony/Components/RequestHandler/Exception/NotFoundHttpException.php
index 47f94bce1a406..1a917ec593cf4 100644
--- a/src/Symfony/Components/RequestHandler/Exception/NotFoundHttpException.php
+++ b/src/Symfony/Components/RequestHandler/Exception/NotFoundHttpException.php
@@ -2,6 +2,22 @@
namespace Symfony\Components\RequestHandler\Exception;
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * NotFoundHttpException.
+ *
+ * @package Symfony
+ * @subpackage Components_RequestHandler
+ * @author Fabien Potencier
+ */
class NotFoundHttpException extends HttpException
{
public function __construct($message = '')
diff --git a/src/Symfony/Components/RequestHandler/Exception/UnauthorizedHttpException.php b/src/Symfony/Components/RequestHandler/Exception/UnauthorizedHttpException.php
index c4b30efdbc8cf..1bca81d022e32 100644
--- a/src/Symfony/Components/RequestHandler/Exception/UnauthorizedHttpException.php
+++ b/src/Symfony/Components/RequestHandler/Exception/UnauthorizedHttpException.php
@@ -2,6 +2,22 @@
namespace Symfony\Components\RequestHandler\Exception;
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * UnauthorizedHttpException.
+ *
+ * @package Symfony
+ * @subpackage Components_RequestHandler
+ * @author Fabien Potencier
+ */
class UnauthorizedHttpException extends HttpException
{
public function __construct($message = '')
diff --git a/src/Symfony/Components/RequestHandler/Request.php b/src/Symfony/Components/RequestHandler/Request.php
index 5c5ba3da8ae7f..d3b6fa0699205 100644
--- a/src/Symfony/Components/RequestHandler/Request.php
+++ b/src/Symfony/Components/RequestHandler/Request.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\RequestHandler;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -19,8 +19,8 @@
*
* You can reinitialize the request by calling the setParameters() method.
*
- * @package symfony
- * @subpackage request_handler
+ * @package Symfony
+ * @subpackage Components_RequestHandler
* @author Fabien Potencier
*/
class Request implements RequestInterface
@@ -29,6 +29,8 @@ class Request implements RequestInterface
protected $requestParameters;
protected $queryParameters;
protected $serverParameters;
+ protected $filesParameters;
+ protected $cookiesParameters;
protected $languages;
protected $charsets;
protected $acceptableContentTypes;
@@ -45,11 +47,16 @@ class Request implements RequestInterface
/**
* Constructor.
*
- * @param array $parameters An array of parameters (see setParameters())
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $path The parameters parsed from the PATH_INFO (see Router)
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
*/
- public function __construct(array $parameters = array())
+ public function __construct(array $query = null, array $request = null, array $path = null, array $cookies = null, array $files = null, array $server = null)
{
- $this->setParameters($parameters);
+ $this->setParameters($request, $query, $path, $cookies, $files, $server);
}
/**
@@ -57,21 +64,21 @@ public function __construct(array $parameters = array())
*
* This method also re-initializes all properties.
*
- * The parameters can define four elements:
- *
- * * request: The POST parameters
- * * query: The GET parameters
- * * path: The parameters parsed from the PATH_INFO (see Router)
- * * server: The SERVER parameters
- *
- * @param array $parameters An array of parameters
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $path The parameters parsed from the PATH_INFO
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
*/
- public function setParameters(array $parameters = array())
+ public function setParameters(array $query = null, array $request = null, array $path = null, array $cookies = null, array $files = null, array $server = null)
{
- $this->requestParameters = isset($parameters['request']) ? $parameters['request'] : $_POST;
- $this->queryParameters = isset($parameters['query']) ? $parameters['query'] : $_GET;
- $this->pathParameters = isset($parameters['path']) ? $parameters['path'] : array();
- $this->serverParameters = isset($parameters['server']) ? $parameters['server'] : $_SERVER;
+ $this->requestParameters = null !== $request ? $request : $_POST;
+ $this->queryParameters = null !== $query ? $query : $_GET;
+ $this->pathParameters = null !== $path ? $path : array();
+ $this->cookiesParameters = null !== $cookies ? $cookies : $_COOKIE;
+ $this->filesParameters = self::convertFileInformation(null !== $files ? $files : $_FILES);
+ $this->serverParameters = null !== $server ? $server : $_SERVER;
$this->languages = null;
$this->charsets = null;
@@ -85,43 +92,81 @@ public function setParameters(array $parameters = array())
$this->format = null;
}
- public function duplicate(array $parameters = array())
+ /**
+ * Creates a Request based on a given URI and configuration.
+ *
+ * @param string $uri The URI
+ * @param string $method The HTTP method
+ * @param array $parameters The request (GET) or query (POST) parameters
+ * @param array $cookies The request cookies ($_COOKIE)
+ * @param array $files The request files ($_FILES)
+ * @param array $server The server parameters ($_SERVER)
+ *
+ * @return Request A Request instance
+ */
+ static public function createFromUri($uri, $method = 'get', $parameters = array(), $cookies = array(), $files = array(), $server = array())
{
- $request = clone $this;
+ if (in_array($method, array('post', 'put', 'delete')))
+ {
+ $request = $parameters;
+ $query = array();
+ }
+ else
+ {
+ $request = array();
+ $query = $parameters;
+ }
- foreach (array('request', 'query', 'path', 'server') as $key)
+ $queryString = false !== ($pos = strpos($uri, '?')) ? html_entity_decode(substr($uri, $pos + 1)) : '';
+ parse_str($queryString, $qs);
+ if (is_array($qs))
{
- if (isset($parameters[$key]))
- {
- $request->{$key.'Parameters'} = $parameters[$key];
- }
+ $query = array_replace($qs, $query);
}
- $this->languages = null;
- $this->charsets = null;
- $this->acceptableContentTypes = null;
- $this->scriptName = null;
- $this->pathInfo = null;
- $this->requestUri = null;
- $this->baseUrl = null;
- $this->basePath = null;
- $this->method = null;
- $this->format = null;
+ $server = array_replace(array(
+ 'HTTP_HOST' => 'localhost',
+ 'SERVER_NAME' => 'localhost',
+ 'SERVER_PORT' => 80,
+ 'HTTP_USER_AGENT' => 'SymfonyClient/1.0',
+ 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
+ 'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
+ 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
+ 'REMOTE_ADDR' => '127.0.0.1',
+ 'REQUEST_METHOD' => strtoupper($method),
+ 'PATH_INFO' => '',
+ 'REQUEST_URI' => $uri,
+ 'SCRIPT_NAME' => '',
+ 'SCRIPT_FILENAME' => '',
+ 'QUERY_STRING' => $queryString,
+ ), $server);
- return $request;
+ return new self($request, $query, array(), $cookies, $files, $server);
}
/**
- * Gets a cookie value.
- *
- * @param string $name Cookie name
- * @param string $defaultValue Default value returned when no cookie with given name is found
+ * Clones a request and overrides some of its parameters.
*
- * @return mixed The cookie value
+ * @param array $query The GET parameters
+ * @param array $request The POST parameters
+ * @param array $path The parameters parsed from the PATH_INFO
+ * @param array $cookies The COOKIE parameters
+ * @param array $files The FILES parameters
+ * @param array $server The SERVER parameters
*/
- public function getCookie($name, $default = null)
- {
- return isset($_COOKIE[$name]) ? $_COOKIE[$name] : $default;
+ public function duplicate(array $query = null, array $request = null, array $path = null, array $cookies = null, array $files = null, array $server = null)
+ {
+ $dup = clone $this;
+ $dup->setParameters(
+ null !== $query ? $query : $this->queryParameters,
+ null !== $request ? $request : $this->requestParameters,
+ null !== $path ? $path : $this->pathParameters,
+ null !== $cookies ? $cookies : $this->cookiesParameters,
+ null !== $files ? $files : $this->filesParameters,
+ null !== $server ? $server : $this->serverParameters
+ );
+
+ return $dup;
}
// Order of precedence: GET, PATH, POST, COOKIE
@@ -134,51 +179,145 @@ public function getParameter($key, $default = null)
return $this->getQueryParameter($key, $this->getPathParameter($key, $this->getRequestParameter($key, $default)));
}
+ /**
+ * Returns the server parameters ($_SERVER).
+ *
+ * @return array An array of server parameters
+ */
public function getServerParameters()
{
return $this->serverParameters;
}
- public function getServerParameter($name, $default = null)
+ /**
+ * Returns a server parameter ($_SERVER).
+ *
+ * @param string $key The key
+ * @param mixed $default The default value
+ */
+ public function getServerParameter($key, $default = null)
{
- return isset($this->serverParameters[$name]) ? $this->serverParameters[$name] : $default;
+ return isset($this->serverParameters[$key]) ? $this->serverParameters[$key] : $default;
}
+ /**
+ * Returns the path parameters.
+ *
+ * @return array An array of path parameters
+ */
public function getPathParameters()
{
return $this->pathParameters;
}
+ /**
+ * Sets the path parameters.
+ *
+ * @param array An array of path parameters
+ */
public function setPathParameters(array $parameters)
{
$this->pathParameters = $parameters;
}
+ /**
+ * Returns a path parameter.
+ *
+ * @param string $key The key
+ * @param mixed $default The default value
+ */
public function getPathParameter($key, $default = null)
{
return isset($this->pathParameters[$key]) ? $this->pathParameters[$key] : $default;
}
+ /**
+ * Returns the request parameters ($_POST).
+ *
+ * @return array An array of request parameters
+ */
public function getRequestParameters()
{
return $this->requestParameters;
}
+ /**
+ * Returns a request parameter ($_POST).
+ *
+ * @param string $key The server key
+ * @param mixed $default The default value
+ */
public function getRequestParameter($key, $default = null)
{
return isset($this->requestParameters[$key]) ? $this->requestParameters[$key] : $default;
}
+ /**
+ * Returns the query parameters ($_GET).
+ *
+ * @return array An array of query parameters
+ */
public function getQueryParameters()
{
return $this->queryParameters;
}
+ /**
+ * Returns a query parameter ($_GET).
+ *
+ * @param string $key The server key
+ * @param mixed $default The default value
+ */
public function getQueryParameter($key, $default = null)
{
return isset($this->queryParameters[$key]) ? $this->queryParameters[$key] : $default;
}
+ /**
+ * Returns a cookie value ($_COOKIE).
+ *
+ * @param string $key The key
+ * @param mixed $default The default value
+ *
+ * @return mixed The cookie value
+ */
+ public function getCookie($key, $default = null)
+ {
+ return isset($this->cookiesParameters[$key]) ? $cookiesParameters[$key] : $default;
+ }
+
+ /**
+ * Returns the array of cookies ($_COOKIE).
+ *
+ * @param array An array of cookies
+ */
+ public function getCookies()
+ {
+ return $this->cookiesParameters;
+ }
+
+ /**
+ * Returns a file from the request ($_FILES).
+ *
+ * @param string $key A key
+ *
+ * @return array The associated file
+ */
+ public function getFile($key)
+ {
+ return isset($this->filesParameters[$key]) ? $this->filesParameters[$key] : array();
+ }
+
+ /**
+ * Returns the array of files ($_FILES).
+ *
+ * @return array An associative array of files
+ */
+ public function getFiles()
+ {
+ return $this->filesParameters;
+ }
+
public function getHttpHeader($name, $default = null)
{
return $this->getServerParameter('HTTP_'.strtoupper(strtr($name, '-', '_')), $default);
@@ -359,7 +498,7 @@ public function getFormat($mimeType)
foreach (static::$formats as $format => $mimeTypes)
{
- if (in_array($mimeType, $mimeTypes))
+ if (in_array($mimeType, (array) $mimeTypes))
{
return $format;
}
@@ -648,13 +787,13 @@ protected function prepareBaseUrl()
// Does the baseUrl have anything in common with the request_uri?
$requestUri = $this->getRequestUri();
- if (0 === strpos($requestUri, $baseUrl))
+ if ($baseUrl && 0 === strpos($requestUri, $baseUrl))
{
// full $baseUrl matches
return $baseUrl;
}
- if (0 === strpos($requestUri, dirname($baseUrl)))
+ if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl)))
{
// directory portion of $baseUrl matches
return rtrim(dirname($baseUrl), '/');
@@ -741,6 +880,26 @@ protected function preparePathInfo()
return (string) $pathInfo;
}
+ /**
+ * Converts uploaded file array to a format following the $_GET and $POST naming convention.
+ *
+ * It's safe to pass an already converted array, in which case this method just returns the original array unmodified.
+ *
+ * @param array $taintedFiles An array representing uploaded file information
+ *
+ * @return array An array of re-ordered uploaded file information
+ */
+ protected function convertFileInformation(array $taintedFiles)
+ {
+ $files = array();
+ foreach ($taintedFiles as $key => $data)
+ {
+ $files[$key] = $this->fixPhpFilesArray($data);
+ }
+
+ return $files;
+ }
+
static protected function initializeFormats()
{
static::$formats = array(
@@ -753,4 +912,34 @@ static protected function initializeFormats()
'atom' => 'application/atom+xml',
);
}
+
+ static protected function fixPhpFilesArray($data)
+ {
+ $fileKeys = array('error', 'name', 'size', 'tmp_name', 'type');
+ $keys = array_keys($data);
+ sort($keys);
+
+ if ($fileKeys != $keys || !isset($data['name']) || !is_array($data['name']))
+ {
+ return $data;
+ }
+
+ $files = $data;
+ foreach ($fileKeys as $k)
+ {
+ unset($files[$k]);
+ }
+ foreach (array_keys($data['name']) as $key)
+ {
+ $files[$key] = self::fixPhpFilesArray(array(
+ 'error' => $data['error'][$key],
+ 'name' => $data['name'][$key],
+ 'type' => $data['type'][$key],
+ 'tmp_name' => $data['tmp_name'][$key],
+ 'size' => $data['size'][$key],
+ ));
+ }
+
+ return $files;
+ }
}
diff --git a/src/Symfony/Components/RequestHandler/RequestHandler.php b/src/Symfony/Components/RequestHandler/RequestHandler.php
index 1346c3a30d174..3f917bb8010ef 100644
--- a/src/Symfony/Components/RequestHandler/RequestHandler.php
+++ b/src/Symfony/Components/RequestHandler/RequestHandler.php
@@ -7,7 +7,7 @@
use Symfony\Components\RequestHandler\Exception\NotFoundHttpException;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
/**
* RequestHandler notifies events to convert a Request object to a Response one.
*
- * @package symfony
- * @subpackage request_handler
+ * @package Symfony
+ * @subpackage Components_RequestHandler
* @author Fabien Potencier
*/
class RequestHandler
@@ -46,6 +46,8 @@ public function __construct(EventDispatcher $dispatcher)
* @param Boolean $main Whether this is the main request or not
*
* @return ResponseInterface $response A Response instance
+ *
+ * @throws \Exception When Exception couldn't be catch by event processing
*/
public function handle(RequestInterface $request, $main = true)
{
@@ -78,7 +80,8 @@ public function handle(RequestInterface $request, $main = true)
*
* @return ResponseInterface $response A Response instance
*
- * @throws \LogicException if one of the listener does not behave as expected
+ * @throws \LogicException If one of the listener does not behave as expected
+ * @throws NotFoundHttpException When controller cannot be found
*/
public function handleRaw(RequestInterface $request, $main = true)
{
diff --git a/src/Symfony/Components/RequestHandler/RequestInterface.php b/src/Symfony/Components/RequestHandler/RequestInterface.php
index 0a1b69edbbd2f..6e445d2031fb2 100644
--- a/src/Symfony/Components/RequestHandler/RequestInterface.php
+++ b/src/Symfony/Components/RequestHandler/RequestInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\RequestHandler;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* RequestInterface is the interface that all client request classes must implement.
*
- * @package symfony
- * @subpackage request_handler
+ * @package Symfony
+ * @subpackage Components_RequestHandler
* @author Fabien Potencier
*/
interface RequestInterface
diff --git a/src/Symfony/Components/RequestHandler/Response.php b/src/Symfony/Components/RequestHandler/Response.php
index d373b91316573..2e50f1938f3c1 100644
--- a/src/Symfony/Components/RequestHandler/Response.php
+++ b/src/Symfony/Components/RequestHandler/Response.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\RequestHandler;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Response is the base implementation of a server response.
*
- * @package symfony
- * @subpackage request_handler
+ * @package Symfony
+ * @subpackage Components_RequestHandler
* @author Fabien Potencier
*/
class Response implements ResponseInterface
@@ -144,10 +144,12 @@ public function getProtocolVersion()
* @param string $domain Domain name
* @param bool $secure If secure
* @param bool $httpOnly If uses only HTTP
+ *
+ * @throws \InvalidArgumentException When cookie expire parameter is not valid
*/
public function setCookie($name, $value, $expire = null, $path = '/', $domain = '', $secure = false, $httpOnly = false)
{
- if (!is_null($expire))
+ if (null !== $expire)
{
if (is_numeric($expire))
{
@@ -192,6 +194,7 @@ public function getCookies()
* @param string $code HTTP status code
* @param string $text HTTP status text
*
+ * @throws \InvalidArgumentException When the HTTP status code is not valid
*/
public function setStatusCode($code, $text = null)
{
@@ -228,7 +231,7 @@ public function setHeader($name, $value, $replace = true)
{
$name = $this->normalizeHeaderName($name);
- if (is_null($value))
+ if (null === $value)
{
unset($this->headers[$name]);
diff --git a/src/Symfony/Components/RequestHandler/ResponseInterface.php b/src/Symfony/Components/RequestHandler/ResponseInterface.php
index d0ffd64d8c247..0fa110dffc375 100644
--- a/src/Symfony/Components/RequestHandler/ResponseInterface.php
+++ b/src/Symfony/Components/RequestHandler/ResponseInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\RequestHandler;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* ResponseInterface is the interface that all server response classes must implement.
*
- * @package symfony
- * @subpackage request_handler
+ * @package Symfony
+ * @subpackage Components_RequestHandler
* @author Fabien Potencier
*/
interface ResponseInterface
diff --git a/src/Symfony/Components/Routing/CompiledRoute.php b/src/Symfony/Components/Routing/CompiledRoute.php
index 2c6eae43f491f..5884c16f4476b 100644
--- a/src/Symfony/Components/Routing/CompiledRoute.php
+++ b/src/Symfony/Components/Routing/CompiledRoute.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* CompiledRoutes are returned by the RouteCompiler class.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class CompiledRoute
@@ -31,7 +31,7 @@ class CompiledRoute
*
* @param Route $route A original Route instance
* @param string $staticPrefix The static prefix of the compiled route
- * @param string $regex The regular expresion to use to match this route
+ * @param string $regex The regular expression to use to match this route
* @param array $tokens An array of tokens to use to generate URL for this route
* @param array $variables An array of variables
*/
diff --git a/src/Symfony/Components/Routing/FileResource.php b/src/Symfony/Components/Routing/FileResource.php
index e01eb2f58175f..80523f2ffe145 100644
--- a/src/Symfony/Components/Routing/FileResource.php
+++ b/src/Symfony/Components/Routing/FileResource.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* FileResource represents a resource stored on the filesystem.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class FileResource implements ResourceInterface
diff --git a/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumper.php b/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumper.php
index 89f263365c2b7..c09f767bb20cb 100644
--- a/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumper.php
+++ b/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumper.php
@@ -6,7 +6,7 @@
use Symfony\Components\Routing\Route;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* GeneratorDumper is the base class for all built-in generator dumpers.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
abstract class GeneratorDumper implements GeneratorDumperInterface
@@ -41,6 +41,8 @@ public function __construct(RouteCollection $routes)
* @param array $options An array of options
*
* @return string The representation of the routing
+ *
+ * @throws \LogicException When this abstrass class is not implemented
*/
public function dump(array $options = array())
{
diff --git a/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumperInterface.php b/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumperInterface.php
index 3a6d1503cb014..3960fee4c41ef 100644
--- a/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumperInterface.php
+++ b/src/Symfony/Components/Routing/Generator/Dumper/GeneratorDumperInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Generator\Dumper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* GeneratorDumperInterface is the interface that all generator dumper classes must implement.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface GeneratorDumperInterface
diff --git a/src/Symfony/Components/Routing/Generator/Dumper/PhpGeneratorDumper.php b/src/Symfony/Components/Routing/Generator/Dumper/PhpGeneratorDumper.php
index e901f2f0cc970..15a9a963d6e2e 100644
--- a/src/Symfony/Components/Routing/Generator/Dumper/PhpGeneratorDumper.php
+++ b/src/Symfony/Components/Routing/Generator/Dumper/PhpGeneratorDumper.php
@@ -5,7 +5,7 @@
use Symfony\Components\Routing\Route;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* PhpGeneratorDumper creates a PHP class able to generate URLs for a given set of routes.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class PhpGeneratorDumper extends GeneratorDumper
diff --git a/src/Symfony/Components/Routing/Generator/UrlGenerator.php b/src/Symfony/Components/Routing/Generator/UrlGenerator.php
index e28f82e3a77e4..54169dc997191 100644
--- a/src/Symfony/Components/Routing/Generator/UrlGenerator.php
+++ b/src/Symfony/Components/Routing/Generator/UrlGenerator.php
@@ -6,7 +6,7 @@
use Symfony\Components\Routing\RouteCollection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* UrlGenerator generates URL based on a set of routes.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class UrlGenerator implements UrlGeneratorInterface
@@ -38,7 +38,7 @@ class UrlGenerator implements UrlGeneratorInterface
public function __construct(RouteCollection $routes, array $context = array(), array $defaults = array())
{
$this->routes = $routes;
- $this->context = array_merge(array('base_url' => ''), $context);
+ $this->context = $context;
$this->defaults = $defaults;
$this->cache = array();
}
@@ -51,6 +51,8 @@ public function __construct(RouteCollection $routes, array $context = array(), a
* @param Boolean $absolute Whether to generate an absolute URL
*
* @return string The generated URL
+ *
+ * @throws \InvalidArgumentException When route doesn't exist
*/
public function generate($name, array $parameters, $absolute = false)
{
@@ -67,6 +69,9 @@ public function generate($name, array $parameters, $absolute = false)
return $this->doGenerate($this->cache[$name]->getVariables(), $route->getDefaults(), $route->getRequirements(), $this->cache[$name]->getTokens(), $parameters, $name, $absolute);
}
+ /**
+ * @throws \InvalidArgumentException When route has some missing mandatory parameters
+ */
protected function doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute)
{
$defaults = array_merge($this->defaults, $defaults);
@@ -123,7 +128,7 @@ protected function doGenerate($variables, $defaults, $requirements, $tokens, $pa
$url .= '?'.http_build_query($extra);
}
- $url = $this->context['base_url'].$url;
+ $url = (isset($this->context['base_url']) ? $this->context['base_url'] : '').$url;
if ($absolute && isset($this->context['host']))
{
diff --git a/src/Symfony/Components/Routing/Generator/UrlGeneratorInterface.php b/src/Symfony/Components/Routing/Generator/UrlGeneratorInterface.php
index 60b4a5c00e15c..a2af32ba8cbd5 100644
--- a/src/Symfony/Components/Routing/Generator/UrlGeneratorInterface.php
+++ b/src/Symfony/Components/Routing/Generator/UrlGeneratorInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Generator;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* UrlGeneratorInterface is the interface that all URL generator classes must implements.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface UrlGeneratorInterface
diff --git a/src/Symfony/Components/Routing/Loader/FileLoader.php b/src/Symfony/Components/Routing/Loader/FileLoader.php
index a8bda96e4f3cd..7384cb4d1eab8 100644
--- a/src/Symfony/Components/Routing/Loader/FileLoader.php
+++ b/src/Symfony/Components/Routing/Loader/FileLoader.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* FileLoader is the abstract class used by all built-in loaders that are file based.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
abstract class FileLoader implements LoaderInterface
@@ -37,6 +37,9 @@ public function __construct($paths = array())
$this->paths = $paths;
}
+ /**
+ * @throws \InvalidArgumentException When file is not found
+ */
protected function findFile($file)
{
$path = $this->getAbsolutePath($file);
diff --git a/src/Symfony/Components/Routing/Loader/LoaderInterface.php b/src/Symfony/Components/Routing/Loader/LoaderInterface.php
index a9cc6575dd6cf..bd467fcddad60 100644
--- a/src/Symfony/Components/Routing/Loader/LoaderInterface.php
+++ b/src/Symfony/Components/Routing/Loader/LoaderInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Loader;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* LoaderInterface is the interface that all loaders classes must implement.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface LoaderInterface
diff --git a/src/Symfony/Components/Routing/Loader/XmlFileLoader.php b/src/Symfony/Components/Routing/Loader/XmlFileLoader.php
index dddba62632670..31c92ba692912 100644
--- a/src/Symfony/Components/Routing/Loader/XmlFileLoader.php
+++ b/src/Symfony/Components/Routing/Loader/XmlFileLoader.php
@@ -7,7 +7,7 @@
use Symfony\Components\Routing\FileResource;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
/**
* XmlFileLoader loads XML routing files.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class XmlFileLoader extends FileLoader
@@ -30,6 +30,8 @@ class XmlFileLoader extends FileLoader
* @param string $file A XML file path
*
* @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When a tag can't be parsed
*/
public function load($file)
{
@@ -123,6 +125,9 @@ protected function parseImport(RouteCollection $collection, $node, $file)
$collection->addCollection($loader->load($importedFile), (string) $node->getAttribute('prefix'));
}
+ /**
+ * @throws \InvalidArgumentException When loading of XML file returns error
+ */
protected function loadFile($path)
{
$dom = new \DOMDocument();
@@ -139,6 +144,9 @@ protected function loadFile($path)
return $dom;
}
+ /**
+ * @throws \InvalidArgumentException When xml doesn't validate its xsd schema
+ */
protected function validate($dom, $file)
{
libxml_use_internal_errors(true);
diff --git a/src/Symfony/Components/Routing/Loader/YamlFileLoader.php b/src/Symfony/Components/Routing/Loader/YamlFileLoader.php
index a1f10de067ad7..5f104799230fd 100644
--- a/src/Symfony/Components/Routing/Loader/YamlFileLoader.php
+++ b/src/Symfony/Components/Routing/Loader/YamlFileLoader.php
@@ -8,7 +8,7 @@
use Symfony\Components\Yaml\Yaml;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -19,8 +19,8 @@
/**
* YamlFileLoader loads Yaml routing files.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class YamlFileLoader extends FileLoader
@@ -31,6 +31,8 @@ class YamlFileLoader extends FileLoader
* @param string $file A Yaml file path
*
* @return RouteCollection A RouteCollection instance
+ *
+ * @throws \InvalidArgumentException When route can't be parsed
*/
public function load($file)
{
@@ -60,6 +62,9 @@ public function load($file)
return $collection;
}
+ /**
+ * @throws \InvalidArgumentException When config pattern is not defined for the given route
+ */
protected function parseRoute(RouteCollection $collection, $name, $config, $file)
{
$defaults = isset($config['defaults']) ? $config['defaults'] : array();
@@ -76,6 +81,9 @@ protected function parseRoute(RouteCollection $collection, $name, $config, $file
$collection->addRoute($name, $route);
}
+ /**
+ * @throws \InvalidArgumentException When import resource is not defined
+ */
protected function parseImport(RouteCollection $collection, $name, $import, $file)
{
if (!isset($import['resource']))
diff --git a/src/Symfony/Components/Routing/Matcher/ApacheUrlMatcher.php b/src/Symfony/Components/Routing/Matcher/ApacheUrlMatcher.php
index cac89a3fd6f94..719b2d382f92b 100644
--- a/src/Symfony/Components/Routing/Matcher/ApacheUrlMatcher.php
+++ b/src/Symfony/Components/Routing/Matcher/ApacheUrlMatcher.php
@@ -6,7 +6,7 @@
use Symfony\Components\Routing\RouteCollection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper).
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class ApacheUrlMatcher extends UrlMatcher
diff --git a/src/Symfony/Components/Routing/Matcher/Dumper/ApacheMatcherDumper.php b/src/Symfony/Components/Routing/Matcher/Dumper/ApacheMatcherDumper.php
index edbb7b5732b24..450d2352f8dff 100644
--- a/src/Symfony/Components/Routing/Matcher/Dumper/ApacheMatcherDumper.php
+++ b/src/Symfony/Components/Routing/Matcher/Dumper/ApacheMatcherDumper.php
@@ -5,7 +5,7 @@
use Symfony\Components\Routing\Route;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* ApacheMatcherDumper dumps a matcher in the Apache .htaccess format.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class ApacheMatcherDumper extends MatcherDumper
@@ -32,6 +32,8 @@ class ApacheMatcherDumper extends MatcherDumper
* @param array $options An array of options
*
* @return string A PHP class representing the matcher class
+ *
+ * @throws \RuntimeException When a route has more than 9 variables
*/
public function dump(array $options = array())
{
diff --git a/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumper.php b/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumper.php
index 41e6eef0b1811..2e57e2964bb6a 100644
--- a/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumper.php
+++ b/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumper.php
@@ -6,7 +6,7 @@
use Symfony\Components\Routing\Route;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* MatcherDumper is the abstract class for all built-in matcher dumpers.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
abstract class MatcherDumper implements MatcherDumperInterface
@@ -41,6 +41,8 @@ public function __construct(RouteCollection $routes)
* @param array $options An array of options
*
* @return string The representation of the routing
+ *
+ * @throws \LogicException When this abstrass class is not implemented
*/
public function dump(array $options = array())
{
diff --git a/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumperInterface.php b/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumperInterface.php
index 8e8022af4173b..6d7cf5971017a 100644
--- a/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumperInterface.php
+++ b/src/Symfony/Components/Routing/Matcher/Dumper/MatcherDumperInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Matcher\Dumper;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* MatcherDumperInterface is the interface that all matcher dumper classes must implement.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface MatcherDumperInterface
diff --git a/src/Symfony/Components/Routing/Matcher/Dumper/PhpMatcherDumper.php b/src/Symfony/Components/Routing/Matcher/Dumper/PhpMatcherDumper.php
index dad60fea89077..682956304e769 100644
--- a/src/Symfony/Components/Routing/Matcher/Dumper/PhpMatcherDumper.php
+++ b/src/Symfony/Components/Routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -5,7 +5,7 @@
use Symfony\Components\Routing\Route;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* PhpMatcherDumper creates a PHP class able to match URLs for a given set of routes.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class PhpMatcherDumper extends MatcherDumper
diff --git a/src/Symfony/Components/Routing/Matcher/UrlMatcher.php b/src/Symfony/Components/Routing/Matcher/UrlMatcher.php
index 27f6d07434174..ef1a31375ec46 100644
--- a/src/Symfony/Components/Routing/Matcher/UrlMatcher.php
+++ b/src/Symfony/Components/Routing/Matcher/UrlMatcher.php
@@ -6,7 +6,7 @@
use Symfony\Components\Routing\RouteCollection;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* UrlMatcher matches URL based on a set of routes.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class UrlMatcher implements UrlMatcherInterface
diff --git a/src/Symfony/Components/Routing/Matcher/UrlMatcherInterface.php b/src/Symfony/Components/Routing/Matcher/UrlMatcherInterface.php
index 4386e38d82a81..f4f4009e0dee3 100644
--- a/src/Symfony/Components/Routing/Matcher/UrlMatcherInterface.php
+++ b/src/Symfony/Components/Routing/Matcher/UrlMatcherInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing\Matcher;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* UrlMatcherInterface is the interface that all URL matcher classes must implements.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface UrlMatcherInterface
diff --git a/src/Symfony/Components/Routing/ResourceInterface.php b/src/Symfony/Components/Routing/ResourceInterface.php
index 19f718e981952..c524b4e3bfc60 100644
--- a/src/Symfony/Components/Routing/ResourceInterface.php
+++ b/src/Symfony/Components/Routing/ResourceInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* ResourceInterface is the interface that must be implemented by all Resource classes.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface ResourceInterface
diff --git a/src/Symfony/Components/Routing/Route.php b/src/Symfony/Components/Routing/Route.php
index 2d2c25d4bfda6..322688c702aa4 100644
--- a/src/Symfony/Components/Routing/Route.php
+++ b/src/Symfony/Components/Routing/Route.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* A Route describes a route and its parameters.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class Route
diff --git a/src/Symfony/Components/Routing/RouteCollection.php b/src/Symfony/Components/Routing/RouteCollection.php
index ea9c49be46f2a..339bc11ae9fde 100644
--- a/src/Symfony/Components/Routing/RouteCollection.php
+++ b/src/Symfony/Components/Routing/RouteCollection.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* A RouteCollection represents a set of Route instances.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class RouteCollection
@@ -37,6 +37,8 @@ public function __construct()
*
* @param string $name The route name
* @param Route $route A Route instance
+ *
+ * @throws \InvalidArgumentException When route name contains non valid characters
*/
public function addRoute($name, Route $route)
{
diff --git a/src/Symfony/Components/Routing/RouteCompiler.php b/src/Symfony/Components/Routing/RouteCompiler.php
index fc01978f5955b..5df61be52d055 100644
--- a/src/Symfony/Components/Routing/RouteCompiler.php
+++ b/src/Symfony/Components/Routing/RouteCompiler.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* RouteCompiler compiles Route instances to CompiledRoute instances.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class RouteCompiler implements RouteCompilerInterface
@@ -127,6 +127,8 @@ protected function postCompile()
/**
* Tokenizes the route.
+ *
+ * @throws \InvalidArgumentException When route can't be parsed
*/
protected function tokenize()
{
diff --git a/src/Symfony/Components/Routing/RouteCompilerInterface.php b/src/Symfony/Components/Routing/RouteCompilerInterface.php
index 0cdc3f18447d5..446d23796d938 100644
--- a/src/Symfony/Components/Routing/RouteCompilerInterface.php
+++ b/src/Symfony/Components/Routing/RouteCompilerInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* RouteCompilerInterface is the interface that all RouteCompiler classes must implements.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface RouteCompilerInterface
diff --git a/src/Symfony/Components/Routing/Router.php b/src/Symfony/Components/Routing/Router.php
index 188e914e95a3f..77b7ed418d173 100644
--- a/src/Symfony/Components/Routing/Router.php
+++ b/src/Symfony/Components/Routing/Router.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -15,8 +15,8 @@
* The Router class is an example of the integration of all pieces of the
* routing system for easier use.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
class Router implements RouterInterface
@@ -41,6 +41,8 @@ class Router implements RouterInterface
* @param array $options An array of options
* @param array $context The context
* @param array $defaults The default values
+ *
+ * @throws \InvalidArgumentException When unsupported option is provided
*/
public function __construct($loader, array $options = array(), array $context = array(), array $defaults = array())
{
@@ -52,7 +54,7 @@ public function __construct($loader, array $options = array(), array $context =
'debug' => false,
'generator_class' => 'Symfony\\Components\\Routing\\Generator\\UrlGenerator',
'generator_base_class' => 'Symfony\\Components\\Routing\\Generator\\UrlGenerator',
- 'generator_dumper_class' => 'Symfony\Components\Routing\Generator\Dumper\PhpGeneratorDumper',
+ 'generator_dumper_class' => 'Symfony\\Components\\Routing\\Generator\\Dumper\\PhpGeneratorDumper',
'generator_cache_class' => 'ProjectUrlGenerator',
'matcher_class' => 'Symfony\\Components\\Routing\\Matcher\\UrlMatcher',
'matcher_base_class' => 'Symfony\\Components\\Routing\\Matcher\\UrlMatcher',
@@ -249,6 +251,9 @@ protected function getCacheFile($class, $extension = 'php')
return $this->options['cache_dir'].'/'.$class.'.'.$extension;
}
+ /**
+ * @throws \RuntimeException When cache file can't be wrote
+ */
protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
diff --git a/src/Symfony/Components/Routing/RouterInterface.php b/src/Symfony/Components/Routing/RouterInterface.php
index 6267050d573f2..69c1c407619e9 100644
--- a/src/Symfony/Components/Routing/RouterInterface.php
+++ b/src/Symfony/Components/Routing/RouterInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Routing;
/*
- * This file is part of the symfony framework.
+ * This file is part of the Symfony framework.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
*
* This interface is the concatenation of UrlMatcherInterface and UrlGeneratorInterface.
*
- * @package symfony
- * @subpackage routing
+ * @package Symfony
+ * @subpackage Components_Routing
* @author Fabien Potencier
*/
interface RouterInterface
diff --git a/src/Symfony/Components/Templating/DebuggerInterface.php b/src/Symfony/Components/Templating/DebuggerInterface.php
index 685718db2f003..59fcfa957f13e 100644
--- a/src/Symfony/Components/Templating/DebuggerInterface.php
+++ b/src/Symfony/Components/Templating/DebuggerInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -15,8 +15,8 @@
* DebuggerInterface is the interface you need to implement
* to debug template loader instances.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
interface DebuggerInterface
diff --git a/src/Symfony/Components/Templating/Engine.php b/src/Symfony/Components/Templating/Engine.php
index 8fff1dcf96b6f..39abfb42492d7 100644
--- a/src/Symfony/Components/Templating/Engine.php
+++ b/src/Symfony/Components/Templating/Engine.php
@@ -5,9 +5,10 @@
use Symfony\Components\Templating\Loader\LoaderInterface;
use Symfony\Components\Templating\Renderer\PhpRenderer;
use Symfony\Components\Templating\Renderer\RendererInterface;
+use Symfony\Components\Templating\Helper\HelperInterface;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -18,8 +19,8 @@
/**
* Engine is the main class of the templating component.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class Engine
@@ -31,6 +32,7 @@ class Engine
protected $parents;
protected $stack;
protected $charset;
+ protected $cache;
/**
* Constructor.
@@ -171,7 +173,7 @@ public function addHelpers(array $helpers = array())
* Sets a helper.
*
* @param HelperInterface $value The helper instance
- * @param string $alias An alias
+ * @param string $alias An alias
*/
public function set(HelperInterface $helper, $alias = null)
{
@@ -181,7 +183,7 @@ public function set(HelperInterface $helper, $alias = null)
$this->helpers[$alias] = $helper;
}
- $helper->setEngine($this);
+ $helper->setCharset($this->charset);
}
/**
diff --git a/src/Symfony/Components/Templating/Helper/AssetsHelper.php b/src/Symfony/Components/Templating/Helper/AssetsHelper.php
index 834ea4b4969df..96e38f72c4685 100644
--- a/src/Symfony/Components/Templating/Helper/AssetsHelper.php
+++ b/src/Symfony/Components/Templating/Helper/AssetsHelper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Helper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -20,8 +20,8 @@
*
*
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class AssetsHelper extends Helper
diff --git a/src/Symfony/Components/Templating/Helper/Helper.php b/src/Symfony/Components/Templating/Helper/Helper.php
index 7b99c7364e0a9..c735c927dc08d 100644
--- a/src/Symfony/Components/Templating/Helper/Helper.php
+++ b/src/Symfony/Components/Templating/Helper/Helper.php
@@ -2,10 +2,8 @@
namespace Symfony\Components\Templating\Helper;
-use Symfony\Components\Templating\Engine;
-
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,31 +14,31 @@
/**
* Helper is the base class for all helper classes.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
abstract class Helper implements HelperInterface
{
- protected $engine;
+ protected $charset = 'UTF-8';
/**
- * Sets the engine associated with this helper.
+ * Sets the default charset.
*
- * @param Engine $engine A Engine instance
+ * @param string $charset The charset
*/
- public function setEngine(Engine $engine = null)
+ public function setCharset($charset)
{
- $this->engine = $engine;
+ $this->charset = $charset;
}
/**
- * Gets the engine associated with this helper.
+ * Gets the default charset.
*
- * @return Engine A Engine instance
+ * @return string The default charset
*/
- public function getEngine()
+ public function getCharset()
{
- return $this->engine;
+ return $this->charset;
}
}
diff --git a/src/Symfony/Components/Templating/Helper/HelperInterface.php b/src/Symfony/Components/Templating/Helper/HelperInterface.php
index 389abc51938c1..61704fc596aa7 100644
--- a/src/Symfony/Components/Templating/Helper/HelperInterface.php
+++ b/src/Symfony/Components/Templating/Helper/HelperInterface.php
@@ -2,10 +2,8 @@
namespace Symfony\Components\Templating\Helper;
-use Symfony\Components\Templating\Engine;
-
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,8 +14,8 @@
/**
* HelperInterface is the interface all helpers must implement.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
interface HelperInterface
@@ -30,16 +28,16 @@ interface HelperInterface
function getName();
/**
- * Sets the engine associated with this helper.
+ * Sets the default charset.
*
- * @param Engine $engine A Engine instance
+ * @param string $charset The charset
*/
- function setEngine(Engine $engine = null);
+ function setCharset($charset);
/**
- * Gets the engine associated with this helper.
+ * Gets the default charset.
*
- * @return Engine A Engine instance
+ * @return string The default charset
*/
- function getEngine();
+ function getCharset();
}
diff --git a/src/Symfony/Components/Templating/Helper/JavascriptsHelper.php b/src/Symfony/Components/Templating/Helper/JavascriptsHelper.php
index fcacd03cfec9b..7f3ef61497412 100644
--- a/src/Symfony/Components/Templating/Helper/JavascriptsHelper.php
+++ b/src/Symfony/Components/Templating/Helper/JavascriptsHelper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Helper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -21,13 +21,24 @@
* echo $this->javascripts;
*
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class JavascriptsHelper extends Helper
{
protected $javascripts = array();
+ protected $assetHelper;
+
+ /**
+ * Constructor.
+ *
+ * @param AssetsHelper $assetHelper A AssetsHelper instance
+ */
+ public function __construct(AssetsHelper $assetHelper)
+ {
+ $this->assetHelper = $assetHelper;
+ }
/**
* Adds a JavaScript file.
@@ -37,7 +48,7 @@ class JavascriptsHelper extends Helper
*/
public function add($javascript, $attributes = array())
{
- $this->javascripts[$this->engine->get('assets')->getUrl($javascript)] = $attributes;
+ $this->javascripts[$this->assetHelper->getUrl($javascript)] = $attributes;
}
/**
@@ -63,7 +74,7 @@ public function render()
$atts = '';
foreach ($attributes as $key => $value)
{
- $atts .= ' '.sprintf('%s="%s"', $key, $this->engine->escape($value));
+ $atts .= ' '.sprintf('%s="%s"', $key, htmlspecialchars($value, ENT_QUOTES, $this->charset));
}
$html .= sprintf('', $path, $atts)."\n";
@@ -74,7 +85,7 @@ public function render()
/**
* Outputs HTML representation of the links to JavaScripts.
- *
+ *
*/
public function output()
{
diff --git a/src/Symfony/Components/Templating/Helper/SlotsHelper.php b/src/Symfony/Components/Templating/Helper/SlotsHelper.php
index 130bc0676d4d7..5a0450c0dd100 100644
--- a/src/Symfony/Components/Templating/Helper/SlotsHelper.php
+++ b/src/Symfony/Components/Templating/Helper/SlotsHelper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Helper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* SlotsHelper manages template slots.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class SlotsHelper extends Helper
diff --git a/src/Symfony/Components/Templating/Helper/StylesheetsHelper.php b/src/Symfony/Components/Templating/Helper/StylesheetsHelper.php
index 900d8254c9450..969956a50466c 100644
--- a/src/Symfony/Components/Templating/Helper/StylesheetsHelper.php
+++ b/src/Symfony/Components/Templating/Helper/StylesheetsHelper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Helper;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -21,13 +21,24 @@
* echo $this->stylesheets;
*
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class StylesheetsHelper extends Helper
{
protected $stylesheets = array();
+ protected $assetHelper;
+
+ /**
+ * Constructor.
+ *
+ * @param AssetsHelper $assetHelper A AssetsHelper instance
+ */
+ public function __construct(AssetsHelper $assetHelper)
+ {
+ $this->assetHelper = $assetHelper;
+ }
/**
* Adds a stylesheets file.
@@ -37,7 +48,7 @@ class StylesheetsHelper extends Helper
*/
public function add($stylesheet, $attributes = array())
{
- $this->stylesheets[$this->engine->get('assets')->getUrl($stylesheet)] = $attributes;
+ $this->stylesheets[$this->assetHelper->getUrl($stylesheet)] = $attributes;
}
/**
@@ -63,7 +74,7 @@ public function render()
$atts = '';
foreach ($attributes as $key => $value)
{
- $atts .= ' '.sprintf('%s="%s"', $key, $this->engine->escape($value));
+ $atts .= ' '.sprintf('%s="%s"', $key, htmlspecialchars($value, ENT_QUOTES, $this->charset));
}
$html .= sprintf('', $path, $atts)."\n";
@@ -74,7 +85,7 @@ public function render()
/**
* Outputs HTML representation of the links to stylesheets.
- *
+ *
*/
public function output()
{
diff --git a/src/Symfony/Components/Templating/Loader/CacheLoader.php b/src/Symfony/Components/Templating/Loader/CacheLoader.php
index 1d25de0d7bdfc..ff63e3a7df0d1 100644
--- a/src/Symfony/Components/Templating/Loader/CacheLoader.php
+++ b/src/Symfony/Components/Templating/Loader/CacheLoader.php
@@ -6,7 +6,7 @@
use Symfony\Components\Templating\Storage\FileStorage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -19,10 +19,10 @@
* on the filesystem.
*
* This cache only caches on disk to allow PHP accelerators to cache the opcodes.
- * All other mecanism would imply the use of `eval()`.
+ * All other mechanism would imply the use of `eval()`.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class CacheLoader extends Loader
diff --git a/src/Symfony/Components/Templating/Loader/ChainLoader.php b/src/Symfony/Components/Templating/Loader/ChainLoader.php
index 714919217f89a..7b26f5a46de5c 100644
--- a/src/Symfony/Components/Templating/Loader/ChainLoader.php
+++ b/src/Symfony/Components/Templating/Loader/ChainLoader.php
@@ -5,7 +5,7 @@
use Symfony\Components\Templating\Storage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* ChainLoader is a loader that calls other loaders to load templates.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class ChainLoader extends Loader
diff --git a/src/Symfony/Components/Templating/Loader/CompilableLoaderInterface.php b/src/Symfony/Components/Templating/Loader/CompilableLoaderInterface.php
index 242f562acc407..583f2d207c2e1 100644
--- a/src/Symfony/Components/Templating/Loader/CompilableLoaderInterface.php
+++ b/src/Symfony/Components/Templating/Loader/CompilableLoaderInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Loader;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -15,8 +15,8 @@
* CompilableLoaderInterface is the interface a template loader must implement
* if the templates are compilable.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
interface CompilableLoaderInterface
diff --git a/src/Symfony/Components/Templating/Loader/FilesystemLoader.php b/src/Symfony/Components/Templating/Loader/FilesystemLoader.php
index 120a558be7111..1a0e7fedacfd2 100644
--- a/src/Symfony/Components/Templating/Loader/FilesystemLoader.php
+++ b/src/Symfony/Components/Templating/Loader/FilesystemLoader.php
@@ -6,7 +6,7 @@
use Symfony\Components\Templating\Storage\FileStorage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* FilesystemLoader is a loader that read templates from the filesystem.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class FilesystemLoader extends Loader
diff --git a/src/Symfony/Components/Templating/Loader/Loader.php b/src/Symfony/Components/Templating/Loader/Loader.php
index 4df24149bed06..1ac5a77efc0eb 100644
--- a/src/Symfony/Components/Templating/Loader/Loader.php
+++ b/src/Symfony/Components/Templating/Loader/Loader.php
@@ -5,7 +5,7 @@
use Symfony\Components\Templating\DebuggerInterface;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* Loader is the base class for all template loader classes.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
abstract class Loader implements LoaderInterface
diff --git a/src/Symfony/Components/Templating/Loader/LoaderInterface.php b/src/Symfony/Components/Templating/Loader/LoaderInterface.php
index 9dda9a1ec235a..a664defb1d308 100644
--- a/src/Symfony/Components/Templating/Loader/LoaderInterface.php
+++ b/src/Symfony/Components/Templating/Loader/LoaderInterface.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Loader;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* LoaderInterface is the interface all loaders must implement.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
interface LoaderInterface
diff --git a/src/Symfony/Components/Templating/Renderer/PhpRenderer.php b/src/Symfony/Components/Templating/Renderer/PhpRenderer.php
index b83fd830b1545..14b8de5741da2 100644
--- a/src/Symfony/Components/Templating/Renderer/PhpRenderer.php
+++ b/src/Symfony/Components/Templating/Renderer/PhpRenderer.php
@@ -7,7 +7,7 @@
use Symfony\Components\Templating\Storage\StringStorage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -18,8 +18,8 @@
/**
* PhpRenderer is a renderer for PHP templates.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class PhpRenderer extends Renderer
diff --git a/src/Symfony/Components/Templating/Renderer/Renderer.php b/src/Symfony/Components/Templating/Renderer/Renderer.php
index 65e815cbca16f..aedf69cee3655 100644
--- a/src/Symfony/Components/Templating/Renderer/Renderer.php
+++ b/src/Symfony/Components/Templating/Renderer/Renderer.php
@@ -5,7 +5,7 @@
use Symfony\Components\Templating\Engine;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -16,8 +16,8 @@
/**
* Renderer is the base class for all template renderer.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
abstract class Renderer implements RendererInterface
diff --git a/src/Symfony/Components/Templating/Renderer/RendererInterface.php b/src/Symfony/Components/Templating/Renderer/RendererInterface.php
index a7ffd8c676245..e186175c0ae75 100644
--- a/src/Symfony/Components/Templating/Renderer/RendererInterface.php
+++ b/src/Symfony/Components/Templating/Renderer/RendererInterface.php
@@ -6,7 +6,7 @@
use Symfony\Components\Templating\Storage\Storage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -17,8 +17,8 @@
/**
* RendererInterface is the interface all renderer classes must implement.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
interface RendererInterface
@@ -27,7 +27,7 @@ interface RendererInterface
* Evaluates a template.
*
* @param Storage $template The template to render
- * @param array $parameters An array of parameters to pass to the template
+ * @param array $parameters An array of parameters to pass to the template
*
* @return string|false The evaluated template, or false if the renderer is unable to render the template
*/
diff --git a/src/Symfony/Components/Templating/Storage/FileStorage.php b/src/Symfony/Components/Templating/Storage/FileStorage.php
index 9cc74f74ce686..1ba70892cd75e 100644
--- a/src/Symfony/Components/Templating/Storage/FileStorage.php
+++ b/src/Symfony/Components/Templating/Storage/FileStorage.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Storage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* FileStorage represents a template stored on the filesystem.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class FileStorage extends Storage
diff --git a/src/Symfony/Components/Templating/Storage/Storage.php b/src/Symfony/Components/Templating/Storage/Storage.php
index 157e0f15ec1f4..2760f418c0d5c 100644
--- a/src/Symfony/Components/Templating/Storage/Storage.php
+++ b/src/Symfony/Components/Templating/Storage/Storage.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Storage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Storage is the base class for all storage classes.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
abstract class Storage
diff --git a/src/Symfony/Components/Templating/Storage/StringStorage.php b/src/Symfony/Components/Templating/Storage/StringStorage.php
index b14a003450c74..0e24b52f6255c 100644
--- a/src/Symfony/Components/Templating/Storage/StringStorage.php
+++ b/src/Symfony/Components/Templating/Storage/StringStorage.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Templating\Storage;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* StringStorage represents a template stored in a string.
*
- * @package symfony
- * @subpackage templating
+ * @package Symfony
+ * @subpackage Components_Templating
* @author Fabien Potencier
*/
class StringStorage extends Storage
diff --git a/src/Symfony/Components/Yaml/Dumper.php b/src/Symfony/Components/Yaml/Dumper.php
index 2db3f6cf1e00d..98484365aaab9 100644
--- a/src/Symfony/Components/Yaml/Dumper.php
+++ b/src/Symfony/Components/Yaml/Dumper.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Yaml;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
@@ -13,8 +13,8 @@
/**
* Dumper dumps PHP variables to YAML strings.
*
- * @package symfony
- * @subpackage yaml
+ * @package Symfony
+ * @subpackage Components_Yaml
* @author Fabien Potencier
*/
class Dumper
diff --git a/src/Symfony/Components/Yaml/Exception.php b/src/Symfony/Components/Yaml/Exception.php
index 49cb7949ee6df..efcf8fc085c26 100644
--- a/src/Symfony/Components/Yaml/Exception.php
+++ b/src/Symfony/Components/Yaml/Exception.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Yaml;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
*
* (c) Fabien Potencier
*
@@ -14,8 +14,8 @@
/**
* Exception class used by all exceptions thrown by the component.
*
- * @package symfony
- * @subpackage yaml
+ * @package Symfony
+ * @subpackage Components_Yaml
* @author Fabien Potencier
*/
class Exception extends \Exception
diff --git a/src/Symfony/Components/Yaml/Inline.php b/src/Symfony/Components/Yaml/Inline.php
index 854f4bba59763..8d4c730a8a7c1 100644
--- a/src/Symfony/Components/Yaml/Inline.php
+++ b/src/Symfony/Components/Yaml/Inline.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Yaml;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
@@ -13,8 +13,8 @@
/**
* Inline implements a YAML parser/dumper for the YAML inline syntax.
*
- * @package symfony
- * @subpackage yaml
+ * @package Symfony
+ * @subpackage Components_Yaml
* @author Fabien Potencier
*/
class Inline
@@ -37,15 +37,30 @@ static public function load($value)
return '';
}
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
+ {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
switch ($value[0])
{
case '[':
- return self::parseSequence($value);
+ $result = self::parseSequence($value);
+ break;
case '{':
- return self::parseMapping($value);
+ $result = self::parseMapping($value);
+ break;
default:
- return self::parseScalar($value);
+ $result = self::parseScalar($value);
+ }
+
+ if (isset($mbEncoding))
+ {
+ mb_internal_encoding($mbEncoding);
}
+
+ return $result;
}
/**
@@ -54,6 +69,8 @@ static public function load($value)
* @param mixed $value The PHP variable to convert
*
* @return string The YAML string representing the PHP array
+ *
+ * @throws Exception When trying to dump PHP resource
*/
static public function dump($value)
{
@@ -142,6 +159,8 @@ static protected function dumpArray($value)
* @param boolean $evaluate
*
* @return string A YAML string
+ *
+ * @throws ParserException When malformed inline YAML string is parsed
*/
static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
{
@@ -187,6 +206,8 @@ static public function parseScalar($scalar, $delimiters = null, $stringDelimiter
* @param integer $i
*
* @return string A YAML string
+ *
+ * @throws ParserException When malformed inline YAML string is parsed
*/
static protected function parseQuotedScalar($scalar, &$i)
{
@@ -220,6 +241,8 @@ static protected function parseQuotedScalar($scalar, &$i)
* @param integer $i
*
* @return string A YAML string
+ *
+ * @throws ParserException When malformed inline YAML string is parsed
*/
static protected function parseSequence($sequence, &$i = 0)
{
@@ -280,6 +303,8 @@ static protected function parseSequence($sequence, &$i = 0)
* @param integer $i
*
* @return string A YAML string
+ *
+ * @throws ParserException When malformed inline YAML string is parsed
*/
static protected function parseMapping($mapping, &$i = 0)
{
diff --git a/src/Symfony/Components/Yaml/Parser.php b/src/Symfony/Components/Yaml/Parser.php
index 3873c6b4d3967..519cf8b9656b7 100644
--- a/src/Symfony/Components/Yaml/Parser.php
+++ b/src/Symfony/Components/Yaml/Parser.php
@@ -3,7 +3,7 @@
namespace Symfony\Components\Yaml;
/*
- * This file is part of the symfony package.
+ * This file is part of the Symfony package.
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
@@ -13,8 +13,8 @@
/**
* Parser parses YAML strings to convert them to PHP arrays.
*
- * @package symfony
- * @subpackage yaml
+ * @package Symfony
+ * @subpackage Components_Yaml
* @author Fabien Potencier
*/
class Parser
@@ -42,7 +42,7 @@ public function __construct($offset = 0)
*
* @return mixed A PHP value
*
- * @throws \InvalidArgumentException If the YAML is not valid
+ * @throws ParserException If the YAML is not valid
*/
public function parse($value)
{
@@ -50,6 +50,12 @@ public function parse($value)
$this->currentLine = '';
$this->lines = explode("\n", $this->cleanup($value));
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
+ {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
+
$data = array();
while ($this->moveToNextLine())
{
@@ -83,11 +89,7 @@ public function parse($value)
}
else
{
- if (preg_match('/^([^ ]+)\: +({.*?)$/', $values['value'], $matches))
- {
- $data[] = array($matches[1] => Inline::load($matches[2]));
- }
- elseif (isset($values['leadspaces'])
+ if (isset($values['leadspaces'])
&& ' ' == $values['leadspaces']
&& preg_match('#^(?P