/home/kueuepay/public_html/vendor/laravel/serializable-closure/src/Support/ReflectionClosure.php
<?php

namespace Laravel\SerializableClosure\Support;

defined('T_NAME_QUALIFIED') || define('T_NAME_QUALIFIED', -4);
defined('T_NAME_FULLY_QUALIFIED') || define('T_NAME_FULLY_QUALIFIED', -5);
defined('T_FN') || define('T_FN', -6);
defined('T_NULLSAFE_OBJECT_OPERATOR') || define('T_NULLSAFE_OBJECT_OPERATOR', -7);

use Closure;
use ReflectionFunction;

class ReflectionClosure extends ReflectionFunction
{
    protected $code;
    protected $tokens;
    protected $hashedName;
    protected $useVariables;
    protected $isStaticClosure;
    protected $isScopeRequired;
    protected $isBindingRequired;
    protected $isShortClosure;

    protected static $files = [];
    protected static $classes = [];
    protected static $functions = [];
    protected static $constants = [];
    protected static $structures = [];

    /**
     * Creates a new reflection closure instance.
     *
     * @param  \Closure  $closure
     * @param  string|null  $code
     * @return void
     */
    public function __construct(Closure $closure, $code = null)
    {
        parent::__construct($closure);
    }

    /**
     * Checks if the closure is "static".
     *
     * @return bool
     */
    public function isStatic(): bool
    {
        if ($this->isStaticClosure === null) {
            $this->isStaticClosure = strtolower(substr($this->getCode(), 0, 6)) === 'static';
        }

        return $this->isStaticClosure;
    }

    /**
     * Checks if the closure is a "short closure".
     *
     * @return bool
     */
    public function isShortClosure()
    {
        if ($this->isShortClosure === null) {
            $code = $this->getCode();

            if ($this->isStatic()) {
                $code = substr($code, 6);
            }

            $this->isShortClosure = strtolower(substr(trim($code), 0, 2)) === 'fn';
        }

        return $this->isShortClosure;
    }

    /**
     * Get the closure's code.
     *
     * @return string
     */
    public function getCode()
    {
        if ($this->code !== null) {
            return $this->code;
        }

        $fileName = $this->getFileName();
        $line = $this->getStartLine() - 1;

        $className = null;

        if (null !== $className = $this->getClosureScopeClass()) {
            $className = '\\'.trim($className->getName(), '\\');
        }

        $builtin_types = self::getBuiltinTypes();
        $class_keywords = ['self', 'static', 'parent'];

        $ns = $this->getClosureNamespaceName();
        $nsf = $ns == '' ? '' : ($ns[0] == '\\' ? $ns : '\\'.$ns);

        $_file = var_export($fileName, true);
        $_dir = var_export(dirname($fileName), true);
        $_namespace = var_export($ns, true);
        $_class = var_export(trim($className ?: '', '\\'), true);
        $_function = $ns.($ns == '' ? '' : '\\').'{closure}';
        $_method = ($className == '' ? '' : trim($className, '\\').'::').$_function;
        $_function = var_export($_function, true);
        $_method = var_export($_method, true);
        $_trait = null;

        $tokens = $this->getTokens();
        $state = $lastState = 'start';
        $inside_structure = false;
        $isFirstClassCallable = false;
        $isShortClosure = false;

        $inside_structure_mark = 0;
        $open = 0;
        $code = '';
        $id_start = $id_start_ci = $id_name = $context = '';
        $classes = $functions = $constants = null;
        $use = [];
        $lineAdd = 0;
        $isUsingScope = false;
        $isUsingThisObject = false;

        for ($i = 0, $l = count($tokens); $i < $l; $i++) {
            $token = $tokens[$i];

            switch ($state) {
                case 'start':
                    if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) {
                        $code .= $token[1];

                        $state = $token[0] === T_FUNCTION ? 'function' : 'static';
                    } elseif ($token[0] === T_FN) {
                        $isShortClosure = true;
                        $code .= $token[1];
                        $state = 'closure_args';
                    } elseif ($token[0] === T_PUBLIC || $token[0] === T_PROTECTED || $token[0] === T_PRIVATE) {
                        $code = '';
                        $isFirstClassCallable = true;
                    }
                    break;
                case 'static':
                    if ($token[0] === T_WHITESPACE || $token[0] === T_COMMENT || $token[0] === T_FUNCTION) {
                        $code .= $token[1];
                        if ($token[0] === T_FUNCTION) {
                            $state = 'function';
                        }
                    } elseif ($token[0] === T_FN) {
                        $isShortClosure = true;
                        $code .= $token[1];
                        $state = 'closure_args';
                    } else {
                        $code = '';
                        $state = 'start';
                    }
                    break;
                case 'function':
                    switch ($token[0]) {
                        case T_STRING:
                            if ($isFirstClassCallable) {
                                $state = 'closure_args';
                                break;
                            }

                            $code = '';
                            $state = 'named_function';
                            break;
                        case '(':
                            $code .= '(';
                            $state = 'closure_args';
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                    }
                    break;
                case 'named_function':
                    if ($token[0] === T_FUNCTION || $token[0] === T_STATIC) {
                        $code = $token[1];
                        $state = $token[0] === T_FUNCTION ? 'function' : 'static';
                    } elseif ($token[0] === T_FN) {
                        $isShortClosure = true;
                        $code .= $token[1];
                        $state = 'closure_args';
                    }
                    break;
                case 'closure_args':
                    switch ($token[0]) {
                        case T_NAME_QUALIFIED:
                            [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]);
                            $context = 'args';
                            $state = 'id_name';
                            $lastState = 'closure_args';
                            break;
                        case T_NS_SEPARATOR:
                        case T_STRING:
                            $id_start = $token[1];
                            $id_start_ci = strtolower($id_start);
                            $id_name = '';
                            $context = 'args';
                            $state = 'id_name';
                            $lastState = 'closure_args';
                            break;
                        case T_USE:
                            $code .= $token[1];
                            $state = 'use';
                            break;
                        case T_DOUBLE_ARROW:
                            $code .= $token[1];
                            if ($isShortClosure) {
                                $state = 'closure';
                            }
                            break;
                        case ':':
                            $code .= ':';
                            $state = 'return';
                            break;
                        case '{':
                            $code .= '{';
                            $state = 'closure';
                            $open++;
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                    }
                    break;
                case 'use':
                    switch ($token[0]) {
                        case T_VARIABLE:
                            $use[] = substr($token[1], 1);
                            $code .= $token[1];
                            break;
                        case '{':
                            $code .= '{';
                            $state = 'closure';
                            $open++;
                            break;
                        case ':':
                            $code .= ':';
                            $state = 'return';
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                            break;
                    }
                    break;
                case 'return':
                    switch ($token[0]) {
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            $code .= $token[1];
                            break;
                        case T_NS_SEPARATOR:
                        case T_STRING:
                            $id_start = $token[1];
                            $id_start_ci = strtolower($id_start);
                            $id_name = '';
                            $context = 'return_type';
                            $state = 'id_name';
                            $lastState = 'return';
                            break 2;
                        case T_NAME_QUALIFIED:
                            [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]);
                            $context = 'return_type';
                            $state = 'id_name';
                            $lastState = 'return';
                            break 2;
                        case T_DOUBLE_ARROW:
                            $code .= $token[1];
                            if ($isShortClosure) {
                                $state = 'closure';
                            }
                            break;
                        case '{':
                            $code .= '{';
                            $state = 'closure';
                            $open++;
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                            break;
                    }
                    break;
                case 'closure':
                    switch ($token[0]) {
                        case T_CURLY_OPEN:
                        case T_DOLLAR_OPEN_CURLY_BRACES:
                        case '{':
                            $code .= is_array($token) ? $token[1] : $token;
                            $open++;
                            break;
                        case '}':
                            $code .= '}';
                            if (--$open === 0 && ! $isShortClosure) {
                                break 3;
                            } elseif ($inside_structure) {
                                $inside_structure = ! ($open === $inside_structure_mark);
                            }
                            break;
                        case '(':
                        case '[':
                            $code .= $token[0];
                            if ($isShortClosure) {
                                $open++;
                            }
                            break;
                        case ')':
                        case ']':
                            if ($isShortClosure) {
                                if ($open === 0) {
                                    break 3;
                                }
                                $open--;
                            }
                            $code .= $token[0];
                            break;
                        case ',':
                        case ';':
                            if ($isShortClosure && $open === 0) {
                                break 3;
                            }
                            $code .= $token[0];
                            break;
                        case T_LINE:
                            $code .= $token[2] - $line + $lineAdd;
                            break;
                        case T_FILE:
                            $code .= $_file;
                            break;
                        case T_DIR:
                            $code .= $_dir;
                            break;
                        case T_NS_C:
                            $code .= $_namespace;
                            break;
                        case T_CLASS_C:
                            $code .= $inside_structure ? $token[1] : $_class;
                            break;
                        case T_FUNC_C:
                            $code .= $inside_structure ? $token[1] : $_function;
                            break;
                        case T_METHOD_C:
                            $code .= $inside_structure ? $token[1] : $_method;
                            break;
                        case T_COMMENT:
                            if (substr($token[1], 0, 8) === '#trackme') {
                                $timestamp = time();
                                $code .= '/**'.PHP_EOL;
                                $code .= '* Date      : '.date(DATE_W3C, $timestamp).PHP_EOL;
                                $code .= '* Timestamp : '.$timestamp.PHP_EOL;
                                $code .= '* Line      : '.($line + 1).PHP_EOL;
                                $code .= '* File      : '.$_file.PHP_EOL.'*/'.PHP_EOL;
                                $lineAdd += 5;
                            } else {
                                $code .= $token[1];
                            }
                            break;
                        case T_VARIABLE:
                            if ($token[1] == '$this' && ! $inside_structure) {
                                $isUsingThisObject = true;
                            }
                            $code .= $token[1];
                            break;
                        case T_STATIC:
                        case T_NS_SEPARATOR:
                        case T_STRING:
                            $id_start = $token[1];
                            $id_start_ci = strtolower($id_start);
                            $id_name = '';
                            $context = 'root';
                            $state = 'id_name';
                            $lastState = 'closure';
                            break 2;
                        case T_NAME_QUALIFIED:
                            [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]);
                            $context = 'root';
                            $state = 'id_name';
                            $lastState = 'closure';
                            break 2;
                        case T_NEW:
                            $code .= $token[1];
                            $context = 'new';
                            $state = 'id_start';
                            $lastState = 'closure';
                            break 2;
                        case T_USE:
                            $code .= $token[1];
                            $context = 'use';
                            $state = 'id_start';
                            $lastState = 'closure';
                            break;
                        case T_INSTANCEOF:
                        case T_INSTEADOF:
                            $code .= $token[1];
                            $context = 'instanceof';
                            $state = 'id_start';
                            $lastState = 'closure';
                            break;
                        case T_OBJECT_OPERATOR:
                        case T_NULLSAFE_OBJECT_OPERATOR:
                        case T_DOUBLE_COLON:
                            $code .= $token[1];
                            $lastState = 'closure';
                            $state = 'ignore_next';
                            break;
                        case T_FUNCTION:
                            $code .= $token[1];
                            $state = 'closure_args';
                            if (! $inside_structure) {
                                $inside_structure = true;
                                $inside_structure_mark = $open;
                            }
                            break;
                        case T_TRAIT_C:
                            if ($_trait === null) {
                                $startLine = $this->getStartLine();
                                $endLine = $this->getEndLine();
                                $structures = $this->getStructures();

                                $_trait = '';

                                foreach ($structures as &$struct) {
                                    if ($struct['type'] === 'trait' &&
                                        $struct['start'] <= $startLine &&
                                        $struct['end'] >= $endLine
                                    ) {
                                        $_trait = ($ns == '' ? '' : $ns.'\\').$struct['name'];
                                        break;
                                    }
                                }

                                $_trait = var_export($_trait, true);
                            }

                            $code .= $_trait;
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                    }
                    break;
                case 'ignore_next':
                    switch ($token[0]) {
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            $code .= $token[1];
                            break;
                        case T_CLASS:
                        case T_NEW:
                        case T_STATIC:
                        case T_VARIABLE:
                        case T_STRING:
                        case T_CLASS_C:
                        case T_FILE:
                        case T_DIR:
                        case T_METHOD_C:
                        case T_FUNC_C:
                        case T_FUNCTION:
                        case T_INSTANCEOF:
                        case T_LINE:
                        case T_NS_C:
                        case T_TRAIT_C:
                        case T_USE:
                            $code .= $token[1];
                            $state = $lastState;
                            break;
                        default:
                            $state = $lastState;
                            $i--;
                    }
                    break;
                case 'id_start':
                    switch ($token[0]) {
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            $code .= $token[1];
                            break;
                        case T_NS_SEPARATOR:
                        case T_NAME_FULLY_QUALIFIED:
                        case T_STRING:
                        case T_STATIC:
                            $id_start = $token[1];
                            $id_start_ci = strtolower($id_start);
                            $id_name = '';
                            $state = 'id_name';
                            break 2;
                        case T_NAME_QUALIFIED:
                            [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]);
                            $state = 'id_name';
                            break 2;
                        case T_VARIABLE:
                            $code .= $token[1];
                            $state = $lastState;
                            break;
                        case T_CLASS:
                            $code .= $token[1];
                            $state = 'anonymous';
                            break;
                        default:
                            $i--; //reprocess last
                            $state = 'id_name';
                    }
                    break;
                case 'id_name':
                    switch ($token[0]) {
                        case $token[0] === ':' && $context !== 'instanceof':
                            if ($lastState === 'closure' && $context === 'root') {
                                $state = 'closure';
                                $code .= $id_start.$token;
                            }

                            break;
                        case T_NAME_QUALIFIED:
                        case T_NS_SEPARATOR:
                        case T_STRING:
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            $id_name .= $token[1];
                            break;
                        case '(':
                            if ($isShortClosure) {
                                $open++;
                            }
                            if ($context === 'new' || false !== strpos($id_name, '\\')) {
                                if ($id_start_ci === 'self' || $id_start_ci === 'static') {
                                    if (! $inside_structure) {
                                        $isUsingScope = true;
                                    }
                                } elseif ($id_start !== '\\' && ! in_array($id_start_ci, $class_keywords)) {
                                    if ($classes === null) {
                                        $classes = $this->getClasses();
                                    }
                                    if (isset($classes[$id_start_ci])) {
                                        $id_start = $classes[$id_start_ci];
                                    }
                                    if ($id_start[0] !== '\\') {
                                        $id_start = $nsf.'\\'.$id_start;
                                    }
                                }
                            } else {
                                if ($id_start !== '\\') {
                                    if ($functions === null) {
                                        $functions = $this->getFunctions();
                                    }
                                    if (isset($functions[$id_start_ci])) {
                                        $id_start = $functions[$id_start_ci];
                                    } elseif ($nsf !== '\\' && function_exists($nsf.'\\'.$id_start)) {
                                        $id_start = $nsf.'\\'.$id_start;
                                        // Cache it to functions array
                                        $functions[$id_start_ci] = $id_start;
                                    }
                                }
                            }
                            $code .= $id_start.$id_name.'(';
                            $state = $lastState;
                            break;
                        case T_VARIABLE:
                        case T_DOUBLE_COLON:
                            if ($id_start !== '\\') {
                                if ($id_start_ci === 'self' || $id_start_ci === 'parent') {
                                    if (! $inside_structure) {
                                        $isUsingScope = true;
                                    }
                                } elseif ($id_start_ci === 'static') {
                                    if (! $inside_structure) {
                                        $isUsingScope = $token[0] === T_DOUBLE_COLON;
                                    }
                                } elseif (! (\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))) {
                                    if ($classes === null) {
                                        $classes = $this->getClasses();
                                    }
                                    if (isset($classes[$id_start_ci])) {
                                        $id_start = $classes[$id_start_ci];
                                    }
                                    if ($id_start[0] !== '\\') {
                                        $id_start = $nsf.'\\'.$id_start;
                                    }
                                }
                            }

                            $code .= $id_start.$id_name.$token[1];
                            $state = $token[0] === T_DOUBLE_COLON ? 'ignore_next' : $lastState;
                            break;
                        default:
                            if ($id_start !== '\\' && ! defined($id_start)) {
                                if ($constants === null) {
                                    $constants = $this->getConstants();
                                }
                                if (isset($constants[$id_start])) {
                                    $id_start = $constants[$id_start];
                                } elseif ($context === 'new') {
                                    if (in_array($id_start_ci, $class_keywords)) {
                                        if (! $inside_structure) {
                                            $isUsingScope = true;
                                        }
                                    } else {
                                        if ($classes === null) {
                                            $classes = $this->getClasses();
                                        }
                                        if (isset($classes[$id_start_ci])) {
                                            $id_start = $classes[$id_start_ci];
                                        }
                                        if ($id_start[0] !== '\\') {
                                            $id_start = $nsf.'\\'.$id_start;
                                        }
                                    }
                                } elseif ($context === 'use' ||
                                    $context === 'instanceof' ||
                                    $context === 'args' ||
                                    $context === 'return_type' ||
                                    $context === 'extends' ||
                                    $context === 'root'
                                ) {
                                    if (in_array($id_start_ci, $class_keywords)) {
                                        if (! $inside_structure && ! $id_start_ci === 'static') {
                                            $isUsingScope = true;
                                        }
                                    } elseif (! (\PHP_MAJOR_VERSION >= 7 && in_array($id_start_ci, $builtin_types))) {
                                        if ($classes === null) {
                                            $classes = $this->getClasses();
                                        }
                                        if (isset($classes[$id_start_ci])) {
                                            $id_start = $classes[$id_start_ci];
                                        }
                                        if ($id_start[0] !== '\\') {
                                            $id_start = $nsf.'\\'.$id_start;
                                        }
                                    }
                                }
                            }
                            $code .= $id_start.$id_name;
                            $state = $lastState;
                            $i--; //reprocess last token
                    }
                    break;
                case 'anonymous':
                    switch ($token[0]) {
                        case T_NAME_QUALIFIED:
                            [$id_start, $id_start_ci, $id_name] = $this->parseNameQualified($token[1]);
                            $state = 'id_name';
                            $lastState = 'anonymous';
                            break 2;
                        case T_NS_SEPARATOR:
                        case T_STRING:
                            $id_start = $token[1];
                            $id_start_ci = strtolower($id_start);
                            $id_name = '';
                            $state = 'id_name';
                            $context = 'extends';
                            $lastState = 'anonymous';
                            break;
                        case '{':
                            $state = 'closure';
                            if (! $inside_structure) {
                                $inside_structure = true;
                                $inside_structure_mark = $open;
                            }
                            $i--;
                            break;
                        default:
                            $code .= is_array($token) ? $token[1] : $token;
                    }
                    break;
            }
        }

        if ($isShortClosure) {
            $this->useVariables = $this->getStaticVariables();
        } else {
            $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use));
        }

        $this->isShortClosure = $isShortClosure;
        $this->isBindingRequired = $isUsingThisObject;
        $this->isScopeRequired = $isUsingScope;

        if (PHP_VERSION_ID >= 80100) {
            $attributesCode = array_map(function ($attribute) {
                $arguments = $attribute->getArguments();

                $name = $attribute->getName();
                $arguments = implode(', ', array_map(function ($argument, $key) {
                    $argument = sprintf("'%s'", str_replace("'", "\\'", $argument));

                    if (is_string($key)) {
                        $argument = sprintf('%s: %s', $key, $argument);
                    }

                    return $argument;
                }, $arguments, array_keys($arguments)));

                return "#[$name($arguments)]";
            }, $this->getAttributes());

            if (! empty($attributesCode)) {
                $code = implode("\n", array_merge($attributesCode, [$code]));
            }
        }

        $this->code = $code;

        return $this->code;
    }

    /**
     * Get PHP native built in types.
     *
     * @return array
     */
    protected static function getBuiltinTypes()
    {
        // PHP 8.1
        if (PHP_VERSION_ID >= 80100) {
            return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null', 'never'];
        }

        // PHP 8
        if (\PHP_MAJOR_VERSION === 8) {
            return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object', 'mixed', 'false', 'null'];
        }

        // PHP 7
        switch (\PHP_MINOR_VERSION) {
            case 0:
                return ['array', 'callable', 'string', 'int', 'bool', 'float'];
            case 1:
                return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void'];
            default:
                return ['array', 'callable', 'string', 'int', 'bool', 'float', 'iterable', 'void', 'object'];
        }
    }

    /**
     * Gets the use variables by the closure.
     *
     * @return array
     */
    public function getUseVariables()
    {
        if ($this->useVariables !== null) {
            return $this->useVariables;
        }

        $tokens = $this->getTokens();
        $use = [];
        $state = 'start';

        foreach ($tokens as &$token) {
            $is_array = is_array($token);

            switch ($state) {
                case 'start':
                    if ($is_array && $token[0] === T_USE) {
                        $state = 'use';
                    }
                    break;
                case 'use':
                    if ($is_array) {
                        if ($token[0] === T_VARIABLE) {
                            $use[] = substr($token[1], 1);
                        }
                    } elseif ($token == ')') {
                        break 2;
                    }
                    break;
            }
        }

        $this->useVariables = empty($use) ? $use : array_intersect_key($this->getStaticVariables(), array_flip($use));

        return $this->useVariables;
    }

    /**
     * Checks if binding is required.
     *
     * @return bool
     */
    public function isBindingRequired()
    {
        if ($this->isBindingRequired === null) {
            $this->getCode();
        }

        return $this->isBindingRequired;
    }

    /**
     * Checks if access to the scope is required.
     *
     * @return bool
     */
    public function isScopeRequired()
    {
        if ($this->isScopeRequired === null) {
            $this->getCode();
        }

        return $this->isScopeRequired;
    }

    /**
     * The the hash of the current file name.
     *
     * @return string
     */
    protected function getHashedFileName()
    {
        if ($this->hashedName === null) {
            $this->hashedName = sha1($this->getFileName());
        }

        return $this->hashedName;
    }

    /**
     * Get the file tokens.
     *
     * @return array
     */
    protected function getFileTokens()
    {
        $key = $this->getHashedFileName();

        if (! isset(static::$files[$key])) {
            static::$files[$key] = token_get_all(file_get_contents($this->getFileName()));
        }

        return static::$files[$key];
    }

    /**
     * Get the tokens.
     *
     * @return array
     */
    protected function getTokens()
    {
        if ($this->tokens === null) {
            $tokens = $this->getFileTokens();
            $startLine = $this->getStartLine();
            $endLine = $this->getEndLine();
            $results = [];
            $start = false;

            foreach ($tokens as &$token) {
                if (! is_array($token)) {
                    if ($start) {
                        $results[] = $token;
                    }

                    continue;
                }

                $line = $token[2];

                if ($line <= $endLine) {
                    if ($line >= $startLine) {
                        $start = true;
                        $results[] = $token;
                    }

                    continue;
                }

                break;
            }

            $this->tokens = $results;
        }

        return $this->tokens;
    }

    /**
     * Get the classes.
     *
     * @return array
     */
    protected function getClasses()
    {
        $key = $this->getHashedFileName();

        if (! isset(static::$classes[$key])) {
            $this->fetchItems();
        }

        return static::$classes[$key];
    }

    /**
     * Get the functions.
     *
     * @return array
     */
    protected function getFunctions()
    {
        $key = $this->getHashedFileName();

        if (! isset(static::$functions[$key])) {
            $this->fetchItems();
        }

        return static::$functions[$key];
    }

    /**
     * Gets the constants.
     *
     * @return array
     */
    protected function getConstants()
    {
        $key = $this->getHashedFileName();

        if (! isset(static::$constants[$key])) {
            $this->fetchItems();
        }

        return static::$constants[$key];
    }

    /**
     * Get the structures.
     *
     * @return array
     */
    protected function getStructures()
    {
        $key = $this->getHashedFileName();

        if (! isset(static::$structures[$key])) {
            $this->fetchItems();
        }

        return static::$structures[$key];
    }

    /**
     * Fetch the items.
     *
     * @return void.
     */
    protected function fetchItems()
    {
        $key = $this->getHashedFileName();

        $classes = [];
        $functions = [];
        $constants = [];
        $structures = [];
        $tokens = $this->getFileTokens();

        $open = 0;
        $state = 'start';
        $lastState = '';
        $prefix = '';
        $name = '';
        $alias = '';
        $isFunc = $isConst = false;

        $startLine = $endLine = 0;
        $structType = $structName = '';
        $structIgnore = false;

        foreach ($tokens as $token) {
            switch ($state) {
                case 'start':
                    switch ($token[0]) {
                        case T_CLASS:
                        case T_INTERFACE:
                        case T_TRAIT:
                            $state = 'before_structure';
                            $startLine = $token[2];
                            $structType = $token[0] == T_CLASS
                                                    ? 'class'
                                                    : ($token[0] == T_INTERFACE ? 'interface' : 'trait');
                            break;
                        case T_USE:
                            $state = 'use';
                            $prefix = $name = $alias = '';
                            $isFunc = $isConst = false;
                            break;
                        case T_FUNCTION:
                            $state = 'structure';
                            $structIgnore = true;
                            break;
                        case T_NEW:
                            $state = 'new';
                            break;
                        case T_OBJECT_OPERATOR:
                        case T_DOUBLE_COLON:
                            $state = 'invoke';
                            break;
                    }
                    break;
                case 'use':
                    switch ($token[0]) {
                        case T_FUNCTION:
                            $isFunc = true;
                            break;
                        case T_CONST:
                            $isConst = true;
                            break;
                        case T_NS_SEPARATOR:
                            $name .= $token[1];
                            break;
                        case T_STRING:
                            $name .= $token[1];
                            $alias = $token[1];
                            break;
                        case T_NAME_QUALIFIED:
                            $name .= $token[1];
                            $pieces = explode('\\', $token[1]);
                            $alias = end($pieces);
                            break;
                        case T_AS:
                            $lastState = 'use';
                            $state = 'alias';
                            break;
                        case '{':
                            $prefix = $name;
                            $name = $alias = '';
                            $state = 'use-group';
                            break;
                        case ',':
                        case ';':
                            if ($name === '' || $name[0] !== '\\') {
                                $name = '\\'.$name;
                            }

                            if ($alias !== '') {
                                if ($isFunc) {
                                    $functions[strtolower($alias)] = $name;
                                } elseif ($isConst) {
                                    $constants[$alias] = $name;
                                } else {
                                    $classes[strtolower($alias)] = $name;
                                }
                            }
                            $name = $alias = '';
                            $state = $token === ';' ? 'start' : 'use';
                            break;
                    }
                    break;
                case 'use-group':
                    switch ($token[0]) {
                        case T_NS_SEPARATOR:
                            $name .= $token[1];
                            break;
                        case T_NAME_QUALIFIED:
                            $name .= $token[1];
                            $pieces = explode('\\', $token[1]);
                            $alias = end($pieces);
                            break;
                        case T_STRING:
                            $name .= $token[1];
                            $alias = $token[1];
                            break;
                        case T_AS:
                            $lastState = 'use-group';
                            $state = 'alias';
                            break;
                        case ',':
                        case '}':

                            if ($prefix === '' || $prefix[0] !== '\\') {
                                $prefix = '\\'.$prefix;
                            }

                            if ($alias !== '') {
                                if ($isFunc) {
                                    $functions[strtolower($alias)] = $prefix.$name;
                                } elseif ($isConst) {
                                    $constants[$alias] = $prefix.$name;
                                } else {
                                    $classes[strtolower($alias)] = $prefix.$name;
                                }
                            }
                            $name = $alias = '';
                            $state = $token === '}' ? 'use' : 'use-group';
                            break;
                    }
                    break;
                case 'alias':
                    if ($token[0] === T_STRING) {
                        $alias = $token[1];
                        $state = $lastState;
                    }
                    break;
                case 'new':
                    switch ($token[0]) {
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            break 2;
                        case T_CLASS:
                            $state = 'structure';
                            $structIgnore = true;
                            break;
                        default:
                            $state = 'start';
                    }
                    break;
                case 'invoke':
                    switch ($token[0]) {
                        case T_WHITESPACE:
                        case T_COMMENT:
                        case T_DOC_COMMENT:
                            break 2;
                        default:
                            $state = 'start';
                    }
                    break;
                case 'before_structure':
                    if ($token[0] == T_STRING) {
                        $structName = $token[1];
                        $state = 'structure';
                    }
                    break;
                case 'structure':
                    switch ($token[0]) {
                        case '{':
                        case T_CURLY_OPEN:
                        case T_DOLLAR_OPEN_CURLY_BRACES:
                            $open++;
                            break;
                        case '}':
                            if (--$open == 0) {
                                if (! $structIgnore) {
                                    $structures[] = [
                                        'type'  => $structType,
                                        'name'  => $structName,
                                        'start' => $startLine,
                                        'end'   => $endLine,
                                    ];
                                }
                                $structIgnore = false;
                                $state = 'start';
                            }
                            break;
                        default:
                            if (is_array($token)) {
                                $endLine = $token[2];
                            }
                    }
                    break;
            }
        }

        static::$classes[$key] = $classes;
        static::$functions[$key] = $functions;
        static::$constants[$key] = $constants;
        static::$structures[$key] = $structures;
    }

    /**
     * Returns the namespace associated to the closure.
     *
     * @return string
     */
    protected function getClosureNamespaceName()
    {
        $ns = $this->getNamespaceName();

        // First class callables...
        if ($this->getName() !== '{closure}' && empty($ns) && ! is_null($this->getClosureScopeClass())) {
            $ns = $this->getClosureScopeClass()->getNamespaceName();
        }

        return $ns;
    }

    /**
     * Parse the given token.
     *
     * @param  string  $token
     * @return array
     */
    protected function parseNameQualified($token)
    {
        $pieces = explode('\\', $token);

        $id_start = array_shift($pieces);

        $id_start_ci = strtolower($id_start);

        $id_name = '\\'.implode('\\', $pieces);

        return [$id_start, $id_start_ci, $id_name];
    }
}
About
top

About NFC Pay: Our Story and Mission

NFC Pay was founded with a vision to transform the way people handle transactions. Our journey is defined by a commitment to innovation, security, and convenience. We strive to deliver seamless, user-friendly payment solutions that make everyday transactions effortless and secure. Our mission is to empower you to pay with ease and confidence, anytime, anywhere.

  • Simplifying Payments, One Tap at a Time.
  • Reinventing Your Wallet for Modern Convenience.
  • Smart Payments for a Effortless Lifestyle.
  • Experience the Ease of Tap and Pay.
  • Innovative Solutions for Your Daily Transactions.

Frequently Asked Questions About NFC Pay

Here are answers to some common questions about NFC Pay. We aim to provide clear and concise information to help you understand how our platform works and how it can benefit you. If you have any further inquiries, please don’t hesitate to contact our support team.

faq-img

How do I register for NFC Pay?

Download the app and sign up using your email or phone number, then complete the verification process.

Is my payment information secure?

Yes, we use advanced encryption and security protocols to protect your payment details.

Can I add multiple cards to my NFC Pay wallet?

Absolutely, you can link multiple debit or credit cards to your wallet.

How do I transfer money to another user?

Go to the transfer section, select the recipient, enter the amount, and authorize the transfer.

What should I do if I forget my PIN?

Use the “Forgot PIN” feature in the app to reset it following the provided instructions.

How can I activate my merchant account?

Sign up for a merchant account through the app and follow the setup instructions to start accepting payments.

Can I track my payment status?

Yes, you can view and track your payment status in the account dashboard