Laravel - 从设置表中设置全局变量
我正在尝试将 settings
表中的所有设置存储到一个全局变量中,但我现在被卡住了(我不知道下一步是什么),这是我的实际模型和播种机:
模型 - Settings.php
class 设置扩展模型{受保护的 $table = '设置';公共 $timestamps = false;受保护的 $fillable = ['名称','价值',];}
播种机 - SettingsTableSeeder.php
class SettingsTableSeeder 扩展 Seeder{公共函数运行(){$设置= [['姓名' =>'title', 'value' =>''],['姓名' =>'脸书', '价值' =>''],['姓名' =>'推特', '价值' =>''],['姓名' =>'instagram', '价值' =>'']];foreach($settings 作为 $setting){AppSetting::create($setting);}}}
如何将所有数据存储在设置表中,然后可以从刀片、任何控制器或视图访问?
编辑
<小时>现在,我的问题是,如何更新表单中的单个或多个值?
我已经设置了:
我的路线:
Route::put('/', ['as' => 'setting.update', 'uses' => 'AdminAdminConfiguracoesController@update']);
我的管理员AdminConfiguracoesController:
class AdminConfiguracoesController 扩展了 AdminBaseController{私人 $repository;公共函数 __construct(SettingRepository $repository){$this->repository = $repository;}公共函数geral(){返回视图('admin.pages.admin.configuracoes.geral.index');}公共功能社交(){返回视图('admin.pages.admin.configuracoes.social.index');}公共功能分析(){返回视图('admin.pages.admin.configuracoes.analytics.index');}公共函数更新($id,工厂 $cache,设置 $setting){$this->repository->findByName($setting);$cache->forget('settings');返回重定向('管理员');}}
我的设置存储库:
class SettingRepository{私人 $model;公共函数 __construct(设置 $model){$this->model = $model;}公共函数 findByName($name){返回 $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>@万一<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">
{!!表单::关闭() !!}
但事情并不奏效.如何将值更新到表中?
解决方案查看更新 2 中改进的答案
我会为此添加一个专门的服务提供商.它将读取存储在数据库中的所有设置并将它们添加到 Laravel 配置中.这样,设置只有一个数据库请求,您可以像这样访问所有控制器和视图中的配置:
config('settings.facebook');
第 1 步:创建服务提供者.
您可以使用 artisan 创建服务提供者:
php artisan make:provider SettingsServiceProvider
这将创建文件 app/Providers/SettingsServiceProvider.php
.
第 2 步:将其添加到您刚刚创建的提供程序的引导方法中:
/*** 引导应用程序服务.** @return 无效*/公共函数引导(){//Laravel >= 5.2,对于 Laravel <= 5.1 使用 'lists' 而不是 'pluck'config()->set('settings', AppSetting::pluck('value', 'name')->all());}
来自 Laravel 文档:
<块引用>[启动方法] 在所有其他服务提供者注册后调用,这意味着您可以访问框架注册的所有其他服务.
http://laravel.com/docs/5.1/providers#the-启动方法
第 3 步:在您的应用中注册提供商.
将此行添加到 config/app.php
中的 providers
数组:
AppProvidersSettingsServiceProvider::class,
就是这样.快乐编码!
更新: 我想补充一点,引导方法支持依赖注入.因此,您可以注入存储库/绑定到存储库的接口,而不是硬编码 AppSetting
,这非常适合测试.
更新 2: 作为 Jeemusu 在他的评论中提到,该应用程序将在每次请求时查询数据库.为了阻止这种情况,您可以缓存设置.基本上有两种方法可以做到这一点.
每次管理员更新时将数据放入缓存中设置.
只需记住缓存中的设置一段时间,并在管理员每次更新设置时清除缓存.
为了让思考更具容错性,我会使用第二个选项.缓存可能会被无意清除.只要管理员没有设置设置或者您在服务器崩溃后重新安装,第一个选项就会在全新安装时失败.
对于第二个选项,更改服务提供商启动方法:
/*** 引导应用程序服务.** @param IlluminateContractsCacheFactory $cache* @param AppSetting $settings** @return 无效*/公共功能引导(工厂 $cache,设置 $settings){$settings = $cache->remember('settings', 60, function() use ($settings){//Laravel >= 5.2,对于 Laravel <= 5.1 使用 'lists' 而不是 'pluck'返回 $settings->pluck('value', 'name')->all();});config()->set('settings', $settings);}
现在你只需要在管理员更新设置后让缓存忘记设置键:
/*** 更新设置.** @param int $id* @param IlluminateContractsCacheFactory $cache** @return IlluminateHttpRedirectResponse*/公共函数更新($id,工厂 $cache){//...//当设置更新后,清除键 'settings' 的缓存:$cache->forget('settings');//例如,重定向回设置索引页面并显示成功的提示信息return redirect()->route('admin.settings.index')->with('更新', 真);}
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){
AppSetting::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' => 'AdminAdminConfiguracoesController@update']);
My AdminAdminConfiguracoesController:
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', AppSetting::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
:
AppProvidersSettingsServiceProvider::class,
And that's it. Happy coding!
Update: I want to add that the boot-method supports dependency injection. So instead of hard coding AppSetting
, 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.
Put the data into the cache every time the admin is updating the settings.
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 IlluminateContractsCacheFactory $cache
* @param AppSetting $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 IlluminateContractsCacheFactory $cache
*
* @return IlluminateHttpRedirectResponse
*/
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);
}
相关文章