Location: PHPKode > projects > FiForms Framework > FiForms/FiForms-includes/FiForms_iInput.inc.php
<?php

/*
*******************************************************************************

    FiForms -- A collection of PHP classes designed 
    to facilitate rapid development of web-database software

    Copyright (C) 2003-2008  Daniel McFeeters

    This library 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 library 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 library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


    The original author of this library can be contacted at the following 
    address:

    Daniel McFeeters
    182 Baker Rd.
    Faubush, KY 42544-6526
    email:databases [at] fiforms [dot] org
    http://www.fiforms.org/


iInput class
Project Started May 4, 2003
*******************************************************************************
FiForms_iInput.inc.php

iInput Definition File

This file contains the definitions for the top-level iInput

*******************************************************************************
*/

require_once("FiForms_genericIcons.inc.php");
/* ?><code><?php */
include_once($GLOBALS['FIFORMS_CONFIG']['SCRIPT_PATH']."themes/".$FIFORMS_CONFIG['ICON_SET']."/iconset.php");


class iInput
// a generic data bound input class from which other inputs are derived
{
    // NOTE about formatStr and FormatStrRO:
    // In the early days of FiForms, these two properties of iInput 
    // fromed the basis of FiForms. Each was a string "template" containing
    // attribute names enclosed in %% symbols, which was then passed through
    // the fillVars function. FiForms version 0.9.3 worked this way.
    // As the framework became more complex, these were re-purposed as 
    // functions to be eval'ed (to improve performance), although they have 
    // now been deprecated (as of version 1.1) in favor of custom code in
    // the formatOutput function

    protected $formatStr;  // the string "template" for the output of the 
                         // controls. Variable names enclosed in %% symbols 
                         // will be replaced by class variables of the same 
                         // name.
    protected $formatStrRO;// used as $formatStr if $readOnly==TRUE

    public $otherTags;  // Place to insert additional property tags
    public $caption;    // caption displayed on form
    public $value;      // value retreived from database
    public $dbField;    // database field control is bound to, or other for
                         // a non data-bound control
    public $valueToSave;
                         // Value retreived from POST to be committed to 
                         // database, if matching %dbField% is found in table
             // if valueToSave === false, then save a null value to field
    public $functionToSave;  // Function to save to database instead of value
    public $readOnly;   // Specifies whether this control should be updateable
    //var $validateFunction; // name of function to execute to validate 
                               // data
    public $error;      // Set to true if an error resulted in validating
                         // data
    public $errorMsg;   // error message resulting in this iInput
    public $useHex;     // If true, save this to the database using hexadecimal 
                         // rather than a quoted string.
    public $allowUserSort; // Allow users to sort on this field
    public $visible;    // if false, the control is not created in HTML
    public $rowReport;
    public $rowExpression;
    public $dynamicUpdateOthers; // Boolean flag to dynamically 
                                 // update other fields on an AJAX update?
    public $depends;
    public $autoReload;
    public $isBin;   // true to treat value as binary
    public $autoFilter;  // true to show autoFilter symbol in sheetView
    public $transform;   // transform content to upper or lowercase
    public $formatexp;   // regular expression that data must match, or else an error is thrown
    public $formaterror;    // error message to be displayed on non-matching formatexp
    public $displaymatch;   // "search" part of preg_replace for display formatting 
                            // (matching database data)
    public $displayformat;  // "replace" part of preg_replace for display formatting
    public $inputmatch;     // "search" part of preg_replace for parsing user input
                            // (note: this MUST be able to match displayformat and parse
                            //  back into the original data. Otherwise data will be lost)
    public $inputformat;    // "replace" part of preg_replace for parsing user input
    private $freshData;  // true if data is fresh
    private $ajaxLoad;   // true if allowed to load data by AJAX


    static function buildMyURL($excludeTerms)
        // build the base URL for the links using the URL of the current page
    {
        $myURL = $GLOBALS['FIFORMS_CONFIG']['SERVER_ADDRESS'].
                 $_SERVER["PHP_SELF"]."?";

        foreach($_GET as $getName => $getValue)
        {
            if(array_search(substr($getName,0,11),$excludeTerms) === false)
            {
                if(get_magic_quotes_gpc())
                {
                    $getValue = stripslashes($getValue);
                }
                $myURL .= $getName."=".
                htmlspecialchars($getValue);
                $myURL .= "&amp;";
            } 
        } // foreach 
            return($myURL);
    } // function buildMyURL

    function iInput($theArgs)
    // generic constructor. designed to be called by child classes with a 
        // single argument retured by func_get_args()
    {
        $this->visible = true;
        $this->dbField = $theArgs[0];
        $this->caption = $theArgs[1];
        if($this->caption == "")
        {
           $this->caption = $this->dbField;
        }
        $this->error = FALSE;
        $this->useHex = FALSE;
        $this->functionToSave = FALSE;
        $this->isBin = false;
        $this->getValueToSave();
        $this->allowUserSort = TRUE; //default to allow sorting on all fields
        $this->autoReload = TRUE;
        $this->dynamicUpdateOthers = FALSE;
        $this->autoFilter = FALSE;
        $this->transform = $_GLOBAL['FIFORMS_CONFIG']['DEFAULT_TRANSFORM'];
        $this->formatexp = "";
        $this->formaterror = "";
        $this->freshData = false;
        $this->ajaxLoad = false;
        $this->displaymatch = "";
        $this->displayformat = "";
        $this->inputmatch = "";
        $this->inputformat = "";
    } // function iInput
    
    function setValue($value)
    {
        $this->value =
             preg_replace("/\&amp\;\#(\d+)\;/","&#\$1;",htmlentities($value));
            $this->freshData = true;
    }

    function throwError($errorMessage)
    {
        $this->error = TRUE;
        $this->errorMsg .= $errorMessage."<br />";
    }

    function getValueToSave()
    //    Retreives a value from _POST with the key matching dbField. This
    //    can be overridden in child classes to do any processing necessary
    //    before the value is committed to the database.
    {
        if(!isset($this->dbField))
        {
            $this->valueToSave = FALSE;
            return(TRUE);
        }
        if(array_key_exists($this->dbField,$_POST))
        {
            $this->valueToSave = $_POST[$this->dbField];
            if($this->transform == "uppercase")
            {
                $this->valueToSave = strtoupper($this->valueToSave);
            }
            elseif($this->transform == "lowercase")
            {
                $this->valueToSave = strtolower($this->valueToSave);
            }
            if($this->inputmatch)
            {
                $this->valueToSave = @preg_replace(substr($this->inputmatch,0,1) == '/' ? $this->inputmatch : '/'.$this->inputmatch.'/',$this->inputformat,$this->valueToSave);
                if($this->valueToSave === NULL)
                {
                    $this->throwError('Error in inputmatch regular expression.');
                }
            }
            $this->validateBeforeSave();
            return(TRUE);
        } // if key exists
        else
        {
            $this->valueToSave = FALSE;
        }

    }  // function getValueToSave

    function validateBeforeSave()
    {
        if(!$this->error && $this->formatexp && 
            !@preg_match(substr($this->formatexp,0,1) == '/' ? $this->formatexp : '/'.$this->formatexp.'/',$this->valueToSave))
        {
            $this->throwError($this->formaterror);
        }
    } // function validateBeforeSave

    function checkRO()
    // Checks if $readOnly is true, and sets the formatStr accordingly
    {
        if ($this->formatStrRO == "")
        {
            $this->formatStrRO = $this->formatStr;
        }
    } //function checkRO

    function preProcess()
    // Do any more processing or error checking 
    // after data retreived from DB
    {
    }

    function drawInput()
    // returns the HTML representation of this iInput
    {
        $this->checkRO();
        if($this->displaymatch)
        {
            $this->value = @preg_replace(substr($this->displaymatch,0,1) == '/' ? $this->displaymatch : '/'.$this->displaymatch.'/',$this->displayformat,$this->value);
            if($this->value === NULL)
            {
                $this->throwError('Error in displaymatch regular expression.');
            }
        }
        return($this->formatOutput().$this->getAJAXScript());
    }  // function drawInput

    function formatOutput()
    {
        if ($this->readOnly == TRUE)
        {
            return(fillVars($this,$this->formatStrRO));
        }
        else
        {
            return(fillVars($this,$this->formatStr));
        }
    }
    
    function getRefreshLink()
    {
        if(($this->rowReport || $this->rowExpression) && $this->autoReload !== "always")
        {
            $icons = new iconset();
            $link = "<a href=\"javascript:reloadSelectRows('".$this->dbField."',false);\">".$icons->refresh."</a>";
        }
        else
        {
             $link = "";
        }
        return $link;
    }  // function getRefreshLink
    
    function getAJAXScript()
    {
        $str_End = "";
        if($this->rowReport || $this->rowExpression)
        {
            $str_End .= "<script type=\"text/javascript\">\n\n";
            if($this->rowReport)
            {
                $app = htmlentities($_GET['app']);
                $str_End .= "setSelectElementRowSrc(\"".$this->dbField."\",\"'generate.php?filename=".
                $this->rowReport.
                "&amp;app=$app".
                "&amp;_TYPE=_xml&amp;ajax_operation=fill_select&amp;ajax_select_id=".
                $this->dbField."'";
                if($this->depends)
                {
                    foreach($this->depends as $dkey => $depend)
                    {
                        $str_End .= "+'&amp;$dkey='+document.forms[0].$depend.value";
                    }
                }
                $str_End .= "\",".($this->autoReload ? 'true':'false').",".
                            ($this->dynamicUpdateOthers ? 'true':'false').");\n";
                    
            }
            else
            {
                $str_End .= "setSelectElementRowFunction(\"".$this->dbField."\",\"".
                        $this->rowExpression."\",".
                    ($this->autoReload ? 'true':'false').");\n";
            }
            if($this->depends)
            {
                foreach($this->depends as $depend)
                {
                    $str_End .= "setSelectDepends('".$this->dbField."','$depend');\n";
                }
            }
            $str_End .= "\n</script>";
        }
        return $str_End;
    }  // function getAJAXScript

    function drawCaption()
    // returns the HTML representation of a caption for this iInput
    {
        if($this->allowUserSort && $_GET['sheetView'] == 'YES')
        {
            $url = $this->buildMyURL(array('sort','st'));
            if($_GET['st'] != 'DESC' && $_GET['sort'] == $this->dbField && $this->dbField)
            {
                $st = 'DESC';       
            }
            else
            {
                $st = 'ASC';
            }
            if($this->dbField && $_GET['sort'] == $this->dbField)
            {
                $ico = new iconset();
                if($_GET['st'] != 'DESC')
                {
                    $img = $ico->ascSort;
                }
                else
                {
                    $img = $ico->descSort;
                }
            }
            if($_GET['st'] == 'DESC' && $_GET['sort'] == $this->dbField && $this->dbField)
            {
                $link = "<a href=\"$url\">$this->caption $img</a>";
            }
            else
            {
                $link = "<a href=\"$url&amp;sort=$this->dbField&amp;st=$st\">$this->caption $img</a>";
            }
        }
        else
        {
            $link = $this->caption;
        }
        if($this->autoFilter && $_GET['sheetView'] == 'YES')
        {
        $ico = new iconset();
        if(array_key_exists($this->dbField,$_GET))
        {
            $fimg = $ico->filterActive;
        }
        else
        {
            $fimg = $ico->filter;
        }
        $url = $this->buildMyURL($_GET);
        $divID = $this->dbField."_filter_div"; 
        $formID = $this->dbField."_filter_form"; 
        $link .= <<<EOD
    <a href="$url" onclick="buildFiFormFilter('$this->dbField');return false;">$fimg</a>
<div class="filter" style="display: none;" id="$divID">
<form action="$url" method="get" id="$formID" name="$formID" onsubmit="enableInheritedFields('$formID');">
<fieldset>
<legend>Filter On</legend>
EOD;
        foreach($_GET as $name => $value)
        {
            if(get_magic_quotes_gpc())
            {
                $value = stripslashes($value);
            }
            $value = htmlentities($value);
            if(!strpos($name,'_display') && $name != $this->dbField)
            {
                $link .= "<input type=\"hidden\" name=\"$name\" id=\"$name"."_$formID\" value=\"$value\" />\n";
            }
        }
        $this->readOnly = FALSE;
        $tmpOTags = $this->otherTags;
        $this->otherTags = "";
        $link .= $this->drawInput();
        $this->otherTags = $tmpOTags;
        $this->readOnly = TRUE;
        //<input type="text" name="$this->dbField" id="$this->dbField" /><br />
        $link .= <<<EOD
<br />
<input type="submit" value="Filter" />
<input type="button" value="Un-Filter" onclick="removeFiFormFilter('$this->dbField');" />
<input type="button" value="Cancel" onclick="cancelFiFormFilter('$this->dbField');" />
</fieldset>
</form>
</div>
EOD;
        }
        return $link;
    }

    function hide()
    {
        $this->formatStr = "";
        $this->formatStrRO = "";
        $this->caption = "";
    }
    
    function disableIn()
    {
        $this->otherTags .= " readonly=\"readonly\" ";
    }

    
    function addInputTagFromXML(&$input,$tag)
    {
        if($input->attributes->getNamedItem($tag))
        {
            $this->otherTags .= " $tag=\"".
                        $input->attributes->getNamedItem($tag)->nodeValue."\" ";
        }
    } // addTag

    function buildFromXML($input)
    {
        // Load input configuration from XML element $input

        if($input->attributes->getNamedItem('default'))
        {
            if($input->attributes->getNamedItem('default')->nodeValue ==
                        "_username")
            {
                // FIXME: get auth username
                //$this->value = $this->auth->username;  
            }
            else
            {
                $this->value =
                    $input->attributes->getNamedItem('default')->nodeValue;
            }
        }
        $this->addInputTagFromXML($input,'onchange');
        $windowToggles =
            array('menubar','toolbar','scrollbars','resizable','location');
        $this->windowopts = "";
        $reload = false;
        foreach($input->attributes as $attr)
        {
            $name = $attr->nodeName;
            switch($name)
            {
                case "size":
                    $this->size = $attr->nodeValue;
                    break;
                case "width":
                    $this->width = $attr->nodeValue;
                    $this->windowOpts .= "width=".$attr->nodeValue.",";
                    break;
                case "height":
                    $this->height = $attr->nodeValue;
                    $this->windowOpts .= "height=".$attr->nodeValue.",";
                    break;
                case "cols":
                    $this->cols = $attr->nodeValue;
                    break;
                case "rows":
                    $this->rows = $attr->nodeValue;
                    break;
                case "rowQuery":
                    $this->rowQuery = $attr->nodeValue;
                    break;
                case "extended":
                    if($attr->nodeValue == 'attributes')
                    {
                        $this->extendedAtt = true;
                    }
                    break;
                case "digits":
                    $this->digits = $attr->nodeValue;
                    break;
                case "decimals":
                    $this->decimals = $attr->nodeValue;
                    break;
                case "collapse":
                    $this->collapse = $attr->nodeValue;
                    break;
                case "prefix":
                    $this->prefix = $attr->nodeValue;
                    break;
                case "suffix":
                    $this->suffix = $attr->nodeValue;
                    break;
                case "transform":
                    $this->transform = $attr->nodeValue;
                    $reload=true;
                    break;
                case "displaymatch":
                    $this->displaymatch = $attr->nodeValue;
                    break;
                case "displayformat":
                    $this->displayformat = $attr->nodeValue;
                    break;
                case "inputmatch":
                    $this->inputmatch = $attr->nodeValue;
                    $reload=true;
                    break;
                case "inputformat":
                    $this->inputformat = $attr->nodeValue;
                    $reload=true;
                    break;
                case "formatexp":
                    $this->formatexp = $attr->nodeValue;
                    $reload=true;
                    break;
                case "formaterror":
                    $this->formaterror = $attr->nodeValue;
                    $reload=true;
                    break;
                case "thseperator":
                    $this->thseperator = $attr->nodeValue;
                    $reload=true;
                    break;
                case "decpoint":
                    $this->decpoint = $attr->nodeValue;
                    $reload=true;
                    break;
                case "style":
                    if($attr->nodeValue == 'radio')
                    {
                        $this->radioStyle = TRUE;
                    }
                    else if($attr->nodeValue == 'dynamic')
                    {
                            $this->dynamic = TRUE;
                    }
                    break;
                case "linktext":
                    $this->contents = $attr->nodeValue;
                    break;
                case "window":
                    $this->openIn = $attr->nodeValue;
                    break;
                case "menubar":
                    $this->windowOpts .= 'menubar='.
                        ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    break;
                case "toolbar":
                    $this->windowOpts .= 'toolbar='.
                        ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    break;
                case "scrollbars":
                    $this->windowOpts .= 'scrollbars='.
                        ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    break;
                case "resizable":
                    $this->windowOpts .= 'resizable='.
                        ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    break;
                case "location":
                    $this->windowOpts .= 'location='.
                        ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    break;
                case "params":
                    $this->params = $attr->nodeValue;
                    break;
                case "readonly":
                    $this->disableIn();
                    break;
                case "displayField":
                    $this->displayField = $attr->nodeValue;
                case "viewmode":
                    // for iSubform
                    if(is_a($this,'iSubform'))
                    {
                        $this->sheetView = ($attr->nodeValue != "form");
                    }
                    else
                    {
                        // for iFile
                        if($attr->nodeValue == 'image')
                        {
                            $this->showAsImage = true;
                        }
                    }
                    break;
                case "view":
                        if($attr->nodeValue == 'sheet')
                            $this->params .= '&sheetView=YES';
                        else if($attr->nodeValue == 'new')
                            $this->params .= '&currentRec=new';
                    break;
                case "type":
                case "field":
                case "caption":
                    break;
                default:
                    if(in_array($name,$windowToggles))
                    {
                        $this->windowOpts .= $name.'='.
                            ($attr->nodeValue == 'no' ? 'no' : 'yes').',';
                    }
                    break;
            } // switch
        } // for each property
        if($reload)
        {
            $this->getValueToSave();
        }

        if(property_exists($this,'windowOpts'))
        {
            foreach($windowToggles as $toggle)
            {
                if(!strpos($this->windowOpts, $toggle))
                {
                    $this->windowOpts .= $toggle.'=yes,';
                } // if set
            } // foreach windowToggles
        } // if windowOpts
        //if($this->ajaxLoad)
        {
            $this->getAjaxParams($input);
        }

    } // function buildFromXML

    function getAjaxParams($input)
    // called from buildFromXML function. Gets the ajax parameters for element
    {
        $child = $input->firstChild;

        // Load the "expression" and "loaddata" elements for dynamic
        // data loading properties
        while($child)
        {
            if($child->localName == "expression" 
                || $child->localName == "loaddata")
            {
                if($child->localName == "loaddata")
                {
                    $this->rowReport = $child->nodeValue;
                }
                else
                {
                    $this->rowExpression = $child->nodeValue;
                }
                if($child->attributes && 
                    $child->attributes->getNamedItem('auto') &&
                    $child->attributes->getNamedItem('auto')->nodeValue 
                      == 'always')
                {
                    $this->autoReload = "always";
                }
                else if($child->attributes &&
                        ($child->attributes->getNamedItem('auto') &&
                        ($child->attributes->getNamedItem('auto')->nodeValue 
                            == 'noauto' ||
                        ($child->attributes->getNamedItem('auto')->nodeValue 
                            == 'onlynew') 
                        && $this->currentRec != 'new')))
                {
                    $this->autoReload = FALSE;
                }
                else
                {
                        $this->autoReload = TRUE;
                }
                if($child->attributes &&
                    $child->attributes->getNamedItem('update') &&
                    $child->attributes->getNamedItem('update')->nodeValue 
                        == 'all')
                {
                    $this->dynamicUpdateOthers = TRUE;
                }
            } // if expression or loaddata element
            if($child->localName == "depends")
            {
                $depend = $child->nodeValue;
                if(($child->attributes) &&
                    ($child->attributes->getNamedItem('param')))
                {
                    $param =
                        $child->attributes->getNamedItem('param')->nodeValue;
                }
                else
                {
                    $param = "";
                }

                if(!trim($param))
                {
                    $param = $depend;
                }
                $this->depends[$param] = $depend;
            } // if depends
            $child = $child->nextSibling;
        } // while child 

    }  // function getAjaxParams

    function drawHead()
    {
        return(fillVars($this,$this->formatStr->head));
    }

    function drawFoot()
    {
        return(fillVars($this,$this->formatStr->foot));
    }

    function drawBody($type)
    {
        return(fillVars($this,$this->formatStr->body));
    }

} // class iInput

/* ?></code><?php */

?>
Return current item: FiForms Framework