diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs
index d931db0..9271f1b 100644
--- a/.git-blame-ignore-revs
+++ b/.git-blame-ignore-revs
@@ -44,4 +44,5 @@ e224e927dabcd3046455985118ed424c43aba054
e85fae4f7290329ac9cfae159e19c1bb55062e4b
10daa978ac4beebdbc8e9dcc6fa07657001fd91e
7bb064715cf4fb35fd1c9add945addb3959405c4
-5bd6cc77c40f19059dbdda4704d2f380099b29e3
\ No newline at end of file
+5bd6cc77c40f19059dbdda4704d2f380099b29e3eb7e6e7d13e3fe753ae5219fb67452e15cd90c65
+7e6e995f8e32353104b95c1b4394faf1bf030dbb
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..fc958c8
--- /dev/null
+++ b/src/Objects/Support/Traits/Macroable.php
@@ -0,0 +1,142 @@
+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 = [];
+ }
+
+ 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));
+ }
+
+ 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));
+ }
+}
\ No newline at end of file