<?php

namespace WPForms\Vendor;

/**
 * Parses string representations into their corresponding native PHP
 * variable type. The base implementation does a simple type-check.
 */
class HTMLPurifier_VarParser
{
    const C_STRING = 1;
    const ISTRING = 2;
    const TEXT = 3;
    const ITEXT = 4;
    const C_INT = 5;
    const C_FLOAT = 6;
    const C_BOOL = 7;
    const LOOKUP = 8;
    const ALIST = 9;
    const HASH = 10;
    const C_MIXED = 11;
    /**
     * Lookup table of allowed types. Mainly for backwards compatibility, but
     * also convenient for transforming string type names to the integer constants.
     */
    public static $types = array('string' => self::C_STRING, 'istring' => self::ISTRING, 'text' => self::TEXT, 'itext' => self::ITEXT, 'int' => self::C_INT, 'float' => self::C_FLOAT, 'bool' => self::C_BOOL, 'lookup' => self::LOOKUP, 'list' => self::ALIST, 'hash' => self::HASH, 'mixed' => self::C_MIXED);
    /**
     * Lookup table of types that are string, and can have aliases or
     * allowed value lists.
     */
    public static $stringTypes = array(self::C_STRING => \true, self::ISTRING => \true, self::TEXT => \true, self::ITEXT => \true);
    /**
     * Validate a variable according to type.
     * It may return NULL as a valid type if $allow_null is true.
     *
     * @param mixed $var Variable to validate
     * @param int $type Type of variable, see HTMLPurifier_VarParser->types
     * @param bool $allow_null Whether or not to permit null as a value
     * @return string Validated and type-coerced variable
     * @throws HTMLPurifier_VarParserException
     */
    public final function parse($var, $type, $allow_null = \false)
    {
        if (\is_string($type)) {
            if (!isset(HTMLPurifier_VarParser::$types[$type])) {
                throw new HTMLPurifier_VarParserException("Invalid type '{$type}'");
            } else {
                $type = HTMLPurifier_VarParser::$types[$type];
            }
        }
        $var = $this->parseImplementation($var, $type, $allow_null);
        if ($allow_null && $var === null) {
            return null;
        }
        // These are basic checks, to make sure nothing horribly wrong
        // happened in our implementations.
        switch ($type) {
            case self::C_STRING:
            case self::ISTRING:
            case self::TEXT:
            case self::ITEXT:
                if (!\is_string($var)) {
                    break;
                }
                if ($type == self::ISTRING || $type == self::ITEXT) {
                    $var = \strtolower($var);
                }
                return $var;
            case self::C_INT:
                if (!\is_int($var)) {
                    break;
                }
                return $var;
            case self::C_FLOAT:
                if (!\is_float($var)) {
                    break;
                }
                return $var;
            case self::C_BOOL:
                if (!\is_bool($var)) {
                    break;
                }
                return $var;
            case self::LOOKUP:
            case self::ALIST:
            case self::HASH:
                if (!\is_array($var)) {
                    break;
                }
                if ($type === self::LOOKUP) {
                    foreach ($var as $k) {
                        if ($k !== \true) {
                            $this->error('Lookup table contains value other than true');
                        }
                    }
                } elseif ($type === self::ALIST) {
                    $keys = \array_keys($var);
                    if (\array_keys($keys) !== $keys) {
                        $this->error('Indices for list are not uniform');
                    }
                }
                return $var;
            case self::C_MIXED:
                return $var;
            default:
                $this->errorInconsistent(\get_class($this), $type);
        }
        $this->errorGeneric($var, $type);
    }
    /**
     * Actually implements the parsing. Base implementation does not
     * do anything to $var. Subclasses should overload this!
     * @param mixed $var
     * @param int $type
     * @param bool $allow_null
     * @return string
     */
    protected function parseImplementation($var, $type, $allow_null)
    {
        return $var;
    }
    /**
     * Throws an exception.
     * @throws HTMLPurifier_VarParserException
     */
    protected function error($msg)
    {
        throw new HTMLPurifier_VarParserException($msg);
    }
    /**
     * Throws an inconsistency exception.
     * @note This should not ever be called. It would be called if we
     *       extend the allowed values of HTMLPurifier_VarParser without
     *       updating subclasses.
     * @param string $class
     * @param int $type
     * @throws HTMLPurifier_Exception
     */
    protected function errorInconsistent($class, $type)
    {
        throw new HTMLPurifier_Exception("Inconsistency in {$class}: " . HTMLPurifier_VarParser::getTypeName($type) . " not implemented");
    }
    /**
     * Generic error for if a type didn't work.
     * @param mixed $var
     * @param int $type
     */
    protected function errorGeneric($var, $type)
    {
        $vtype = \gettype($var);
        $this->error("Expected type " . HTMLPurifier_VarParser::getTypeName($type) . ", got {$vtype}");
    }
    /**
     * @param int $type
     * @return string
     */
    public static function getTypeName($type)
    {
        static $lookup;
        if (!$lookup) {
            // Lazy load the alternative lookup table
            $lookup = \array_flip(HTMLPurifier_VarParser::$types);
        }
        if (!isset($lookup[$type])) {
            return 'unknown';
        }
        return $lookup[$type];
    }
}
// vim: et sw=4 sts=4
