HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers95/rentman.io/app/Http/Middleware/WildcardResolver.php
<?php

namespace App\Http\Middleware;

use App\Komma\Routes\Models\Route;
use Closure;

final class WildcardResolver extends AbstractResolver
{
    private $wildcardFileNamespace = 'App\Http\Wildcards\\';

    /**
     * @param \Illuminate\Http\Request $request
     * @param Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Check if middleware could be skipped or is already resolved
        if ($this->isRouteResolved($request) || $this->isKmsRoute($request) || $this->isRootRoute($request)) {
            return $next($request);
        }

        // Resolve type routing
        $wildcardRequest = $this->resolveType($request->segments());

        // If route alias doesn't exist continue as usual
        // Or if the tail has no items that means that the wildcard type page is inactive
        // Will most likely throw 404 error...
        if (! $wildcardRequest || (isset($wildcardRequest->tail) && count($wildcardRequest->tail) == 0)) {
            return $next($request);
        }

        //Duplicate the request so we can generate an restful Request
        $modifiedRequest = $request->duplicate();

        // Create wildcard instance for type
        $wildcardInstanceName = $this->resolveWildcardNamespace($wildcardRequest->type->route);
        $wildcardInstance = new $wildcardInstanceName;

        // Let the wildcard instance handle the rest of resolving
        $modifiedRequest = $wildcardInstance->handle($modifiedRequest, $wildcardRequest);

        //Set the resolved key on the request to tell other route solving things that they don't need to resolve
        $modifiedRequest = $this->setRouteResolved($modifiedRequest, true);

        return $next($modifiedRequest);
    }

    /**
     * Resolve route into type and tail
     *
     * @param $segments
     * @return null|object
     */
    private function resolveType($segments)
    {
        // Find all Route models which aren't of page type
        $resolvableRoutes = Route::where('route', 'NOT LIKE', 'pages/%')
            ->get();

        // Set parameters
        $filterSegments = [];
        $typeRoute = null;

        // Loop backwards through the segment to find the highest resolvable route
        // Until there no more segments or the type is resolved
        do {
            // Generate type alias by given segments
            $lastSegmentKey = (count($segments) - 1);
            $typeAlias = '';
            foreach ($segments as $key => $segment) {
                $typeAlias .= $segment;
                if ($key != $lastSegmentKey) {
                    $typeAlias .= '/';
                }
            }

            // Try to find the alias in the resolvable routes
            $searchInResolvableRoutes = $resolvableRoutes->where('alias', $typeAlias);

            // If not empty then, it is the highest resolvable route
            if ($searchInResolvableRoutes->isNotEmpty()) {
                $typeRoute = $searchInResolvableRoutes->first();
            } else {
                // Append segment to filter segments, and remove from search segments
                $filterSegments[] = $segments[$lastSegmentKey];
                array_forget($segments, $lastSegmentKey);
            }
        } while (count($segments) > 0 && $typeRoute == null);

        // If no type route is found, return false
        if (! isset($typeRoute)) {
            return null;
        }

        //Get language of the route
        $language = $typeRoute->pageTranslation->language;

        //Check if URL matches the set language else redefine it
        if (isset($language) && \App::getLanguage() != $language) {
            \App::setLanguage($language);
        }

        return (object) [
            'type' => $typeRoute,
            'tail' => $filterSegments,
        ];
    }

    /**
     * @param string $type
     * @return string
     */
    private function resolveWildcardNamespace(string $type)
    {
        $wildcardClass = ucfirst($type.'Wildcard');
        $wildcardFQCN = $this->wildcardFileNamespace.$wildcardClass;

        if (! class_exists($wildcardFQCN)) {
            throw new \InvalidArgumentException("$wildcardClass isn't implemented in the wildcard folder");
        }

        return $wildcardFQCN;
    }
}