From 345e331c7ed754f7986b4f3950c2d5b47a925292 Mon Sep 17 00:00:00 2001 From: Marc Beinder Date: Wed, 3 Sep 2025 11:51:20 -0500 Subject: [PATCH 1/5] Create Macroable Trait --- .idea/php.xml | 5 +- .idea/stdlib.iml | 5 +- src/Objects/Support/Traits/Macroable.php | 148 +++++++++++++++++++++++ 3 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 src/Objects/Support/Traits/Macroable.php diff --git a/.idea/php.xml b/.idea/php.xml index 2aa006e..4da245d 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -44,7 +44,6 @@ - @@ -58,7 +57,6 @@ - @@ -115,6 +113,9 @@ + + + diff --git a/.idea/stdlib.iml b/.idea/stdlib.iml index b687b1e..101fa13 100644 --- a/.idea/stdlib.iml +++ b/.idea/stdlib.iml @@ -58,8 +58,6 @@ - - @@ -92,6 +90,9 @@ + + + diff --git a/src/Objects/Support/Traits/Macroable.php b/src/Objects/Support/Traits/Macroable.php new file mode 100644 index 0000000..e303841 --- /dev/null +++ b/src/Objects/Support/Traits/Macroable.php @@ -0,0 +1,148 @@ +getMethods( + ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED + ); + + foreach ($methods as $method) { + if ($replace || !static::hasMacro($method->name)) { + static::macro($method->name, $method->invoke($mixin)); + } + } + } + + public static function hasMacro(string $name): bool + { + return isset(static::$macros[$name]); + } + + public static function flushMacros(): void + { + static::$macros = []; + } + + public static function __callStatic(string $method, array $parameters): mixed + { + // Check if a macro exists for the method + if (static::hasMacro($method)) { + $macro = static::$macros[$method]; + + if ($macro instanceof Closure) { + $macro = $macro->bindTo(null, static::class); + } + + return $macro(...$parameters); + } + + // Defer to the parent class's __callStatic if it exists + $parentClass = get_parent_class(static::class); + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod('__callStatic')) { + return parent::__callStatic($method, $parameters); + } + + // If the class is an Eloquent model, defer to Laravel's handling + if (static::canDeferToLaravel()) { + return static::deferToLaravel($method, $parameters, true); + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } + + public function __call(string $method, array $parameters): mixed + { + // Check if a macro exists for the method + if (static::hasMacro($method)) { + $macro = static::$macros[$method]; + + if ($macro instanceof Closure) { + $macro = $macro->bindTo($this, static::class); + } + + return $macro(...$parameters); + } + + // Defer to the parent class's __call if it exists + $parentClass = get_parent_class($this); + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod('__call')) { + return parent::__call($method, $parameters); + } + + // If the class is an Eloquent model, defer to Laravel's handling + if (static::canDeferToLaravel()) { + return $this->deferToEloquentInstance($method, $parameters); + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } + + protected static function canDeferToLaravel(): bool + { + return class_exists(Model::class) && + is_subclass_of(static::class, Model::class); + } + + /** + * Defer static method call to the parent class's __callStatic for Eloquent models. + * + * @param string $method + * @param array $parameters + * @param bool $static + * @return mixed + */ + protected static function deferToLaravel(string $method, array $parameters, bool $static = false) + { + if (static::canDeferToLaravel()) { + // Defer to the parent class's __callStatic (e.g., Model::__callStatic) + $parentClass = get_parent_class(static::class); + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__callStatic")) { + return parent::__callStatic($method, $parameters); + } + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } + + /** + * Defer instance method call to the parent class's __call for Eloquent models. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + protected function deferToEloquentInstance(string $method, array $parameters): mixed + { + if (static::canDeferToLaravel()) { + // Defer to the parent class's __call (e.g., Model::__call) + $parentClass = get_parent_class($this); + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__call")) { + return parent::__call($method, $parameters); + } + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } +} \ No newline at end of file From eb7e6e7d13e3fe753ae5219fb67452e15cd90c65 Mon Sep 17 00:00:00 2001 From: EncoreBot Date: Wed, 3 Sep 2025 17:08:42 +0000 Subject: [PATCH 2/5] Rectifying --- src/Objects/Support/Traits/Macroable.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Objects/Support/Traits/Macroable.php b/src/Objects/Support/Traits/Macroable.php index e303841..1ce8bcf 100644 --- a/src/Objects/Support/Traits/Macroable.php +++ b/src/Objects/Support/Traits/Macroable.php @@ -60,7 +60,7 @@ public static function __callStatic(string $method, array $parameters): mixed // Defer to the parent class's __callStatic if it exists $parentClass = get_parent_class(static::class); - if ($parentClass && (new ReflectionClass($parentClass))->hasMethod('__callStatic')) { + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__callStatic")) { return parent::__callStatic($method, $parameters); } @@ -87,7 +87,7 @@ public function __call(string $method, array $parameters): mixed // Defer to the parent class's __call if it exists $parentClass = get_parent_class($this); - if ($parentClass && (new ReflectionClass($parentClass))->hasMethod('__call')) { + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__call")) { return parent::__call($method, $parameters); } @@ -108,9 +108,6 @@ protected static function canDeferToLaravel(): bool /** * Defer static method call to the parent class's __callStatic for Eloquent models. * - * @param string $method - * @param array $parameters - * @param bool $static * @return mixed */ protected static function deferToLaravel(string $method, array $parameters, bool $static = false) @@ -128,10 +125,6 @@ protected static function deferToLaravel(string $method, array $parameters, bool /** * Defer instance method call to the parent class's __call for Eloquent models. - * - * @param string $method - * @param array $parameters - * @return mixed */ protected function deferToEloquentInstance(string $method, array $parameters): mixed { From 97717fc893e60cec560ffce7b8ee820287fc66ea Mon Sep 17 00:00:00 2001 From: EncoreBot Date: Wed, 3 Sep 2025 17:08:42 +0000 Subject: [PATCH 3/5] Ignore Rector Commit in Git Blame --- .git-blame-ignore-revs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index d931db0..1e6f57d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -44,4 +44,4 @@ e224e927dabcd3046455985118ed424c43aba054 e85fae4f7290329ac9cfae159e19c1bb55062e4b 10daa978ac4beebdbc8e9dcc6fa07657001fd91e 7bb064715cf4fb35fd1c9add945addb3959405c4 -5bd6cc77c40f19059dbdda4704d2f380099b29e3 \ No newline at end of file +5bd6cc77c40f19059dbdda4704d2f380099b29e3eb7e6e7d13e3fe753ae5219fb67452e15cd90c65 From 7e6e995f8e32353104b95c1b4394faf1bf030dbb Mon Sep 17 00:00:00 2001 From: EncoreBot Date: Wed, 3 Sep 2025 17:08:56 +0000 Subject: [PATCH 4/5] Dusting --- src/Objects/Support/Traits/Macroable.php | 81 ++++++++++++------------ 1 file changed, 41 insertions(+), 40 deletions(-) diff --git a/src/Objects/Support/Traits/Macroable.php b/src/Objects/Support/Traits/Macroable.php index 1ce8bcf..fc958c8 100644 --- a/src/Objects/Support/Traits/Macroable.php +++ b/src/Objects/Support/Traits/Macroable.php @@ -1,4 +1,5 @@ hasMethod("__callStatic")) { + return parent::__callStatic($method, $parameters); + } + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } + + /** + * Defer instance method call to the parent class's __call for Eloquent models. + */ + protected function deferToEloquentInstance(string $method, array $parameters): mixed + { + if (static::canDeferToLaravel()) { + // Defer to the parent class's __call (e.g., Model::__call) + $parentClass = get_parent_class($this); + if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__call")) { + return parent::__call($method, $parameters); + } + } + + throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); + } + public static function __callStatic(string $method, array $parameters): mixed { // Check if a macro exists for the method @@ -98,44 +139,4 @@ public function __call(string $method, array $parameters): mixed throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); } - - protected static function canDeferToLaravel(): bool - { - return class_exists(Model::class) && - is_subclass_of(static::class, Model::class); - } - - /** - * Defer static method call to the parent class's __callStatic for Eloquent models. - * - * @return mixed - */ - protected static function deferToLaravel(string $method, array $parameters, bool $static = false) - { - if (static::canDeferToLaravel()) { - // Defer to the parent class's __callStatic (e.g., Model::__callStatic) - $parentClass = get_parent_class(static::class); - if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__callStatic")) { - return parent::__callStatic($method, $parameters); - } - } - - throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); - } - - /** - * Defer instance method call to the parent class's __call for Eloquent models. - */ - protected function deferToEloquentInstance(string $method, array $parameters): mixed - { - if (static::canDeferToLaravel()) { - // Defer to the parent class's __call (e.g., Model::__call) - $parentClass = get_parent_class($this); - if ($parentClass && (new ReflectionClass($parentClass))->hasMethod("__call")) { - return parent::__call($method, $parameters); - } - } - - throw new BadMethodCallException(sprintf("Method %s::%s does not exist.", static::class, $method)); - } } \ No newline at end of file From cf18c25c1d9e42e457d53e00637e8266daf70683 Mon Sep 17 00:00:00 2001 From: EncoreBot Date: Wed, 3 Sep 2025 17:08:56 +0000 Subject: [PATCH 5/5] Ignore Duster Commit in Git Blame --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 1e6f57d..9271f1b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -45,3 +45,4 @@ e85fae4f7290329ac9cfae159e19c1bb55062e4b 10daa978ac4beebdbc8e9dcc6fa07657001fd91e 7bb064715cf4fb35fd1c9add945addb3959405c4 5bd6cc77c40f19059dbdda4704d2f380099b29e3eb7e6e7d13e3fe753ae5219fb67452e15cd90c65 +7e6e995f8e32353104b95c1b4394faf1bf030dbb