diff --git a/src/Symfony/Component/Config/CHANGELOG.md b/src/Symfony/Component/Config/CHANGELOG.md index 8426abd57b..63c244078f 100644 --- a/src/Symfony/Component/Config/CHANGELOG.md +++ b/src/Symfony/Component/Config/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * added numerical type handling for config definitions * added convenience methods for optional configuration sections to ArrayNodeDefinition + * added a utils class for XML manipulations 2.1.0 ----- diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml b/src/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml new file mode 100644 index 0000000000..4c25228263 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/Util/document_type.xml @@ -0,0 +1,3 @@ + +]> + diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml b/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml new file mode 100644 index 0000000000..a07af9fd85 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid.xml @@ -0,0 +1,2 @@ + + diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml b/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml new file mode 100644 index 0000000000..e2725a2c2a --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/Util/invalid_schema.xml @@ -0,0 +1,2 @@ + + diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd b/src/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd new file mode 100644 index 0000000000..e56820f691 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/Util/schema.xsd @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml b/src/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml new file mode 100644 index 0000000000..a96bb38267 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Fixtures/Util/valid.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php new file mode 100644 index 0000000000..a3d264e189 --- /dev/null +++ b/src/Symfony/Component/Config/Tests/Util/XmlUtilsTest.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Tests\Loader; + +use Symfony\Component\Config\Util\XmlUtils; + +class XmlUtilsTest extends \PHPUnit_Framework_TestCase +{ + public function testLoadFile() + { + $fixtures = __DIR__.'/../Fixtures/Util/'; + + try { + XmlUtils::loadFile($fixtures.'invalid.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('ERROR 77', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'document_type.xml'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('Document types are not allowed', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', $fixtures.'schema.xsd'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('ERROR 1845', $e->getMessage()); + } + + try { + XmlUtils::loadFile($fixtures.'invalid_schema.xml', 'invalid_callback_or_file'); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('XSD file or callable', $e->getMessage()); + } + + $mock = $this->getMock(__NAMESPACE__.'\Validator'); + $mock->expects($this->exactly(2))->method('validate')->will($this->onConsecutiveCalls(false, true)); + + try { + XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate')); + $this->fail(); + } catch (\InvalidArgumentException $e) { + $this->assertContains('is not valid', $e->getMessage()); + } + + $this->assertInstanceOf('DOMDocument', XmlUtils::loadFile($fixtures.'valid.xml', array($mock, 'validate'))); + } + + /** + * @dataProvider getDataForConvertDomToArray + */ + public function testConvertDomToArray($expected, $xml, $root = false, $checkPrefix = true) + { + $dom = new \DOMDocument(); + $dom->loadXML($root ? $xml : ''.$xml.''); + + $this->assertSame($expected, XmlUtils::convertDomElementToArray($dom->documentElement, $checkPrefix)); + } + + public function getDataForConvertDomToArray() + { + return array( + array(null, ''), + array('bar', 'bar'), + array(array('bar' => 'foobar'), '', true), + array(array('foo' => null), ''), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => array('foo' => 'bar')), ''), + array(array('foo' => array('foo' => 'bar')), 'bar'), + array(array('foo' => array('foo' => 'bar', 'value' => 'text')), 'text'), + array(array('foo' => array('attr' => 'bar', 'foo' => 'text')), 'text'), + array(array('foo' => array('bar', 'text')), 'bartext'), + array(array('foo' => array(array('foo' => 'bar'), array('foo' => 'text'))), ''), + array(array('foo' => array('foo' => array('bar', 'text'))), 'text'), + array(array('foo' => 'bar'), 'bar'), + array(array('foo' => 'text'), 'text'), + array(array('foo' => array('bar' => 'bar', 'value' => 'text')), 'text', false, false), + array(array('attr' => 1, 'b' => 'hello'), 'hello2', true), + ); + } + + /** + * @dataProvider getDataForPhpize + */ + public function testPhpize($expected, $value) + { + $this->assertSame($expected, XmlUtils::phpize($value)); + } + + public function getDataForPhpize() + { + return array( + array(null, 'null'), + array(true, 'true'), + array(false, 'false'), + array(null, 'Null'), + array(true, 'True'), + array(false, 'False'), + array(0, '0'), + array(1, '1'), + array(0777, '0777'), + array(255, '0xFF'), + array(100.0, '1e2'), + array(-120.0, '-1.2E2'), + array(-10100.1, '-10100.1'), + array(-10100.1, '-10,100.1'), + array('foo', 'foo'), + ); + } +} + +interface Validator +{ + public function validate(); +} diff --git a/src/Symfony/Component/Config/Util/XmlUtils.php b/src/Symfony/Component/Config/Util/XmlUtils.php new file mode 100644 index 0000000000..9317e15e7c --- /dev/null +++ b/src/Symfony/Component/Config/Util/XmlUtils.php @@ -0,0 +1,222 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Config\Util; + +/** + * XMLUtils is a bunch of utility methods to XML operations. + * + * This class contains static methods only and is not meant to be instantiated. + * + * @author Fabien Potencier + * @author Martin HasoĊˆ + */ +class XmlUtils +{ + /** + * This class should not be instantiated + */ + private function __construct() + { + } + + /** + * Loads an XML file. + * + * @param string $file An XML file path + * @param string|callable $schemaOrCallable An XSD schema file path or callable + * + * @return \DOMDocument + * + * @throws \InvalidArgumentException When loading of XML file returns error + */ + public static function loadFile($file, $schemaOrCallable = null) + { + $internalErrors = libxml_use_internal_errors(true); + $disableEntities = libxml_disable_entity_loader(true); + libxml_clear_errors(); + + $dom = new \DOMDocument(); + $dom->validateOnParse = true; + if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { + libxml_disable_entity_loader($disableEntities); + + throw new \InvalidArgumentException(implode("\n", static::getXmlErrors($internalErrors))); + } + + $dom->normalizeDocument(); + + libxml_use_internal_errors($internalErrors); + libxml_disable_entity_loader($disableEntities); + + foreach ($dom->childNodes as $child) { + if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { + throw new \InvalidArgumentException('Document types are not allowed.'); + } + } + + if (null !== $schemaOrCallable) { + $internalErrors = libxml_use_internal_errors(true); + libxml_clear_errors(); + + $e = null; + if (is_callable($schemaOrCallable)) { + try { + $valid = call_user_func($schemaOrCallable, $dom, $internalErrors); + } catch (\Exception $e) { + $valid = false; + } + } elseif (!is_array($schemaOrCallable) && is_file((string) $schemaOrCallable)) { + $valid = @$dom->schemaValidate($schemaOrCallable); + } else { + libxml_use_internal_errors($internalErrors); + + throw new \InvalidArgumentException('The schemaOrCallable argument has to be a valid path to XSD file or callable.'); + } + + if (!$valid) { + $messages = static::getXmlErrors($internalErrors); + if (empty($messages)) { + $messages = array(sprintf('The XML file "%s" is not valid.', $file)); + } + throw new \InvalidArgumentException(implode("\n", $messages), 0, $e); + } + + libxml_use_internal_errors($internalErrors); + } + + return $dom; + } + + /** + * Converts a \DomElement object to a PHP array. + * + * The following rules applies during the conversion: + * + * * Each tag is converted to a key value or an array + * if there is more than one "value" + * + * * The content of a tag is set under a "value" key (bar) + * if the tag also has some nested tags + * + * * The attributes are converted to keys () + * + * * The nested-tags are converted to keys (bar) + * + * @param \DomElement $element A \DomElement instance + * @param Boolean $checkPrefix Check prefix in an element or an attribute name + * + * @return array A PHP array + */ + public static function convertDomElementToArray(\DomElement $element, $checkPrefix = true) + { + $prefix = (string) $element->prefix; + $empty = true; + $config = array(); + foreach ($element->attributes as $name => $node) { + if ($checkPrefix && !in_array((string) $node->prefix, array('', $prefix), true)) { + continue; + } + $config[$name] = static::phpize($node->value); + $empty = false; + } + + $nodeValue = false; + foreach ($element->childNodes as $node) { + if ($node instanceof \DOMText) { + if (trim($node->nodeValue)) { + $nodeValue = trim($node->nodeValue); + $empty = false; + } + } elseif ($checkPrefix && $prefix != (string) $node->prefix) { + continue; + } elseif (!$node instanceof \DOMComment) { + $value = static::convertDomElementToArray($node, $checkPrefix); + + $key = $node->localName; + if (isset($config[$key])) { + if (!is_array($config[$key]) || !is_int(key($config[$key]))) { + $config[$key] = array($config[$key]); + } + $config[$key][] = $value; + } else { + $config[$key] = $value; + } + + $empty = false; + } + } + + if (false !== $nodeValue) { + $value = static::phpize($nodeValue); + if (count($config)) { + $config['value'] = $value; + } else { + $config = $value; + } + } + + return !$empty ? $config : null; + } + + /** + * Converts an xml value to a php type. + * + * @param mixed $value + * + * @return mixed + */ + public static function phpize($value) + { + $value = (string) $value; + $lowercaseValue = strtolower($value); + + switch (true) { + case 'null' === $lowercaseValue: + return null; + case ctype_digit($value): + $raw = $value; + $cast = intval($value); + + return '0' == $value[0] ? octdec($value) : (((string) $raw == (string) $cast) ? $cast : $raw); + case 'true' === $lowercaseValue: + return true; + case 'false' === $lowercaseValue: + return false; + case is_numeric($value): + return '0x' == $value[0].$value[1] ? hexdec($value) : floatval($value); + case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $value): + return floatval(str_replace(',', '', $value)); + default: + return $value; + } + } + + protected static function getXmlErrors($internalErrors) + { + $errors = array(); + foreach (libxml_get_errors() as $error) { + $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', + LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', + $error->code, + trim($error->message), + $error->file ? $error->file : 'n/a', + $error->line, + $error->column + ); + } + + libxml_clear_errors(); + libxml_use_internal_errors($internalErrors); + + return $errors; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index 6f2c8eba1a..f8f4336736 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Loader; use Symfony\Component\Config\Resource\FileResource; +use Symfony\Component\Config\Util\XmlUtils; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Alias; @@ -202,33 +203,17 @@ class XmlFileLoader extends FileLoader * * @return SimpleXMLElement * - * @throws \InvalidArgumentException When loading of XML file returns error + * @throws InvalidArgumentException When loading of XML file returns error */ protected function parseFile($file) { - $internalErrors = libxml_use_internal_errors(true); - $disableEntities = libxml_disable_entity_loader(true); - libxml_clear_errors(); - - $dom = new \DOMDocument(); - $dom->validateOnParse = true; - if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { - libxml_disable_entity_loader($disableEntities); - - throw new InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); - } - $dom->normalizeDocument(); - - libxml_use_internal_errors($internalErrors); - libxml_disable_entity_loader($disableEntities); - - foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - throw new InvalidArgumentException('Document types are not allowed.'); - } + try { + $dom = XmlUtils::loadFile($file, array($this, 'validateSchema')); + } catch (\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); } - $this->validate($dom, $file); + $this->validateExtensions($dom, $file); return simplexml_import_dom($dom, 'Symfony\\Component\\DependencyInjection\\SimpleXMLElement'); } @@ -285,28 +270,14 @@ class XmlFileLoader extends FileLoader } } - /** - * Validates an XML document. - * - * @param \DOMDocument $dom - * @param string $file - */ - private function validate(\DOMDocument $dom, $file) - { - $this->validateSchema($dom, $file); - $this->validateExtensions($dom, $file); - } - /** * Validates a documents XML schema. * * @param \DOMDocument $dom - * @param string $file * - * @throws RuntimeException When extension references a non-existent XSD file - * @throws InvalidArgumentException When xml doesn't validate its xsd schema + * @throws RuntimeException When extension references a non-existent XSD file */ - private function validateSchema(\DOMDocument $dom, $file) + public function validateSchema(\DOMDocument $dom) { $schemaLocations = array('http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd')); @@ -360,18 +331,13 @@ $imports EOF ; - $current = libxml_use_internal_errors(true); - libxml_clear_errors(); - $valid = @$dom->schemaValidateSource($source); foreach ($tmpfiles as $tmpfile) { @unlink($tmpfile); } - if (!$valid) { - throw new InvalidArgumentException(implode("\n", $this->getXmlErrors($current))); - } - libxml_use_internal_errors($current); + + return $valid; } /** @@ -403,33 +369,6 @@ EOF } } - /** - * Returns an array of XML errors. - * - * @param Boolean $internalErrors - * - * @return array - */ - private function getXmlErrors($internalErrors) - { - $errors = array(); - foreach (libxml_get_errors() as $error) { - $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', - LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', - $error->code, - trim($error->message), - $error->file ? $error->file : 'n/a', - $error->line, - $error->column - ); - } - - libxml_clear_errors(); - libxml_use_internal_errors($internalErrors); - - return $errors; - } - /** * Loads from an extension. * @@ -472,50 +411,6 @@ EOF */ public static function convertDomElementToArray(\DomElement $element) { - $empty = true; - $config = array(); - foreach ($element->attributes as $name => $node) { - $config[$name] = SimpleXMLElement::phpize($node->value); - $empty = false; - } - - $nodeValue = false; - foreach ($element->childNodes as $node) { - if ($node instanceof \DOMText) { - if (trim($node->nodeValue)) { - $nodeValue = trim($node->nodeValue); - $empty = false; - } - } elseif (!$node instanceof \DOMComment) { - if ($node instanceof \DOMElement && '_services' === $node->nodeName) { - $value = new Reference($node->getAttribute('id')); - } else { - $value = static::convertDomElementToArray($node); - } - - $key = $node->localName; - if (isset($config[$key])) { - if (!is_array($config[$key]) || !is_int(key($config[$key]))) { - $config[$key] = array($config[$key]); - } - $config[$key][] = $value; - } else { - $config[$key] = $value; - } - - $empty = false; - } - } - - if (false !== $nodeValue) { - $value = SimpleXMLElement::phpize($nodeValue); - if (count($config)) { - $config['value'] = $value; - } else { - $config = $value; - } - } - - return !$empty ? $config : null; + return XmlUtils::convertDomElementToArray($element); } } diff --git a/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php b/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php index d154602fd3..cc5e311987 100644 --- a/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php +++ b/src/Symfony/Component/DependencyInjection/SimpleXMLElement.php @@ -11,6 +11,8 @@ namespace Symfony\Component\DependencyInjection; +use Symfony\Component\Config\Util\XmlUtils; + /** * SimpleXMLElement class. * @@ -101,27 +103,6 @@ class SimpleXMLElement extends \SimpleXMLElement */ public static function phpize($value) { - $value = (string) $value; - $lowercaseValue = strtolower($value); - - switch (true) { - case 'null' === $lowercaseValue: - return null; - case ctype_digit($value): - $raw = $value; - $cast = intval($value); - - return '0' == $value[0] ? octdec($value) : (((string) $raw == (string) $cast) ? $cast : $raw); - case 'true' === $lowercaseValue: - return true; - case 'false' === $lowercaseValue: - return false; - case is_numeric($value): - return '0x' == $value[0].$value[1] ? hexdec($value) : floatval($value); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $value): - return floatval(str_replace(',', '', $value)); - default: - return $value; - } + return XmlUtils::phpize($value); } } diff --git a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php index a07c7f80a5..00a6012719 100644 --- a/src/Symfony/Component/Routing/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Routing/Loader/XmlFileLoader.php @@ -15,6 +15,7 @@ use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; use Symfony\Component\Config\Resource\FileResource; use Symfony\Component\Config\Loader\FileLoader; +use Symfony\Component\Config\Util\XmlUtils; /** * XmlFileLoader loads XML routing files. @@ -172,74 +173,7 @@ class XmlFileLoader extends FileLoader */ protected function loadFile($file) { - $internalErrors = libxml_use_internal_errors(true); - $disableEntities = libxml_disable_entity_loader(true); - libxml_clear_errors(); - - $dom = new \DOMDocument(); - $dom->validateOnParse = true; - if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { - libxml_disable_entity_loader($disableEntities); - - throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($internalErrors))); - } - $dom->normalizeDocument(); - - libxml_use_internal_errors($internalErrors); - libxml_disable_entity_loader($disableEntities); - - foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - throw new \InvalidArgumentException('Document types are not allowed.'); - } - } - - $this->validate($dom); - - return $dom; - } - - /** - * Validates a loaded XML file. - * - * @param \DOMDocument $dom A loaded XML file - * - * @throws \InvalidArgumentException When XML doesn't validate its XSD schema - */ - protected function validate(\DOMDocument $dom) - { - $current = libxml_use_internal_errors(true); - libxml_clear_errors(); - - if (!$dom->schemaValidate(__DIR__ . static::SCHEME_PATH)) { - throw new \InvalidArgumentException(implode("\n", $this->getXmlErrors($current))); - } - libxml_use_internal_errors($current); - } - - /** - * Retrieves libxml errors and clears them. - * - * @return array An array of libxml error strings - */ - private function getXmlErrors($internalErrors) - { - $errors = array(); - foreach (libxml_get_errors() as $error) { - $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', - LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', - $error->code, - trim($error->message), - $error->file ? $error->file : 'n/a', - $error->line, - $error->column - ); - } - - libxml_clear_errors(); - libxml_use_internal_errors($internalErrors); - - return $errors; + return XmlUtils::loadFile($file, __DIR__ . static::SCHEME_PATH); } /** diff --git a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php index 4925abb44d..6b25f18817 100644 --- a/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Validator\Mapping\Loader; use Symfony\Component\Validator\Exception\MappingException; use Symfony\Component\Validator\Mapping\ClassMetadata; +use Symfony\Component\Config\Util\XmlUtils; class XmlFileLoader extends FileLoader { @@ -185,54 +186,12 @@ class XmlFileLoader extends FileLoader */ protected function parseFile($file) { - $internalErrors = libxml_use_internal_errors(true); - $disableEntities = libxml_disable_entity_loader(true); - libxml_clear_errors(); - - $dom = new \DOMDocument(); - $dom->validateOnParse = true; - if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) { - libxml_disable_entity_loader($disableEntities); - - throw new MappingException(implode("\n", $this->getXmlErrors($internalErrors))); - } - - libxml_disable_entity_loader($disableEntities); - - if (!$dom->schemaValidate(__DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd')) { - throw new MappingException(implode("\n", $this->getXmlErrors($internalErrors))); - } - - $dom->normalizeDocument(); - - libxml_use_internal_errors($internalErrors); - - foreach ($dom->childNodes as $child) { - if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) { - throw new MappingException('Document types are not allowed.'); - } + try { + $dom = XmlUtils::loadFile($file, __DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd'); + } catch (\Exception $e) { + throw new MappingException($e->getMessage(), $e->getCode(), $e); } return simplexml_import_dom($dom); } - - protected function getXmlErrors($internalErrors) - { - $errors = array(); - foreach (libxml_get_errors() as $error) { - $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)', - LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR', - $error->code, - trim($error->message), - $error->file ? $error->file : 'n/a', - $error->line, - $error->column - ); - } - - libxml_clear_errors(); - libxml_use_internal_errors($internalErrors); - - return $errors; - } } diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index a52d33bb21..e3cb106914 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -21,12 +21,14 @@ "require-dev": { "symfony/http-foundation": "2.2.*", "symfony/locale": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" }, "suggest": { "doctrine/common": ">=2.1,<2.4-dev", "symfony/http-foundation": "2.2.*", - "symfony/yaml": "2.2.*" + "symfony/yaml": "2.2.*", + "symfony/config": "2.2.*" }, "autoload": { "psr-0": { "Symfony\\Component\\Validator\\": "" }