diff --git a/src/SettingsServiceProvider.php b/src/SettingsServiceProvider.php
index 8374da4..6a7d9df 100644
--- a/src/SettingsServiceProvider.php
+++ b/src/SettingsServiceProvider.php
@@ -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');
}
/**
diff --git a/src/app/Http/Controllers/SettingCrudController.php b/src/app/Http/Controllers/SettingCrudController.php
index 245578b..52aaa1f 100644
--- a/src/app/Http/Controllers/SettingCrudController.php
+++ b/src/app/Http/Controllers/SettingCrudController.php
@@ -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',
],
]);
}
@@ -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();
@@ -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);
@@ -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;
+ }
}
diff --git a/src/app/Models/Setting.php b/src/app/Models/Setting.php
index 01976f9..c8b12e8 100644
--- a/src/app/Models/Setting.php
+++ b/src/app/Models/Setting.php
@@ -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 ''.$value.'';
+ break;
+ case 'email':
+ return ''.$value.'';
+ break;
+ case 'checkbox':
+ if ($value == 1) {
+ // if true return success label with YES string
+ $html = 'YES';
+ } else {
+ // if false return danger label with NO string
+ $html = 'NO';
+ }
+
+ return $html;
+ break;
+ case 'image':
+ return '
';
+ break;
+ case 'password':
+ return '';
+ break;
+ case 'number':
+ return $value;
+ break;
+ case 'icon_picker':
+ return '';
+ break;
+ default:
+ return $type;
+ break;
+ }
+ }
}
diff --git a/src/config/backpack/settings.php b/src/config/backpack/settings.php
new file mode 100644
index 0000000..f410401
--- /dev/null
+++ b/src/config/backpack/settings.php
@@ -0,0 +1,15 @@
+ 'uploads', // disk where images will be saved
+ 'images_folder' => 'images', // folder where images will be saved inside it in the specified disk
+ 'image_upload_enabled' => true, // set to true to allow uploading, false to disable
+ 'image_crop_enabled' => true, // set to true to allow cropping, false to disable
+ 'image_aspect_ratio' => 1, // ommit or set to 0 to allow any aspect ratio
+ 'image_prefix' => 'uploads/', // in case you only store the filename in the database, this text will be prepended to the database value
+
+];
diff --git a/src/database/migrations/2015_08_04_131614_create_settings_table.php b/src/database/migrations/2015_08_04_131614_create_settings_table.php
index 559417d..f7da299 100644
--- a/src/database/migrations/2015_08_04_131614_create_settings_table.php
+++ b/src/database/migrations/2015_08_04_131614_create_settings_table.php
@@ -19,7 +19,7 @@ public function up()
$table->string('description')->nullable();
$table->text('value')->nullable();
$table->text('field');
- $table->tinyInteger('active');
+ $table->tinyInteger('active')->default(1);
$table->timestamps();
});
}
diff --git a/src/resources/lang/en/settings.php b/src/resources/lang/en/settings.php
index 1bb425c..7c81279 100644
--- a/src/resources/lang/en/settings.php
+++ b/src/resources/lang/en/settings.php
@@ -9,10 +9,14 @@
| The following language lines are used for Laravel Backpack - Settings
|
*/
- 'name' => 'Name',
- 'value' => 'Value',
- 'description' => 'Description',
- 'setting_singular' => 'setting',
- 'setting_plural' => 'settings',
+ 'name' => 'Name',
+ 'value' => 'Value',
+ 'key' => 'Key',
+ 'select_field' => 'Select field type',
+ 'active' => 'is Active',
+ 'description' => 'Description',
+ 'setting_singular' => 'setting',
+ 'setting_plural' => 'settings',
+ 'delete_image_file_not_message' => "There's been an error. Your image might not have been deleted from the disk.",
];