Skip to content

Commit

Permalink
Make Accessible trait as minimal as possible and hide as much of the …
Browse files Browse the repository at this point in the history
…implementation as possible to internal classes.
  • Loading branch information
marguskaidja authored Nov 10, 2022
1 parent 3f23de6 commit 86bdf61
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 43 deletions.
15 changes: 5 additions & 10 deletions src/Accessible.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ trait Accessible
*/
public function __call(string $method, array $args): mixed
{
return ClassConf::findConf(static::class)
->handleMagicCall($this, $method, $args);
return ClassConf::handleMagicCall($this, $method, $args);
}

/**
Expand All @@ -38,8 +37,7 @@ public function __call(string $method, array $args): mixed
*/
public function __get(string $propertyName): mixed
{
return ClassConf::findConf(static::class)
->handleMagicGet($this, $propertyName);
return ClassConf::handleMagicGet($this, $propertyName);
}

/**
Expand All @@ -51,8 +49,7 @@ public function __get(string $propertyName): mixed
*/
public function __set(string $propertyName, mixed $propertyValue): void
{
ClassConf::findConf(static::class)
->handleMagicSet($this, $propertyName, $propertyValue);
ClassConf::handleMagicSet($this, $propertyName, $propertyValue);
}

/**
Expand All @@ -63,8 +60,7 @@ public function __set(string $propertyName, mixed $propertyValue): void
*/
public function __isset(string $propertyName): bool
{
return ClassConf::findConf(static::class)
->handleMagicIsset($this, $propertyName);
return ClassConf::handleMagicIsset($this, $propertyName);
}

/**
Expand All @@ -75,7 +71,6 @@ public function __isset(string $propertyName): bool
*/
public function __unset(string $propertyName): void
{
ClassConf::findConf(static::class)
->handleMagicUnset($this, $propertyName);
ClassConf::handleMagicUnset($this, $propertyName);
}
}
76 changes: 43 additions & 33 deletions src/ClassConf.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use function call_user_func;
use function count;
use function current;
use function get_class;
use function get_parent_class;
use function in_array;
use function is_string;
Expand Down Expand Up @@ -171,7 +172,7 @@ private function __construct(
* @return ClassConf
* @throws ReflectionException
*/
public static function findConf(string $name): ClassConf
private static function findConf(string $name): ClassConf
{
if (!isset(self::$classes[$name])) {
self::$classes[$name] = new self($name);
Expand Down Expand Up @@ -343,10 +344,12 @@ private function isClassUsingAccessibleTrait(ReflectionClass $rfClass): array
*
* @return mixed
*/
public function handleMagicCall(object $object, string $method, array $args): mixed
public static function handleMagicCall(object $object, string $method, array $args): mixed
{
$classConf = self::findConf(get_class($object));

/** @var Format $attr */
$attr = $this->attributes->get(Format::class);
$attr = $classConf->attributes->get(Format::class);
$format = $attr->instance();

if (null !== ($parsedMethod = $format->matchCalled($method))) {
Expand Down Expand Up @@ -376,7 +379,7 @@ public function handleMagicCall(object $object, string $method, array $args): mi
) {
if ($nArgs > 1) {
throw InvalidArgumentException::dueMultiPropertyAccessorCanHaveExactlyOneArgument(
self::class,
$classConf->name,
$method
);
}
Expand All @@ -386,7 +389,7 @@ public function handleMagicCall(object $object, string $method, array $args): mi
} elseif (
// Check if whole method name is property name like $obj->somePropertyName('somevalue')
null === $accessorMethod
&& null !== $this->properties->findConf($propertyName, true)
&& null !== $classConf->properties->findConf($propertyName, true)
&& $format->allowPropertyNameOnly()
) {
// If there are zero arguments, then interpret the call as Getter
Expand All @@ -401,7 +404,7 @@ public function handleMagicCall(object $object, string $method, array $args): mi

// Accessor method must be resolved at this point, or we fail
if (null === $accessorMethod) {
throw BadMethodCallException::dueUnknownAccessorMethod(self::class, $method);
throw BadMethodCallException::dueUnknownAccessorMethod($classConf->name, $method);
}

$propertyNameCI = false;
Expand All @@ -411,14 +414,14 @@ public function handleMagicCall(object $object, string $method, array $args): mi
if (0 === count($propertiesList)) {
if ('' === $propertyName) {
if (!count($args)) {
throw InvalidArgumentException::dueMethodIsMissingPropertyNameArgument(self::class, $method);
throw InvalidArgumentException::dueMethodIsMissingPropertyNameArgument($classConf->name, $method);
}

$propertyName = array_shift($args);

if (!is_string($propertyName)) {
throw InvalidArgumentException::duePropertyNameArgumentMustBeString(
self::class,
$classConf->name,
$method,
count($args) + 1
);
Expand All @@ -433,7 +436,7 @@ public function handleMagicCall(object $object, string $method, array $args): mi
if ($accessorMethodIsSetOrWith) {
if (!count($args)) {
throw InvalidArgumentException::dueMethodIsMissingPropertyValueArgument(
self::class,
$classConf->name,
$method,
$nArgs + 1
);
Expand All @@ -445,7 +448,7 @@ public function handleMagicCall(object $object, string $method, array $args): mi
// Fail if there are more arguments specified than we are willing to process
if (count($args)) {
throw InvalidArgumentException::dueMethodHasMoreArgumentsThanExpected(
self::class,
$classConf->name,
$method,
$nArgs - count($args)
);
Expand All @@ -466,18 +469,18 @@ public function handleMagicCall(object $object, string $method, array $args): mi
$result = clone $result;
}

$accessorImpl = $this->setter;
$accessorImpl = $classConf->setter;

foreach ($propertiesList as $propertyName => $propertyValue) {
if (!is_string($propertyName)) {
throw InvalidArgumentException::dueMultiPropertyArrayContainsNonStringProperty(
self::class,
$classConf->name,
$method,
$propertyName
);
}

$propertyConf = $this->properties->findConf($propertyName, $propertyNameCI);
$propertyConf = $classConf->properties->findConf($propertyName, $propertyNameCI);
$immutable = ($propertyConf?->isImmutable()) ?? false;

// Check if mutable/immutable property was called using correct method:
Expand All @@ -489,12 +492,12 @@ public function handleMagicCall(object $object, string $method, array $args): mi
) {
if ($immutable) {
throw BadMethodCallException::dueImmutablePropertiesMustBeCalledUsingWith(
self::class,
$classConf->name,
$propertyName
);
} else {
throw BadMethodCallException::dueMutablePropertiesMustBeCalledUsingSet(
self::class,
$classConf->name,
$propertyName
);
}
Expand All @@ -505,59 +508,64 @@ public function handleMagicCall(object $object, string $method, array $args): mi
} else {
/** @var 'get'|'isset'|'unset' $accessorMethod */
$accessorImpl = match ($accessorMethod) {
Method::TYPE_GET => $this->getter,
Method::TYPE_ISSET => $this->isSetter,
Method::TYPE_UNSET => $this->unSetter
Method::TYPE_GET => $classConf->getter,
Method::TYPE_ISSET => $classConf->isSetter,
Method::TYPE_UNSET => $classConf->unSetter
};

foreach ($propertiesList as $propertyName) {
if (!is_string($propertyName)) {
throw InvalidArgumentException::dueMultiPropertyArrayContainsNonStringProperty(
self::class,
$classConf->name,
$method,
$propertyName
);
}

$propertyConf = $this->properties->findConf($propertyName, $propertyNameCI);
$propertyConf = $classConf->properties->findConf($propertyName, $propertyNameCI);
$result = $accessorImpl($result, $propertyName, $propertyConf);
}
}

return $result;
}

public function handleMagicGet(object $object, string $propertyName): mixed
public static function handleMagicGet(object $object, string $propertyName): mixed
{
return ($this->getter)(
$classConf = self::findConf(get_class($object));

return ($classConf->getter)(
$object,
$propertyName,
$this->properties->findConf($propertyName)
$classConf->properties->findConf($propertyName)
);
}

public function handleMagicIsset(object $object, string $propertyName): bool
public static function handleMagicIsset(object $object, string $propertyName): bool
{
return ($this->isSetter)(
$classConf = self::findConf(get_class($object));

return ($classConf->isSetter)(
$object,
$propertyName,
$this->properties->findConf($propertyName)
$classConf->properties->findConf($propertyName)
);
}

public function handleMagicSet(object $object, string $propertyName, mixed $propertyValue): void
public static function handleMagicSet(object $object, string $propertyName, mixed $propertyValue): void
{
$propertyConf = $this->properties->findConf($propertyName);
$classConf = self::findConf(get_class($object));
$propertyConf = $classConf->properties->findConf($propertyName);
$immutable = $propertyConf?->isImmutable();

if ($immutable) {
throw BadMethodCallException::dueImmutablePropertiesCantBeSetUsingAssignmentOperator(
$this->name,
$classConf->name,
$propertyName
);
}

($this->setter)(
($classConf->setter)(
$object,
'set',
$propertyName,
Expand All @@ -566,12 +574,14 @@ public function handleMagicSet(object $object, string $propertyName, mixed $prop
);
}

public function handleMagicUnset(object $object, string $propertyName): void
public static function handleMagicUnset(object $object, string $propertyName): void
{
($this->unSetter)(
$classConf = self::findConf(get_class($object));

($classConf->unSetter)(
$object,
$propertyName,
$this->properties->findConf($propertyName)
$classConf->properties->findConf($propertyName)
);
}
}
1 change: 1 addition & 0 deletions src/Format/Method.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

namespace margusk\Accessors\Format;

/** @api */
final class Method
{
public const TYPE_GET = 'get';
Expand Down
1 change: 1 addition & 0 deletions src/Format/Standard.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
* $value = $foo->bar(); // Same as $value = $foo->bar;
* $foo->bar('new value'); // Same as $foo->bar = `new value`;
* ```
* @api
*/
class Standard implements FormatContract
{
Expand Down

0 comments on commit 86bdf61

Please sign in to comment.