Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality for Explicit Parsing #86

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Exceptions/DataTypeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,9 @@ public static function handlerNotFoundForValue($value): self

return new static("Meta handler not found for value of type '{$type}'");
}

public static function handlerInvalid(string $class): self
{
return new static("Class'{$class}' is not a valid meta handler");
}
}
16 changes: 15 additions & 1 deletion src/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ class Meta extends Model
*/
protected $cachedValue;

public function __construct(array $attributes = [])
{
if ($attributes['type'] ?? null) {
$this->forceFill(['type' => $attributes['type']]);

unset($attributes['type']);
}
parent::__construct($attributes);
}


/**
* Metable Relation.
*
Expand Down Expand Up @@ -92,7 +103,10 @@ public function setValueAttribute($value): void
{
$registry = $this->getDataTypeRegistry();

$this->attributes['type'] = $registry->getTypeForValue($value);
if ($this->isClean('type')) {
$this->attributes['type'] = $registry->getTypeForValue($value);
}

$this->attributes['value'] = $registry->getHandlerForType($this->type)
->serializeValue($value);

Expand Down
30 changes: 28 additions & 2 deletions src/Metable.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Plank\Metable\DataType\HandlerInterface;
use Plank\Metable\Exceptions\DataTypeException;
use Traversable;

/**
Expand Down Expand Up @@ -568,11 +568,37 @@ protected function makeMeta(string $key = '', $value = ''): Meta

$meta = new $className([
'key' => $key,
'type' => $this->getMetaType($key),
'value' => $value,
]);
$meta->metable_type = $this->getMorphClass();
$meta->metable_id = $this->getKey();

return $meta;
}

protected function getMetaType(string $key): ?string
{
$handlerClass = $this->getMetaCasts()[$key] ?? null;

if (! $handlerClass) {
return null;
}

if (! is_a($handlerClass, HandlerInterface::class, true)) {
throw DataTypeException::handlerInvalid($handlerClass);
}

return (new $handlerClass)->getDataType();
}

/**
* Use default casting for given Meta keys
*
* @return array<array-key, class-string<HandlerInterface>
*/
protected function getMetaCasts(): array
{
return $this->metaCasts ?? [];
}
}
43 changes: 43 additions & 0 deletions tests/Integration/DefaultHandlersMetableTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Plank\Metable\Tests\Integration;

use Plank\Metable\Exceptions\DataTypeException;
use Plank\Metable\Tests\Mocks\SampleMetableTypes;
use Plank\Metable\Tests\TestCase;

class DefaultHandlersMetableTest extends TestCase
{
public function test_it_parses_given_variables_according_to_given_metaCasts()
{
$this->useDatabase();
$metable = $this->createMetable();

$metable->setMeta('fooBool', 'oooo');
$this->assertEquals(true, $metable->getMeta('fooBool'));

$metable->setMeta('fooBool', '');
$this->assertEquals(false, $metable->getMeta('fooBool'));

$metable->setMeta('fooString', 1234);
$this->assertEquals('1234', $metable->getMeta('fooString'));

$metable->setMeta('random', 1234); // auto choose
$this->assertEquals(1234, $metable->getMeta('random'));
}

public function test_it_throws_exception_if_metaCast_value_is_not_a_handler()
{
$this->useDatabase();
$metable = $this->createMetable();

$this->expectException(DataTypeException::class);

$metable->setMeta('fooWrong', 'oooo');
}

private function createMetable(array $attributes = []): SampleMetableTypes
{
return factory(SampleMetableTypes::class)->create($attributes);
}
}
21 changes: 21 additions & 0 deletions tests/Mocks/SampleMetableTypes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Plank\Metable\Tests\Mocks;

use Illuminate\Database\Eloquent\Model;
use Plank\Metable\DataType\BooleanHandler;
use Plank\Metable\DataType\StringHandler;
use Plank\Metable\Metable;

class SampleMetableTypes extends Model
{
use Metable;

protected $table = 'sample_metables';

protected $metaCasts = [
'fooBool' => BooleanHandler::class,
'fooString' => StringHandler::class,
'fooWrong' => SampleMetable::class
];
}
5 changes: 5 additions & 0 deletions tests/factories/MetableFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use Plank\Metable\Tests\Mocks\SampleMetable;
use Plank\Metable\Tests\Mocks\SampleMetableSoftDeletes;
use Plank\Metable\Tests\Mocks\SampleMetableTypes;

$factory->define(SampleMetable::class, function (Faker\Generator $faker) {
return [];
Expand All @@ -10,3 +11,7 @@
$factory->define(SampleMetableSoftDeletes::class, function (Faker\Generator $faker) {
return [];
});

$factory->define(SampleMetableTypes::class, function (Faker\Generator $faker) {
return [];
});