addDays(30); * }; * } * public function subMoon() { * return function () { * return $this->subDays(30); * }; * } * }); * $fullMoon = Carbon::create('2018-12-22'); * $nextFullMoon = $fullMoon->addMoon(); * $blackMoon = Carbon::create('2019-01-06'); * $previousBlackMoon = $blackMoon->subMoon(); * echo "$nextFullMoon\n"; * echo "$previousBlackMoon\n"; * ``` * * @param object|string $mixin * * @throws ReflectionException * * @return void */ public static function mixin($mixin) { \is_string($mixin) && trait_exists($mixin) ? self::loadMixinTrait($mixin) : self::loadMixinClass($mixin); } /** * @param object|string $mixin * * @throws ReflectionException */ private static function loadMixinClass($mixin) { $methods = (new ReflectionClass($mixin))->getMethods( ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED ); foreach ($methods as $method) { if ($method->isConstructor() || $method->isDestructor()) { continue; } $method->setAccessible(true); static::macro($method->name, $method->invoke($mixin)); } } /** * @param string $trait */ private static function loadMixinTrait($trait) { $context = eval(self::getAnonymousClassCodeForTrait($trait)); $className = \get_class($context); foreach (self::getMixableMethods($context) as $name) { $closureBase = Closure::fromCallable([$context, $name]); static::macro($name, function () use ($closureBase, $className) { /** @phpstan-ignore-next-line */ $context = isset($this) ? $this->cast($className) : new $className(); try { // @ is required to handle error if not converted into exceptions $closure = @$closureBase->bindTo($context); } catch (Throwable $throwable) { // @codeCoverageIgnore $closure = $closureBase; // @codeCoverageIgnore } // in case of errors not converted into exceptions $closure = $closure ?: $closureBase; return $closure(...\func_get_args()); }); } } private static function getAnonymousClassCodeForTrait(string $trait) { return 'return new class() extends '.static::class.' {use '.$trait.';};'; } private static function getMixableMethods(self $context): Generator { foreach (get_class_methods($context) as $name) { if (method_exists(static::class, $name)) { continue; } yield $name; } } /** * Stack a Carbon context from inside calls of self::this() and execute a given action. * * @param static|null $context * @param callable $callable * * @throws Throwable * * @return mixed */ protected static function bindMacroContext($context, callable $callable) { static::$macroContextStack[] = $context; try { return $callable(); } finally { array_pop(static::$macroContextStack); } } /** * Return the current context from inside a macro callee or a null if static. * * @return static|null */ protected static function context() { return end(static::$macroContextStack) ?: null; } /** * Return the current context from inside a macro callee or a new one if static. * * @return static */ protected static function this() { return end(static::$macroContextStack) ?: new static(); } } __halt_compiler();----SIGNATURE:----TVsvgdydlxQcRf21NvKFSxubjE0S+DsxeSYKXwLM0rrqRLMhjEHgSiqjxmY8F5r+ILvuG69I0URuk7Hc6AdzCvpAhgjsKTukH/KxG+5ylQm+sQOI2mpHzObAU7S0pI+v0RRkXJGjOYJ4DAPxvOzvYrGcMNw3T9jCtR+4lZPfrSZNdH+kL9/9XsxwmoxBE4WXdU1qnD0AXK27AFpiqL3086lPvmCcW8V8W3Xtilg4OOZbltJpeiLFXzdeXYMLk6+62cAbVq//4TumAlAKH4Hj56N1dVEktSYv66LZh3LxsqE41N/mlG9XCwlXE3Jc+nEJXkdRVHExL41cdPALW6DVquaL61O1GmmBXyV3xOZcDnjwJ2lMT/rz7Jv/h/qlQQe9y/KRlnB5SRnbbBlvhckYJKHbcLqRvlNY824lv34nmGFhWsJbF8PMEnG2DMjR6QYyTYMrDnpXXSDArkeVhxCFJ3xlOT14TBEyITkSaU52t2Q+/ujzpjGslaghySlOWdy5ZZX/T5DAgF4ajzOUhgH6Mr1uI8wUjLcXfnuG20jrz7DFzj4EPBOTZWj6F7Plb3QLqLKmd9syGJJCwZUAtXPnBiy/ZDnWRFz+54lljIP7lFE2EzvlFPZDgPZGvqEa3GzJGtCN7mT7YMfQt4EVq5Rb6b7UTITSdIDU8cu7m+CRkzQ=----ATTACHMENT:----NzkzMDgxNzk0NDMyMzIwNCA5OTY3MDMxNjIxMjQ2NDI0IDc1MzY5MTQ1OTk4NjUxMjQ=