caffeinated / modules

:package: Modules package for Laravel
https://caffeinatedpackages.com
MIT License
954 stars 230 forks source link

Suggestion: GuessModule middleware #248

Closed drjonnicholson closed 8 years ago

drjonnicholson commented 8 years ago

Our project uses Caffeinated/Modules with Laravel Spark. Spark has it's own routes set up that are difficult to modify without overriding/replacing classes etc.

In our case each module defines a subdomain where some (all, no) aspects of Spark will be available in certain subdomains. Or rather, the UI of how to get there is hidden/different per subdomain.

To solve this I made the middleware GuessModule that attempts to guess the module based on the first part of the hosts' domain. It can be added to the web middleware so that all routes use it, but if the IdentifyModule middleware also exists on a route then the session value will be explicitly overridden.

This is more a concept I thought would be good to share and any feedback welcome. This could be extended to also look at the first part of a path if that's how the modules are accessed, perhaps controllable from settings? Thoughts?

<?php

namespace App\Http\Middleware;

use Caffeinated\Modules\Modules;
use Closure;

class GuessModule
{
    /**
     * @var Caffeinated\Modules
     */
    protected $modules;

    /**
     * Create a new GuessModule instance.
     *
     * @param Caffeinated\Modules $module
     */
    public function __construct(Modules $modules)
    {
        $this->modules = $modules;
    }

    /**
     *  Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->session()->has('module')) {
            return $next($request);
        }

        $module = $this->modules->where('slug', explode(".", $request->server()['HTTP_HOST'], 2)[0]);
        if ($module) {
            $request->session()->flash('module', $module);
        }
        return $next($request);
    }
}
kaidesu commented 8 years ago

Interesting. Can't say that I would add this to the package itself, but I do see its use case.

I would say that the IdentifyModule middleware could check if the session already has a module key is set and continue to the next request (like you have in your GuessModule middleware). That way you could use your middleware as long as its fired beforehand~

drjonnicholson commented 8 years ago

Agreed, more I think of it I don't think this is something to add to the project as it is quite a specific use case. I'll do a gist instead in case anyone has a similar use case. Feel free to close the issue.

Regarding tweaking IdentifyModule... it's not necessary. If GuessModule runs first it populates the session with a possible result, the IdentifyModule Middleware overrides that guess. If it happens to execute the other way the guess shouldn't override the explicit IdentifyModule middleware. So no changes to your code needed :)

kaidesu commented 8 years ago

Ah, right, good catch!