From 9635256ac44da6da3cbbd480ae0b8aa1e165ac14 Mon Sep 17 00:00:00 2001 From: Yarob Al-Taay Date: Sun, 26 Feb 2017 14:22:06 +0000 Subject: [PATCH] internal casting implementation use Collections for settings --- README.md | 37 +++++++++++++++++---------- src/HasSettings.php | 26 ++++++++++++++++--- src/Services/ModelSettingsService.php | 23 ++++++++++------- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 9134277..f6870a2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,11 @@ Add settings feature to Eloquent models in Laravel 5. ## Background -This has been developed to simplify adding "settings" feature to any eloquent model on your laravel project. Settings WILL be stored in `json` format, which has it's pros and cons! +This has been developed to simplify adding "settings" feature to any eloquent model on your laravel project. + +Settings WILL be stored in `json` format/object! Is `json` the best way? Well it's your call! pros: super flexible, you can add/remove settings without code alteration (apart from `app/config/model-settings.php` see below). cons: expensive when querying/searching for certain `key => value` in `settings` per model. + +`settings` will be casted into Laravel `Collection` for maximum functionality and usage. ## Installation To install the package via Composer: @@ -29,7 +33,7 @@ php artisan vendor:publish --provider="Yarob\LaravelModelSettings\ServiceProvide ## Updating your Eloquent Models Your models should use the `hasSettings` trait. -You must also add `settings` to your `fillable` array, and then cast `settings` to `json` as shown in the example below +You must also add `settings` to your `fillable` array as shown in the example below ```php use Yarob\LaravelModelSettings\HasSettings; @@ -46,21 +50,15 @@ class User extends Model protected $fillable = [ 'name', 'email', 'settings' ]; - - - /** - * The attributes that should be casted. - * - * @var array - */ - protected $casts = [ - 'settings' =>'json', - ]; } ``` -Your model and database must have column named `settings` in the database to store the settings values. You can add this manually via a migration on the intended model. The column should be text and big enough to store all settings after json encoded. +## Migration +Your model MUST have column named `settings` in the database to store the settings values. + +You can add this manually via a migration on the intended model ```php $table->json('settings')->nullable(); ```. +The column should be big enough to accommodate all settings after json encoded. ## Usage @@ -74,7 +72,7 @@ $user->settings()->save(array( 'phone_number' => '0123456789' )); -dd($user->settings); +print_r($user->settings); ``` ## Configuration @@ -95,7 +93,18 @@ return [ ]; ``` +Pay attention that Model name in `model-settings.php` is case sensitive! so if you have a `foo` Model, then +```php +return [ + 'foo' => [ + 'key1', + 'key2', + ... + ], + ... +]; +``` ## Copyright and License diff --git a/src/HasSettings.php b/src/HasSettings.php index 90007ea..3144512 100644 --- a/src/HasSettings.php +++ b/src/HasSettings.php @@ -2,6 +2,7 @@ namespace Yarob\LaravelModelSettings; +use ErrorException; use Yarob\LaravelModelSettings\Services\ModelSettingsService; /** @@ -44,13 +45,32 @@ public static function settingsSaved($callback) } /** - * Return the sluggable configuration array for this model. - * Must be implemented at the model class * - * @return array + * @return \Yarob\LaravelModelSettings\Services\ModelSettingsService */ public function settings() { return new ModelSettingsService($this); } + + /** + * Define `settings` Accessor for Models + * + * @param $settings + * @return collection + * @throws ErrorException + */ + public function getSettingsAttribute($settings) + { + $jsonDecodedSettings = json_decode($settings); + + if(json_last_error() == JSON_ERROR_NONE) + { + return collect( $jsonDecodedSettings ); + } + else + { + throw new ErrorException('None json format encountered in `settings` column on `'.$this->getTable().'` table on database!'); + } + } } diff --git a/src/Services/ModelSettingsService.php b/src/Services/ModelSettingsService.php index 93c00d6..faa536c 100644 --- a/src/Services/ModelSettingsService.php +++ b/src/Services/ModelSettingsService.php @@ -33,34 +33,39 @@ public function __construct(Model $model=null) /** * Save settings for current model. * - * @param null $settings - * @return bool + * @param array $rawSettings + * @return bool/collection * @throws ErrorException * @internal param Model $model */ - public function save($settings=null) + public function save($rawSettings=array()) { - if(!empty($settings) and !empty($this->model)) + if(!empty($this->model) and is_array($rawSettings) and !empty($rawSettings)) { if (!Schema::hasColumn($this->model->getTable(), 'settings')) { - throw new ErrorException('"settings" column seems to be missing on "'.class_basename($this->model).'" table on database!'); + throw new ErrorException('`settings` column seems to be missing on `'.$this->model->getTable().'` table on database!'); } else { $allowedSettingsKeys = $this->getConfiguration(); - $oldSettings = is_array($this->model->settings)?$this->model->settings:array(); - $settings = array_merge( + $oldSettings = $this->model->settings->toArray(); + + $newSettings = array_merge( $oldSettings, array_only( - $settings, + $rawSettings, $allowedSettingsKeys ) ); - return $this->model->update(compact('settings')); + if($this->model->update( array( 'settings' => json_encode($newSettings) ) )) + { + return collect($newSettings); + } } } + return false; } /**