FancyClosure.php

<?php

namespace Lia\Utility;

/**
 * Normalize callable usage & bind paramaters to a callable, like you can in javascript
 *
 * @todo Remove FancyClosure from Liaison, as its not used (pretty sure). It should go in my util repo
 */
class FancyClosure {

    /** array of paramaters to pass to the callable when invoked */
    public $bound;
    /** The source callable as it was passed to this class */
    public $origCallable;

    /** An anonymous function, if the callable is an anonymous function */
    public $function = null;
    /** The fully qualified classname, if the callable is an array like `[$object || 'classname', 'methodname']`. */
    public $class = null;
    /** The object, if the callable is an array like `[$object, 'methodName']` */
    public $object = null;
    /** The function name, if the callable is an array like `[$object || 'classname', 'methodname']` */
    public $funcName = null;

    /** true if the callable is a static class function */
    public $isStatic = false;
    /** true if the callable is an anonymous function */
    public $isAnonymous = false;

    /**
     *
     * @param $callable A callable... a string function name, anonymous function, or array callable.
     * @param $boundParamaters an array of values to pass to the callable when invoked. Or empty array.
     */
    public function __construct($callable, $boundParamaters){
        $this->origCallable = $callable;
        $this->bound = $boundParamaters;
        if (is_array($callable)){
            $src = $callable[0];
            $this->funcName = $callable[1];
            if (is_object($src)){
                $this->object = $src;
                $this->class = get_class($src);
            } else if (is_string($src)){
                $this->class = $src;
                $this->isStatic = true;
            }
        } else if (is_string($callable)){
            $this->funcName = $callable;
            $this->function = $callable;
        } else {
            $this->function = $callable;
            $this->isAnonymous = true;
        }
    }

    /**
     * Invoke the given callable with any bound paramaters
     * @param ...$args any additional args to pass to the callable. These come after bound args
     */
    public function __invoke(...$args){
        $bound = $this->bound;
        $args = $args;
        $pass = array_merge($bound, $args);
        $callable = $this->origCallable;
        return call_user_func_array($callable,$pass);
    }
}