Laravel-从设置表设置全局变量 [英] Laravel - Set global variable from settings table

查看:121
本文介绍了Laravel-从设置表设置全局变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试将我的settings表中的所有设置存储到全局变量中,但是现在我被困住了(我不知道下一步是什么),这是我的实际模型和播种器:

模型-Settings.php

class Setting extends Model
{
    protected $table = 'settings';

    public $timestamps = false;

    protected $fillable = [
        'name',
        'value',
    ];
}

seeder-SettingsTableSeeder.php

class SettingsTableSeeder extends Seeder
{
    public function run()
    {

        $settings = [
            ['name' => 'title', 'value' => ''],
            ['name' => 'facebook', 'value' => ''],
            ['name' => 'twitter', 'value' => ''],
            ['name' => 'instagram', 'value' => '']
        ];

        foreach($settings as $setting){
            \App\Setting::create($setting);
        }
    }
}

我如何将所有数据存储在设置表中,然后从刀片服务器,任何控制器或视图中访问这些数据?

编辑


现在,我的问题是,如何从表单更新单个或多个值?

我已经设置好了

我的路线:

Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController@update']);

我的Admin \ AdminConfiguracoesController:

class AdminConfiguracoesController extends AdminBaseController
{
    private $repository;

    public function __construct(SettingRepository $repository){
        $this->repository = $repository;
    }

    public function geral()
    {
        return view('admin.pages.admin.configuracoes.geral.index');
    }

    public function social()
    {
        return view('admin.pages.admin.configuracoes.social.index');
    }

    public function analytics()
    {
        return view('admin.pages.admin.configuracoes.analytics.index');
    }

    public function update($id, Factory $cache, Setting $setting)
    {
        $this->repository->findByName($setting);

        $cache->forget('settings');

        return redirect('admin');
    }
}

我的设置资料库:

class SettingRepository
{
    private $model;

    public function __construct(Setting $model)
    {
        $this->model = $model;
    }

    public function findByName($name){
        return $this->model->where('name', $name)->update();
    }
}

我的刀片形式:

{!! Form::model(config('settings'), ['class' => 's-form', 'route' => ['setting.update']]) !!}
{{ method_field('PUT') }}
<div class="s-form-item text">
    <div class="item-title required">Título do artigo</div>
    {!! Form::text('title', null, ['placeholder' => 'Nome do site']) !!}
    @if($errors->has('title'))
        <div class="item-desc">{{ $errors->first('title') }}</div>
    @endif
</div>
<div class="s-form-item s-btn-group s-btns-right">
    <a href="{{ url('admin') }}" class="s-btn cancel">Voltar</a>
    <input class="s-btn" type="submit" value="Atualizar">
</div>
{!! Form::close() !!}

但是事情不起作用.如何将值更新到表中?

解决方案

查看更新2中的改进答案

我将为此添加专门的服务提供商.它将读取存储在数据库中的所有设置,并将它们添加到Laravels配置中.这样,只需要一个数据库请求设置,就可以在所有控制器和视图中访问该配置,如下所示:

 config('settings.facebook');
 

第1步:创建服务提供商.

您可以与工匠一起创建服务提供商:

php artisan make:provider SettingsServiceProvider

这将创建文件app/Providers/SettingsServiceProvider.php.

步骤2:将其添加到刚创建的提供程序的引导方法中:

 /**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1
    config()->set('settings', \App\Setting::pluck('value', 'name')->all());
}
 

来自Laravel文档:

[启动方法]在所有其他服务提供者都已注册之后被调用,这意味着您可以访问框架已注册的所有其他服务.

http://laravel.com/docs/5.1/providers#the-引导方法

第3步:在您的应用中注册提供商.

将此行添加到config/app.php中的providers数组中:

 App\Providers\SettingsServiceProvider::class,
 

就是这样.编码愉快!

更新:我想补充一下,该引导方法支持依赖项注入.因此,您可以注入一个存储库/绑定到该存储库的接口,而不是对\App\Setting进行硬编码,这对于测试非常有用.

更新2: /** * Bootstrap the application services. * * @param \Illuminate\Contracts\Cache\Factory $cache * @param \App\Setting $settings * * @return void */ public function boot(Factory $cache, Setting $settings) { $settings = $cache->remember('settings', 60, function() use ($settings) { // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1 return $settings->pluck('value', 'name')->all(); }); config()->set('settings', $settings); }

现在,您只需要在管理员更新设置后使缓存忘记设置键即可.

 /**
 * Updates the settings.
 *
 * @param int                                 $id
 * @param \Illuminate\Contracts\Cache\Factory $cache
 *
 * @return \Illuminate\Http\RedirectResponse
 */
public function update($id, Factory $cache)
{
    // ...

    // When the settings have been updated, clear the cache for the key 'settings':
    $cache->forget('settings');

    // E.g., redirect back to the settings index page with a success flash message
    return redirect()->route('admin.settings.index')
        ->with('updated', true);
}
 

I'm trying to store all my settings from my settings table into a global variable, but I'm stucked now(I have no idea what's the next step), this is my actual model and seeder:

model - Settings.php

class Setting extends Model
{
    protected $table = 'settings';

    public $timestamps = false;

    protected $fillable = [
        'name',
        'value',
    ];
}

seeder - SettingsTableSeeder.php

class SettingsTableSeeder extends Seeder
{
    public function run()
    {

        $settings = [
            ['name' => 'title', 'value' => ''],
            ['name' => 'facebook', 'value' => ''],
            ['name' => 'twitter', 'value' => ''],
            ['name' => 'instagram', 'value' => '']
        ];

        foreach($settings as $setting){
            \App\Setting::create($setting);
        }
    }
}

How can I store all the data inside the settings table and make then acessible from blade, or any controller or view?

Edit


Now, my question is, how can i update a single or multiple value(s) from a form?

I have set this up:

My route:

Route::put('/', ['as' => 'setting.update', 'uses' => 'Admin\AdminConfiguracoesController@update']);

My Admin\AdminConfiguracoesController:

class AdminConfiguracoesController extends AdminBaseController
{
    private $repository;

    public function __construct(SettingRepository $repository){
        $this->repository = $repository;
    }

    public function geral()
    {
        return view('admin.pages.admin.configuracoes.geral.index');
    }

    public function social()
    {
        return view('admin.pages.admin.configuracoes.social.index');
    }

    public function analytics()
    {
        return view('admin.pages.admin.configuracoes.analytics.index');
    }

    public function update($id, Factory $cache, Setting $setting)
    {
        $this->repository->findByName($setting);

        $cache->forget('settings');

        return redirect('admin');
    }
}

My SettingRepository:

class SettingRepository
{
    private $model;

    public function __construct(Setting $model)
    {
        $this->model = $model;
    }

    public function findByName($name){
        return $this->model->where('name', $name)->update();
    }
}

My blade form:

{!! Form::model(config('settings'), ['class' => 's-form', 'route' => ['setting.update']]) !!}
{{ method_field('PUT') }}
<div class="s-form-item text">
    <div class="item-title required">Título do artigo</div>
    {!! Form::text('title', null, ['placeholder' => 'Nome do site']) !!}
    @if($errors->has('title'))
        <div class="item-desc">{{ $errors->first('title') }}</div>
    @endif
</div>
<div class="s-form-item s-btn-group s-btns-right">
    <a href="{{ url('admin') }}" class="s-btn cancel">Voltar</a>
    <input class="s-btn" type="submit" value="Atualizar">
</div>
{!! Form::close() !!}

But things does not work. How can I update the values into the table?

解决方案

See improved answer in Update 2

I would add a dedicated Service Provider for this. It will read all your settings stored in the database and add them to Laravels config. This way there is only one database request for the settings and you can access the configuration in all controllers and views like this:

config('settings.facebook');

Step 1: Create the Service Provider.

You can create the Service Provider with artisan:

php artisan make:provider SettingsServiceProvider

This will create the file app/Providers/SettingsServiceProvider.php.

Step 2: Add this to the boot-method of the provider you have just created:

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{
    // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1
    config()->set('settings', \App\Setting::pluck('value', 'name')->all());
}

From the Laravel Docs:

[The boot method] is called after all other service providers have been registered, meaning you have access to all other services that have been registered by the framework.

http://laravel.com/docs/5.1/providers#the-boot-method

Step 3: Register the provider in your App.

Add this line to the providers array in config/app.php:

App\Providers\SettingsServiceProvider::class,

And that's it. Happy coding!

Update: I want to add that the boot-method supports dependency injection. So instead of hard coding \App\Setting, you could inject a repository / an interface that is bound to the repository, which is great for testing.

Update 2: As Jeemusu mentioned in his comment, the app will query the database on every request. In order to hinder that, you can cache the settings. There are basically two ways you can do that.

  1. Put the data into the cache every time the admin is updating the settings.

  2. Just remember the settings in the cache for some time and clear the cache every time the admin updates the settings.

To make thinks more fault tolerant, I'd use the second option. Caches can be cleared unintentionally. The first option will fail on fresh installations as long as the admin did not set the settings or you reinstall after a server crash.

For the second option, change the Service Providers boot-method:

/**
 * Bootstrap the application services.
 *
 * @param \Illuminate\Contracts\Cache\Factory $cache
 * @param \App\Setting                        $settings
 * 
 * @return void
 */
public function boot(Factory $cache, Setting $settings)
{
    $settings = $cache->remember('settings', 60, function() use ($settings)
    {
        // Laravel >= 5.2, use 'lists' instead of 'pluck' for Laravel <= 5.1
        return $settings->pluck('value', 'name')->all();
    });

    config()->set('settings', $settings);
}

Now you only have to make the cache forget the settings key after the admin updates the settings:

/**
 * Updates the settings.
 *
 * @param int                                 $id
 * @param \Illuminate\Contracts\Cache\Factory $cache
 *
 * @return \Illuminate\Http\RedirectResponse
 */
public function update($id, Factory $cache)
{
    // ...

    // When the settings have been updated, clear the cache for the key 'settings':
    $cache->forget('settings');

    // E.g., redirect back to the settings index page with a success flash message
    return redirect()->route('admin.settings.index')
        ->with('updated', true);
}

这篇关于Laravel-从设置表设置全局变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆