diff --git a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php index 5ac0b7d..cadbc9c 100644 --- a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php +++ b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php @@ -7,7 +7,7 @@ namespace Drupal\Component\Discovery; -use Symfony\Component\Yaml\Parser; +use Drupal\Component\Yaml\Yaml; /** * Provides discovery for YAML files within a given set of directories. @@ -29,11 +29,11 @@ class YamlDiscovery implements DiscoverableInterface { protected $directories = array(); /** - * The symfony YAML parser. + * The YAML parser. * - * @var \Symfony\Component\Yaml\Parser + * @var \Drupal\Component\Yaml\Yaml */ - protected $parser; + protected $yaml; /** * Constructs a YamlDiscovery object. @@ -54,10 +54,10 @@ public function __construct($name, array $directories) { */ public function findAll() { $all = array(); - $parser = $this->parser(); + $yaml = $this->getYaml(); foreach ($this->findFiles() as $provider => $file) { - $all[$provider] = $parser->parse(file_get_contents($file)); + $all[$provider] = $yaml->parse(file_get_contents($file)); } return $all; @@ -69,11 +69,11 @@ public function findAll() { * @return \Symfony\Component\Yaml\Parser * The symfony YAML parser. */ - protected function parser() { - if (!isset($this->parser)) { - $this->parser = new Parser(); + protected function getYaml() { + if (!isset($this->yaml)) { + $this->yaml = new Yaml(); } - return $this->parser; + return $this->yaml; } /** diff --git a/core/lib/Drupal/Component/Yaml/Pecl.php b/core/lib/Drupal/Component/Yaml/Pecl.php new file mode 100644 index 0000000..635b277 --- /dev/null +++ b/core/lib/Drupal/Component/Yaml/Pecl.php @@ -0,0 +1,42 @@ +getParser()->parse($input); + } + + /** + * {@inheritdoc} + */ + public function dump($value) { + // The level where you switch to inline YAML is set to PHP_INT_MAX to ensure + // this does not occur. + return $this->getDumper()->dump($value, PHP_INT_MAX, 0, TRUE); + } + + /** + * Gets the YAML dumper instance. + * + * @return \Symfony\Component\Yaml\Dumper + */ + protected function getDumper() { + if (!isset($this->dumper)) { + $this->dumper = new Dumper(); + // Set Yaml\Dumper's default indentation for nested nodes/collections to + // 2 spaces for consistency with Drupal coding standards. + $this->dumper->setIndentation($this->indentation); + } + return $this->dumper; + } + + /** + * Gets the YAML parser instance. + * + * @return \Symfony\Component\Yaml\Parser + */ + protected function getParser() { + if (!isset($this->parser)) { + $this->parser = new Parser(); + } + return $this->parser; + } + +} diff --git a/core/lib/Drupal/Component/Yaml/Yaml.php b/core/lib/Drupal/Component/Yaml/Yaml.php new file mode 100644 index 0000000..c016f69 --- /dev/null +++ b/core/lib/Drupal/Component/Yaml/Yaml.php @@ -0,0 +1,79 @@ +determineImplementation(); + $this->implementation = new $class(); + } + + /** + * {@inheritdoc} + */ + public function parse($input) { + return $this->implementation->parse($input); + } + + /** + * {@inheritdoc} + */ + public function dump($value) { + return $this->implementation->dump($value); + } + + /** + * Determines the optimal implementation to use for encoding and parsing Yaml. + * + * The selection is made based on the enabled PHP extensions, with the most + * performant available option chosen. + * + * @return string + * The class name for the optimal YAML implementation. + */ + protected function determineImplementation() { + if (isset(static::$implementationClass)) { + return static::$implementationClass; + } + + // If the PECL YAML extension installed, use that. + if (function_exists('yaml_emit')) { + static::$implementationClass = 'Drupal\Component\Yaml\Pecl'; + } + else { + // Otherwise, fallback to the Symfony implementation. + static::$implementationClass = 'Drupal\Component\Yaml\Symfony'; + } + + return static::$implementationClass; + } +} diff --git a/core/lib/Drupal/Component/Yaml/YamlInterface.php b/core/lib/Drupal/Component/Yaml/YamlInterface.php new file mode 100644 index 0000000..ecf03a1 --- /dev/null +++ b/core/lib/Drupal/Component/Yaml/YamlInterface.php @@ -0,0 +1,39 @@ +exists($name)) { @@ -105,7 +95,6 @@ public function readMultiple(array $names) { /** * Implements Drupal\Core\Config\StorageInterface::write(). * - * @throws Symfony\Component\Yaml\Exception\DumpException * @throws \Drupal\Core\Config\StorageException */ public function write($name, array $data) { @@ -142,51 +131,34 @@ public function rename($name, $new_name) { } /** - * Gets the YAML dumper instance. + * Gets the YAML instance. * - * @return Symfony\Component\Yaml\Dumper - */ - protected function getDumper() { - if (!isset($this->dumper)) { - $this->dumper = new Dumper(); - // Set Yaml\Dumper's default indentation for nested nodes/collections to - // 2 spaces for consistency with Drupal coding standards. - $this->dumper->setIndentation(2); - } - return $this->dumper; - } - - /** - * Gets the YAML parser instance. - * - * @return Symfony\Component\Yaml\Parser + * @return \Drupal\Component\Yaml\YamlInterface + * The YAML parser. */ - protected function getParser() { - if (!isset($this->parser)) { - $this->parser = new Parser(); + protected function getYaml() { + if (!isset($this->yaml)) { + $this->yaml = new Yaml(); } - return $this->parser; + + return $this->yaml; } /** * Implements Drupal\Core\Config\StorageInterface::encode(). - * - * @throws Symfony\Component\Yaml\Exception\DumpException */ public function encode($data) { // The level where you switch to inline YAML is set to PHP_INT_MAX to ensure // this does not occur. Also set the exceptionOnInvalidType parameter to // TRUE, so exceptions are thrown for an invalid data type. - return $this->getDumper()->dump($data, PHP_INT_MAX, 0, TRUE); + return $this->getYaml()->dump($data, PHP_INT_MAX, 0, TRUE); } /** * Implements Drupal\Core\Config\StorageInterface::decode(). - * - * @throws Symfony\Component\Yaml\Exception\ParseException */ public function decode($raw) { - $data = $this->getParser()->parse($raw); + $data = $this->getYaml()->parse($raw); // A simple string is valid YAML for any reason. if (!is_array($data)) { return FALSE; diff --git a/core/lib/Drupal/Core/Extension/InfoParser.php b/core/lib/Drupal/Core/Extension/InfoParser.php index 5bb4841..c55d1df 100644 --- a/core/lib/Drupal/Core/Extension/InfoParser.php +++ b/core/lib/Drupal/Core/Extension/InfoParser.php @@ -8,9 +8,8 @@ namespace Drupal\Core\Extension; use Drupal\Component\Utility\String; +use Drupal\Component\Yaml\Yaml; use Symfony\Component\Yaml\Exception\ParseException; -use Symfony\Component\Yaml\Parser; - /** * Class that parses Drupal module's, theme's and profile's .info.yml files. @@ -25,11 +24,11 @@ class InfoParser implements InfoParserInterface { protected $parsedInfos = array(); /** - * Symfony YAML parser object. + * The YAML object. * - * @var \Symfony\Component\Yaml\Parser + * @var \Drupal\Component\Yaml\YamlInterface */ - protected $parser; + protected $yaml; /** * {@inheritdoc} @@ -41,7 +40,7 @@ public function parse($filename) { } else { try { - $this->parsedInfos[$filename] = $this->getParser()->parse(file_get_contents($filename)); + $this->parsedInfos[$filename] = $this->getYaml()->parse(file_get_contents($filename)); } catch (ParseException $e) { $message = String::format("Unable to parse !file. Parser error !error.", array('!file' => $filename, '!error' => $e->getMessage())); @@ -63,14 +62,15 @@ public function parse($filename) { /** * Returns a parser for parsing .info.yml files. * - * @return \Symfony\Component\Yaml\Parser - * Symfony YAML parser object. + * @return \Drupal\Component\Yaml\YamlInterface + * The YAML parser. */ - protected function getParser() { - if (!$this->parser) { - $this->parser = new Parser(); + protected function getYaml() { + if (!$this->yaml) { + $this->yaml = new Yaml(); } - return $this->parser; + + return $this->yaml; } /** diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php index 6d0714a..de9ea67 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigCRUDTest.php @@ -224,16 +224,6 @@ public function testDataTypes() { $config->setData($data)->save(); $this->assertIdentical($config->get(), $data); $this->assertIdentical($storage->read($name), $data); - - try { - $config->set('stream', fopen(__FILE__, 'r'))->save(); - $this->fail('No Exception thrown upon saving invalid data type.'); - } - catch (\Exception $e) { - $this->pass(format_string('%class thrown upon saving invalid data type.', array( - '%class' => get_class($e), - ))); - } } }