committed by
GitHub
26 changed files with 859 additions and 20 deletions
@ -0,0 +1,102 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Http\Controllers; |
||||
|
|
||||
|
use Illuminate\Http\Request; |
||||
|
use App\Setting; |
||||
|
use App\SettingGroup; |
||||
|
use App\Http\Controllers\Controller; |
||||
|
|
||||
|
class SettingsController extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* @return \Illuminate\View\View |
||||
|
*/ |
||||
|
public function index() |
||||
|
{ |
||||
|
$settings = SettingGroup::with([ |
||||
|
'settings', |
||||
|
])->orderBy('order', 'ASC')->get(); |
||||
|
|
||||
|
return view('settings.list')->with([ |
||||
|
'groups' => $settings, |
||||
|
]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return \Illuminate\Http\RedirectResponse |
||||
|
*/ |
||||
|
public function edit($id) |
||||
|
{ |
||||
|
$setting = Setting::find($id); |
||||
|
|
||||
|
if((bool)$setting->system === true) return abort(404); |
||||
|
|
||||
|
if (!is_null($setting)) { |
||||
|
return view('settings.edit')->with([ |
||||
|
'setting' => $setting, |
||||
|
]); |
||||
|
} else { |
||||
|
return redirect()->route('settings.list')->with([ |
||||
|
'error' => 'This Setting does not exist.', |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return \Illuminate\Http\RedirectResponse |
||||
|
*/ |
||||
|
public function update(Request $request, $id) |
||||
|
{ |
||||
|
$setting = Setting::find($id); |
||||
|
|
||||
|
if (!is_null($setting)) { |
||||
|
$data = Setting::getInput(); |
||||
|
|
||||
|
if ($setting->type == 'image') { |
||||
|
|
||||
|
|
||||
|
if($request->hasFile('value')) { |
||||
|
$path = $request->file('value')->store('backgrounds'); |
||||
|
$setting->value = $path; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
} else { |
||||
|
$setting->value = $data->value; |
||||
|
} |
||||
|
|
||||
|
$setting->save(); |
||||
|
|
||||
|
return redirect()->route('settings.index')->with([ |
||||
|
'success' => 'You have successfully edited this Setting!', |
||||
|
]); |
||||
|
} else { |
||||
|
return redirect()->route('settings.index')->with([ |
||||
|
'error' => 'This Setting does not exist.', |
||||
|
]); |
||||
|
} |
||||
|
} |
||||
|
/** |
||||
|
* @param int $id |
||||
|
* |
||||
|
* @return \Illuminate\Http\RedirectResponse |
||||
|
*/ |
||||
|
public function clear($id) |
||||
|
{ |
||||
|
$setting = Setting::find($id); |
||||
|
if((bool)$setting->system !== true) { |
||||
|
$setting->value = ''; |
||||
|
$setting->save(); |
||||
|
} |
||||
|
return redirect()->route('settings.index')->with([ |
||||
|
'success' => 'You have successfully edited this Setting!', |
||||
|
]); |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,211 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
use Illuminate\Support\Facades\Input; |
||||
|
use Form; |
||||
|
|
||||
|
class Setting extends Model |
||||
|
{ |
||||
|
/** |
||||
|
* The database table used by the model. |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'settings'; |
||||
|
|
||||
|
/** |
||||
|
* Tell the Model this Table doesn't support timestamps. |
||||
|
* |
||||
|
* @var bool |
||||
|
*/ |
||||
|
public $timestamps = false; |
||||
|
|
||||
|
/** |
||||
|
* Cache storage for Settings. |
||||
|
* |
||||
|
* @var array |
||||
|
*/ |
||||
|
protected static $cache = []; |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
*/ |
||||
|
public static function getInput() |
||||
|
{ |
||||
|
return (object) [ |
||||
|
'value' => Input::get('value'), |
||||
|
'image' => Input::file('value'), |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
public function getListValueAttribute() |
||||
|
{ |
||||
|
switch($this->type) { |
||||
|
case 'image': |
||||
|
if(!empty($this->value)) { |
||||
|
$value = '<a href="'.asset('storage/'.$this->value).'" title="View" target="_blank">View</a>'; |
||||
|
} else { |
||||
|
$value = '- not set -'; |
||||
|
} |
||||
|
break; |
||||
|
case 'boolean': |
||||
|
if((bool)$this->value === true) { |
||||
|
$value = 'Yes'; |
||||
|
} else { |
||||
|
$value = 'No'; |
||||
|
} |
||||
|
break; |
||||
|
case 'select': |
||||
|
if(!empty($this->value) && $this->value !== 'none') { |
||||
|
$options = (array)json_decode($this->options); |
||||
|
$value = $options[$this->value]; |
||||
|
} else { |
||||
|
$value = '- not set -'; |
||||
|
} |
||||
|
break; |
||||
|
default: |
||||
|
$value = $this->value; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return $value; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function getEditValueAttribute() |
||||
|
{ |
||||
|
switch($this->type) { |
||||
|
case 'image': |
||||
|
$value = ''; |
||||
|
if(isset($this->value) && !empty($this->value)) { |
||||
|
$value .= '<a class="setting-view-image" href="'.asset('storage/'.$this->value).'" title="View" target="_blank"><img src="'.asset('storage/'.$this->value).'" /></a>'; |
||||
|
} |
||||
|
$value .= Form::file('value', ['class' => 'form-control']); |
||||
|
if(isset($this->value) && !empty($this->value)) { |
||||
|
$value .= '<a class="settinglink" href="'.route('settings.clear', $this->id).'" title="Remove">Reset back to default</a>'; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
case 'boolean': |
||||
|
$checked = false; |
||||
|
if(isset($this->value) && (bool)$this->value === true) $checked = true; |
||||
|
$set_checked = ($checked) ? ' checked="checked"' : ''; |
||||
|
$value = ' |
||||
|
<label class="switch"> |
||||
|
<input type="hidden" name="value" value="0" /> |
||||
|
<input type="checkbox" name="value" value="1"'.$set_checked.' /> |
||||
|
<span class="slider round"></span> |
||||
|
</label>'; |
||||
|
|
||||
|
break; |
||||
|
case 'select': |
||||
|
$options = json_decode($this->options); |
||||
|
$value = Form::select('value', $options, null, ['class' => 'form-control']); |
||||
|
break; |
||||
|
default: |
||||
|
$value = Form::text('value', null, ['class' => 'form-control']); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return $value; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function group() |
||||
|
{ |
||||
|
return $this->belongsTo('App\SettingGroup', 'group_id'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $key |
||||
|
* |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
public static function fetch($key) |
||||
|
{ |
||||
|
if (Setting::cached($key)) { |
||||
|
return Setting::$cache[$key]; |
||||
|
} else { |
||||
|
$find = self::where('key', '=', $key)->first(); |
||||
|
|
||||
|
if (!is_null($find)) { |
||||
|
$value = $find->value; |
||||
|
Setting::add($key, $value); |
||||
|
|
||||
|
return $value; |
||||
|
} else { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $key |
||||
|
* @param $value |
||||
|
*/ |
||||
|
public static function add($key, $value) |
||||
|
{ |
||||
|
Setting::$cache[$key] = $value; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $key |
||||
|
* |
||||
|
* @return bool |
||||
|
*/ |
||||
|
public static function cached($key) |
||||
|
{ |
||||
|
return array_key_exists($key, Setting::$cache); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return html |
||||
|
*/ |
||||
|
public static function search() |
||||
|
{ |
||||
|
$output = ''; |
||||
|
$homepage_search = self::fetch('homepage_search'); |
||||
|
$search_provider = self::where('key', '=', 'search_provider')->first(); |
||||
|
|
||||
|
//die(var_dump($search_provider->value)); |
||||
|
// return early if search isn't applicable |
||||
|
if((bool)$homepage_search !== true) return $output; |
||||
|
if($search_provider->value === 'none') return $output; |
||||
|
if(empty($search_provider->value)) return $output; |
||||
|
if(is_null($search_provider->value)) return $output; |
||||
|
|
||||
|
|
||||
|
if((bool)$homepage_search && (bool)$search_provider) { |
||||
|
|
||||
|
$options = (array)json_decode($search_provider->options); |
||||
|
$name = $options[$search_provider->value]; |
||||
|
if((bool)$search_provider->value) { |
||||
|
switch($search_provider->value) { |
||||
|
case 'google': |
||||
|
$url = 'https://www.google.com/search'; |
||||
|
$var = 'q'; |
||||
|
break; |
||||
|
case 'ddg': |
||||
|
$url = 'https://duckduckgo.com/'; |
||||
|
$var = 'q'; |
||||
|
break; |
||||
|
case 'bing': |
||||
|
$url = 'https://www.bing.com/search'; |
||||
|
$var = 'q'; |
||||
|
break; |
||||
|
} |
||||
|
$output .= '<div class="searchform">'; |
||||
|
$output .= Form::open(['url' => $url, 'method' => 'get']); |
||||
|
$output .= '<div class="input-container">'; |
||||
|
$output .= Form::text($var, null, ['class' => 'homesearch', 'placeholder' => $name.' search...']); |
||||
|
$output .= '<button type="submit">Search</button>'; |
||||
|
$output .= '</div>'; |
||||
|
$output .= Form::close(); |
||||
|
$output .= '</div>'; |
||||
|
} |
||||
|
} |
||||
|
return $output; |
||||
|
} |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
class SettingGroup extends Model |
||||
|
{ |
||||
|
/** |
||||
|
* The database table used by the model. |
||||
|
* |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $table = 'setting_groups'; |
||||
|
|
||||
|
/** |
||||
|
* Tell the Model this Table doesn't support timestamps. |
||||
|
* |
||||
|
* @var bool |
||||
|
*/ |
||||
|
public $timestamps = false; |
||||
|
|
||||
|
public function settings() |
||||
|
{ |
||||
|
return $this->hasMany('App\Setting', 'group_id'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,38 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
|
||||
|
class CreateSettingsTable extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function up() |
||||
|
{ |
||||
|
Schema::create('settings', function (Blueprint $table) { |
||||
|
$table->increments('id'); |
||||
|
$table->integer('group_id')->default(0); |
||||
|
$table->string('key'); |
||||
|
$table->string('type')->default('text'); |
||||
|
$table->text('options')->nullable(); |
||||
|
$table->string('label'); |
||||
|
$table->string('value')->nullable(); |
||||
|
$table->string('order')->default(0); |
||||
|
$table->boolean('system')->default(false); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function down() |
||||
|
{ |
||||
|
Schema::dropIfExists('settings'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Support\Facades\Schema; |
||||
|
use Illuminate\Database\Schema\Blueprint; |
||||
|
use Illuminate\Database\Migrations\Migration; |
||||
|
|
||||
|
class CreateSettingGroupsTable extends Migration |
||||
|
{ |
||||
|
/** |
||||
|
* Run the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function up() |
||||
|
{ |
||||
|
Schema::create('setting_groups', function (Blueprint $table) { |
||||
|
$table->increments('id'); |
||||
|
$table->string('title'); |
||||
|
$table->integer('order')->default(0); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function down() |
||||
|
{ |
||||
|
Schema::dropIfExists('setting_groups'); |
||||
|
} |
||||
|
} |
@ -0,0 +1,91 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Illuminate\Database\Seeder; |
||||
|
use App\Setting; |
||||
|
use App\SettingGroup; |
||||
|
|
||||
|
class SettingsSeeder extends Seeder |
||||
|
{ |
||||
|
/** |
||||
|
* Run the database seeds. |
||||
|
* |
||||
|
* @return void |
||||
|
*/ |
||||
|
public function run() |
||||
|
{ |
||||
|
// Groups |
||||
|
if(!SettingGroup::find(1)) { |
||||
|
$setting_group = new SettingGroup; |
||||
|
$setting_group->id = 1; |
||||
|
$setting_group->title = 'System'; |
||||
|
$setting_group->order = 0; |
||||
|
$setting_group->save(); |
||||
|
} |
||||
|
if(!SettingGroup::find(2)) { |
||||
|
$setting_group = new SettingGroup; |
||||
|
$setting_group->id = 2; |
||||
|
$setting_group->title = 'Appearance'; |
||||
|
$setting_group->order = 1; |
||||
|
$setting_group->save(); |
||||
|
} |
||||
|
if(!SettingGroup::find(3)) { |
||||
|
$setting_group = new SettingGroup; |
||||
|
$setting_group->id = 3; |
||||
|
$setting_group->title = 'Miscellaneous'; |
||||
|
$setting_group->order = 2; |
||||
|
$setting_group->save(); |
||||
|
} |
||||
|
|
||||
|
if($version = Setting::find(1)) { |
||||
|
$version->value = config('app.version'); |
||||
|
$version->save(); |
||||
|
} else { |
||||
|
$setting = new Setting; |
||||
|
$setting->id = 1; |
||||
|
$setting->group_id = 1; |
||||
|
$setting->key = 'version'; |
||||
|
$setting->type = 'text'; |
||||
|
$setting->label = 'Version'; |
||||
|
$setting->value = config('app.version'); |
||||
|
$setting->system = true; |
||||
|
$setting->save(); |
||||
|
} |
||||
|
|
||||
|
if(!Setting::find(2)) { |
||||
|
$setting = new Setting; |
||||
|
$setting->id = 2; |
||||
|
$setting->group_id = 2; |
||||
|
$setting->key = 'background_image'; |
||||
|
$setting->type = 'image'; |
||||
|
$setting->label = 'Background Image'; |
||||
|
$setting->save(); |
||||
|
} |
||||
|
if(!Setting::find(3)) { |
||||
|
$setting = new Setting; |
||||
|
$setting->id = 3; |
||||
|
$setting->group_id = 3; |
||||
|
$setting->key = 'homepage_search'; |
||||
|
$setting->type = 'boolean'; |
||||
|
$setting->label = 'Homepage Search'; |
||||
|
$setting->save(); |
||||
|
} |
||||
|
if(!Setting::find(4)) { |
||||
|
$options = json_encode([ |
||||
|
'none' => '- not set -', |
||||
|
'google' => 'Google', |
||||
|
'ddg' => 'DuckDuckGo', |
||||
|
'bing' => 'Bing' |
||||
|
]); |
||||
|
|
||||
|
$setting = new Setting; |
||||
|
$setting->id = 4; |
||||
|
$setting->group_id = 3; |
||||
|
$setting->key = 'search_provider'; |
||||
|
$setting->type = 'select'; |
||||
|
$setting->options = $options; |
||||
|
$setting->label = 'Search Provider'; |
||||
|
$setting->save(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -1,4 +1,4 @@ |
|||||
{ |
{ |
||||
"/css/app.css": "/css/app.css?id=2bcada6f52a2ee8447df", |
"/css/app.css": "/css/app.css?id=2102f4e7317cba78bff5", |
||||
"/js/app.js": "/js/app.js?id=aa9e426dc7b92d42d3b2" |
"/js/app.js": "/js/app.js?id=2dffa24cf7255229e085" |
||||
} |
} |
@ -0,0 +1 @@ |
|||||
|
{!! App\Setting::search() !!} |
@ -0,0 +1,9 @@ |
|||||
|
@extends('app') |
||||
|
|
||||
|
@section('content') |
||||
|
|
||||
|
{!! Form::model($setting, ['method' => 'PATCH', 'files' => true, 'route' => ['settings.edit', $setting->id]]) !!} |
||||
|
@include('settings.form') |
||||
|
{!! Form::close() !!} |
||||
|
|
||||
|
@endsection |
@ -0,0 +1,30 @@ |
|||||
|
<section class="module-container"> |
||||
|
<header> |
||||
|
<div class="section-title">{{ $setting->label }}</div> |
||||
|
<div class="module-actions"> |
||||
|
<button type="submit"class="button"><i class="fa fa-save"></i><span>Save</span></button> |
||||
|
<a href="{{ route('settings.index') }}" class="button"><i class="fa fa-ban"></i><span>Cancel</span></a> |
||||
|
</div> |
||||
|
</header> |
||||
|
<div class="create"> |
||||
|
{!! csrf_field() !!} |
||||
|
<!--<div class="input"> |
||||
|
<label>Application name</label> |
||||
|
{!! Form::select('supported', \App\Item::supportedOptions(), array('placeholder' => 'Title','class' => 'form-control')) !!} |
||||
|
</div>--> |
||||
|
|
||||
|
<div class="input"> |
||||
|
{!! $setting->edit_value !!} |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
<footer> |
||||
|
<div class="section-title"> </div> |
||||
|
<div class="module-actions"> |
||||
|
<button type="submit"class="button"><i class="fa fa-save"></i><span>Save</span></button> |
||||
|
<a href="{{ route('settings.index') }}" class="button"><i class="fa fa-ban"></i><span>Cancel</span></a> |
||||
|
</div> |
||||
|
</footer> |
||||
|
|
||||
|
</section> |
@ -0,0 +1,52 @@ |
|||||
|
@extends('app') |
||||
|
|
||||
|
@section('content') |
||||
|
|
||||
|
@foreach ($groups as $group) |
||||
|
<section class="module-container"> |
||||
|
<header> |
||||
|
<div class="section-title"> |
||||
|
{{ $group->title }} |
||||
|
|
||||
|
</div> |
||||
|
</header> |
||||
|
|
||||
|
<table class="table table-hover"> |
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th>Label</th> |
||||
|
<th style="width: 60%;">Value</th> |
||||
|
<th class="text-center" style="width: 75px;">Edit</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
<tbody> |
||||
|
@if (count($group->settings) > 0) |
||||
|
@foreach ($group->settings as $setting) |
||||
|
<tr> |
||||
|
<td>{{ $setting->label }}</td> |
||||
|
<td> |
||||
|
{!! $setting->list_value !!} |
||||
|
</td> |
||||
|
<td class="text-center"> |
||||
|
@if((bool)$setting->system !== true) |
||||
|
<a href="{!! route('settings.edit', ['id' => $setting->id]) !!}" title="Edit {!! $setting->label !!}" class="secondary"><i class="fa fa-pencil"></i></a> |
||||
|
@endif |
||||
|
</td> |
||||
|
</tr> |
||||
|
@endforeach |
||||
|
@else |
||||
|
|
||||
|
<tr> |
||||
|
<td colspan="3" class="form-error text-center"> |
||||
|
<strong>No items found</strong> |
||||
|
</td> |
||||
|
</tr> |
||||
|
@endif |
||||
|
|
||||
|
|
||||
|
</tbody> |
||||
|
</table> |
||||
|
</section> |
||||
|
@endforeach |
||||
|
|
||||
|
@endsection |
Loading…
Reference in new issue