117 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace Illuminate\Support\Traits;
 | 
						|
 | 
						|
use BadMethodCallException;
 | 
						|
use Closure;
 | 
						|
use ReflectionClass;
 | 
						|
use ReflectionMethod;
 | 
						|
 | 
						|
trait Macroable
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * The registered string macros.
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected static $macros = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * Register a custom macro.
 | 
						|
     *
 | 
						|
     * @param  string  $name
 | 
						|
     * @param  object|callable  $macro
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    public static function macro($name, $macro)
 | 
						|
    {
 | 
						|
        static::$macros[$name] = $macro;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Mix another object into the class.
 | 
						|
     *
 | 
						|
     * @param  object  $mixin
 | 
						|
     * @param  bool  $replace
 | 
						|
     * @return void
 | 
						|
     *
 | 
						|
     * @throws \ReflectionException
 | 
						|
     */
 | 
						|
    public static function mixin($mixin, $replace = true)
 | 
						|
    {
 | 
						|
        $methods = (new ReflectionClass($mixin))->getMethods(
 | 
						|
            ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED
 | 
						|
        );
 | 
						|
 | 
						|
        foreach ($methods as $method) {
 | 
						|
            if ($replace || ! static::hasMacro($method->name)) {
 | 
						|
                $method->setAccessible(true);
 | 
						|
                static::macro($method->name, $method->invoke($mixin));
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Checks if macro is registered.
 | 
						|
     *
 | 
						|
     * @param  string  $name
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public static function hasMacro($name)
 | 
						|
    {
 | 
						|
        return isset(static::$macros[$name]);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Dynamically handle calls to the class.
 | 
						|
     *
 | 
						|
     * @param  string  $method
 | 
						|
     * @param  array  $parameters
 | 
						|
     * @return mixed
 | 
						|
     *
 | 
						|
     * @throws \BadMethodCallException
 | 
						|
     */
 | 
						|
    public static function __callStatic($method, $parameters)
 | 
						|
    {
 | 
						|
        if (! static::hasMacro($method)) {
 | 
						|
            throw new BadMethodCallException(sprintf(
 | 
						|
                'Method %s::%s does not exist.', static::class, $method
 | 
						|
            ));
 | 
						|
        }
 | 
						|
 | 
						|
        $macro = static::$macros[$method];
 | 
						|
 | 
						|
        if ($macro instanceof Closure) {
 | 
						|
            $macro = $macro->bindTo(null, static::class);
 | 
						|
        }
 | 
						|
 | 
						|
        return $macro(...$parameters);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Dynamically handle calls to the class.
 | 
						|
     *
 | 
						|
     * @param  string  $method
 | 
						|
     * @param  array  $parameters
 | 
						|
     * @return mixed
 | 
						|
     *
 | 
						|
     * @throws \BadMethodCallException
 | 
						|
     */
 | 
						|
    public function __call($method, $parameters)
 | 
						|
    {
 | 
						|
        if (! static::hasMacro($method)) {
 | 
						|
            throw new BadMethodCallException(sprintf(
 | 
						|
                'Method %s::%s does not exist.', static::class, $method
 | 
						|
            ));
 | 
						|
        }
 | 
						|
 | 
						|
        $macro = static::$macros[$method];
 | 
						|
 | 
						|
        if ($macro instanceof Closure) {
 | 
						|
            $macro = $macro->bindTo($this, static::class);
 | 
						|
        }
 | 
						|
 | 
						|
        return $macro(...$parameters);
 | 
						|
    }
 | 
						|
}
 |