Location: PHPKode > scripts > AuriumForm > auriumform/class.auriumform.php
<?php
// ---------------------------------------------------------------------------
// Forms fields manipulator and generator by Alfred Reinold Baudisch <hide@address.com>
// Copyright © 2005 AuriumSoft - www.auriumsoft.com.br
// ---------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// ---------------------------------------------------------------------------

/**
 * Import the fields generator class
 */
if(!class_exists('AuriumFormFields'))
{
    require_once 'class.auriumformfields.php';
}

/**
 * Template definitions
 */
// Field label
define('AURIUMFORM_TP_LABEL', '|LABEL|');
// The field
define('AURIUMFORM_TP_FIELD', '|FIELD|');
// Errors messages
define('AURIUMFORM_TP_ERROR', '|ERROR|');

// Default form method (POST or GET)
define('AURIUMFORM_DEFAULT_METHOD', 'POST');
// Default form action
define('AURIUMFORM_DEFAULT_ACTION', $_SERVER['PHP_SELF']);

/**
 * Engine of forms fields manipulator and generator
 *
 * @author Alfred Reinold Baudisch <hide@address.com>
 * @since Feb 12, 2005
 * @version 1.1.8 - Feb 23, 2005
 *
 * -> Feb 17, 2005
 * - Added a new if case in function TemplateReplace. Is the if to recognize
 * the fields that have attribute no_template
 * - ereg functions on SetTemplate replaced by strstr, to avoid conflicts in case
 * of using chars like |, ( and ) on template definitions (e.g.: AURIUMFORM_TP_LABEL)
 * - Added new field Type, brstates
 * - Added new parameter to ShowError, if $Print is true (default value) the error message
 * will be directly printed
 * - Added function SetConfig
 * - Added new features on function Debug, now it shows info about the forms
 * - Added aliases and function ProcessAliases to process them
 * - Added function Debug
 *
 * -> Feb 23, 2005
 * - Corrected a bug in SetData() on the moment of calling ProcessAliases. It were giving
 * a multiarray instead of array of a unique field.
 * Before: $this->ProcessAliases($Data); - Now: $this->ProcessAliases($Data[$i]);
 */
class AuriumForm extends AuriumFormFields
{
    /**#@+
     * @access private
     */
    /**
     * Valid field types recognized by the class
     * @var array $Types
     */
    var $Types = array(
        'text',
        'textarea',
        'password',
        'selectbox',
        'checkbox',
        'radio',
        'hidden',
        'file',
        'button',
        'image',
        'brstates'
    );

    /**
     * If an error has occurred
     * @var boolean $Error
     */
    var $Error = false;

    /**
     * Data of the fields
     * @var array $Data
     */
    var $Data = array();

    /**
     * Field count
     * @var array $Count
     */
    var $Count = array();

    /**
     * Global config and templates
     * Recognized values:
     *  'size'      (default size)
     *  'css'       (default css)
     *  'css_error' (default error css)
     *  'template_open'
     *  'template_label' @
     *  'template_field' @
     *  'template_error' @
     *  'template_close'
     *  'template_line'
     *  'template_field_one'
     *  'template_file' - (optional) the path to the file with the template
     *  @ required values
     *
     * @var array $Config
     */
    var $Config = array();

    /**
     * Data from created forms
     * @var array $Forms
     */
    var $Forms = array();
    /**#@-*/

    /**
     * Constructor
     * Receives the global config and templates
     *
     * @param array $Config
     * @access public
     */
    function AuriumForm($Config = false)
    {
        if(is_array($Config) && sizeof($Config))
        {
            $this->SetConfig($Config);
        }
        
        //
        // Add default template values if any was not given
        //
        if(!$this->Config['template_label'])
        {
            $this->Config['template_label'] = '<B>' . AURIUMFORM_TP_LABEL . '</B>: ';
        }
        if(!$this->Config['template_field'])
        {
            $this->Config['template_field'] = AURIUMFORM_TP_FIELD;
        }
        if(!$this->Config['template_error'])
        {
            $this->Config['template_error'] = '<BR>- ' . AURIUMFORM_TP_ERROR;
        }
        if(!$this->Config['template_line'])
        {
            $this->Config['template_line'] = '<BR>';
        }
        if(!$this->Config['template_field_one'])
        {
            $this->Config['template_field_one'] = AURIUMFORM_TP_FIELD;
        }
    }

    /**
     * Set class configuration
     *
     * @param array $Config Array with the settings. It can have all fields or only one
     * @since Feb 17, 2005
     * @access public
     */
    function SetConfig($Config)
    {
        // Parameter $Config must be an array
        if(!is_array($Config))
        {
            $this->ShowError('<B>SetConfig:</B> $Config must be an array!');
            return false;
        }
        
        // There is no Config yet, so pass all the array to the class
        if(!sizeof($this->Config))
        {
            $NoPrevious = true;
            $this->Config = $Config;
        }

        // Is to import the template from a file
        if(isset($Config['template_file']))
        {
            $this->Config['template_file'] = $Config['template_file'];
            require $this->Config['template_file'];

            $this->SetTemplate($Template);

            return true;
        }

        // Has template fields, so add it to the class
        if( eregi( 'template', implode(' ', array_keys($Config))) )
        {
            $this->SetTemplate($Config);
        }

        if($NoPrevious)
        {
            return true;
        }

        //
        // Set individual fields
        //
        if(isset($Config['size']))
        {
            $this->Config['size'] = $Config['size'];
        }
        if(isset($Config['css_error']))
        {
            $this->Config['css_error'] = $Config['css_error'];
        }
        if(isset($Config['css']))
        {
            $this->Config['css'] = $Config['css'];
        }
    }

    /**
     * Set new values to the template and check it they are valid
     *
     * If called after the constructor and any value was not given, the earlier
     * value will be keeped
     *
     * @param array $Template New values. Can have 1 or more new values
     * @access public
     */
    function SetTemplate($Template)
    {
        if($Template['template_label'] != false)
        {
            if(!strstr($Template['template_label'], AURIUMFORM_TP_LABEL))
            {
                $this->ShowError('Invalid LABEL template (template_label). It needs to have the string <I>' . AURIUMFORM_TP_LABEL . '</I>');
            }

            $this->Config['template_label'] = $Template['template_label'];
        }

        if($Template['template_field'] != false)
        {
            if(!strstr($Template['template_field'], AURIUMFORM_TP_FIELD))
            {
                $this->ShowError('Invalid FIELD template (template_field). It needs to have the string <I>' . AURIUMFORM_TP_FIELD . '</I>');
            }

            $this->Config['template_field'] = $Template['template_field'];
        }

        if($Template['template_error'] != false)
        {
            if(!strstr($Template['template_error'], AURIUMFORM_TP_ERROR))
            {
                $this->ShowError('Invalid ERROR template (template_error). It needs to have the string <I>' . AURIUMFORM_TP_ERROR . '</I>');
            }

            $this->Config['template_error'] = $Template['template_error'];
        }

        if($Template['template_field_one'] != false)
        {
            if(!strstr($Template['template_field_one'], AURIUMFORM_TP_FIELD))
            {
                $this->ShowError('Invalid FIELD ALONE template (template_field_one). It needs to have the string <I>' . AURIUMFORM_TP_FIELD . '</I>');
            }

            $this->Config['template_field_one'] = $Template['template_field_one'];
        }

        if($Template['template_open'] != false)
        {
            $this->Config['template_open'] = $Template['template_open'];
        }

        if($Template['template_close'] != false)
        {
            $this->Config['template_close'] = $Template['template_close'];
        }

        if($Template['template_line'] != false)
        {
            $this->Config['template_line'] = $Template['template_line'];
        }
    }

    /**
     * Verify a array with the form fields and if is valid
     * pass it to the var Data of the class
     *
     * @param array $Data Array with all the fields data
     * @access public
     */
    function SetData($Data = array())
    {
        for($i = 0; $i < sizeof($Data); ++$i)
        {
            $this->ProcessAliases($Data[$i]);

            if(!$this->CheckType($Data[$i]['type']))
            {
                return false;
            }
        }

        // Everything looks ok, pass it to the class
        $this->Data = $Data;

        return true;
    }

    /**
     * Check if a given field type is valid
     *
     * @param string $Type Type to check
     * @access private
     */
    function CheckType(&$Type)
    {
        $Type = strtolower($Type);

        // Verify if the user has given the type
        if(!$Type)
        {
            $this->ShowError('You have to give the field type');
            return false;
        }
        // Check if it is a valid type
        if(!in_array($Type, $this->Types))
        {
            $this->ShowError('Invalid field type: <B>' . $Type . '</B>');
            return false;
        }

        return true;
    }
    
    /**
     * Returns a unique field of a given array
     *
     * @param array $Data Field data
     * @access public
     */
    function OneField($Data)
    {
        $this->ProcessAliases($Data);

        if(!$this->CheckType($Data['type']))
        {
            return false;
        }

        // Show the field only if no errors have occurred
        if(!$this->Error)
        {
            $Form .= $this->GenerateField($Data);
            return $Form;
        }

        return false;
    }

    /**
     * Replace the aliases for the real key
     *
     * Current Aliases for Forms:
     * a for action
     * m for method
     * p for POST
     * g for GET
     * u for upload
     *
     * Current Aliases for Fields:
     * s for size
     * t for type
     * n for name
     * l for label
     * e for errors
     * v for value
     *
     * @param array   $Data Field data
     * @param boolean $Form If is processing alias from opening a form
     *
     * @since Feb 17, 2005
     * @access private
     */
    function ProcessAliases(&$Data, $Form = false)
    {
        //
        // Forms
        //
        if($Form)
        {
            if($Data['a'])
            {
                $Data['action'] = $Data['a'];
                unset($Data['a']);
            }
            if($Data['m'])
            {
                $Data['method'] = $Data['m'];
                unset($Data['m']);
            }
            if($Data['method'] == 'p')
            {
                $Data['method'] = 'POST';
            }
            elseif($Data['method'] == 'g')
            {
                $Data['method'] = 'GET';
            }

            if($Data['u'])
            {
                $Data['upload'] = $Data['u'];
                unset($Data['u']);
            }

            return;
        }

        //
        // All Fields
        //
        if($Data['t'])
        {
            $Data['type'] = $Data['t'];
            unset($Data['t']);
        }
        if($Data['l'])
        {
            $Data['label'] = $Data['l'];
            unset($Data['l']);
        }
        if($Data['s'])
        {
            $Data['size'] = $Data['s'];
            unset($Data['s']);
        }
        if($Data['n'])
        {
            $Data['name'] = $Data['n'];
            unset($Data['n']);
        }
        if($Data['e'])
        {
            $Data['errors'] = $Data['e'];
            unset($Data['e']);
        }
        if($Data['v'])
        {
            $Data['value'] = $Data['v'];
            unset($Data['v']);
        }

        return;
    }

    /**
     * Generate all the fields using the given array
     * on function SetData()
     *
     * @access public
     */
    function ShowFields()
    {
        // Show the fields only if no errors have occurred
        if(!$this->Error)
        {
            // Where all the filed will be stored
            $Form = '';

            for($i = 0; $i < sizeof($this->Data); ++$i)
            {
                // Pass the array from the actual loop iteration
                $Field = $this->Data[$i];

                // Generate the field
                $Form .= $this->GenerateField($Field);

                if($Data['type'] !== 'hidden')
                {
                    // If has more fields, add new line string (from the template)
                    if($i < sizeof($this->Data)-1)
                    {
                        $Form .= $this->Config['template_line'];
                    }
                }
            }

            return $Form;
        }
    }

    /**
     * Generate a field
     *
     * @param array $Data Field data
     * @access private
     */
    function GenerateField(&$Data)
    {
        // Function to call
        $Function = 'Field_' . $Data['type'];
        
        // Generate the field
        $field_string = $this->$Function($Data);

        if($Data['type'] == 'hidden')
        {
            return $field_string;
        }

        // Get the template with this field
        $Field = $this->TemplateReplace($field_string, $Data);

        return $Field;
    }

    /**
     * Put a field in the template strings
     *
     * @param string $Field The generated field
     * @param array $Data Data from the field
     * @version Feb 17, 2005
     * @access private
     */
    function TemplateReplace($Field, &$Data)
    {
        //
        // Doesn't use template
        //
        if($this->Config['no_template'] || $Data['no_template'])
        {
            if($Data['label'])
            {
                $Return = $Data['label'] . ' ';
            }

            $Return .= $Field;

            if(sizeof($Data['errors']))
            {
                foreach($Data['errors'] as $err)
                {
                    $Return .= str_replace(AURIUMFORM_TP_ERROR, $err, $this->Config['template_error']);
                }
            }

            return $Return;
        }

        //
        // Normal AuriumForm use
        //

        //
        // The fields alone, using the special template
        //
        if($Data['alone'])
        {
            $First = str_replace(array(AURIUMFORM_TP_LABEL, AURIUMFORM_TP_FIELD), array($Data['label'], $Field), $this->Config['template_field_one']);

            return $First;
        }

        //
        // Normal insert for the field
        //

        $First = $this->Config['template_open'];

        //
        // Add label
        //
        if($Data['label'] !== false)
        {
            if(!$Data['label'])
            {
                $Data['label'] = ucwords($Data['type']) . ' #' . $this->Count[$Data['type']];
            }

            $First .= str_replace(AURIUMFORM_TP_LABEL, $Data['label'], $this->Config['template_label']);
        }

        //
        // Replace the field in the template
        //
        $Second = str_replace(AURIUMFORM_TP_FIELD, $Field, $this->Config['template_field']);

        //
        // Add errors messages
        //
        if(sizeof($Data['errors']))
        {
            $Third = '';
            foreach($Data['errors'] as $err)
            {
                $Third .= str_replace(AURIUMFORM_TP_ERROR, $err, $this->Config['template_error']);
            }
        }

        $Third .= $this->Config['template_close'];

        return $First . $Second . $Third;
    }

    /**
     * Open the form with the given config
     *
     * Values:
     * - action (if not given, will use the default)
     * - method (if not given, will use the default)
     * - name
     * - upload (if the form has upload)
     * - extras
     *
     * @param array $Data Data to the form
     * @access public
     */
    function OpenForm($Data = false)
    {
        $this->ProcessAliases($Data, true);

        // Pass this form to the class
        $this->Forms[] = $Data;

        $return .= '<form action="';
        if($Data['action'])
        {
            $return .= $Data['action'];
        }
        else
        {
            $return .= AURIUMFORM_DEFAULT_ACTION;
        }
        $return .= '"';

        $return .= ' method="';
        if($Data['method'])
        {
            $return .= $Data['method'];
        }
        else
        {
            $return .= AURIUMFORM_DEFAULT_METHOD;
        }
        $return .= '"';


        if($Data['name'])
        {
            $return .= ' name="' . $Data['name'] . '"';
        }

        if($Data['upload'])
        {
            $return .= ' enctype="multipart/form-data"';
        }

        if($Data['extras'])
        {
            $return .= ' ' . $Data['extras'];
        }

        $return .= '>';

        return $return;
    }

    /**
     * Closes a form
     *
     * @access public
     */
    function CloseForm()
    {
        $return .= '</form>';
        return $return;
    }

    /**
     * Increment the counting of a specific type
     *
     * @param string $Type The type to increment counting
     * @since Feb 13, 2005
     * @access private
     */
    function IncrementCount($Type)
    {
        $this->Count[$Type]++;
    }

    /**
     * Prints errors messages
     *
     * @param string $Message The error message
     * @param boolen $Print If is to print the error message
     * @version Feb 17, 2005
     * @access public
     */
    function ShowError($Message, $Print = true)
    {
        $this->Error = true;

        $Msg .= '<BR><div style="background-color: white"><font face="verdana" size="2" color="red"><B>AuriumForm ERROR: </B></font>';
        $Msg .= '<font face="verdana" size="2" color="black">' . $Message . '</font>';
        $Msg .= '</div><BR>';

        if($Print)
        {
            echo $Msg;
        }

        return $Msg;
    }

    /**
     * Show information about the class usage
     *
     * @since Feb 13, 2005
     * @version 1.1 Feb 17, 2005
     * @access public
     */
    function Debug()
    {
        echo '
        <BR><BR>
        <table border="0" cellpadding="10" cellspacing="0" align="center" style="background-color: white; font-family: verdana; font-size: 10pt; color: black">
        <tr><td style="background-color: white; font-family: verdana; font-size: 10pt; color: black"><font color="red" size="3"><B>AuriumForm DEBUG</B></font><BR><B>Fields Counting</B><BR>
        ';

        if(sizeof($this->Count))
        {
            $i = 0;

            foreach($this->Count as $Field => $Quantity)
            {
                echo '- <B>' . $Field . '</B> = ' . $Quantity . '<BR>
                ';
                $i++;
            }
            echo '<BR>Total: ' . $i;
        }
        else
        {
            echo 'No Fields';
        }

        echo'
        <hr color="black" size="1">
        </td></tr>
        ';

        echo '<tr><td style="background-color: white; font-family: verdana; font-size: 10pt; color: black"><B>Forms Created</B><BR>
        ';

        if(sizeof($this->Forms))
        {
            echo 'Total: ' . sizeof($this->Forms) . ' form(s).<BR>';

            $i = 1;

            foreach($this->Forms as $Form)
            {
                echo '<BR>Data from Form #' . $i . ':<BR>';

                if(!is_array($Form))
                {
                    echo '<I>Using only default values.</I><br>- <B>action</B> = ' . AURIUMFORM_DEFAULT_ACTION . '<BR>- <B>method</B> = ' . AURIUMFORM_DEFAULT_METHOD . '<BR>
                    ';
                }
                else
                {
                    foreach($Form as $Attribute => $Value)
                    {
                        echo '- <B>' . $Attribute . '</B> = ' . $Value . '<BR>
                        ';
                    }

                    if(!$Form['action'])
                    {
                        echo '- <B>action</B> = ' . AURIUMFORM_DEFAULT_ACTION . ' <I>(default)</I><BR>
                        ';
                    }
                    if(!$Form['method'])
                    {
                        echo '- <B>method</B> = ' . AURIUMFORM_DEFAULT_METHOD . ' <I>(default)</I><BR>
                        ';
                    }
                }

                unset($Form);
                ++$i;
            }
        }
        else
        {
            echo 'No Forms';
        }

        echo' 
        </td></tr>
        </table>
        <BR><BR>
        ';
    }
}

?>
Return current item: AuriumForm