Support the ongoing development of Laravel.io →
Configuration Requests Architecture
Last updated 1 year ago.
0

I would just try. Setup a new 'api' environment for api.example.com and then try to query a route that shouldn't work with it.

Last updated 1 year ago.
0

So, for the future googlers out there, here is what I ended up doing. I add a "sub" environment to my environment detection for configurations. So, now, I have environment detection based on machine name AND beneath that site detection based on subdoman (or root). My configs now cascade:

app/config/environment/site/file.php app/config/environment/file.php app/config/file.php

or

app/config/local/api/app.php app/config/local/app.php app/config/app.php (production)

This allows me to load specific configurations (including Facades and Service Providers) for my subdomains while maintaining different environments.

Here how I did it (I haven't tested this for security vulnerabilities on production yet, but its pretty simple):

Step One: Modify Environment Detection
In my bootstrap/start.php, I edited $app->detectEnvironment like so

$env = $app->detectEnvironment(	function () use ($app) {
    
    // First, we find the environment
    $hosts = array(
	'dev' => array('DarkeMedia'),
	'staging' => array('SomethingElse'),
    );

    $args = isset($_SERVER['argv']) ? $_SERVER['argv'] : null;

    $environment = $app['env'] = with(new Illuminate\Foundation\EnvironmentDetector())->detect($hosts, $args);

    // Now, discover the subdomain site
    $http_pieces = explode(".", $app->request->server('HTTP_HOST') );
    
    $GLOBALS['site'] = ( count($http_pieces) > 2 ) ? array_shift($http_pieces) : 'root';

    return $environment;
});

Step Two: Extend the FileLoader to cascade the extra level
First, created my own Application class that extended Illuminate\Foundation\Application.
Next, I instantiated my application in bootstrap/start.php.

//$app = new Illuminate\Foundation\Application;

$app = new Director\Application;

In my Application, I overloaded the getConfigLoader() method. This method is responsible for return an instance of the Config File Loader. This loader is what actually finds and loads the config files. I wanted to adapt this to search another layer deeper. In order to accomplish this without editing core, I simply extended FileLoader and told Laravel to use mine instead.

namespace Director;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Application as LaravelApp;

Class Application extends LaravelApp\{  
    
    /*
     * Overload the Config Loader
     */
    public function getConfigLoader()
    {
            // This FileLoader is under my namespace (Director\FileLoader)
	    return new FileLoader(new Filesystem, $this['path'].'/config');
    }

Step Three: Adapt the FileLoader
Now, I created the FileLoader Class that extends \Illuminate\Config\FileLoader

namespace Director;
use \Illuminate\Config\FileLoader;

Class FileLoader extends FileLoader{  
    
    /*
     * Overload the Config Loader
     */
	public function load($environment, $group, $namespace = null)
	{
	    // Call the parent, so it looks in all the normal place
		$items = parent::load($environment,$group,$namespace);
		
		// Now look for one more level of cascade based on the global $site we created in bootstrap/start.php
                $path = $this->getPath($namespace);
		$site = $GLOBALS['site'];
		
		$file = "{$path}/{$environment}/{$site}/{$group}.php";

		if (file_exists($file))
		{
			$items = $this->mergeEnvironment($items, $file);
		}

		return $items;
	}

It may not be the most elegant solution, but it worked for me. Interested to know how I could clean this up!

Last updated 1 year ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.