Permalink
Browse files

http://www.laragle.com/2017/04/laravel-mysql-json-manager.html

  • Loading branch information...
darwinluague committed Apr 16, 2017
1 parent f137076 commit a1c13e0dc1def3d061f782aaa158765542395478
@@ -0,0 +1,167 @@
<?php
namespace App\Managers;
use Illuminate\Database\Eloquent\Model;
class MySQLJSONColumnManager
{
/**
* The model instance
*
* @var mixed
*/
protected $model;
/**
* The list of data
*
* @var array
*/
protected $data;
/**
* The the model attribute name.
*
* @var string
*/
protected $attribute;
/**
* Create a new data instance
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $attribute
*/
public function __construct(Model $model, string $attribute)
{
$this->model = $model;
$this->attribute = $attribute;
$this->data = $model->$attribute ?: [];
}
/**
* Retrieve a given setting
*
* @param string $key
* @return string
*/
public function get($key)
{
if ($this->has($key)) {
return array_get($this->data, $key);
}
}
/**
* Add a new item in the json column.
*
* @param array|string $key
* @param string $value
*/
public function add($key, $value = null)
{
if (is_array($key)) {
foreach ($key as $key => $value) {
$this->data[$key] = $value;
}
} else {
$this->data[$key] = $value;
}
$this->persist();
}
/**
* Remove item from the data.
*
* @param array|string $key
* @return mixed
*/
public function delete($key)
{
$exist = false;
if (is_array($key)) {
foreach ($key as $value) {
if (isset($this->data[$value])) {
unset($this->data[$value]);
$exist = true;
}
}
}
if (is_string($key) && isset($this->data[$key])) {
unset($this->data[$key]);
$exist = true;
}
if ($exist) {
return $this->persist();
}
}
/**
* Retrieve an array of all data
*
* @return array
*/
public function all()
{
return $this->data;
}
/**
* Determine if the given setting exists.
*
* @param string $key
* @return boolean
*/
protected function has($key)
{
return array_key_exists($key, $this->data);
}
/**
* Update an item in the json column.
*
* @param array|string $key
* @param string $value
* @return mixed
*/
public function update($key, $value = null)
{
if (! is_array($key)) {
$key = [$key => $value];
}
$this->data = array_merge(
$this->data,
array_only($key, array_keys($this->data))
);
$this->persist();
}
/**
* Persist the data
*
* @return mixed
*/
protected function persist()
{
return $this->model->update([$this->attribute => $this->data]);
}
/**
* Magic property access for data
*
* @param string $key
* @return string
*/
public function __get($key)
{
return $this->get($key);
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\Traits;
use App\Managers\MySQLJSONColumnManager as BaseManager;
trait MySQLJSONColumnManager
{
public function __call($method, $arguments)
{
if (property_exists($this, 'casts')) {
if (array_key_exists($method, $this->casts)) {
return new BaseManager($this, $method);
}
}
return parent::__call($method, $arguments);
}
}
@@ -3,21 +3,22 @@
namespace App;
use App\Events\UserHasRegistered;
use App\Traits\MySQLJSONColumnManager;
use Illuminate\Notifications\Notifiable;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable, Sluggable;
use Notifiable, Sluggable, MySQLJSONColumnManager;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'first_name', 'last_name', 'email', 'password', 'email_verification_token',
'first_name', 'last_name', 'email', 'password', 'email_verification_token', 'options',
];
/**
@@ -38,6 +39,15 @@ class User extends Authenticatable
'password', 'remember_token',
];
/**
* The attributes that should be casted to native types.
*
* @var array
*/
protected $casts = [
'options' => 'array'
];
/**
* Get all the user tweets
*
@@ -21,6 +21,7 @@ public function up()
$table->string('email')->unique();
$table->string('password');
$table->string('email_verification_token')->nullable();
$table->json('options')->nullable();
$table->rememberToken();
$table->timestamps();
});
@@ -36,7 +36,7 @@ public function a_user_can_register()
'email' => $email
]);
$response->assertRedirect('/home');
$response->assertRedirect('/');
}
/** @test */
@@ -2,6 +2,7 @@
namespace Tests;
use Illuminate\Foundation\Exceptions\Handler;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
@@ -0,0 +1,108 @@
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class MySQLJSONManagerTest extends TestCase
{
use DatabaseMigrations;
/** @test */
public function can_add_an_item_to_the_json_column()
{
$user = factory('App\User')->create();
$user->options()->add('key1', '123456');
$this->assertDatabaseHas('users', ['options' => '{"key1":"123456"}']);
}
/** @test */
public function the_add_method_can_work_with_array()
{
$user = factory('App\User')->create();
$user->options()->add(['key1' => '123456', 'key2' => '654321']);
$this->assertDatabaseHas('users', ['options' => '{"key1":"123456","key2":"654321"}']);
}
/** @test */
public function can_update_an_item_in_the_json_column()
{
$user = factory('App\User')->create();
$user->options()->add(['key1' => '123456', 'key2' => '654321']);
$user->options()->update('key1', 'updated');
$this->assertDatabaseHas('users', ['options' => '{"key1":"updated","key2":"654321"}']);
}
/** @test */
public function the_update_method_can_work_with_array()
{
$user = factory('App\User')->create();
$user->options()->add(['key1' => '123456', 'key2' => '654321']);
$user->options()->update(['key1' => 'updated', 'key2' => 'updated']);
$this->assertDatabaseHas('users', ['options' => '{"key1":"updated","key2":"updated"}']);
}
/** @test */
public function can_delete_an_item_in_the_json_column()
{
$user = factory('App\User')->create();
$user->options()->add(['key1' => '123456', 'key2' => '654321']);
$user->options()->delete('key1');
$this->assertDatabaseHas('users', ['options' => '{"key2":"654321"}']);
}
/** @test */
public function the_delete_method_can_work_with_array()
{
$user = factory('App\User')->create();
$user->options()->add(['key1' => '123456', 'key2' => '654321']);
$user->options()->delete(['key1', 'key2']);
$this->assertDatabaseHas('users', ['options' => '[]']);
}
/** @test */
public function can_get_specific_value_by_key()
{
$user = factory('App\User')->create();
$key1 = '123456';
$user->options()->add(['key1' => $key1, 'key2' => '654321']);
$this->assertEquals($key1, $user->options()->get('key1'));
}
/** @test */
public function can_use_dynamic_property()
{
$user = factory('App\User')->create();
$key1 = '123456';
$user->options()->add(['key1' => $key1, 'key2' => '654321']);
$this->assertEquals($key1, $user->options()->key1);
}
/** @test */
public function can_get_all_data_using_all_method()
{
$user = factory('App\User')->create();
$options = ['key1' => '123456', 'key2' => '654321'];
$user->options()->add($options);
$this->assertEquals($options, $user->options()->all());
}
}

0 comments on commit a1c13e0

Please sign in to comment.