<commit_before><?php
/**
 * @copyright (c) 2016 Quicken Loans Inc.
 *
 * For full license information, please view the LICENSE distributed with this source code.
 */

namespace QL\Panthor\Middleware;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use QL\Panthor\Exception\Exception;
use Slim\App;
use Interop\Container\ContainerInterface;

/**
 * Convert a flat array into slim routes and attaches them to the slim application.
 *
 * This hook should be attached to the "slim.before.router" event.
 */
class RouteLoaderMiddleware
{
    /**
     * A hash of valid http methods. The keys are the methods.
     *
     * @type array
     */
    private $methods;

    /**
     * @type App
     */
    private $slim;

    /**
     * @type ContainerInterface
     */
    private $container;

    /**
     * @type array
     */
    private $routes;

    /**
     * @param ContainerInterface $container
     * @param array $routes
     */
    public function __construct(ContainerInterface $container, array $routes = [])
    {
        $this->slim = $container->get('panthor.slim');
        $this->container = $container;
        $this->routes = $routes;

        // These are the only methods supported by Slim
        $validMethods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT'];
        $this->methods = array_fill_keys($validMethods, true);
    }

    /**
     * @param array $routes
     *
     * @return void
     */
    public function addRoutes(array $routes)
    {
        $this->routes = array_merge($this->routes, $routes);
    }

    public function __invoke(RequestInterface $request, ResponseInterface $response, $next)
    {
        $this->loadRoutes($this->slim, $this->routes);
        return $next($request, $response);
    }

    /**
     * Load routes into the application
     *
     * @param App $slim
     * @param array $routes
     *
     * @return void
     */
    public function loadRoutes(App $slim, $routes = null)
    {
        if (is_null($routes)) {
            $routes = $this->routes;
        }
        foreach ($routes as $name => $details) {

            $methods = $this->methods($details);
            $group = $this->nullable('group', $details);
            $url = $details['route'];
            $stack = $this->nullable('stack', $details);
            if (!is_null($stack)) {
                $stack = $this->convertStackToCallables($details['stack']);
            }

            // Create route
            if (!is_null($group)) {
                //Groups can't be named or have methods, just their constituents.
                $access = $this;
                $route = $slim->group($url, function () use ($slim, $group, $access) {
                    $access->loadRoutes($slim, $group);
                });

            } else {
                $route = $slim->map($methods, $url, array_pop($stack));
                $route->setName($name);
            }

            if (count($stack) > 0) {
                array_map([$route, 'add'], $stack);
            }
        }
    }

    /**
     * Convert an array of keys to middleware callables
     *
     * @param string[] $stack
     *
     * @return callable[]
     */
    private function convertStackToCallables(array $stack)
    {
        $container = $this->container;
        foreach ($stack as &$key) {
            $key = function ($req, $res, $var) use ($container, $key) {
                return call_user_func($container->get($key), $req, $res, $var);
            };
        }

        return $stack;
    }

    /**
     * @param array $routeDetails
     * 
     * @throws Exception
     *
     * @return string[]
     */
    private function methods(array $routeDetails)
    {
        // No method matches ANY method
        if (!$methods = $this->nullable('method', $routeDetails)) {
            return array_keys($this->methods);
        }

        if ($methods && !is_array($methods)) {
            $methods = [$methods];
        }

        if ($methods === ['GET']) {
            array_push($methods, 'HEAD');
        }

        return $methods;
    }

    /**
     * @param string $key
     * @param array $data
     *
     * @return mixed|null
     */
    private function nullable($key, array $data)<commit_msg>Allow use of any protocol in route loader<commit_after><?php
/**
 * @copyright (c) 2016 Quicken Loans Inc.
 *
 * For full license information, please view the LICENSE distributed with this source code.
 */

namespace QL\Panthor\Middleware;

use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use QL\Panthor\Exception\Exception;
use Slim\App;
use Interop\Container\ContainerInterface;

/**
 * Convert a flat array into slim routes and attaches them to the slim application.
 *
 * This hook should be attached to the "slim.before.router" event.
 */
class RouteLoaderMiddleware
{
    /**
     * A hash of valid http methods. The keys are the methods.
     *
     * @type array
     */
    private $methods;

    /**
     * @type App
     */
    private $slim;

    /**
     * @type ContainerInterface
     */
    private $container;

    /**
     * @type array
     */
    private $routes;

    /**
     * @param ContainerInterface $container
     * @param array $routes
     */
    public function __construct(ContainerInterface $container, array $routes = [])
    {
        $this->slim = $container->get('panthor.slim');
        $this->container = $container;
        $this->routes = $routes;

        // These are the only methods supported by Slim
        $validMethods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT'];
        $this->methods = array_fill_keys($validMethods, true);
    }

    /**
     * @param array $routes
     *
     * @return void
     */
    public function addRoutes(array $routes)
    {
        $this->routes = array_merge($this->routes, $routes);
    }

    public function __invoke(RequestInterface $request, ResponseInterface $response, $next)
    {
        $this->loadRoutes($this->slim, $this->routes);
        return $next($request, $response);
    }

    /**
     * Load routes into the application
     *
     * @param App $slim
     * @param array $routes
     *
     * @return void
     */
    public function loadRoutes(App $slim, $routes = null)
    {
        if (is_null($routes)) {
            $routes = $this->routes;
        }
        foreach ($routes as $name => $details) {

            $methods = $this->methods($details);
            $group = $this->nullable('group', $details);
            $url = $details['route'];
            $stack = $this->nullable('stack', $details);
            if (!is_null($stack)) {
                $stack = $this->convertStackToCallables($details['stack']);
            }

            // Create route
            if (!is_null($group)) {
                //Groups can't be named or have methods, just their constituents.
                $access = $this;
                $route = $slim->group($url, function () use ($slim, $group, $access) {
                    $access->loadRoutes($slim, $group);
                });

            } else {
                $route = $slim->map($methods, $url, array_pop($stack));
                $route->setName($name);
            }

            if (count($stack) > 0) {
                array_map([$route, 'add'], $stack);
            }
        }
    }

    /**
     * Convert an array of keys to middleware callables
     *
     * @param string[] $stack
     *
     * @return callable[]
     */
    private function convertStackToCallables(array $stack)
    {
        $container = $this->container;
        foreach ($stack as &$key) {
            $key = function ($req, $res, $var) use ($container, $key) {
                return call_user_func($container->get($key), $req, $res, $var);
            };
        }

        return $stack;
    }

    /**
     * @param array $routeDetails
     * 
     * @throws Exception
     *
     * @return string[]
     */
    private function methods(array $routeDetails)
    {
        // No method matches ANY method
        if (!$methods = $this->nullable('method', $routeDetails)) {
            return array_keys($this->methods);
        }

        if ($methods && !is_array($methods)) {
            $methods = [$methods];
        }

        return $methods;
    }

    /**
     * @param string $key
     * @param array $data
     *
     * @return mixed|null
     */
    private function nullable($key, array $data)
{'fraction_non_alphanumeric': 0.1407635031320175, 'fraction_numerical': 0.0011818933932159319, 'mean_word_length': 1.9209527096996892, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 53, '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': '4427849', 'n_tokens_mistral': 2455, 'n_tokens_neox': 2424, 'n_words': 619}