Bryce Bryce - 4 months ago 42
PHP Question

Laravel view.php use config::get variable in base_path

I am trying to do this in laravel 5.2 view.php (edit base_path to use a config variable in the string):

<?php

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Request;

return [

/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/

'paths' => [
realpath(base_path('resources/views/layouts/' . Config::get('api.' . Request::get('domain') . '.layout'))),
],


But now I receive this error:


Fatal error: Uncaught exception 'ReflectionException' with message 'Class log does not exist' in /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php:734 Stack trace: #0 /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php(734): ReflectionClass->__construct('log') #1 /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php(629): Illuminate\Container\Container->build('log', Array) #2 /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(697): Illuminate\Container\Container->make('log', Array) #3 /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php(849): Illuminate\Foundation\Application->make('Psr\Log\LoggerI...') #4 /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php(804): Illuminate\Container\Container->resolveClass(Object(ReflectionParameter)) #5 /Applications/AMPPS/www/loan/vendor/l in /Applications/AMPPS/www/loan/vendor/laravel/framework/src/Illuminate/Container/Container.php on line 734


How do I fix this? Because everything I try doesn't work.
Thanks ahead of time!

Answer

You need to move this logic out to your ViewServiceProvider instead of trying to do this directly in the config file, that's a big no no.

So what we're going to do is

php artisan make:provider MyViewServiceProvider

Which is going to result in a file existing at:

App\Providers\MyViewServiceProvider

Now we're going to open config/app.php. Find the existing ViewServiceProvider::class in this file and replace it with the namespaced path above. It should look something like this:

//the old Illuminate\View\ViewServiceProvider::class
App\Providers\MyViewServiceProvider::class,

Now inside of the registerViewFinder() function, we can overload our view paths.

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Config;

public function registerViewFinder()
{
    $this->app->bind('view.finder', function ($app) {
        $custom_path = base_path('resources/views/layouts/' . Config::get('api.' . $this->app->request()->get('domain') . '.layout')
        $paths = array_merge(
            [$custom_path],
            $app['config']['view.paths']
        );

        return new FileViewFinder($app['files'], $paths);
    });
}

Going this route will ensure that your path is observed first. If the view is not found in that path, then you can fallback to Laravel's default view path.

Edit

It's important to note that your class needs to extend the default ViewServiceProvider, and that there are 2 other functions you must declare, the whole file should look like below:

<?php

namespace App\Providers;

use Illuminate\View\ViewServiceProvider;
use Illuminate\Support\Facades\Config;

class MyViewServiceProvider extends ViewServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        parent::register();
    }

    /**
     * Register the view finder implementation.
     *
     * @return void
     */
    public function registerViewFinder()
    {
        $this->app->bind('view.finder', function ($app) {
            $custom_path = base_path('resources/views/layouts/' . Config::get('api.' . $this->app->request->get('domain') . '.layout')
            $paths = array_merge(
                [$custom_path],
                $app['config']['view.paths']
            );

            return new FileViewFinder($app['files'], $paths);
        });
    }
}
Comments