Search code examples
phplaravelrequestconfigbase-path

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!


Solution

  • 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);
            });
        }
    }