diff options
-rw-r--r-- | db/migrations/2018_09_24_000000_create_event_config_table.php | 101 | ||||
-rw-r--r-- | src/Models/EventConfig.php | 93 | ||||
-rw-r--r-- | tests/Unit/HasDatabase.php | 1 | ||||
-rw-r--r-- | tests/Unit/Models/EventConfigTest.php | 128 |
4 files changed, 323 insertions, 0 deletions
diff --git a/db/migrations/2018_09_24_000000_create_event_config_table.php b/db/migrations/2018_09_24_000000_create_event_config_table.php new file mode 100644 index 00000000..18298100 --- /dev/null +++ b/db/migrations/2018_09_24_000000_create_event_config_table.php @@ -0,0 +1,101 @@ +<?php + +namespace Engelsystem\Migrations; + +use Carbon\Carbon; +use Engelsystem\Database\Migration\Migration; +use Engelsystem\Models\EventConfig; +use Illuminate\Database\Schema\Blueprint; + +class CreateEventConfigTable extends Migration +{ + protected $mapping = [ + 'buildup_start_date' => 'buildup_start', + 'event_start_date' => 'event_start', + 'event_end_date' => 'event_end', + 'teardown_end_date' => 'teardown_end', + ]; + + /** + * Run the migration + */ + public function up() + { + $this->schema->create('event_config', function (Blueprint $table) { + $table->string('name')->index()->unique(); + $table->json('value'); + $table->timestamps(); + }); + + if ($this->schema->hasTable('EventConfig')) { + $config = $this->schema->getConnection() + ->table('EventConfig') + ->first(); + + if (!empty($config)) { + (new EventConfig([ + 'name' => 'name', + 'value' => $config->event_name, + ]))->save(); + + (new EventConfig([ + 'name' => 'welcome_msg', + 'value' => $config->event_welcome_msg, + ]))->save(); + + foreach ($this->mapping as $old => $new) { + (new EventConfig([ + 'name' => $new, + 'value' => (new Carbon())->setTimestamp($config->{$old}), + ]))->save(); + } + } + + $this->schema->drop('EventConfig'); + } + } + + /** + * Reverse the migration + */ + public function down() + { + $this->schema->create('EventConfig', function (Blueprint $table) { + $table->string('event_name')->nullable(); + $table->integer('buildup_start_date')->nullable(); + $table->integer('event_start_date')->nullable(); + $table->integer('event_end_date')->nullable(); + $table->integer('teardown_end_date')->nullable(); + $table->string('event_welcome_msg')->nullable(); + }); + + $config = new EventConfig(); + $data = [ + 'event_name' => $config->findOrNew('name')->value, + 'event_welcome_msg' => $config->findOrNew('welcome_msg')->value, + ]; + foreach ($this->mapping as $new => $old) { + /** @var Carbon $value */ + $value = $config->findOrNew($old)->value; + + if (!$value) { + continue; + } + + $data[$new] = $value->getTimestamp(); + } + + $dataNotEmpty = false; + foreach ($data as $value) { + $dataNotEmpty |= !empty($value); + } + + if ($dataNotEmpty) { + $this->schema->getConnection() + ->table('EventConfig') + ->insert($data); + } + + $this->schema->dropIfExists('event_config'); + } +} diff --git a/src/Models/EventConfig.php b/src/Models/EventConfig.php new file mode 100644 index 00000000..e2f832cb --- /dev/null +++ b/src/Models/EventConfig.php @@ -0,0 +1,93 @@ +<?php + +namespace Engelsystem\Models; + +use Carbon\Carbon; + +class EventConfig extends BaseModel +{ + /** @var string The primary key for the model */ + protected $primaryKey = 'name'; + + /** @var bool Indicates if the IDs are auto-incrementing */ + public $incrementing = false; + + /** @var string Required because it is not event_configs */ + protected $table = 'event_config'; + + /** @var array Values that are mass assignable */ + protected $fillable = ['name', 'value']; + + /** @var array The configuration values that should be cast to native types */ + protected $valueCasts = [ + 'buildup_start' => 'date', + 'event_start' => 'date', + 'event_end' => 'date', + 'teardown_end' => 'date', + ]; + + /** @var bool It could be interesting to know when a value changed the last time */ + public $timestamps = true; + + /** + * Value accessor + * + * @param mixed $value + * @return mixed + */ + public function getValueAttribute($value) + { + $value = $this->fromJson($value); + + /** @see \Illuminate\Database\Eloquent\Concerns\HasAttributes::castAttribute */ + if (!empty($value)) { + switch ($this->getValueCast($this->name)) { + case 'date': + return Carbon::createFromFormat('Y-m-d', $value) + ->setTime(0, 0); + case 'datetime': + return Carbon::createFromFormat(Carbon::ISO8601, $value); + } + } + + return $value; + } + + /** + * Value mutator + * + * @param mixed $value + * @return static + */ + public function setValueAttribute($value) + { + if (!empty($value)) { + switch ($this->getValueCast($this->name)) { + case 'date': + /** @var Carbon $value */ + $value = $value->toDateString(); + break; + case 'datetime': + /** @var Carbon $value */ + $value = $value->toIso8601String(); + break; + } + } + + $value = $this->castAttributeAsJson('value', $value); + $this->attributes['value'] = $value; + + return $this; + } + + /** + * Check if the value has to be casted + * + * @param string $value + * @return string|null + */ + protected function getValueCast($value) + { + return isset($this->valueCasts[$value]) ? $this->valueCasts[$value] : null; + } +} diff --git a/tests/Unit/HasDatabase.php b/tests/Unit/HasDatabase.php index 467f95fc..264d0a9c 100644 --- a/tests/Unit/HasDatabase.php +++ b/tests/Unit/HasDatabase.php @@ -21,6 +21,7 @@ trait HasDatabase { $dbManager = new CapsuleManager(); $dbManager->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); + $dbManager->bootEloquent(); $connection = $dbManager->getConnection(); $connection->getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); diff --git a/tests/Unit/Models/EventConfigTest.php b/tests/Unit/Models/EventConfigTest.php new file mode 100644 index 00000000..f08e8801 --- /dev/null +++ b/tests/Unit/Models/EventConfigTest.php @@ -0,0 +1,128 @@ +<?php + +namespace Engelsystem\Test\Unit\Models; + +use Carbon\Carbon; +use Engelsystem\Models\EventConfig; +use Engelsystem\Test\Unit\HasDatabase; +use PHPUnit\Framework\TestCase; + +class EventConfigTest extends TestCase +{ + use HasDatabase; + + /** + * @covers \Engelsystem\Models\EventConfig::setValueAttribute + */ + public function testSetValueAttribute() + { + (new EventConfig()) + ->setAttribute('name', 'foo') + ->setAttribute('value', 'bar') + ->save(); + $this->assertEquals( + '"bar"', + $this->database + ->selectOne("SELECT `value` FROM event_config WHERE name='foo'") + ->value + ); + + (new EventConfig()) + ->setAttribute('name', 'buildup_start') + ->setAttribute('value', new Carbon('2000-01-01 10:20')) + ->save(); + $this->assertEquals( + '"2000-01-01"', + $this->database + ->selectOne("SELECT `value` FROM event_config WHERE name='buildup_start'") + ->value + ); + + ($this->getEventConfig()) + ->setAttribute('name', 'event_start') + ->setValueCast('event_start', 'datetime') + ->setAttribute('value', new Carbon('2010-11-11 20:22')) + ->save(); + $this->assertEquals( + '"' . (new Carbon('2010-11-11 20:22'))->format(Carbon::ATOM) . '"', + $this->database + ->selectOne("SELECT `value` FROM event_config WHERE name='event_start'") + ->value + ); + } + + /** + * @covers \Engelsystem\Models\EventConfig::getValueAttribute + */ + public function testGetValueAttribute() + { + $model = new EventConfig(['name', 'buildup_start', 'value' => '']); + $this->assertEquals('', $model->value); + + (new EventConfig()) + ->setAttribute('name', 'buildup_start') + ->setAttribute('value', new Carbon('2001-02-03 11:12')) + ->save(); + $this->assertEquals( + '2001-02-03 00:00', + EventConfig::find('buildup_start') + ->value + ->format('Y-m-d H:i') + ); + + ($this->getEventConfig()) + ->setAttribute('name', 'event_start') + ->setValueCast('event_start', 'datetime') + ->setAttribute('value', new Carbon('2010-11-11 20:22')) + ->save(); + $this->assertEquals( + '2010-11-11 20:22', + ($this->getEventConfig())->find('event_start') + ->setValueCast('event_start', 'datetime') + ->value + ->format('Y-m-d H:i') + ); + } + + /** + * @covers \Engelsystem\Models\EventConfig::getValueCast + */ + public function testGetValueCast() + { + $model = new EventConfig(['value' => 'bar']); + $this->assertEquals('bar', $model->value); + + return; + } + + /** + * Init a new EventConfig class + * + * @return EventConfig + */ + protected function getEventConfig() + { + return new class extends EventConfig + { + /** + * @param string $value + * @param string $type + * @return EventConfig + */ + public function setValueCast($value, $type) + { + $this->valueCasts[$value] = $type; + + return $this; + } + }; + } + + /** + * Prepare test + */ + protected function setUp() + { + $this->initDatabase(); + } +} |