<?php
/* Author: Leon Bukhman *******************************************/
/* Form Generation Class ******************************************/
/* Revision: $Id: class_form.phps 148 2005-10-14 20:20:38Z leon $ **/

/******************************************************************
This class generates forms using templates. It extends the Template
class and provides aditionally sopports saving form state between
form submits.

Note, in order to save the formstate, a hidden form field must be
present in the template called __FORMSTATE. Use the following
template as guide:
<form action="<?=$_SERVER['PHP_SELF']?>" method="POST" name="<?=$formname?>">
    <input type="hidden" name="__FORMSTATE" value="<?=$_POST['__FORMSTATE']?>">
    <input type="hidden" name="__FORMACTION">
    <input type="hidden" name="__FORMPARAM">
    ...
    <input type="submit" name="Submit" value="Submit">
</form>

Also use the following JavaScript function to postback with commands
function mySubmit(action, param) {
    document.forms[0].__FORMACTION.value = action;
    document.forms[0].__FORMPARAM.value = param;
    document.forms[0].submit();   
}

Public Methods:
    DisplayForm()
        save the state and return the processed form content
        returns string

    set($name, $value, $save=true)
        overrides the base class function to store values in state
        
    set_vars($vars, $clear = false, $save=true)
        overrides the base class function to store values in state

Private Methods:
    _saveState()
        saves the form variables into __FORMSTATE
        data is encrypted using BLOWFISH with session_id as key

    _restoreState()
        restore form state from __FORMSTATE

    _updateState()
        update the form state with POST values after a postback
    
Requires:
    class_template.php

Todo:
*******************************************************************/

class FormTemplate extends Template{
    
//$name is the form name
    
var $name;          //string
    //$template is the template that will be rendered
    
var $template;      //string
    //$persistant if form state is to be saved between form submits
    
var $persistant;    //bool
    //$state_vars are the values to be stored in the session
    
var $state_vars;    //array
    //$form_controls is an array of state_var=>control name 
    
var $form_controls//array

    
function FormTemplate($template$name=""$persistant=false$form_controls=array()) {
        
parent::Template(TEMPLATE_PATH);
        
        
$this->name $name;
        
$this->template $template;
        
$this->persistant $persistant;
        
$this->form_controls $form_controls;
        
        if (
$this->persistant) {
            
$this->_restoreState();
            if (
$this->IsPostback()) {
                
$this->_updateState();
            }
        }
    }

    
/*Public Methods***********************************************/
    
function DisplayForm() {
        if (
$this->persistant)
            
$this->_saveState();
        
parent::set("formname",$this->name);
        return 
parent::fetch($this->template);
    }

    function 
IsPostback() {
        return 
$this->get("__IsPostback");
    }
    
    
/*Public Overriden Methods*************************************/
    
function set($name$value$save=true) {
        
parent::set($name$value);
        if (
$this->persistant && $save) {
            
$this->state_vars[$name] = $value;
        }
    }
    
    function 
set_vars($vars$clear false$save=true) {
        
parent::set_vars($vars$clear);
        if(
$this->persistant && $save && is_array($vars))
            if (
$clear) {
                
$this->state_vars=vars;
            } else {
                
$this->state_vars array_merge($this->state_vars$vars);
            }
    }
    
    
/*Private Methods**********************************************/
    
function _saveState() {
        
//var_dump($this->state_vars);
        
$this->set("__IsPostback",true);
        
$state chunk_split(encrypt(serialize($this->state_vars),session_id()));
        
$_POST["__FORMSTATE"] = $state;
    }

    function 
_restoreState() {
        if(isset(
$_POST['__FORMSTATE'])) {
            
$state decrypt($_POST['__FORMSTATE'],session_id());
            
$this->vars unserialize($state);
            
$this->state_vars $this->vars;
        }
    }
    
    function 
_updateState() {
        if (
is_array($this->form_controls)) {
            foreach (
$this->form_controls as $state_var => $control_name) {
                
$this->set($state_var$_POST[$control_name]);
            }
        }
    }
}

?>