annotate core/lib/Drupal/Component/Serialization/YamlPecl.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Component\Serialization;
Chris@0 4
Chris@0 5 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Provides default serialization for YAML using the PECL extension.
Chris@0 9 */
Chris@0 10 class YamlPecl implements SerializationInterface {
Chris@0 11
Chris@0 12 /**
Chris@0 13 * {@inheritdoc}
Chris@0 14 */
Chris@0 15 public static function encode($data) {
Chris@0 16 static $init;
Chris@0 17 if (!isset($init)) {
Chris@0 18 ini_set('yaml.output_indent', 2);
Chris@0 19 // Do not break lines at 80 characters.
Chris@0 20 ini_set('yaml.output_width', -1);
Chris@0 21 $init = TRUE;
Chris@0 22 }
Chris@0 23 return yaml_emit($data, YAML_UTF8_ENCODING, YAML_LN_BREAK);
Chris@0 24 }
Chris@0 25
Chris@0 26 /**
Chris@0 27 * {@inheritdoc}
Chris@0 28 */
Chris@0 29 public static function decode($raw) {
Chris@0 30 static $init;
Chris@0 31 if (!isset($init)) {
Chris@0 32 // Decode binary, since Symfony YAML parser encodes binary from 3.1
Chris@0 33 // onwards.
Chris@0 34 ini_set('yaml.decode_binary', 1);
Chris@0 35 // We never want to unserialize !php/object.
Chris@0 36 ini_set('yaml.decode_php', 0);
Chris@0 37 $init = TRUE;
Chris@0 38 }
Chris@0 39 // yaml_parse() will error with an empty value.
Chris@0 40 if (!trim($raw)) {
Chris@0 41 return NULL;
Chris@0 42 }
Chris@0 43 // @todo Use ErrorExceptions when https://drupal.org/node/1247666 is in.
Chris@0 44 // yaml_parse() will throw errors instead of raising an exception. Until
Chris@0 45 // such time as Drupal supports native PHP ErrorExceptions as the error
Chris@0 46 // handler, we need to temporarily set the error handler as ::errorHandler()
Chris@0 47 // and then restore it after decoding has occurred. This allows us to turn
Chris@0 48 // parsing errors into a throwable exception.
Chris@0 49 // @see Drupal\Component\Serialization\Exception\InvalidDataTypeException
Chris@14 50 // @see http://php.net/manual/class.errorexception.php
Chris@0 51 set_error_handler([__CLASS__, 'errorHandler']);
Chris@0 52 $ndocs = 0;
Chris@0 53 $data = yaml_parse($raw, 0, $ndocs, [
Chris@0 54 YAML_BOOL_TAG => '\Drupal\Component\Serialization\YamlPecl::applyBooleanCallbacks',
Chris@0 55 ]);
Chris@0 56 restore_error_handler();
Chris@0 57 return $data;
Chris@0 58 }
Chris@0 59
Chris@0 60 /**
Chris@0 61 * Handles errors for \Drupal\Component\Serialization\YamlPecl::decode().
Chris@0 62 *
Chris@0 63 * @param int $severity
Chris@0 64 * The severity level of the error.
Chris@0 65 * @param string $message
Chris@0 66 * The error message to display.
Chris@0 67 *
Chris@0 68 * @see \Drupal\Component\Serialization\YamlPecl::decode()
Chris@0 69 */
Chris@0 70 public static function errorHandler($severity, $message) {
Chris@0 71 restore_error_handler();
Chris@0 72 throw new InvalidDataTypeException($message, $severity);
Chris@0 73 }
Chris@0 74
Chris@0 75 /**
Chris@0 76 * {@inheritdoc}
Chris@0 77 */
Chris@0 78 public static function getFileExtension() {
Chris@0 79 return 'yml';
Chris@0 80 }
Chris@0 81
Chris@0 82 /**
Chris@0 83 * Applies callbacks after parsing to ignore 1.1 style booleans.
Chris@0 84 *
Chris@0 85 * @param mixed $value
Chris@0 86 * Value from YAML file.
Chris@0 87 * @param string $tag
Chris@0 88 * Tag that triggered the callback.
Chris@0 89 * @param int $flags
Chris@0 90 * Scalar entity style flags.
Chris@0 91 *
Chris@0 92 * @return string|bool
Chris@0 93 * FALSE, false, TRUE and true are returned as booleans, everything else is
Chris@0 94 * returned as a string.
Chris@0 95 */
Chris@0 96 public static function applyBooleanCallbacks($value, $tag, $flags) {
Chris@0 97 // YAML 1.1 spec dictates that 'Y', 'N', 'y' and 'n' are booleans. But, we
Chris@0 98 // want the 1.2 behavior, so we only consider 'false', 'FALSE', 'true' and
Chris@0 99 // 'TRUE' as booleans.
Chris@0 100 if (!in_array(strtolower($value), ['false', 'true'], TRUE)) {
Chris@0 101 return $value;
Chris@0 102 }
Chris@0 103 $map = [
Chris@0 104 'false' => FALSE,
Chris@0 105 'true' => TRUE,
Chris@0 106 ];
Chris@0 107 return $map[strtolower($value)];
Chris@0 108 }
Chris@0 109
Chris@0 110 }