Skip to content

Commit

Permalink
Allow invokable classes and closures to be used in attribute handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
grantholle committed Jun 16, 2023
1 parent 43e5e0f commit cdce5af
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/Import/Hydrators/AttributeHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,17 @@ class AttributeHydrator extends Hydrator
public function hydrate(LdapModel $object, EloquentModel $eloquent): void
{
foreach ($this->getSyncAttributes() as $eloquentField => $ldapField) {
ray($this->isAttributeHandler($ldapField));

if ($this->isAttributeHandler($ldapField)) {
app($ldapField)->handle($object, $eloquent);
$handler = is_callable($ldapField) ? $ldapField : app($ldapField);

if (is_callable($handler)) {
$handler($object, $eloquent);
continue;
}

$handler->handle($object, $eloquent);

continue;
}
Expand Down Expand Up @@ -43,6 +52,11 @@ protected function getSyncAttributes(): array
*/
protected function isAttributeHandler($handler): bool
{
return is_string($handler) && class_exists($handler) && method_exists($handler, 'handle');
if (is_callable($handler)) {
return true;
}

return is_string($handler) && class_exists($handler) &&
(method_exists($handler, 'handle') || method_exists($handler, '__invoke'));
}
}
50 changes: 50 additions & 0 deletions tests/Unit/EloquentHydratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,40 @@ public function test_attribute_hydrator()
$this->assertEquals('baz', $model->foo);
}

public function test_attribute_hydrator_can_use_handle_function_of_class()
{
$entry = new Entry(['bar' => 'baz']);
$model = new TestHydratorModelStub;
AttributeHydrator::with(['sync_attributes' => [TestAttributeHandlerHandleStub::class]])
->hydrate($entry, $model);

$this->assertEquals('baz', $model->foo);
}

public function test_attribute_hydrator_can_use_invokable_class()
{
$entry = new Entry(['bar' => 'baz']);
$model = new TestHydratorModelStub;
AttributeHydrator::with(['sync_attributes' => [TestAttributeHandlerInvokableStub::class]])
->hydrate($entry, $model);

$this->assertEquals('baz', $model->foo);
}

public function test_attribute_hydrator_can_use_inline_function()
{
$entry = new Entry(['bar' => 'baz']);
$model = new TestHydratorModelStub;
AttributeHydrator::with(['sync_attributes' => [
function ($object, $eloquent) {
$eloquent->foo = $object->getFirstAttribute('bar');
}
]])
->hydrate($entry, $model);

$this->assertEquals('baz', $model->foo);
}

public function test_password_hydrator_uses_random_password()
{
$entry = new Entry(['bar' => 'baz']);
Expand Down Expand Up @@ -116,3 +150,19 @@ class TestHydratorModelStub extends Model implements LdapAuthenticatable
{
use AuthenticatesWithLdap;
}

class TestAttributeHandlerHandleStub
{
public function handle($object, $eloquent)
{
$eloquent->foo = $object->getFirstAttribute('bar');
}
}

class TestAttributeHandlerInvokableStub
{
public function __invoke($object, $eloquent)
{
$eloquent->foo = $object->getFirstAttribute('bar');
}
}

0 comments on commit cdce5af

Please sign in to comment.