<commit_before><?php
/**
 * Route - manage a route to an HTTP request and an assigned callback function.
 *
 * @author <NAME> - <EMAIL>
 * @version 3.0
 */

namespace Routing;

use Http\Request;
use Routing\Legacy\RouteParser;
use Routing\Matching\UriValidator;
use Routing\Matching\HostValidator;
use Routing\Matching\MethodValidator;
use Routing\Matching\SchemeValidator;

use Symfony\Component\Routing\Route as SymfonyRoute;


/**
 * The Route class is responsible for routing an HTTP request to an assigned Callback function.
 */
class Route
{
    /**
     * The URI pattern the Route responds to.
     *
     * @var string
     */
    private $uri = null;

    /**
     * Supported HTTP methods.
     *
     * @var array
     */
    private $methods = array();

    /**
     * The route action array.
     *
     * @var array
     */
    protected $action = array();

    /**
     * The default values for the Route.
     *
     * @var array
     */
    protected $defaults = array();

    /**
     * The regular expression requirements.
     *
     * @var array
     */
    protected $wheres = array();

    /**
     * The matched Route parameters.
     *
     * @var array
     */
    private $parameters;

    /**
     * The parameter names for the route.
     *
     * @var array|null
     */
    protected $parameterNames;

    /**
     * The validators used by the routes.
     *
     * @var array
     */
    protected static $validators;

    /**
     * The compiled version of the Route.
     *
     * @var \Symfony\Component\Routing\CompiledRoute
     */
    protected $compiled = null;

    /**
     * The compiled pattern the Route responds to.
     *
     * @var string
     */
    private $pattern = null;

    /**
     * Boolean indicating the use of Named Parameters on not.
     *
     * @var bool $namedParams
     */
    private $namedParams = true;


    /**
     * Constructor.
     *
     * @param string|array $methods HTTP methods
     * @param string $uri URL pattern
     * @param string|array|callable $action Callback function or options
     * @param bool $namedParams Wheter or not are used the Named Parameters
     */
    public function __construct($methods, $uri, $action, $namedParams = true)
    {
        $uri = trim($uri, '/');

        //
        $this->uri = ! empty($uri) ? $uri : '/';

        $this->methods = (array) $methods;

        $this->action = $this->parseAction($action);

        if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {
            $this->methods[] = 'HEAD';
        }

        if (isset($this->action['prefix'])) {
            $this->prefix($this->action['prefix']);
        }

        //
        $this->namedParams = $namedParams;
    }

    /**
     * Run the Route action and return the response.
     *
     * @return mixed
     */
    public function run()
    {
        $parameters = array_filter($this->getParams(), function($param)
        {
            return isset($param);
        });

        return call_user_func_array($this->action['uses'], $parameters);
    }

    /**
     * Checks if a Request matches the Route pattern.
     *
     * @param \Http\Request $request The dispatched Request instance
     * @param bool $includingMethod Wheter or not is matched the HTTP Method
     * @return bool Match status
     */
    public function matches(Request $request, $includingMethod = true)
    {
        $this->compileRoute();

        foreach ($this->getValidators() as $validator) {
            if (! $includingMethod && ($validator instanceof MethodValidator)) continue;

            if (! $validator->matches($this, $request)) return false;
        }

        return true;
    }

    /**
     * Compile the Route pattern for matching and return it.
     *
     * @return string
     */
    public function compileRoute()
    {
        if ($this->namedParams) {
            // The Route use the default Named Parameters.
            $this->pattern = preg_replace('/\{(\w+?)\?\}/', '{$1}', $this->uri);

            $optionals = $this->extractOptionalParameters();

            $requirements = $this->wheres;
        } else {
            // The Route use the legacy Unnamed Parameters.
            list($this->pattern, $optionals, $requirements) = RouteParser::parse(
                $this->uri,
                $this->wheres
            );
        }

        $this->compiled = with(
            new SymfonyRoute($this->pattern, $optionals, $requirements, array(), $this->domain() ?: '')
        )->compile();
    }

    /**
     * Get the optional parameters for the route.
     *
     * @return array
     */
    protected function extractOptionalParameters()
    {
        preg_match_all('/\{(\w+?)\?\}/', $this->uri, $matches);

        return isset($matches[1]) ? $matches[1] : array();
    }

    /**
     * Parse the Route Action into a standard array.<commit_msg>Comment adding on the Routing\Route@compileRoute<commit_after><?php
/**
 * Route - manage a route to an HTTP request and an assigned callback function.
 *
 * @author <NAME> - <EMAIL>
 * @version 3.0
 */

namespace Routing;

use Http\Request;
use Routing\Legacy\RouteParser;
use Routing\Matching\UriValidator;
use Routing\Matching\HostValidator;
use Routing\Matching\MethodValidator;
use Routing\Matching\SchemeValidator;

use Symfony\Component\Routing\Route as SymfonyRoute;


/**
 * The Route class is responsible for routing an HTTP request to an assigned Callback function.
 */
class Route
{
    /**
     * The URI pattern the Route responds to.
     *
     * @var string
     */
    private $uri = null;

    /**
     * Supported HTTP methods.
     *
     * @var array
     */
    private $methods = array();

    /**
     * The route action array.
     *
     * @var array
     */
    protected $action = array();

    /**
     * The default values for the Route.
     *
     * @var array
     */
    protected $defaults = array();

    /**
     * The regular expression requirements.
     *
     * @var array
     */
    protected $wheres = array();

    /**
     * The matched Route parameters.
     *
     * @var array
     */
    private $parameters;

    /**
     * The parameter names for the route.
     *
     * @var array|null
     */
    protected $parameterNames;

    /**
     * The validators used by the routes.
     *
     * @var array
     */
    protected static $validators;

    /**
     * The compiled version of the Route.
     *
     * @var \Symfony\Component\Routing\CompiledRoute
     */
    protected $compiled = null;

    /**
     * The compiled pattern the Route responds to.
     *
     * @var string
     */
    private $pattern = null;

    /**
     * Boolean indicating the use of Named Parameters on not.
     *
     * @var bool $namedParams
     */
    private $namedParams = true;


    /**
     * Constructor.
     *
     * @param string|array $methods HTTP methods
     * @param string $uri URL pattern
     * @param string|array|callable $action Callback function or options
     * @param bool $namedParams Wheter or not are used the Named Parameters
     */
    public function __construct($methods, $uri, $action, $namedParams = true)
    {
        $uri = trim($uri, '/');

        //
        $this->uri = ! empty($uri) ? $uri : '/';

        $this->methods = (array) $methods;

        $this->action = $this->parseAction($action);

        if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {
            $this->methods[] = 'HEAD';
        }

        if (isset($this->action['prefix'])) {
            $this->prefix($this->action['prefix']);
        }

        //
        $this->namedParams = $namedParams;
    }

    /**
     * Run the Route action and return the response.
     *
     * @return mixed
     */
    public function run()
    {
        $parameters = array_filter($this->getParams(), function($param)
        {
            return isset($param);
        });

        return call_user_func_array($this->action['uses'], $parameters);
    }

    /**
     * Checks if a Request matches the Route pattern.
     *
     * @param \Http\Request $request The dispatched Request instance
     * @param bool $includingMethod Wheter or not is matched the HTTP Method
     * @return bool Match status
     */
    public function matches(Request $request, $includingMethod = true)
    {
        $this->compileRoute();

        foreach ($this->getValidators() as $validator) {
            if (! $includingMethod && ($validator instanceof MethodValidator)) continue;

            if (! $validator->matches($this, $request)) return false;
        }

        return true;
    }

    /**
     * Compile the Route pattern for matching and return it.
     *
     * @return string
     */
    public function compileRoute()
    {
        if ($this->namedParams) {
            // The Route use the default Named Parameters.
            $this->pattern = preg_replace('/\{(\w+?)\?\}/', '{$1}', $this->uri);

            $optionals = $this->extractOptionalParameters();

            // The requrements for the compiled Symfony Route are just the wheres.
            $requirements = $this->wheres;
        } else {
            // The Route use the legacy Unnamed Parameters.
            list($this->pattern, $optionals, $requirements) = RouteParser::parse(
                $this->uri,
                $this->wheres
            );
        }

        $this->compiled = with(
            new SymfonyRoute($this->pattern, $optionals, $requirements, array(), $this->domain() ?: '')
        )->compile();
    }

    /**
     * Get the optional parameters for the route.
     *
     * @return array
     */
    protected function extractOptionalParameters()
    {
        preg_match_all('/\{(\w+?)\?\}/', $this->uri, $matches);

        return isset($matches[1]) ? $matches[1] : array();
    }

    /**
     * Parse the Route Action into a standard array.
{'fraction_non_alphanumeric': 0.13240946793445277, 'fraction_numerical': 0.0010115314586283633, 'mean_word_length': 1.9879117558174675, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7286846', 'n_tokens_mistral': 2819, 'n_tokens_neox': 2742, 'n_words': 782}