MODX Revolution PHP Cross Reference Content Management Systems

Source: /core/model/aws/lib/yaml/lib/sfYamlInline.php - 442 lines - 11514 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /*
   4   * This file is part of the symfony package.
   5   * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  require_once dirname(__FILE__).'/sfYaml.php';
  12  
  13  /**
  14   * sfYamlInline implements a YAML parser/dumper for the YAML inline syntax.
  15   *
  16   * @package    symfony
  17   * @subpackage yaml
  18   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  19   * @version    SVN: $Id: sfYamlInline.class.php 16177 2009-03-11 08:32:48Z fabien $
  20   */
  21  class sfYamlInline
  22  {
  23    const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
  24  
  25    /**
  26     * Convert a YAML string to a PHP array.
  27     *
  28     * @param string $value A YAML string
  29     *
  30     * @return array A PHP array representing the YAML string
  31     */
  32    static public function load($value)
  33    {
  34      $value = trim($value);
  35  
  36      if (0 == strlen($value))
  37      {
  38        return '';
  39      }
  40  
  41      if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
  42      {
  43        $mbEncoding = mb_internal_encoding();
  44        mb_internal_encoding('ASCII');
  45      }
  46  
  47      switch ($value[0])
  48      {
  49        case '[':
  50          $result = self::parseSequence($value);
  51          break;
  52        case '{':
  53          $result = self::parseMapping($value);
  54          break;
  55        default:
  56          $result = self::parseScalar($value);
  57      }
  58  
  59      if (isset($mbEncoding))
  60      {
  61        mb_internal_encoding($mbEncoding);
  62      }
  63  
  64      return $result;
  65    }
  66  
  67    /**
  68     * Dumps a given PHP variable to a YAML string.
  69     *
  70     * @param mixed $value The PHP variable to convert
  71     *
  72     * @return string The YAML string representing the PHP array
  73     */
  74    static public function dump($value)
  75    {
  76      if ('1.1' === sfYaml::getSpecVersion())
  77      {
  78        $trueValues = array('true', 'on', '+', 'yes', 'y');
  79        $falseValues = array('false', 'off', '-', 'no', 'n');
  80      }
  81      else
  82      {
  83        $trueValues = array('true');
  84        $falseValues = array('false');
  85      }
  86  
  87      switch (true)
  88      {
  89        case is_resource($value):
  90          throw new InvalidArgumentException('Unable to dump PHP resources in a YAML file.');
  91        case is_object($value):
  92          return '!!php/object:'.serialize($value);
  93        case is_array($value):
  94          return self::dumpArray($value);
  95        case null === $value:
  96          return 'null';
  97        case true === $value:
  98          return 'true';
  99        case false === $value:
 100          return 'false';
 101        case ctype_digit($value):
 102          return is_string($value) ? "'$value'" : (int) $value;
 103        case is_numeric($value):
 104          return is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : (is_string($value) ? "'$value'" : $value);
 105        case false !== strpos($value, "\n") || false !== strpos($value, "\r"):
 106          return sprintf('"%s"', str_replace(array('"', "\n", "\r"), array('\\"', '\n', '\r'), $value));
 107        case preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value):
 108          return sprintf("'%s'", str_replace('\'', '\'\'', $value));
 109        case '' == $value:
 110          return "''";
 111        case preg_match(self::getTimestampRegex(), $value):
 112          return "'$value'";
 113        case in_array(strtolower($value), $trueValues):
 114          return "'$value'";
 115        case in_array(strtolower($value), $falseValues):
 116          return "'$value'";
 117        case in_array(strtolower($value), array('null', '~')):
 118          return "'$value'";
 119        default:
 120          return $value;
 121      }
 122    }
 123  
 124    /**
 125     * Dumps a PHP array to a YAML string.
 126     *
 127     * @param array $value The PHP array to dump
 128     *
 129     * @return string The YAML string representing the PHP array
 130     */
 131    static protected function dumpArray($value)
 132    {
 133      // array
 134      $keys = array_keys($value);
 135      if (
 136        (1 == count($keys) && '0' == $keys[0])
 137        ||
 138        (count($keys) > 1 && array_reduce($keys, create_function('$v,$w', 'return (integer) $v + $w;'), 0) == count($keys) * (count($keys) - 1) / 2))
 139      {
 140        $output = array();
 141        foreach ($value as $val)
 142        {
 143          $output[] = self::dump($val);
 144        }
 145  
 146        return sprintf('[%s]', implode(', ', $output));
 147      }
 148  
 149      // mapping
 150      $output = array();
 151      foreach ($value as $key => $val)
 152      {
 153        $output[] = sprintf('%s: %s', self::dump($key), self::dump($val));
 154      }
 155  
 156      return sprintf('{ %s }', implode(', ', $output));
 157    }
 158  
 159    /**
 160     * Parses a scalar to a YAML string.
 161     *
 162     * @param scalar  $scalar
 163     * @param string  $delimiters
 164     * @param array   $stringDelimiter
 165     * @param integer $i
 166     * @param boolean $evaluate
 167     *
 168     * @return string A YAML string
 169     */
 170    static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
 171    {
 172      if (in_array($scalar[$i], $stringDelimiters))
 173      {
 174        // quoted scalar
 175        $output = self::parseQuotedScalar($scalar, $i);
 176      }
 177      else
 178      {
 179        // "normal" string
 180        if (!$delimiters)
 181        {
 182          $output = substr($scalar, $i);
 183          $i += strlen($output);
 184  
 185          // remove comments
 186          if (false !== $strpos = strpos($output, ' #'))
 187          {
 188            $output = rtrim(substr($output, 0, $strpos));
 189          }
 190        }
 191        else if (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match))
 192        {
 193          $output = $match[1];
 194          $i += strlen($output);
 195        }
 196        else
 197        {
 198          throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', $scalar));
 199        }
 200  
 201        $output = $evaluate ? self::evaluateScalar($output) : $output;
 202      }
 203  
 204      return $output;
 205    }
 206  
 207    /**
 208     * Parses a quoted scalar to YAML.
 209     *
 210     * @param string  $scalar
 211     * @param integer $i
 212     *
 213     * @return string A YAML string
 214     */
 215    static protected function parseQuotedScalar($scalar, &$i)
 216    {
 217      if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/A', substr($scalar, $i), $match))
 218      {
 219        throw new InvalidArgumentException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
 220      }
 221  
 222      $output = substr($match[0], 1, strlen($match[0]) - 2);
 223  
 224      if ('"' == $scalar[$i])
 225      {
 226        // evaluate the string
 227        $output = str_replace(array('\\"', '\\n', '\\r'), array('"', "\n", "\r"), $output);
 228      }
 229      else
 230      {
 231        // unescape '
 232        $output = str_replace('\'\'', '\'', $output);
 233      }
 234  
 235      $i += strlen($match[0]);
 236  
 237      return $output;
 238    }
 239  
 240    /**
 241     * Parses a sequence to a YAML string.
 242     *
 243     * @param string  $sequence
 244     * @param integer $i
 245     *
 246     * @return string A YAML string
 247     */
 248    static protected function parseSequence($sequence, &$i = 0)
 249    {
 250      $output = array();
 251      $len = strlen($sequence);
 252      $i += 1;
 253  
 254      // [foo, bar, ...]
 255      while ($i < $len)
 256      {
 257        switch ($sequence[$i])
 258        {
 259          case '[':
 260            // nested sequence
 261            $output[] = self::parseSequence($sequence, $i);
 262            break;
 263          case '{':
 264            // nested mapping
 265            $output[] = self::parseMapping($sequence, $i);
 266            break;
 267          case ']':
 268            return $output;
 269          case ',':
 270          case ' ':
 271            break;
 272          default:
 273            $isQuoted = in_array($sequence[$i], array('"', "'"));
 274            $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
 275  
 276            if (!$isQuoted && false !== strpos($value, ': '))
 277            {
 278              // embedded mapping?
 279              try
 280              {
 281                $value = self::parseMapping('{'.$value.'}');
 282              }
 283              catch (InvalidArgumentException $e)
 284              {
 285                // no, it's not
 286              }
 287            }
 288  
 289            $output[] = $value;
 290  
 291            --$i;
 292        }
 293  
 294        ++$i;
 295      }
 296  
 297      throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $sequence));
 298    }
 299  
 300    /**
 301     * Parses a mapping to a YAML string.
 302     *
 303     * @param string  $mapping
 304     * @param integer $i
 305     *
 306     * @return string A YAML string
 307     */
 308    static protected function parseMapping($mapping, &$i = 0)
 309    {
 310      $output = array();
 311      $len = strlen($mapping);
 312      $i += 1;
 313  
 314      // {foo: bar, bar:foo, ...}
 315      while ($i < $len)
 316      {
 317        switch ($mapping[$i])
 318        {
 319          case ' ':
 320          case ',':
 321            ++$i;
 322            continue 2;
 323          case '}':
 324            return $output;
 325        }
 326  
 327        // key
 328        $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
 329  
 330        // value
 331        $done = false;
 332        while ($i < $len)
 333        {
 334          switch ($mapping[$i])
 335          {
 336            case '[':
 337              // nested sequence
 338              $output[$key] = self::parseSequence($mapping, $i);
 339              $done = true;
 340              break;
 341            case '{':
 342              // nested mapping
 343              $output[$key] = self::parseMapping($mapping, $i);
 344              $done = true;
 345              break;
 346            case ':':
 347            case ' ':
 348              break;
 349            default:
 350              $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
 351              $done = true;
 352              --$i;
 353          }
 354  
 355          ++$i;
 356  
 357          if ($done)
 358          {
 359            continue 2;
 360          }
 361        }
 362      }
 363  
 364      throw new InvalidArgumentException(sprintf('Malformed inline YAML string %s', $mapping));
 365    }
 366  
 367    /**
 368     * Evaluates scalars and replaces magic values.
 369     *
 370     * @param string $scalar
 371     *
 372     * @return string A YAML string
 373     */
 374    static protected function evaluateScalar($scalar)
 375    {
 376      $scalar = trim($scalar);
 377  
 378      if ('1.1' === sfYaml::getSpecVersion())
 379      {
 380        $trueValues = array('true', 'on', '+', 'yes', 'y');
 381        $falseValues = array('false', 'off', '-', 'no', 'n');
 382      }
 383      else
 384      {
 385        $trueValues = array('true');
 386        $falseValues = array('false');
 387      }
 388  
 389      switch (true)
 390      {
 391        case 'null' == strtolower($scalar):
 392        case '' == $scalar:
 393        case '~' == $scalar:
 394          return null;
 395        case 0 === strpos($scalar, '!str'):
 396          return (string) substr($scalar, 5);
 397        case 0 === strpos($scalar, '! '):
 398          return intval(self::parseScalar(substr($scalar, 2)));
 399        case 0 === strpos($scalar, '!!php/object:'):
 400          return unserialize(substr($scalar, 13));
 401        case ctype_digit($scalar):
 402          $raw = $scalar;
 403          $cast = intval($scalar);
 404          return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
 405        case in_array(strtolower($scalar), $trueValues):
 406          return true;
 407        case in_array(strtolower($scalar), $falseValues):
 408          return false;
 409        case is_numeric($scalar):
 410          return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
 411        case 0 == strcasecmp($scalar, '.inf'):
 412        case 0 == strcasecmp($scalar, '.NaN'):
 413          return -log(0);
 414        case 0 == strcasecmp($scalar, '-.inf'):
 415          return log(0);
 416        case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
 417          return floatval(str_replace(',', '', $scalar));
 418        case preg_match(self::getTimestampRegex(), $scalar):
 419          return strtotime($scalar);
 420        default:
 421          return (string) $scalar;
 422      }
 423    }
 424  
 425    static protected function getTimestampRegex()
 426    {
 427      return <<<EOF
 428      ~^
 429      (?P<year>[0-9][0-9][0-9][0-9])
 430      -(?P<month>[0-9][0-9]?)
 431      -(?P<day>[0-9][0-9]?)
 432      (?:(?:[Tt]|[ \t]+)
 433      (?P<hour>[0-9][0-9]?)
 434      :(?P<minute>[0-9][0-9])
 435      :(?P<second>[0-9][0-9])
 436      (?:\.(?P<fraction>[0-9]*))?
 437      (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
 438      (?::(?P<tz_minute>[0-9][0-9]))?))?)?
 439      $~x
 440  EOF;
 441    }
 442  }

title

Description

title

Description

title

Description

title

title

Body