private function replaceViewFunctionCalls(string $expression) : string
    {
        $phpTokens = token_get_all('<?php ' . $expression . ' ?>');
        $opulenceTokens = [];

        // This is essentially a foreach loop that can be fast-forwarded
        while (list($index, $token) = each($phpTokens)) {
            if (is_string($token)) {
                // Convert the simple token to an array for uniformity
                $opulenceTokens[] = [T_STRING, $token, 0];

                continue;
            }

            switch ($token[0]) {
                case T_STRING:
                    // If this is a function
                    if (count($phpTokens) > $index && $phpTokens[$index + 1] === '(') {
                        $prevToken = $index > 0 ? $phpTokens[$index - 1] : null;

                        // If this is a native PHP function or is really a method call, don't convert it
                        if (
                            (
                                ($prevToken[0] === T_OBJECT_OPERATOR || $prevToken[0] === T_DOUBLE_COLON) &&
                                is_array($prevToken)
                            ) ||
                            function_exists($token[1])
                        ) {
                            $opulenceTokens[] = $token;
                        } else {
                            // This is a view function
                            // Add $__opulenceFortuneTranspiler
                            $opulenceTokens[] = [T_VARIABLE, '$__opulenceFortuneTranspiler', $token[2]];
                            // Add ->
                            $opulenceTokens[] = [T_OBJECT_OPERATOR, '->', $token[2]];
                            // Add callViewFunction("FUNCTION_NAME")
                            $opulenceTokens[] = [T_STRING, 'callViewFunction("' . $token[1] . '")', $token[2]];
                        }
                    } else {
                        $opulenceTokens[] = $token;
                    }

                    break;
                default:
                    $opulenceTokens[] = $token;

                    break;
            }
        }

        // Remove php open/close PHP tags
        array_shift($opulenceTokens);
        array_pop($opulenceTokens);

        // Rejoin the tokens
        $joinedTokens = implode('', array_column($opulenceTokens, 1));

        $replacementCount = 0;
        $callback = function (array $matches) {
            if ($matches[2] === ')') {
                // There were no parameters
                return $matches[1] . ')';
            } else {
                // There were parameters
                return $matches[1] . ', ' . $matches[2];
            }
        };

        /**
         * View functions are left in a broken state
         * For example, 'foo()' will currently look like '...->callViewFunction("foo")()'
         * This should be converted to '...->callViewFunction("foo")'
         * Similarly, 'foo("bar")' will currently look like '...->callViewFunction("foo")("bar")'
         * This should be converted to '...->callViewFunction("foo", "bar")'
         */
        do {
            $joinedTokens = preg_replace_callback(
                '/(\$__opulenceFortuneTranspiler->callViewFunction\([^\)]+)\)\((.)/',
                $callback,
                $joinedTokens,
                -1,
                $replacementCount
            );
        } while ($replacementCount > 0);

        return trim($joinedTokens);
    }
private function replaceViewFunctionCalls(string $expression) : string
    {
        $phpTokens = token_get_all('<?php ' . $expression . ' ?>');
        $opulenceTokens = [];

        // This is essentially a foreach loop that can be fast-forwarded
        while (list($index, $token) = each($phpTokens)) {
            if (is_string($token)) {
                // Convert the simple token to an array for uniformity
                $opulenceTokens[] = [T_STRING, $token, 0];

                continue;
            }

            switch ($token[0]) {
                case T_STRING:
                    // If this is a function
                    if (count($phpTokens) > $index && $phpTokens[$index + 1] === '(') {
                        $prevToken = $index > 0 ? $phpTokens[$index - 1] : null;

                        // If this is a native PHP function or is really a method call, don't convert it
                        if (
                            (
                                ($prevToken[0] === T_OBJECT_OPERATOR || $prevToken[0] === T_DOUBLE_COLON) &&
                                is_array($prevToken)
                            ) ||
                            function_exists($token[1])
                        ) {
                            $opulenceTokens[] = $token;
                        } else {
                            // This is a view function
                            // Add $__opulenceFortuneTranspiler
                            $opulenceTokens[] = [T_VARIABLE, '$__opulenceFortuneTranspiler', $token[2]];
                            // Add ->
                            $opulenceTokens[] = [T_OBJECT_OPERATOR, '->', $token[2]];
                            // Add callViewFunction("FUNCTION_NAME")
                            $opulenceTokens[] = [T_STRING, 'callViewFunction("' . $token[1] . '")', $token[2]];
                        }
                    } else {
                        $opulenceTokens[] = $token;
                    }

                    break;
                default:
                    $opulenceTokens[] = $token;

                    break;
            }
        }

        // Remove php open/close PHP tags
        array_shift($opulenceTokens);
        array_pop($opulenceTokens);

        // Rejoin the tokens
        $joinedTokens = implode('', array_column($opulenceTokens, 1));

        $replacementCount = 0;
        $callback = function (array $matches) {
            if ($matches[2] === ')') {
                // There were no parameters
                return $matches[1] . ')';
            } else {
                // There were parameters
                return $matches[1] . ', ' . $matches[2];
            }
        };

        /**
         * View functions are left in a broken state
         * For example, 'foo()' will currently look like '...->callViewFunction("foo")()'
         * This should be converted to '...->callViewFunction("foo")'
         * Similarly, 'foo("bar")' will currently look like '...->callViewFunction("foo")("bar")'
         * This should be converted to '...->callViewFunction("foo", "bar")'
         */
        do {
            $joinedTokens = preg_replace_callback(
                '/(\$__opulenceFortuneTranspiler->callViewFunction\([^\)]+)\)\((.)/',
                $callback,
                $joinedTokens,
                -1,
                $replacementCount
            );
        } while ($replacementCount > 0);

        return trim($joinedTokens);
    }
private function replaceViewFunctionCalls ( string $ expression ) : string { $ phpTokens = token_get_all ( '<?php ' . $ expression . ' ?>' ) ; $ opulenceTokens = [ ] ; // This is essentially a foreach loop that can be fast-forwarded while ( list ( $ index , $ token ) = each ( $ phpTokens ) ) { if ( is_string ( $ token ) ) { // Convert the simple token to an array for uniformity $ opulenceTokens [ ] = [ T_STRING , $ token , 0 ] ; continue ; } switch ( $ token [ 0 ] ) { case T_STRING : // If this is a function if ( count ( $ phpTokens ) > $ index && $ phpTokens [ $ index + 1 ] === '(' ) { $ prevToken = $ index > 0 ? $ phpTokens [ $ index - 1 ] : null ; // If this is a native PHP function or is really a method call, don't convert it if ( ( ( $ prevToken [ 0 ] === T_OBJECT_OPERATOR || $ prevToken [ 0 ] === T_DOUBLE_COLON ) && is_array ( $ prevToken ) ) || function_exists ( $ token [ 1 ] ) ) { $ opulenceTokens [ ] = $ token ; } else { // This is a view function // Add $__opulenceFortuneTranspiler $ opulenceTokens [ ] = [ T_VARIABLE , '$__opulenceFortuneTranspiler' , $ token [ 2 ] ] ; // Add -> $ opulenceTokens [ ] = [ T_OBJECT_OPERATOR , '->' , $ token [ 2 ] ] ; // Add callViewFunction("FUNCTION_NAME") $ opulenceTokens [ ] = [ T_STRING , 'callViewFunction("' . $ token [ 1 ] . '")' , $ token [ 2 ] ] ; } } else { $ opulenceTokens [ ] = $ token ; } break ; default : $ opulenceTokens [ ] = $ token ; break ; } } // Remove php open/close PHP tags array_shift ( $ opulenceTokens ) ; array_pop ( $ opulenceTokens ) ; // Rejoin the tokens $ joinedTokens = implode ( '' , array_column ( $ opulenceTokens , 1 ) ) ; $ replacementCount = 0 ; $ callback = function ( array $ matches ) { if ( $ matches [ 2 ] === ')' ) { // There were no parameters return $ matches [ 1 ] . ')' ; } else { // There were parameters return $ matches [ 1 ] . ', ' . $ matches [ 2 ] ; } } ; /**
         * View functions are left in a broken state
         * For example, 'foo()' will currently look like '...->callViewFunction("foo")()'
         * This should be converted to '...->callViewFunction("foo")'
         * Similarly, 'foo("bar")' will currently look like '...->callViewFunction("foo")("bar")'
         * This should be converted to '...->callViewFunction("foo", "bar")'
         */ do { $ joinedTokens = preg_replace_callback ( '/(\$__opulenceFortuneTranspiler->callViewFunction\([^\)]+)\)\((.)/' , $ callback , $ joinedTokens , - 1 , $ replacementCount ) ; } while ( $ replacementCount > 0 ) ; return trim ( $ joinedTokens ) ; }
Replaces view function calls with valid PHP calls

@param string $expression The expression to replace calls in
@return string The expression with replaced calls
Replaces view function calls with valid PHP calls