Roller\RouteCompiler::compilePattern PHP Метод

compilePattern() статический публичный Метод

compile pattern
static public compilePattern ( string $pattern, array $options = [] )
$pattern string
$options array
    static function compilePattern($pattern, $options = array())
    {
        $len = strlen($pattern);
        /**
         * contains:
         *   
         *   array( 'text', $text ),
         *   array( 'variable', $match[0][0][0], $regexp, $var);
         *
         */
        $tokens = array();
        $variables = array();
        $pos = 0;
        /**
         *  the path like:
         *
         *      /blog/to/:year/:month
         *
         *  will be separated like:
         *      
         *      [
         *          '/blog/to',  (text token)
         *          '/:year',    (reg exp token)
         *          '/:month',   (reg exp token)
         *      ]
         */
        $matches = self::splitTokens($pattern);
        // build tokens
        foreach ($matches as $match) {
            /*
             * Split tokens from abstract pattern
             * to rebuild regexp pattern.
             */
            if ($text = substr($pattern, $pos, $match[0][1] - $pos)) {
                $tokens[] = array('text', $text);
            }
            // the first char from pattern (seperater)
            $seps = array($pattern[$pos]);
            $pos = $match[0][1] + strlen($match[0][0]);
            // optional pattern
            if ($match[0][0][0] == '(') {
                $optional = $match[2][0];
                $subroute = self::compilePattern($optional, array('default' => @$options['default'], 'requirement' => @$options['requirement'], 'variables' => @$options['variables']));
                $tokens[] = array('optional', $optional[0], $subroute['regex']);
                // $regexp =
                foreach ($subroute['variables'] as $var) {
                    $variables[] = $var;
                }
            } else {
                // field name (variable name)
                $var = $match[1][0];
                /* build field pattern from requirement */
                if (isset($options['requirement'][$var]) && ($req = $options['requirement'][$var])) {
                    $regexp = $req;
                } else {
                    if ($pos !== $len) {
                        $seps[] = $pattern[$pos];
                    }
                    // build regexp (from separater)
                    $regexp = sprintf('[^%s]+?', preg_quote(implode('', array_unique($seps)), '#'));
                }
                $tokens[] = array('variable', $match[0][0][0], $regexp, $var);
                $variables[] = $var;
            }
        }
        if ($pos < $len) {
            $tokens[] = array('text', substr($pattern, $pos));
        }
        // find the first optional token
        $firstOptional = INF;
        for ($i = count($tokens) - 1; $i >= 0; $i--) {
            if ('variable' === $tokens[$i][0] && isset($options['default'][$tokens[$i][3]])) {
                $firstOptional = $i;
            } else {
                break;
            }
        }
        // compute the matching regexp
        $regex = '';
        $indent = 1;
        // token structure:
        //   [0] => token type,
        //   [1] => separator
        //   [2] => pattern
        //   [3] => name ,
        // first optional token and only one token.
        if (1 === count($tokens) && 0 === $firstOptional) {
            $token = $tokens[0];
            ++$indent;
            $regex .= str_repeat(' ', $indent * 4) . sprintf("%s(?:\n", preg_quote($token[1], '#'));
            // regular expression with place holder name. (
            $regex .= str_repeat(' ', $indent * 4) . sprintf("(?P<%s>%s)\n", $token[3], $token[2]);
        } else {
            foreach ($tokens as $i => $token) {
                if ('text' === $token[0]) {
                    $regex .= str_repeat(' ', $indent * 4) . preg_quote($token[1], '#') . "\n";
                } elseif ('optional' === $token[0]) {
                    $regex .= str_repeat(' ', $indent * 4) . "(?:\n";
                    $regex .= $token[2];
                    $regex .= str_repeat(' ', $indent * 4) . ")?\n";
                } else {
                    if ($i >= $firstOptional) {
                        $regex .= str_repeat(' ', $indent * 4) . "(?:\n";
                        ++$indent;
                    }
                    $regex .= str_repeat(' ', $indent * 4) . sprintf("%s(?P<%s>%s)\n", preg_quote($token[1], '#'), $token[3], $token[2]);
                }
            }
        }
        while (--$indent) {
            $regex .= str_repeat(' ', $indent * 4) . ")?\n";
        }
        // save variables
        $options['variables'] = $variables;
        $options['regex'] = $regex;
        // $options['tokens'] = $tokens;
        return $options;
    }