Skip to content

Instantly share code, notes, and snippets.

@chapterjason
Created November 7, 2018 14:11
Show Gist options
  • Select an option

  • Save chapterjason/6de70505206e5ebb107ef27f46cc8ea4 to your computer and use it in GitHub Desktop.

Select an option

Save chapterjason/6de70505206e5ebb107ef27f46cc8ea4 to your computer and use it in GitHub Desktop.

Revisions

  1. chapterjason created this gist Nov 7, 2018.
    113 changes: 113 additions & 0 deletions DynamicMethod.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,113 @@
    <?php
    /**
    * Copyright Jason Schilling
    **/

    interface DynamicMethodsAwareInterface
    {
    }

    trait DynamicMethodsAwareTrait
    {
    protected static $methods = [];

    public static function addMethod($name, $method)
    {
    if (!is_callable($method))
    {
    throw new Error("addMethod parameter $method musst be a callable!");
    }

    self::$methods[$name] = $method;
    }

    public function __call($name, $arguments)
    {
    if (isset(self::$methods[$name]))
    {
    $method = self::$methods[$name];
    $method = \Closure::bind($method, $this, get_class());
    return call_user_func_array($method, $arguments);
    }

    throw new Error("Call to undefined method " . get_class($this) . "::" . $name);
    }

    }

    class Bar
    {

    protected $name;

    public function __construct($name)
    {
    $this->name = $name;
    }

    }

    class Foo implements DynamicMethodsAwareInterface
    {
    use DynamicMethodsAwareTrait;

    protected $bars = [];
    }

    $foo = new Foo;

    function addManyMethods($className, $name)
    {
    $classReflection = new ReflectionClass($className);
    var_dump($classReflection);
    if ($classReflection->implementsInterface(DynamicMethodsAwareInterface::class))
    {
    $singular = $name;
    $plural = $name . 's';

    $className::addMethod("get" . ucfirst($plural) , function () use ($plural)
    {
    return $this->{$plural};
    });

    $className::addMethod("set" . ucfirst($plural) , function ($items) use ($plural)
    {
    $this->{$plural} = $items;

    return $this;
    });

    $className::addMethod("add" . ucfirst($singular) , function ($item) use ($plural)
    {
    $this->{$plural}[] = $item;
    return $this;
    });

    $className::addMethod("remove" . ucfirst($singular) , function ($item) use ($plural)
    {
    $key = array_search($item, $this->{$plural}, true);

    if ($key === false)
    {
    return $this;
    }

    unset($this->{$plural}[$key]);

    return $this;
    });
    }
    }

    addManyMethods(Foo::class , "bar");

    $foo->addBar(new Bar('He'));
    $foo->addBar(new Bar('She'));
    var_dump($foo->getBars());

    $bar = new Bar('It');
    $foo->setBars([$bar, new Bar('Her') ]);
    var_dump($foo->getBars());
    $foo->removeBar($bar);
    var_dump($foo->getBars());