Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Component/Serialization/YamlPecl.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 1fec387a4317 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Component/Serialization/YamlPecl.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,110 @@ +<?php + +namespace Drupal\Component\Serialization; + +use Drupal\Component\Serialization\Exception\InvalidDataTypeException; + +/** + * Provides default serialization for YAML using the PECL extension. + */ +class YamlPecl implements SerializationInterface { + + /** + * {@inheritdoc} + */ + public static function encode($data) { + static $init; + if (!isset($init)) { + ini_set('yaml.output_indent', 2); + // Do not break lines at 80 characters. + ini_set('yaml.output_width', -1); + $init = TRUE; + } + return yaml_emit($data, YAML_UTF8_ENCODING, YAML_LN_BREAK); + } + + /** + * {@inheritdoc} + */ + public static function decode($raw) { + static $init; + if (!isset($init)) { + // Decode binary, since Symfony YAML parser encodes binary from 3.1 + // onwards. + ini_set('yaml.decode_binary', 1); + // We never want to unserialize !php/object. + ini_set('yaml.decode_php', 0); + $init = TRUE; + } + // yaml_parse() will error with an empty value. + if (!trim($raw)) { + return NULL; + } + // @todo Use ErrorExceptions when https://drupal.org/node/1247666 is in. + // yaml_parse() will throw errors instead of raising an exception. Until + // such time as Drupal supports native PHP ErrorExceptions as the error + // handler, we need to temporarily set the error handler as ::errorHandler() + // and then restore it after decoding has occurred. This allows us to turn + // parsing errors into a throwable exception. + // @see Drupal\Component\Serialization\Exception\InvalidDataTypeException + // @see http://php.net/manual/en/class.errorexception.php + set_error_handler([__CLASS__, 'errorHandler']); + $ndocs = 0; + $data = yaml_parse($raw, 0, $ndocs, [ + YAML_BOOL_TAG => '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks', + ]); + restore_error_handler(); + return $data; + } + + /** + * Handles errors for \Drupal\Component\Serialization\YamlPecl::decode(). + * + * @param int $severity + * The severity level of the error. + * @param string $message + * The error message to display. + * + * @see \Drupal\Component\Serialization\YamlPecl::decode() + */ + public static function errorHandler($severity, $message) { + restore_error_handler(); + throw new InvalidDataTypeException($message, $severity); + } + + /** + * {@inheritdoc} + */ + public static function getFileExtension() { + return 'yml'; + } + + /** + * Applies callbacks after parsing to ignore 1.1 style booleans. + * + * @param mixed $value + * Value from YAML file. + * @param string $tag + * Tag that triggered the callback. + * @param int $flags + * Scalar entity style flags. + * + * @return string|bool + * FALSE, false, TRUE and true are returned as booleans, everything else is + * returned as a string. + */ + public static function applyBooleanCallbacks($value, $tag, $flags) { + // YAML 1.1 spec dictates that 'Y', 'N', 'y' and 'n' are booleans. But, we + // want the 1.2 behavior, so we only consider 'false', 'FALSE', 'true' and + // 'TRUE' as booleans. + if (!in_array(strtolower($value), ['false', 'true'], TRUE)) { + return $value; + } + $map = [ + 'false' => FALSE, + 'true' => TRUE, + ]; + return $map[strtolower($value)]; + } + +}