<?php
/**
* Web Application Component Toolkit
*
* @link http://www.phpwact.org/
*
* @author Wact Development Team
* @link http://www.phpwact.org/team
*
* @copyright Copyright 2006, Jeff Moore
* @license http://opensource.org/licenses/mit-license.php MIT
*/

/**
* A Parameter object represents an input parameter to the running program.
* In WACT, all input to the application must be formally declared using
* An instance of a decendant of this class.
*/
abstract class Wact_Request_Parameter {

    /**
    * The name of this parameter.
    * @var string
    */
    protected $name;

    /**
    * The parent parameter if this parameter is a member of a compound parameter.
    * NULL if the parameter is independent.
    * @var Wact_Request_Compound
    */
    protected $parent;

    /**
    * This is the name of the parameter, unique to a given input channel.  It is generally
    * the same as the parameter name.  The parameter name need not be unique and may vary
    * to differentiate between two parameters with the same sourceLocation, but from different
    * channels
    * @var string
    */
    protected $sourceLocation;

    /**
    * Location to bind this parameter into the model.
    * @var string
    */
    protected $modelLocation = NULL;

    /**
    * A default value for this parameter
    * @var string
    */
    protected $defaultValue = NULL;

    /**
    * Parameter contructor
    * @param $name string The name of this parameter and the default source location.
    */
    function __construct($name) {
        $this->name = $name;
        $this->sourceLocation = $name;
    }

    /**
    * Tempate method to accept a relationship with the controller that will define
    * this input parameter.
    */
    function bindToController($definingController) {
    }

    /**
    * Name is used internally to identify this Parameter.  Name is normally
    * identical to the source location, except when parameters on different
    * channels with the same source location must be distinguished.
    */
    function getName() {
        return $this->name;
    }

    /**
    * The source location uniquely identifies this parameter within an input
    * channel.
    */
    function getSourceLocation() {
        return $this->sourceLocation;
    }

    /**
    * Each parameter may have an associated location in the response model.
    * Parameters that have a model location specified are considered session
    * parameters and their state is automatically preserved between requests
    * by the framework, subject to channel limitations.
    */
    function getModelLocation() {
        return $this->modelLocation;
    }

    /**
    * Returns the value for this Parameter from the current request or the default
    * if the parameter is not available.
    */
    function getValue() {
        if ($this->hasValue()) {
            return $this->getRawValue();
        } else {
            return $this->getDefault();
        }
    }

    /**
    * Determine if this value has been defined on the proper input channel.
    */
    abstract function hasValue();

    /**
    * Reads the value of this parameter from the raw input source.
    */
    abstract function getRawValue();

    /**
    * Setter for the parameter default value.
    */
    function defaultTo($value) {
        $this->defaultValue = $value;
        return $this; // Stay fluent
    }

    /**
    * Getter for default value.
    */
    function getDefault() {
        return $this->defaultValue;
    }

    /**
    * Specifies that this parameter is a part of a Wact_Request_Compound
    * Normally not called by framework users.
    */
    function _setParent($parent) {
        $this->parent = $parent;
    }

    /**
    * Establish a connection between this input parameter and a model
    * location, expressed as a Wact_Property_Binder path.
    */
    function bindToModel($modelLocation = NULL) {
        if (is_null($modelLocation)) {
            $this->modelLocation = $this->sourceLocation;
        } else {
            $this->modelLocation = $modelLocation;
        }
        return $this; // fluid interface
    }

    /**
    * Copy input values to their specified location in the responseModel.
    * This is normally called by the controller as a part of the controller lifecycle.
    */
    function copyToModel($model) {
        if (!is_null($this->modelLocation)) {
            Wact_Property_Binder::setPath($model, $this->modelLocation, $this->getValue());
        }
    }

    /**
    * Write a value to a transition, using this parameter as a guide, such that when
    * The transition is taken, this parameter will have that value during that request.
    */
    function WriteValueToTransition($transition, $value) {
    }
    
    /**
    * A utility function to undo the effects of the get_magic_quotes_gpc ini parameter.
    * (bring on PHP 6!)
    */
    protected function undoMagicSlashing($value) {
        // Does not handle nested arrays
        if (get_magic_quotes_gpc()) {
            return stripslashes($value);
        }
        return $value;
    }
    
}

?>