Skip to content

Commit

Permalink
Rename and remove wildcard for performance reasons
Browse files Browse the repository at this point in the history
  • Loading branch information
paulhenri-l committed Sep 2, 2020
1 parent 5018ed7 commit 0de3554
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 74 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "phl/laravel-dynamic-attributes",
"name": "paulhenri-l/laravel-dynamic-attributes",
"description": "Dynamically add attributes to your eloquent models",
"type": "library",
"license": "MIT",
Expand Down
58 changes: 17 additions & 41 deletions src/HasDynamicAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ trait HasDynamicAttributes
*/
protected $dynamicAttributes = [];

/**
* Keep a cached array of previously matched attributes. So that we don't
* run a preg match on every get and set call.
*
* @var ?string[]
*/
protected $previousMatches = [];

/**
* Register a dynamic attribute.
*
Expand Down Expand Up @@ -53,57 +45,41 @@ public function registerDynamicAttributeClass(string $key, DynamicAttribute $dyn
* @param string $key
* @return mixed
*/
public function __get($key)
public function getAttribute($key)
{
if ($daKey = $this->getDynamicAttributeKey($key)) {
return $this->dynamicAttributes[$daKey]->get($key);
if ($da = $this->getDynamicAttributeClass($key)) {
return $da->get($key);
}

return parent::__get($key);
return parent::getAttribute($key);
}

/**
* Call the dynamic attribute setter if there is one or pass to the parent.
*
* @param string $key
* @param mixed $value
* @return void
* @return mixed
*/
public function __set($key, $value)
public function setAttribute($key, $value)
{
if ($daKey = $this->getDynamicAttributeKey($key)) {
$this->dynamicAttributes[$daKey]->set($key, $value);
return;
}
if ($da = $this->getDynamicAttributeClass($key)) {
$da->set($key, $value);

parent::__set($key, $value);
}
return $this;
}

/**
* Flush the cache of previously matched dynamic attribute keys.
*/
public function flushDynamicAttributeKeyCache()
{
$this->previousMatches = [];
return parent::setAttribute($key, $value);
}

/**
* Check if the given key matches with a dynamic attribute.
* Return the dynamic attribute class.
*
* @param string $key
* @return DynamicAttribute|null
*/
protected function getDynamicAttributeKey(string $key): ?string
protected function getDynamicAttributeClass(string $key): ?DynamicAttribute
{
$cache = $this->previousMatches;

if (isset($cache[$key])) {
return $cache[$key];
}

$daKey = array_filter(array_keys($this->dynamicAttributes), function ($da) use ($key) {
return preg_match('/^' . $da . '$/', $key);
});

$result = $cache[$key] = array_shift($daKey);

return $result;
return $this->dynamicAttributes[$key] ?? null;
}
}
32 changes: 0 additions & 32 deletions tests/Unit/DynamicAttributesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,38 +64,6 @@ public function test_dynamic_attribute_class()
$this->assertEquals('hello', $da->get);
$this->assertEquals(['hello' => 'world'], $da->set);
}

public function test_wildcard_attribute()
{
$member = new Member();
$wildcardAttribute = new WildcardAttribute();
$member->registerDynamicAttributeClass('prefix_.*', $wildcardAttribute);
$member->prefix_hello = 'world';
$member->prefix_foo = 'bar';
$member->prefix_test = 'value';
$member->not_prefix_sorry = 'not there';

$this->assertEquals([
'prefix_hello' => 'world',
'prefix_foo' => 'bar',
'prefix_test' => 'value',
], $wildcardAttribute->data);
}
}

class WildcardAttribute implements DynamicAttribute
{
public $data = [];

public function get(string $key)
{
return $data[$key] ?? null;
}

public function set(string $key, $value): void
{
$this->data[$key] = $value;
}
}

class FakeDaClass implements DynamicAttribute
Expand Down

0 comments on commit 0de3554

Please sign in to comment.