<?php
/**
 * An abstract class for controller extensions.
 *
 * This class provides a way to use controller properties and functions outside
 * of the controller. It enables code inside an extension to look identical to
 * code inside a controller.
 */
abstract class controller_extension
{
    /**
     * @var controller The controller.
     */
    protected $controller;
    
    /**
     * @var array The controller properties.
     */
    protected $property;

    ////////////////////////////////////////////////////////////////////////////
    // Construct and destruct functions.

    ////////////////////////////////////////////////////////////////////////////
    // Overload functions.

    /**
     * A shortcut for getting a controller property.
     *
     * @param string $property The property name.
     * @throws outofrangeexception If the property does not exists.
     * @return mixed The value.
     */
    public function __get($property)
    {
        if (!array_key_exists($property, $this->property))
        {
            throw new outofrangeexception('Property ' . $property . ' does not exist.');
        }
        
        return $this->property[$property];
    }

    /**
     * A shortcut for calling a controller function.
     * 
     * @param string $function The function name.
     * @param array $parameter The parameters to provide.
     * @return mixed The functions returning value.
     */
    public function __call($function, array $parameter)
    {
        return call_user_func_array(array($this->controller, $function), $parameter);
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // Interface functions.

    /**
     * Sets the controller.
     * 
     * @param controller $controller The controller.
     * @return controller_extension A fluent interface.
     */
    public function set_controller(controller $controller)
    {
        $this->controller = $controller;
        return $this;
    }

    /**
     * Sets the controller properties.
     * 
     * @param array $controller The controller properties.
     * @return controller_extension A fluent interface.
     */
    public function set_property(array $property)
    {
        $this->property = $property;
        return $this;
    }

    ////////////////////////////////////////////////////////////////////////////
    // Internal functions.
}
