123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- <?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/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)];
- }
- }
|