Snapey's avatar
Level 122

Globally available settings

I've created a Settings model and database table to contain things like email addresses, pagination limits, custom colours - all sorts of settings for the site that I don't want baked into the code.

What I want to create is a helper that loads all the settings on first use and can then be accessed anywhere in the application with just a helper like the session helper, eg setting('email.from')

What's the easiest way to implement?

0 likes
8 replies
arthurvillar's avatar

You could try creating a config file (maybe config/settings.php) that returns an array of whatever you will need from the settings table. Load the values from the model in there (or even better save them in the cache) and you should be able to call config('email.from'). This article may help! This is the most straightforward way I can think of.

1 like
skliche's avatar
skliche
Best Answer
Level 42

No need to create a config file, just push it to the config array at runtime:

config(['settings' => $settings]);

You can access it anywhere you want and use a helper function to encapsulate the call to the config.

Snapey's avatar
Level 122

I forget that the config files are scripts with a return at the top!

Yes, I could create a settings file that loads all from the model and returns it as an array.

I'll have a play in a bit. Thanks @arthurvillar

Snapey's avatar
Level 122

I think creating a settings.php file is an issue as it is being parsed before the database connection is created.

arthurvillar's avatar

Then probably @skliche 's solution should work. You can create the config file inside the boot method in a service provider class like AppServiceProvider. You can probably refactor it later, since it may become ugly soon.

skliche's avatar

Helper

if (! function_exists('settings')) {

    function settings($key = null, $default = null) {
        $prefix = 'settings';

        if (is_null($key)) {
            return app('config')->get($prefix);
        }

        if (is_array($key)) {
            return app('config')->set(
                collect($key)->mapWithKeys(function($value, $key) use ($prefix) {
                    return ["{$prefix}.{$key}" => $value];
                })->toArray()
            );
        }

        return app('config')->get("{$prefix}.{$key}", $default);
    }

}

Setting values

settings(['email' => '[email protected]', 'name' => 'Jeffrey']);

Querying values

dump(settings());
array:2 [▼
  "email" => "[email protected]"
  "name" => "Jeffrey"
]

dump(settings('email'));
"[email protected]"

dump(settings('name'));
"Jeffrey"

dump(config('settings'));
array:2 [▼
  "email" => "[email protected]"
  "name" => "Jeffrey"
]
jlrdw's avatar

Wouldn't hurt to have a class with static methods for global use, of course a use statement is required. As example I use this to figure out a checkbox:

    public static function fixCheck($rchk) {
        $rchk = ($rchk == 'on' || $rchk == '1' || strlen($rchk) > 0 ? '1' : '0');
        return $rchk;
    }

This way a 0 is entered in database if unchecked otherwise a 1 is entered.

Just a quick example. And I have found static methods are pretty darn fast when something is needed on the fly.

Snapey's avatar
Level 122

@arthurvillar / @skliche

Thanks for your help guys. Sorry for the delay but I've been off having my dinner.

I decided to piggy-back on the existing config helper, with the following added to AppServiceProvider

public function boot()
{
    config(['settings' => Settings::pluck('value','key')->toArray()]);    
}

With a Settings table/model that has key and value columns, this gives me anywhere access to for instance; config('settings.memberPaginator') and rather than putting this in the config files, the settings can be changed through the UI.

I marked @skliche best answer because he(?) did put a lot of effort in and it was not his fault it was not used.

@jlrdw you seem to have posted an answer against the wrong question. ;-)

1 like

Please or to participate in this conversation.