Skip to content
Open
8 changes: 8 additions & 0 deletions src/SettingsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public function boot()

// publish translation files
$this->publishes([__DIR__.'/resources/lang' => resource_path('lang/vendor/backpack')], 'lang');

// use the vendor configuration file as fallback
$this->mergeConfigFrom(
__DIR__.'/config/backpack/settings.php',
'backpack.settings'
);
// publish config file
$this->publishes([__DIR__.'/config' => config_path()], 'config');
}

/**
Expand Down
130 changes: 117 additions & 13 deletions src/app/Http/Controllers/SettingCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,67 @@

class SettingCrudController extends CrudController
{
public function __construct()
public function setup()
{
parent::__construct();

$this->crud->setModel("Backpack\Settings\app\Models\Setting");
$this->crud->setEntityNameStrings(trans('backpack::settings.setting_singular'), trans('backpack::settings.setting_plural'));
$this->crud->setRoute(config('backpack.base.route_prefix', 'admin').'/setting');
$this->crud->denyAccess(['create', 'delete']);
$this->crud->setColumns([
[
'name' => 'name',
'label' => trans('backpack::settings.name'),
],
[
'name' => 'value',
'label' => trans('backpack::settings.value'),
'name' => 'key',
'label' => trans('backpack::settings.key'),
],
[
'name' => 'value',
'label' => trans('backpack::settings.value'),
'type' => 'model_function',
'function_name' => 'getValueFunction',
],
[
'name' => 'description',
'label' => trans('backpack::settings.description'),
],
]);
$this->crud->addField([
'name' => 'name',
'label' => trans('backpack::settings.name'),
'type' => 'text',
'attributes' => [
'disabled' => 'disabled',
$this->crud->addFields([
[
'name' => 'name',
'label' => trans('backpack::settings.name'),
'type' => 'text',
],
[
'name' => 'key',
'label' => trans('backpack::settings.key'),
'type' => 'text',
],
[
'name' => 'description',
'label' => trans('backpack::settings.description'),
'type' => 'text',
],
[ // select_from_array
'name' => 'field',
'label' => trans('backpack::settings.select_field'),
'type' => 'select2_from_array',
'options' => [
'text' => 'Text',
'email' => 'Email',
'checkbox' => 'Checkbox',
'number' => 'Number',
'url' => 'URL',
'image' => 'Image',
'password' => 'Password',
'icon_picker' => 'Icon Picker',
],
'allows_null' => false,
],
[
'name' => 'active',
'label' => trans('backpack::settings.active'),
'type' => 'checkbox',
],
]);
}
Expand All @@ -55,6 +88,13 @@ public function index()
return parent::index();
}

/**
* Store a newly created resource in the database.
*
* @param StoreRequest $request - type injection used for validation using Requests
*
* @return \Illuminate\Http\RedirectResponse
*/
public function store(StoreRequest $request)
{
return parent::storeCrud();
Expand All @@ -72,7 +112,7 @@ public function edit($id)
$this->crud->hasAccessOrFail('update');

$this->data['entry'] = $this->crud->getEntry($id);
$this->crud->addField((array) json_decode($this->data['entry']->field)); // <---- this is where it's different
$this->crud->addField((array) $this->getFieldJsonValue($id, $this->isImageField($id))); // <---- this is where it's different
$this->data['crud'] = $this->crud;
$this->data['saveAction'] = $this->getSaveAction();
$this->data['fields'] = $this->crud->getUpdateFields($id);
Expand All @@ -84,8 +124,72 @@ public function edit($id)
return view($this->crud->getEditView(), $this->data);
}

/**
* Update the specified resource in the database.
*
* @param UpdateRequest $request - type injection used for validation using Requests
*
* @return \Illuminate\Http\RedirectResponse
*/
public function update(UpdateRequest $request)
{
return parent::updateCrud();
}

/**
* get the correct field json value to add the correct field to edit form.
*
* @param int $id
* @param bool $isImage
*
* @return array
*/
protected function getFieldJsonValue($id, $isImage = true)
{
$fieldValue = $this->crud->getEntry($id)->field;

$fieldJson = [];

if ($isImage == false) {
$fieldJson['name'] = 'value';
$fieldJson['label'] = 'Value';
$fieldJson['type'] = $fieldValue;

return $fieldJson;
} else {
$fieldJson['name'] = 'value';
$fieldJson['label'] = 'Value';
$fieldJson['type'] = $fieldValue;
$fieldJson['upload'] = config('backpack.settings.image_upload_enabled');
$fieldJson['crop'] = config('backpack.settings.image_crop_enabled');
$fieldJson['aspect_ratio'] = config('backpack.settings.image_aspect_ratio');
$fieldJson['prefix'] = config('backpack.settings.image_prefix');

return $fieldJson;
}
}

/**
* get the correct field type.
*
* @param int $id
*
* @return string
*/
protected function getFieldType($id)
{
return $this->crud->getEntry($id)->field;
}

/**
* get the correct field type.
*
* @param int $id
*
* @return bool
*/
protected function isImageField($id)
{
return $this->getFieldType($id) == 'image' ? true : false;
}
}
188 changes: 187 additions & 1 deletion src/app/Models/Setting.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,197 @@

use Backpack\CRUD\CrudTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
use Prologue\Alerts\Facades\Alert;

/**
* Class Setting.
*/
class Setting extends Model
{
use CrudTrait;

protected $table = 'settings';
protected $fillable = ['value'];
protected $fillable = ['name', 'key', 'value', 'field', 'description', 'active'];

/**
* Model Boot function
* Need it to delete image file from disk if the field type == image.
*/
public static function boot()
{
parent::boot();
static::deleting(function ($obj) {
// 1. get field type
$type = $obj->field;
// 2. check if it's image
if ($type == 'image') {
// 3. delete from disk
if (!Storage::disk(config('backpack.settings.images_disk_name'))->delete($obj->value)) {
// filed to delete image file
Alert::error(trans('backpack::settings.delete_image_file_not_message'))->flash();
}
}
});
}

/**
* set field json to database.
*
* @param $field
*/
public function setFieldAttribute($field)
{
$fieldJson = [];
$fieldJson['name'] = 'value';
$fieldJson['label'] = 'Value';
$fieldJson['type'] = $field;

$this->attributes['field'] = json_encode($fieldJson);
}

/**
* get the correct type value for select2_from_array.
*
* @param $field
*
* @return string
*/
public function getFieldAttribute($field)
{
$fieldDecoded = json_decode($field, true);

return $fieldDecoded['type'];
}

/**
* set the correct value and check if image field.
*
* @param $value
*/
public function setValueAttribute($value)
{
// get item id
$id = $this->id;
// get setting object from database
$setting = DB::table($this->table)->where('id', $id)->first();
// decode field object
$fieldDecoded = json_decode($setting->field, true);
// get field type
$type = $fieldDecoded['type'];

// column attribute name
$attribute_name = 'value';
// get images disk
$disk = config('backpack.settings.images_disk_name');
// get destination folder
$destination_path = config('backpack.settings.images_folder');

switch ($type) {
case 'image':
// if the image was erased
if (is_null($value)) {
// delete the image from disk
if (Storage::disk($disk)->delete($this->{$attribute_name})) {
// set null in the database after the successful delete
$this->attributes[$attribute_name] = null;
}
}

// if a base64 was sent, store it in the db
if (starts_with($value, 'data:image')) {
// 0. Get image extension
preg_match("/^data:image\/(.*);base64/i", $value, $match);
$extension = $match[1];
// 1. Make the image
$image = Image::make($value);
if (!is_null($image)) {
// 2. Generate a filename.
$filename = md5($value.time()).'.'.$extension;

try {
// 3. Store the image on disk.
Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
// 4. Save the path to the database
$this->attributes[$attribute_name] = $destination_path.'/'.$filename;
} catch (\InvalidArgumentException $argumentException) {
// 3. failed to save file
Alert::error($argumentException->getMessage())->flash();
// 4. set as null when fail to save the image to disk
$this->attributes[$attribute_name] = null;
}
}
}
break;
default:
$this->attributes[$attribute_name] = $value;
break;
}
}

/**
* get the correct value and check fields types
* and return the correct tags.
*
* @return mixed
*/
public function getValueFunction()
{
$attribute_name = 'value';

// get item id
$id = $this->id;
// get setting object from database
$setting = DB::table($this->table)->where('id', $id)->first();
// decode field object
$fieldDecoded = json_decode($setting->field, true);
// get field type
$type = $fieldDecoded['type'];
// check value set
if (!isset($setting->{$attribute_name})) {
return false;
}
// get value
$value = $setting->{$attribute_name};

switch ($type) {
case 'text':
return str_limit(strip_tags($value), 80, '[...]');
break;
case 'url':
return '<a href="'.$value.'">'.$value.'</a>';
break;
case 'email':
return '<a href="mailto:'.$value.'" target="_top">'.$value.'</a>';
break;
case 'checkbox':
if ($value == 1) {
// if true return success label with YES string
$html = '<span class="label label-success">YES</span>';
} else {
// if false return danger label with NO string
$html = '<span class="label label-danger">NO</span>';
}

return $html;
break;
case 'image':
return '<a href="'.url(config('backpack.settings.image_prefix').$value).'"><img class="img-circle" width="70px" height="70px" src="'.url('/uploads/'.$value).'" alt="User Avatar"></a>';
break;
case 'password':
return '<a class="btn btn-default"><i class="fa fa-key"></i></a>';
break;
case 'number':
return $value;
break;
case 'icon_picker':
return '<a class="btn btn-default"><i class="fa '.$value.'"></i></a>';
break;
default:
return $type;
break;
}
}
}
Loading