Location: PHPKode > scripts > Form Solution > form-5-10/form/form.inc
<?php

/**
 * Form Solution is a PHP class to simplify user interface programming
 * in PHP.
 *
 * <p>Requires PHP 5 or later.</p>
 *
 * <p>Please make a donation to support our open source development.
 * Update notifications are sent to people who make donations that exceed
 * the small registration threshold.  See the link below.</p>
 *
 * <p>For more information on using this program, read the manual on line
 * via the link below.</p>
 *
 * <p>Form Solution is a trademark of The Analysis and Solutions Company.</p>
 *
 * <pre>
 * ======================================================================
 * SIMPLE PUBLIC LICENSE                        VERSION 1.1   2003-01-21
 *
 * Copyright (c) The Analysis and Solutions Company
 * http://www.analysisandsolutions.com/
 *
 * 1.  Permission to use, copy, modify, and distribute this software and
 * its documentation, with or without modification, for any purpose and
 * without fee or royalty is hereby granted, provided that you include
 * the following on ALL copies of the software and documentation or
 * portions thereof, including modifications, that you make:
 *
 *     a.  The full text of this license in a location viewable to users
 *     of the redistributed or derivative work.
 *
 *     b.  Notice of any changes or modifications to the files,
 *     including the date changes were made.
 *
 * 2.  The name, servicemarks and trademarks of the copyright holders
 * may NOT be used in advertising or publicity pertaining to the
 * software without specific, written prior permission.
 *
 * 3.  Title to copyright in this software and any associated
 * documentation will at all times remain with copyright holders.
 *
 * 4.  THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND
 * COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY
 * OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE
 * OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS,
 * COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
 *
 * 5.  COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DAMAGES, INCLUDING
 * BUT NOT LIMITED TO, DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL,
 * ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
 * ======================================================================
 * </pre>
 *
 * @package    FormSolution
 * @author     Daniel Convissor <hide@address.com>
 * @copyright  The Analysis and Solutions Company, 2001-2009
 * @version    $Name: rel-5-10 $ $Id: form.inc,v 5.49 2009/03/27 00:38:44 danielc Exp $
 * @link       http://www.analysisandsolutions.com/software/form/form.htm
 */


/**
 * Eases user interface programming in PHP.
 *
 * <p>Sanitizes user input.  Generates XHTML compliant date, time and
 * elements. You can offer a complete email contact form to thwart
 * spammers by adding one line of code. Cleans user input, validates and
 * formats date/time and credit card number inputs.</p>
 *
 * @package    FormSolution
 * @author     Daniel Convissor <hide@address.com>
 * @copyright  The Analysis and Solutions Company, 2001-2009
 * @version    $Name: rel-5-10 $
 * @link       http://www.analysisandsolutions.com/software/form/form.htm
 */
class FormSolution {

    /**
     * maximum number of characters that each user submitted field can hold.
     * @var  integer
     */
    protected $Max_FS_RESERVED;

    /**
     * array with type names as keys and preg regular expressions as values.
     * @var  array
     */
    protected $Patterns_FS_RESERVED;


    /**
     * Establishes which characters are acceptable and removes all characters
     * which are not.
     *
     * @param string|array $Keep_FS_RESERVED  There are several predefined
     *                           Keep types. In addition, you can also whip
     *                           up your own special preg pattern for the
     *                           $Keep argument by creating an array where
     *                           the name of the pattern is the key and the
     *                           pattern is the value. Then pass that array
     *                           to the this argument. If the array you
     *                           pass has more than one element, only the
     *                           first one is used. Additional patterns can
     *                           be added later.
     * @param integer      $Max_FS_RESERVED   the maximum number of
     *                           characters a string is allowed to contain
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#constructor
     */
    public function __construct($Keep_FS_RESERVED = 'Default',
            $Max_FS_RESERVED = 200)
    {
        unset($GLOBALS['_REQUEST']);

        $this->Max_FS_RESERVED = $Max_FS_RESERVED;

        if (is_array($Keep_FS_RESERVED)) {
            list($Key, $Val) = each($Keep_FS_RESERVED);
            $this->Patterns_FS_RESERVED[$Key] = $Val;
            $Keep_FS_RESERVED = $Key;
        }

        $this->Patterns_FS_RESERVED['Num']           = '/[^0-9]/';
        $this->Patterns_FS_RESERVED['Decimal']       = '/[^0-9.-]/';
        $this->Patterns_FS_RESERVED['IP']            = '/[^0-9.]/';
        $this->Patterns_FS_RESERVED['Alpha']         = '/[^A-Za-z]/';
        $this->Patterns_FS_RESERVED['AlphaNum']      = '/[^A-Za-z0-9]/';
        $this->Patterns_FS_RESERVED['AlphaNumSpace'] = '/[^A-Za-z0-9 ]/';
        $this->Patterns_FS_RESERVED['AlphaNumAll']   = '/[^A-Za-z0-9\s]/';
        $this->Patterns_FS_RESERVED['AlphaForeign']  = '/[^A-Za-zÀ-ÖØ-öø-ÿ]/';
        $this->Patterns_FS_RESERVED['URI']           = '/[^!#-9:;=?-Z_a-z~]/';
        $this->Patterns_FS_RESERVED['Email']         = '/[^-!#$%&\'*+\/=?^_`{|}~A-Za-z0-9.@]/';

        $this->Patterns_FS_RESERVED['EmailMatch']
                = '/^[-!#$%&\'*+\/=?^_`{|}~a-z0-9]+'
                . '(\.[-!#$%&\'*+\/=?^_`{|}~a-z0-9]+)*'
                . '@([a-z0-9-]+\.)+([a-z]{2,6})$/';
        $this->Patterns_FS_RESERVED['EmailForm']
                = '/[^!#-9:;=?-Z_a-z~"\s]/';
        $this->Patterns_FS_RESERVED['AlphaForeignNum']
                = '/[^A-Za-zÀ-ÖØ-öø-ÿ0-9]/';
        $this->Patterns_FS_RESERVED['AlphaForeignNumSpace']
                = '/[^A-Za-zÀ-ÖØ-öø-ÿ0-9 ]/';
        $this->Patterns_FS_RESERVED['AlphaForeignNumAll']
                = '/[^A-Za-zÀ-ÖØ-öø-ÿ0-9\s]/';
        $this->Patterns_FS_RESERVED['Default']
                = '/[^A-Za-zÀ-ÖØ-öø-ÿ0-9 +.\/:=@_~-]/';

        if (!empty($_GET)) {
            $Source =& $_GET;
            unset($GLOBALS['HTTP_GET_VARS']);
        } elseif (!empty($GLOBALS['HTTP_GET_VARS'])) {
            $Source =& $GLOBALS['HTTP_GET_VARS'];
        } else {
            $Source = array();
        }

        foreach ($Source as $Name => $Val) {
            if (is_array($Val)) {
                foreach ($Val as $Key1 => $Val1) {
                    if (is_array($Val1)) {
                        foreach ($Val1 as $Key2 => $Val2) {
                            // debug tool -> //  echo "<br />GET: Two Dimensional Array (Name: $Name. &nbsp; key1: $Key1 &nbsp; key2: $Key2) = " . $this->StripBadCharacters($Val2, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                            $Temp[$Key1][$Key2] = $this->StripBadCharacters(
                                    $Val2, $Keep_FS_RESERVED,
                                    $Max_FS_RESERVED);
                        }
                    } else {
                        // debug tool -> //  echo "<br />GET: One Dimensional Array (Name: $Name. &nbsp; key: $Key1) = ". $this->StripBadCharacters($Val1, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                        $Temp[$Key1] = $this->StripBadCharacters(
                                $Val1, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                    }
                }

                $this->$Name = $Temp;
                unset($Temp);

            } else {
                $this->$Name = $this->StripBadCharacters(
                        $Val, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                // debug tool -> //  echo "<br />GET: $Name = " . $this->$Name;
            }

            switch ($Name) {
                case 'Keep_FS_RESERVED':
                case 'Max_FS_RESERVED':
                case 'Patterns_FS_RESERVED':
                    echo '<h2 align="center">You submitted a variable ';
                    echo "called &quot;$Name&quot;.<br />That's a ";
                    echo "reserved name.</h2>\n";
                    exit;

                default:
                    unset($GLOBALS[$Name]);
            }
        }

        unset($GLOBALS['_GET']);
        unset($GLOBALS['HTTP_GET_VARS']);

        if (!empty($_POST)) {
            $Source =& $_POST;
            unset($GLOBALS['HTTP_POST_VARS']);
        } elseif (!empty($GLOBALS['HTTP_POST_VARS'])) {
            $Source =& $GLOBALS['HTTP_POST_VARS'];
        } else {
            $Source = array();
        }

        foreach ($Source as $Name => $Val) {
            if (is_array($Val)) {
                foreach ($Val as $Key1 => $Val1) {
                    if (is_array($Val1)) {
                        foreach ($Val1 as $Key2 => $Val2) {
                            // debug tool -> //  echo "<br />Post Two Dimensional Array (Name: $Name. &nbsp; key1: $Key1 &nbsp; key2: $Key2) = " . $this->StripBadCharacters($Val2, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                            $Temp[$Key1][$Key2] = $this->StripBadCharacters(
                                    $Val2, $Keep_FS_RESERVED,
                                    $Max_FS_RESERVED);
                        }
                    } else {
                        // debug tool -> //  echo "<br />Post One Dimensional Array (Name: $Name. &nbsp; key: $Key1) = ". $this->StripBadCharacters($Val1, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                        $Temp[$Key1] = $this->StripBadCharacters(
                                $Val1, $Keep_FS_RESERVED, $Max_FS_RESERVED);
                    }
                }

                $this->$Name = $Temp;
                unset($Temp);

            } else {
                // debug tool -> //  echo "<br />Post: $Name = " . $this->$Name;
                $this->$Name = $this->StripBadCharacters(
                        $Val, $Keep_FS_RESERVED, $Max_FS_RESERVED);
            }

            switch ($Name) {
                case 'Keep_FS_RESERVED':
                case 'Max_FS_RESERVED':
                case 'Patterns_FS_RESERVED':
                    echo '<h2 align="center">You submitted a variable ';
                    echo "called &quot;$Name&quot;.<br />That's a ";
                    echo "reserved name.</h2>\n";
                    exit;

                default:
                    unset($GLOBALS[$Name]);
            }
        }

        unset($GLOBALS['_POST']);
        unset($GLOBALS['HTTP_POST_VARS']);
    }

    /**
     * Examine and clean up the $Input presented.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#StripBadCharacters
     */
    public function StripBadCharacters($Input, $Keep = 'Default', $Max = 200) {
        if (is_array($Input)) {
            return '';
        }

        if (empty($this->Patterns_FS_RESERVED[$Keep])) {
            $Keep = 'Default';
            if (empty($this->Patterns_FS_RESERVED[$Keep])) {
                $this->Patterns_FS_RESERVED[$Keep]
                        = '[^A-Za-zÀ-ÖØ-öø-ÿ0-9 +./:=@_~-]';
            }
        }

        return substr(
            preg_replace($this->Patterns_FS_RESERVED[$Keep], '', $Input),
            0,
            $Max
        );
    }

    /**
     * Generates an option list of date or time segments.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#DateTimeOptionList
     */
    public function DateTimeOptionList($Period, $Default = 'C', $Name = '',
            $Zero = 'N', $Size = 0, $Multiple = 'N',
            $Begin = '', $Years = 5, $Class = '',
            $ID = '')
    {
        $SpFormat = '%02d';
        $FirstItem = '';

        switch ($Period) {
            case 'year':
                if (!preg_match('/^[0-9]{4}$/', $Begin)) {
                    $Begin = date('Y') - 2;
                }
                if (!preg_match('/^[0-9]{1,3}$/', $Years)) {
                    $Years = 5;
                }
                $End = $Begin + $Years - 1;
                if ($End > 9999) {
                    $End = 9999;
                }
                $DtFormat = 'Y';
                $SpFormat = '%04d';
                break;
            case 'month':
                $Begin = 1;
                $End = 12;
                $DtFormat = 'm';
                break;
            case 'day':
                $Begin = 1;
                $End = 31;
                $DtFormat = 'd';
                break;
            case 'hour':
                $Begin = 0;
                $End = 23;
                $DtFormat = 'H';
                break;
            case 'minute':
                $Begin = 0;
                $End = 59;
                $DtFormat = 'i';
                break;
            default:    // 'second' and all else
                $Period = 'second';
                $Begin = 0;
                $End = 59;
                $DtFormat = 's';
        }

        if ($Name == '' or !is_string($Name)) {
            $Name = $Period;
        }

        if (is_array($Default)) {
            $Temp = $Default;
            $Default = array();
            $Expr = '/^(()|[0-9]{' . strlen($End) . '})$/';
            foreach ($Temp as $Val) {
                if (preg_match($Expr, $Val)) {
                    $Default[] = $Val;
                }
            }
            unset($Temp);
            asort($Default);
        } else {
            if ($Default == 'C') {
                $Default = date($DtFormat);

            } else {
                if (!is_string($Default)) {
                    $Default = '';
                }
                switch ($Period) {
                    case 'month':
                    case 'day':
                    case 'year':
                        $Expr = '/^[0-9]{' . strlen($End) . '}$/';
                        if (preg_match('/^0{1,4}$/', $Default)) {
                            switch ($Zero) {
                                case 'B':
                                case 'Y':
                                    $Default = sprintf($SpFormat, 0);
                                    break;
                                case 'E':
                                    $Default = '';
                                    break;
                                default:
                                    //  'N' and errors
                                    $Default = date($DtFormat);
                            }
                        } elseif (preg_match($Expr, $Default)) {
                            $Default = sprintf($SpFormat, $Default);
                        } else {
                            switch ($Zero) {
                                case 'B':
                                case 'E':
                                    $Default = '';
                                    break;
                                default:
                                    //  'Y', 'N' and errors
                                    $Default = date($DtFormat);
                            }
                        }
                        break;

                    default:
                        //  'hour', 'minute', 'second' and errors
                        if (!preg_match('/^[0-9]{2}$/', $Default)) {
                            switch ($Zero) {
                                case 'E':
                                case 'B':
                                    $Default = '';
                                    break;

                                default:
                                    //  'Y', 'N' and errors
                                    $Default = date($DtFormat);
                            }
                        }
                }
            }

            if ($Period == 'year' && $Default != '' && $Default != '0000') {
                if ($Default < $Begin) {
                    $Begin = $Default - 2;
                    $Years = $End - $Begin;
                } elseif ($Default > $End) {
                    $End = $Default + 2;
                    $Years = $End - $Begin;
                }
            }

            $Default = array($Default);
        }

        switch ($Zero) {
            case 'E':
                $FirstItem .= ' <option value=""';
                if (current($Default) == '') {
                    $FirstItem .= ' selected="selected"';
                    next($Default);
                }
                $FirstItem .= "></option>\n";
                break;

            case 'B':
                $FirstItem .= ' <option value=""';
                if (current($Default) == '') {
                    $FirstItem .= ' selected="selected"';
                    next($Default);
                }
                $FirstItem .= "></option>\n";

            case 'Y':
                if ($Period == 'year') {
                    $FirstItem .= ' <option value="0000"';
                    if (current($Default) == '0000') {
                        $FirstItem .= ' selected="selected"';
                        next($Default);
                    }
                    $FirstItem .= ">0000</option>\n";
                } else {
                    $Begin = 0;
                }
        }

        if ($Multiple == 'Y') {
            $BrackTxt = '[]';
            $MultTxt = ' multiple';
        } else {
            $Default = array(current($Default));
            $BrackTxt = '';
            $MultTxt = '';
        }

        if ($Size != '') {
            $SizTxt = " size=\"$Size\"";
        } else {
            $SizTxt = '';
        }

        if ($Class != '') {
            $Class = " class=\"$Class\"";
        }

        if ($ID != '') {
            $ID = " id=\"$ID\"";
        }

        echo "\n\n<select$SizTxt$MultTxt$Class$ID ";
        echo "name=\"{$Name}{$BrackTxt}\">\n$FirstItem";

        for ($Counter = $Begin; $Counter <= $End; $Counter++) {
            $TempC = sprintf($SpFormat, $Counter);
            echo " <option value=\"$TempC\"";
            if ($TempC == current($Default)) {
                echo ' selected="selected"';
                next($Default);
            }
            echo ">$Counter</option>\n";
        }

        echo "</select>\n\n";
    }

    /**
     * Ensures dates entered by users are valid and formatted correctly.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#DateValidateAndFormat
     */
    public function DateValidateAndFormat($Year, $Month, $Day,
            $ObjVarTo = 'Date', $Format = 'Y-m-d', $Zero = 'N')
    {
        if ($Zero=='Y' && $Year==0 && $Month==0 && $Day==0) {
            // This is not a problem.  No date entered.
            $this->$ObjVarTo = preg_replace('/[0-9]/', '0', date($Format, 0));
            return 1;

        } else {
            if (!checkdate($Month, $Day, $Year) || $Year < '1970') {
                $this->$ObjVarTo = '';
                return 0;
            } else {
                // Date was entered and is valid, so format it.
                $this->$ObjVarTo = date($Format,
                        mktime(1, 1, 1, $Month, $Day, $Year));
                return 1;
            }
        }
    }

    /**
     * Ensures times entered by users are valid and formatted correctly.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#TimeValidateAndFormat
     */
    public function TimeValidateAndFormat($Hour, $Minute, $Second,
            $ObjVarTo = 'Time', $Format = 'H:i:s')
    {
        $Hour = preg_replace('/[^0-9]/', '', $Hour);
        if ($Hour > 23 || $Hour < 0) {
            $this->$ObjVarTo = '';
            return 0;
        }

        $Minute = preg_replace('/[^0-9]/', '', $Minute);
        if ($Minute > 59 || $Minute < 0) {
            $this->$ObjVarTo = '';
            return 0;
        }

        $Second = preg_replace('/[^0-9]/', '', $Second);
        if ($Second > 59 || $Second < 0) {
            $this->$ObjVarTo = '';
            return 0;
        }

        $this->$ObjVarTo = date(
            $Format,
            mktime($Hour, $Minute, $Second, 1, 1, 2000)
        );

        return 1;
    }

    /**
     * This function copies the contents of another object to $this object.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#CopyObjectContentsIntoForm
     */
    public function CopyObjectContentsIntoForm($From) {
        global $$From;

        if (!is_object($$From)) {
            echo "\n<br /><code>$From</code> is not an object.\n";
            return 0;
        }

        foreach ($$From as $Name => $Val) {
            $this->$Name = $Val;
        }
    }

    /**
     * Creates a form people browsing your site can use to contact you.
     *
     * @link  http://www.analysisandsolutions.com/software/form/form-man.htm#EmailForm
     */
    public function EmailForm($To, $Opt = array()) {
        if (!isset($Opt['names'])) {
            $Opt['names'] = array(
                'Name' => 'one',
                'Email' => 'two',
                'Subject' => 'three',
                'Message' => 'four',
                'Submit' => 'five',
            );
        }

        foreach ($Opt['names'] as $LocalName => $FormName) {
            if (!isset($this->$FormName)) {
                $this->$FormName = '';
            }

            $RawVarName = 'Raw' . $LocalName;
            $$RawVarName = $this->$FormName;

            $HTMLVarName = 'HTML' . $LocalName;
            $$HTMLVarName = htmlspecialchars($this->$FormName);
        }

        if (is_array($Opt)) {
            foreach ($Opt as $Key => $Val) {
                if (is_array($Val)) {
                    foreach ($Val as $SubKey => $SubVal) {
                        $Opt[$Key][$SubKey] = htmlspecialchars($SubVal);
                    }
                } else {
                    $Opt[$Key] = htmlspecialchars($Val);
                }
            }
        } else {
            $Opt = array();
        }

        $Classp = '';
        if (isset($Opt['classp'])) {
            $Classp .= ' class="' . $Opt['classp'] . '"';
        }

        $Prob = array();

        if ($RawSubmit) {
            if (!preg_match($this->Patterns_FS_RESERVED['EmailMatch'],
                    $RawEmail)) {
                $Prob[] = 'The Email address does not conform to RFC 2822';
            }
            if (strlen($RawEmail) > 255) {
                $Prob[] = 'The Email address was too long';
            }

            if (preg_match("/[^a-z .'-]/i", $RawName)) {
                $Prob[] = 'The Name Field can only have letters, spaces, '
                        . 'periods, hyphens and \' in it';
            }
            if ($RawName == '') {
                $Prob[] = 'The Name Field is blank';
            }
            if (strlen($RawName) > 255) {
                $Prob[] = 'The Name Field was too long';
            }

            if (preg_match("/[^a-z0-9 .,'-]/i", $RawSubject)) {
                $Prob[] = 'The Subject Field can only have letters, numbers, '
                        . 'spaces, periods, commas, hyphens and \' in it';
            }
            if ($RawSubject == '') {
                $Prob[] = 'The Subject Field is blank';
            }
            if (strlen($RawSubject) > 255) {
                $Prob[] = 'The Subject Field was too long';
            }

            if ($RawMessage == '') {
                $Prob[] = 'The Message Field is blank';
            }
            if (strlen($RawMessage) >= $this->Max_FS_RESERVED) {
                $Prob[] = 'The Message Field was too long. We truncated it';
            }

            $RawMessage = trim($RawMessage);
            $RawMessage = wordwrap($RawMessage, 70, "\n");
            $RawMessage = '[Referer: ' . @$_SERVER['HTTP_REFERER'] . "]\n\n"
                    . $RawMessage;

            $HTMLMessage = trim($HTMLMessage);
            $HTMLMessage = wordwrap($HTMLMessage, 70, "\n");

            if (!empty($Prob)) {
                echo "<h2$Classp align=\"center\">There are some problems ";
                echo 'with the message you tried to send.<br />Please fix ';
                echo "them and try again.</h2><ul$Classp>";
                foreach ($Prob as $Val) {
                    echo "<li$Classp>$Val.</li>\n";
                }
                echo '</ul>';

            } elseif ($RawSubmit == 'Send') {
                if (isset($Opt['prefixs'])) {
                    $Subject = $Opt['prefixs'] . $RawSubject;
                } else {
                    $Subject = $RawSubject;
                }

                $Extra  = "From: $RawName <$RawEmail>\n";
                $Extra .= "Reply-To: $RawName <$RawEmail>\n";
                $Extra .= "Content-Type: text/plain;\n";
                $Extra .= "X-Loop: $To";

                $Param = "-f$To";

                if (@mail($To, $Subject, $RawMessage, $Extra, $Param)) {
                    echo "<h2$Classp align=\"center\">Your message was sent.";
                    echo '<br />Thank you.</h2>';
                } else {
                    echo "<h2$Classp align=\"center\">Sorry. The server had ";
                    echo 'a problem sending your message.<br />';
                    echo 'Please try again later.</h2>';

                    // Keep Preview from appearing.
                    $Prob = true;
                }
            }
        }

        //  ------  PREVIEW  ------

        if ($RawSubmit == 'Preview'
            || ($RawSubmit == 'Send' && empty($Prob)
                && empty($Opt['suppressresults'])))
        {
            echo "<table$Classp";

            if (isset($Opt['idp'])) {
                echo ' id="' . $Opt['idp'] . '"';
            }

            if (isset($Opt['borderp'])) {
                echo ' border="' . $Opt['borderp'] . '"';
            } else {
                echo ' border="1"';
            }

            if (isset($Opt['cellpaddingp'])) {
                echo ' cellpadding="' . $Opt['cellpaddingp'] . '"';
            }

            if (isset($Opt['cellspacingp'])) {
                echo ' cellspacing="' . $Opt['cellspacingp'] . '"';
            }

            if (isset($Opt['alignp'])) {
                echo ' align="' . $Opt['alignp'] . '"';
            }

            if (isset($Opt['widthp'])) {
                echo ' width="' . $Opt['widthp'] . '"';
            }

            if (isset($Opt['summaryp'])) {
                echo ' summary="' . $Opt['summaryp'] . '"';
            }

            echo ">\n";

            if (isset($Opt['captionp'])) {
                echo '  <caption';
                if (isset($Opt['captionalignp'])) {
                    echo ' align="' . $Opt['captionalignp'] . '"';
                }
                echo "$Classp>" . $Opt['captionp'] . "</caption>\n";
            }

            echo "  <tr$Classp><td$Classp>Your&nbsp;Name:</td>";
            echo "<td$Classp>$HTMLName</td></tr>\n";

            echo "  <tr$Classp><td$Classp>Your&nbsp;Email&nbsp;Address:</td>";
            echo "<td$Classp>$HTMLEmail</td></tr>\n";

            echo "  <tr$Classp><td$Classp>Subject:</td>";
            echo "<td$Classp>$HTMLSubject</td></tr>\n";

            echo "  <tr$Classp><td$Classp valign=\"top\">Message:</td>";
            echo "<td$Classp><pre$Classp>$HTMLMessage</pre></td></tr>\n";

            if ($RawSubmit == 'Send') {
                echo "  <tr$Classp><td$Classp>Time&nbsp;Sent:</td>";
                echo "<td$Classp>";
                echo date('Y-m-d g:i a') . ' ' . strftime('%Z');
                echo "</td></tr>\n";
            }

            echo " </table>\n";
        }

        //  ------  FORM  ------

        if ($RawSubmit != 'Send' || !empty($Prob)) {
            if (!isset($Opt['size'])) {
                $Opt['size'] = '40';
            }

            if (!isset($Opt['rows'])) {
                $Opt['rows'] = '8';
            }

            echo '<form method="post"';
            echo ' action="' . htmlspecialchars($_SERVER['REQUEST_URI']) . '"';

            if (isset($Opt['idf'])) {
                echo ' id="' . $Opt['idf'] . '"';
            }

            $Classf = '';
            if (isset($Opt['classf'])) {
                $Classf .= ' class="' . $Opt['classf'] . '"';
            }

            echo "$Classf>\n <table$Classf";

            if (isset($Opt['borderf'])) {
                echo ' border="' . $Opt['borderf'] . '"';
            } else {
                echo ' border="0"';
            }

            if (isset($Opt['cellpaddingf'])) {
                echo ' cellpadding="' . $Opt['cellpaddingf'] . '"';
            }

            if (isset($Opt['cellspacingf'])) {
                echo ' cellspacing="' . $Opt['cellspacingf'] . '"';
            }

            if (isset($Opt['alignf'])) {
                echo ' align="' . $Opt['alignf'] . '"';
            }

            if (isset($Opt['widthf'])) {
                echo ' width="' . $Opt['widthf'] . '"';
            }

            if (isset($Opt['summaryf'])) {
                echo ' summary="' . $Opt['summaryf'] . '"';
            }

            echo ">\n";

            if (isset($Opt['captionf'])) {
                echo '  <caption';
                if (isset($Opt['captionalignf'])) {
                    echo ' align="' . $Opt['captionalignf'] . '"';
                }
                echo "$Classf>" . $Opt['captionf'] . "</caption>\n";
            }

            echo '  <tr' . $Classf . '><td' . $Classf . '><u>Y</u>our&nbsp;Name:</td>';
            echo '<td' . $Classf . '>';
            echo '<input' . $Classf . ' type="text"';
            echo ' size="' . $Opt['size'] . '" maxlength="255"';
            echo ' accesskey="y"';
            echo ' name="' . $Opt['names']['Name'] . '" value="' . $HTMLName;
            echo '" /></td></tr>' . "\n";

            echo '  <tr' . $Classf . '><td' . $Classf . '>Your&nbsp;Email&nbsp;Address:</td>';
            echo '<td' . $Classf . '>';
            echo '<input' . $Classf . ' type="text"';
            echo ' size="' . $Opt['size'] . '" maxlength="255"';
            echo ' name="' . $Opt['names']['Email'] . '" value="' . $HTMLEmail;
            echo '" /></td></tr>' . "\n";

            echo '  <tr' . $Classf . '><td' . $Classf . '>Subject:</td>';
            echo '<td' . $Classf . '>';
            echo '<input' . $Classf . ' type="text"';
            echo ' size="' . $Opt['size'] . '" maxlength="255"';
            echo ' name="' . $Opt['names']['Subject'] . '" value="' . $HTMLSubject;
            echo '" /></td></tr>' . "\n";

            echo "  <tr$Classf><td$Classf valign=\"top\">Message:";
            echo "<br /><small$Classf>($this->Max_FS_RESERVED";
            echo '&nbsp;chars.&nbsp;max.)</small></td>';
            echo '<td' . $Classf . '>';
            echo '<textarea' . $Classf;
            echo ' cols="' . $Opt['size'] . '" rows="' . $Opt['rows'] . '"';
            echo ' name="' . $Opt['names']['Message'] . '">' . $HTMLMessage;
            echo '</textarea></td></tr>' . "\n";

            echo '  <tr' . $Classf . '><td' . $Classf . '>&nbsp;</td>';
            echo '<td' . $Classf . '>';
            echo '<input ' . $Classf . ' type="submit"';
            echo ' name="' . $Opt['names']['Submit'] . '" value="Send" /> ';
            echo '<input ' . $Classf . ' type="submit"';
            echo ' name="' . $Opt['names']['Submit'] . '" value="Preview" />';
            echo '</td></tr>' . "\n";

            echo " </table>\n";
            echo "</form>\n\n";
        }
    }
}
Return current item: Form Solution