Get segment data from token (css selector delimited by space and commas)

@param string $token
@param integer $key
@param string[] $tokens

@return object|false $segment
348029
private static function getSegmentFromToken($token, $key, array $tokens)
    {
        $relation_tokens = array('>', '~', '+');

        if (\in_array($token, $relation_tokens, true)) { // not a segment
            return false;
        }

        $segment = (object) array(
            'selector' => '',
            'relation_token' => false,
            'attribute_filters' => array(),
            'pseudo_filters' => array()
        );

        if (isset($tokens[$key-1]) && \in_array($tokens[$key-1], $relation_tokens, true)) { // get relationship token
            $segment->relation_token = $tokens[$key-1];
        }

        if (ctype_alpha($token)) { // simple element selector
            $segment->selector = $token;
            return $segment;
        }

        $char_tmp_replaced = false;
        if (strpos($token, '\\') !== false) {
            $token = preg_replace_callback( // temporary replace escaped characters
                '#(\\\\)(.{1})#',
                function ($matches) {
                    return 'ESCAPED'. \ord($matches[2]);
                },
                $token
            );
            $char_tmp_replaced = true;
        }

        $segment->selector = $token;

        while (preg_match('/(.*)\:(not|contains|has)\((.+)\)$/i', $segment->selector, $matches)) { // pseudo selector
            $segment->selector = $matches[1];
            $segment->pseudo_filters[] = $matches[2].'('.$matches[3].')';
        }

        while (preg_match('/(.*)\:([a-z][a-z\-]+)$/i', $segment->selector, $matches)) { // pseudo selector
            $segment->selector = $matches[1];
            $segment->pseudo_filters[] = $matches[2];
        }

        while (preg_match('/(.*)\[([^]]+)\]$/', $segment->selector, $matches)) { // attribute selector
            $segment->selector = $matches[1];
            $segment->attribute_filters[] = $matches[2];
        }

        while (preg_match('/(.*)\.([^\.\#]+)$/i', $segment->selector, $matches)) { // class selector
            $segment->selector = $matches[1];
            $segment->attribute_filters[] = 'class~="'.$matches[2].'"';
        }

        while (preg_match('/(.*)\#([^\.\#]+)$/i', $segment->selector, $matches)) { // id selector
            $segment->selector = $matches[1];
            $segment->attribute_filters[] = 'id="'.$matches[2].'"';
        }

        if ($char_tmp_replaced) { // restore temporary replaced characters
            $set_escape_back = function (string $str) {
                return preg_replace_callback(
                    '#(ESCAPED)([0-9]{1,3})#',
                    function ($matches) {
                        return \chr($matches[2]);
                    },
                    $str
                );
            };

            $segment->selector = $set_escape_back($segment->selector);

            foreach ($segment->attribute_filters as &$attr_filter) {
                $attr_filter = $set_escape_back($attr_filter);
            }
        }

        return $segment;
    }
216201
public function getTokenAskButton($tokenId, $tokenStatus, $staffToken, $keepCaps)
    {
        if ('O' == $tokenStatus || 'P' == $tokenStatus) {
            if ($staffToken) {
                $menuItem = $this->_getAskMenuItem();
                $label    = $menuItem->get('label');

                if ('P' == $tokenStatus) {
                    $label = $this->_('Continue');
                }

                $link = $menuItem->toActionLink(
                    ($keepCaps ? $label : strtolower($label)),
                    [
                        'gto_id_token' => $tokenId,
                        'can_be_taken' => 1,
                        \Gems_Model::ID_TYPE => 'token',
                    ]);

                if ($link) {
                    $link->title = sprintf($this->_('Answer token %s'), strtoupper($tokenId));

                    return $link;
                }
            }

            return $this->getTokenCopyLink($tokenId, $tokenStatus);
        }
    }
1360686
protected function parseToken($token)
    {
        [$id, $content] = $token;

        if ($id == T_INLINE_HTML) {
            foreach ($this->compilers as $type) {
                $content = $this->{"compile{$type}"}($content);
            }
        }

        return $content;
    }
1301945
public static function label($tokenId, array $tokens) {
		$token = $tokens[$tokenId];
		$hasName = in_array($token['id'], array(
			T_FUNCTION,
			T_CLASS,
			T_INTERFACE,
			T_VARIABLE,
		));
		if ($hasName) {
			if ($token['id'] === T_VARIABLE) {
				return substr($token['content'], 1);
			}
			$total = count($tokens);
			for ($key = $tokenId; $key <= $total; $key++) {
				if ($tokens[$key]['id'] === T_STRING) {
					return $tokens[$key]['content'];
				} elseif (in_array($tokens[$key]['content'], array('(', '{', ':'))) {
					break;
				}
			}
		}
		return null;
	}
835396
public function parse(array $tokens)
    {
        $symbolNodes = $this->detectSymbols($tokens);

        $nodes = $this->createTreeByBrackets($symbolNodes);

        $nodes = $this->transformTreeByFunctions($nodes);

        $this->checkGrammar($nodes);

        // Wrap the nodes in an array node.
        $rootNode = new ContainerNode($nodes);

        return $rootNode;
    }
746980
public function process($tokens, $keys = array()) {

        $base_expr = "";
        $expr = array();
        $currCategory = "";

        if ($this->isStatement($keys)) {
            foreach ($tokens as $token) {

                $trim = trim($token);
                $base_expr .= $token;

                if ($trim === '') {
                    continue;
                }

                $upper = strtoupper($trim);

                switch ($upper) {

                case 'EXTENDED':
                case 'PARTITIONS':
                    return array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $token);
                    break;

                case 'FORMAT':
                    if ($currCategory === '') {
                        $currCategory = $upper;
                        $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);
                    }
                    // else?
                    break;

                case '=':
                    if ($currCategory === 'FORMAT') {
                        $expr[] = array('expr_type' => ExpressionType::OPERATOR, 'base_expr' => $trim);
                    }
                    // else?
                    break;

                case 'TRADITIONAL':
                case 'JSON':
                    if ($currCategory === 'FORMAT') {
                        $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);
                        return array('expr_type' => ExpressionType::EXPRESSION, 'base_expr' => trim($base_expr),
                                     'sub_tree' => $expr);
                    }
                    // else?
                    break;

                default:
                // ignore the other stuff
                    break;
                }
            }
            return empty($expr) ? null : $expr;
        }

        foreach ($tokens as $token) {

            $trim = trim($token);

            if ($trim === '') {
                continue;
            }

            switch ($currCategory) {

            case 'TABLENAME':
                $currCategory = 'WILD';
                $expr[] = array('expr_type' => ExpressionType::COLREF, 'base_expr' => $trim,
                                'no_quotes' => $this->revokeQuotation($trim));
                break;

            case '':
                $currCategory = 'TABLENAME';
                $expr[] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim,
                                'no_quotes' => $this->revokeQuotation($trim), 'alias' => false, 'base_expr' => $trim);
                break;

            default:
                break;
            }
        }
        return empty($expr) ? null : $expr;
    }
1241943
protected static function _matchToken($key, $token)
    {
        switch ($token) {
            case '{n}':
                return is_numeric($key);
            case '{s}':
                return is_string($key);
            case '{*}':
                return true;
            default:
                return is_numeric($token) ? ($key == $token) : $key === $token;
        }
    }
870148
public function findByToken($token)
    {
        /** @var Query $query */
        $query = $this->isValid($token, true);
        if ($query === false) {
            return $query;
        }
        return $query->contain(['Users'])->first();
    }
951248
protected function getLastWhitespaceOfPreviousLine(array $tokens, $index) {
		$currentLine = $tokens[$index]['line'];
		$index--;
		while ($tokens[$index]['line'] === $currentLine) {
			$index--;
		}

		return $index;
	}
431597
private function getCurrentConstantKeyFromClassTokens($tokens)
    {
        $parsingStateConstDeclarationFound = false;
        $constDeclarationKey = 0;

        foreach ($tokens as $key => $token) {
            if (is_array($token) === true && $token[0] === T_CONST) {
                $parsingStateConstDeclarationFound = true;
                $constDeclarationKey = $key;
            }

            if ($parsingStateConstDeclarationFound === true && $token[0] === T_STRING) {
                if ($token[1] === $this->getName()) {
                    break;
                } else {
                    $parsingStateConstDeclarationFound = false;
                }
            }
        }

        return $constDeclarationKey;
    }
285381
private function parseUseStatement(\ArrayIterator $tokens)
    {
        $uses = [];
        $continue = true;

        while ($continue) {
            $this->skipToNextStringOrNamespaceSeparator($tokens);

            list($alias, $fqnn) = $this->extractUseStatement($tokens);
            $uses[$alias] = $fqnn;
            if (self::T_LITERAL_END_OF_USE === $tokens->current()[0]) {
                $continue = false;
            }
        }

        return $uses;
    }
249346
public function parse(Token $token)
    {
        parent::parse($token);

        $split = preg_split(self::REGEX, $token->getValue(), 2, PREG_SPLIT_DELIM_CAPTURE + PREG_SPLIT_NO_EMPTY);
        $splitSize = count($split);
        if (1 === $splitSize) {
            return $this->functionTokenParser->parse($token);
        }

        if (3 !== count($split) && 4 !== count($split)) {
            throw ExpressionLanguageExceptionFactory::createForCouldNotLexValue($token->getValue());
        }

        $values = [
            $this->parser->parse($split[0].$split[1]),
        ];
        if (3 === $splitSize) {
            $values[] = $this->parser->parse('<'.$split[2]);
        }

        if (4 === $splitSize) {
            $values[] = $this->parser->parse($split[2]);
            $values[] = $this->parser->parse('<'.$split[3]);
        }

        return $this->mergeValues($values);
    }
996650
public static function alias(array $tokens) {
        HashMap::assert($tokens, 'tokens');

        $operation = SqlOperation::create($tokens);
        if ($operation === SqlOperations::INSERT) return null;
        if ($operation === SqlOperations::UPDATE) return $tokens['UPDATE'][0]['alias']['name'];
        return $tokens['FROM'][0]['alias']['name'];
    }
794867
public static function create(array $tokens) {
        HashMap::assert($tokens, 'tokens');

        if (empty($tokens['ORDER'])) return [];

        $headers = [];
        $orderQueryArr = array_map(function($order){
            $query = end($order['no_quotes']['parts']);
            if (empty($query)) return null;
            return !isset($order['direction']) ? $query : $query . ' ' . $order['direction'];
        },$tokens['ORDER']);
        array_push($headers, 'Order: '.implode(',',$orderQueryArr));
        return $headers;
    }
779032
protected function getNextTokenFromString($string, $token, $cacheKey)
    {
        $token = $this->parseNextToken($string, $token);

        if ($cacheKey && \strlen($token[self::TOKEN_VALUE]) < $this->maxCacheKeySize) {
            $this->tokenCache[$cacheKey] = $token;
        }

        return $token;
    }
17918
private static function getNamespace(int $key, array $tokens): ?string
    {
        $namespace  = null;
        $tokenCount = \count($tokens);

        for ($i = $key; $i < $tokenCount; $i++) {
            if (self::isPartOfNamespace($tokens[$i])) {
                $namespace .= $tokens[$i][1];
            } elseif ($tokens[$i] === ';') {
                return $namespace;
            }
        }

        return null;
    }
1224005
public static function verify($token, $key)
    {
        // Check values
        if (empty($token) || empty($key)) {
            return false;
        }

        // Split parts
        list($payloadJSON_encoded, $signature) = explode('.', $token);

        // Generate signature to verify
        $signatureGenerated = hash_hmac('SHA256', $payloadJSON_encoded, $key);

        return ($signature === $signatureGenerated);
    }