Location: PHPKode > projects > dizzyPages > dizzypages/include/DzeForm.class.php
<?php
/*
 * Copyright (c) 2004, Doron Enav, dizzyPages
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name dizzyPages nor the names of its contributors may be used
 *   to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * dizzyPages application framework
 *
 * @package dizzyPages
 * @copyright dizzyPages
 * @author Doron Enav <hide@address.com>
 */
/**
 * DzeForm
 *
 * Form processor for a dizzyPage
 *
 * @author Doron Enav
 */
class DzeForm {
   private $recCtName;
   private $errorCt;
   private $state = 0;
   private $property;
   private $recTotalOld;
   private $recTotalNew;
   private $recTotalDel;
   /**#@+
    * @access public
    */
   /**
    * @var array array of form attribute structures.
    *
    * <b>DEBUG USE ONLY</b>
    *
    * Attribute structures contain attribute properties, values and errors.
    * This is a convenient way to get a complete picture of a form.
    * <code>print("DEBUG:\n" . print_r($this->attrib, true));</code>
    * Reading and writing to <b>$attrib</b> is not supported.
    * All production reading and writing to the <b>$attrib</b> should be made through class method calls.
    */
   private $attrib = array();
   /**
    * @var array array of records deleted state
    *
    * <b>DEBUG USE ONLY</b>
    *
    * <code>print("DEBUG:\n" . print_r($delRecs, true));</code>
    * Reading and writing to <b>$delRecs</b> is not supported.
    * All production reading and writing to the <b>$delRecs</b> should be made through class method calls.
    */
   private $delRecs = array();
   /**
    * @var object DzePage handle to current dizzyPage
    */
   protected $page;
   /**
    * @var object DzeMySQL handle to current sql transaction
    */
   protected $sql;
   /**#@-*/

   /**#@+
    * @internal
    * @access private
    */
   private function setRecInfo() {
      if ($this->property['TYPE'] == 'R') {
         $this->recCtName = "__CT__" . $this->property["FORM_NAME"];
         $this->recTotalOld = $this->getFormAttrib($this->recCtName,
            $this->property["R_SAVE_TYPE"]);
         if (is_null($this->recTotalOld)) {
            $this->recTotalOld = 0;
            $this->setFormAttrib($this->recCtName, $this->recTotalOld,
               $this->property["R_SAVE_TYPE"]);
         }

         $this->recTotalDel = 0;
         for ($recCt = 1; $recCt <= $this->recTotalOld; $recCt++) {
            $namePrefix = ($recCt > 1 ? "__" . $recCt . "__" : "");
            $delAttrib = $this->getRequest($namePrefix . "__DT__" . $this->property["FORM_NAME"]);
            if (isset($delAttrib[1]) && $delAttrib[1] == 'Y') {
               $this->recTotalDel++;
               $this->delRecs[$recCt] = "Y";
            }
            else $this->delRecs[$recCt] = "N";
         }

         $this->recTotalNew = $this->recTotalOld;
         
         while (! is_null($this->getRequest("__RC__" . ($this->recTotalNew + 1)))) {
            $this->recTotalNew++;
            $this->delRecs[$this->recTotalNew] = "N";
         }

      }
      else {
         $this->recTotalNew = 1;
         $this->delRecs[1] = "N";
      }
   }

   protected function getRequest($requestName) {
      return
         (isset($_REQUEST[$requestName])
            ? $_REQUEST[$requestName] : null);
   }

   private function getFormDesc() {
      $this->sql->pushResult();

      $this->sql->select(
         "DZE_FORM",
         array("FORM_NAME", "TYPE", "R_SAVE_TYPE", "R_AUDIT_TYPE", "TRAP_ON_ERR_TYPE"),
         array("FORM_NAME" => $this->page->getMember("referrerFormName"))
      );
      $this->property = $this->sql->fetchAssoc();
      $this->sql->freeResult();

      $this->sql->select(
         "DZE_ATTRIB_IN_FORM",
         array("ATTRIB_NAME"),
         array("FORM_NAME" => $this->property["FORM_NAME"]),
         "and ATTRIB_NAME not like '__DT__%'"
      );

      while ($row = $this->sql->fetchAssoc()) {
         $this->attrib[$row["ATTRIB_NAME"]] = $this->page->getAttrib(
            $row["ATTRIB_NAME"],
            array("TYPE", "SAVE_TYPE", "AUDIT_TYPE", "T_FORM_LEN_MAX", "P_ENCRYPT_B")
         );
      }

      $this->sql->freeResult();
      $this->sql->popResult();
   }

   private function auditDelFormAttrib($attribName, $auditType, $recCt = 1) {
      switch ($auditType) {
         case "S": return $this->page->auditDelSesAttrib($attribName, $recCt);
            break;
         case "U": return $this->page->auditDelUserAttrib($attribName, $recCt);
      }
   }

   private function delFormAttrib($attribName, $saveType, $recCt = 1) {
      switch ($saveType) {
         case "S":
            $this->page->delSesAttrib($attribName, $recCt);
            break;
         case "U": 
            $this->page->delUserAttrib($attribName, $recCt);
      }
   }

   private function setFormAttrib($attribName, $value, $saveType, $recCt = 1) {
      switch ($saveType) {
         case "S":
            $this->page->setSesAttrib($attribName, $value, $recCt);
            break;
         case "U":
            $this->page->setUserAttrib($attribName, $value, $recCt);
      }
   }

   private function auditFormAttrib($attribName, $value, $auditType, $recCt = 1) {
      switch ($auditType) {
         case "S":
            $this->page->auditSesAttrib($attribName, $value, $recCt);
            break;
         case "U":
            $this->page->auditUserAttrib($attribName, $value, $recCt);
      }
   }

   private function getFormAttrib($attribName, $saveType, $recCt = 1) {
      switch ($saveType) {
         case "S": return $this->page->getSesAttrib($attribName, $recCt);
         case "U": return $this->page->getUserAttrib($attribName, $recCt);
         default: return '';
      }
   }

   private function getFormData() {
      $this->setRecInfo();
      $isPhpMagicQuotes = get_magic_quotes_gpc();

      foreach (array_keys($this->attrib) as $attribName) {
         // records <= recTotalOld are update or deletes
         // records > recTotalOld are inserts and must be sequential
         for ($recCt = 1; $recCt <= $this->recTotalNew; $recCt++) {
            $old = $this->getFormAttrib($attribName, $this->attrib[$attribName]["SAVE_TYPE"], $recCt);
            if (   is_null($this->getRequest("__RC__" . $recCt))
                && $this->property['TYPE'] == 'R')
               $this->attrib[$attribName][$recCt] = array(
                  "OLD" => $old,
                  "NEW" => $old,
               );
            else {
               $namePrefix = ($recCt > 1 ? "__" . $recCt . "__" : "");
               $reqName = $namePrefix . $attribName;
               $new = $this->getRequest($reqName);

               if (is_null($new))       // No value sent by form
                  $new = $old; 
               else {
                  if (is_array($new)) { // Build the Multi-select User value
                     $new = array_unique($new);
                     sort($new);
                     $new = implode("|", $new);
                  }

                  // PHP might be magicly changing form data if so the
                  // following undoes the changes
                  // http://us3.php.net/get_magic_quotes_gpc
                  if ($isPhpMagicQuotes)
                     $new = stripslashes($new);

                  // white space is always trimmed
                  $new = trim($new);
               }

               if (   $this->attrib[$attribName]["TYPE"] == "P"
                   && $this->attrib[$attribName]["P_ENCRYPT_B"] == "Y")
                  $new = sha1($new);

               $this->attrib[$attribName][$recCt] = array(
                  "OLD" => $old,
                  "NEW" => $new,
               );
            }
            $this->attrib[$attribName][$recCt]["ERROR_B"] = "N";
         }
      }
   }

   /**
    * Inquire whether selected form attribute is valid
    *
    * @param string $attrib attribute name
    * @param integer $rec record number
    * @return boolean true - form attribute is valid.
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    */
   private function checkAttrib($attrib, $rec) {
      if (! isset($this->attrib[$attrib]))
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' does not contain the attribute '" . $attrib . "'.", -203);
      elseif (! isset($this->attrib[$attrib][$rec]))
         if ($this->property['TYPE'] == 'R')
            throw new Exception("Form '" . $this->property["FORM_NAME"] . "' does not have a record number $rec.", -202);
         else
            throw new Exception("Form '" . $this->property["FORM_NAME"] . "' is not a record form.", -201);

      return true;
   }

   /**
    * Try a regular expression rule on a string
    *
    * A record may be added to a form by specifying <b>$rec</b> as one greater than the value of {@link recCount()}
    *
    * @param array rule
    * <code>
    * array (
    *    "RULE" => "regex",  // regex contains the text of the regular expression
    *    "RULE_TYPE" => "M"   // "M" or "N" making the rule look for a match or not match of the <b>$text</b> with the regex
    * }
    * </code>
    * @param string text to perform rule on
    * @return string
    * <ul>
    * <li> 'Y' - yes rule was successful
    * <li> 'N' - no rule failed
    * </ul>
    */
   protected function tryRule($rule, $text) {
      $isError = ereg($rule["RULE"], $text);
      if ($rule["RULE_TYPE"] != "M") $isError = ! $isError;
      return ($isError ? "N" : "Y");
   }

   protected function getMember($memberName) {
      eval ('$memeber = $this->' . $memberName . ';');
      return $memeber;
   }
   /**#@-*/

   /**
    * Create an instance of a dizzyPages form
    *
    * The minimal usage of a DzeForm requires the following steps.
    * <code>
    * // get the form
    * $myForm = new DzeForm(& $this);
    * // process the forms rules
    * $myForm->processRules();
    * // Commit the form attributes to the session and/or user.
    * // Commit the form errors to the session and/or user.
    * $myForm->commit();
    * </code>
    *
    * @param object DzePage handle to the current DzePage instance
    */
   public function __construct(& $dzePage) {
      $this->page = & $dzePage;
      $this->sql = & $this->page->sql;
      $this->page->setFormError('N');

      if ($this->page->getMember("referrerFormName")) {
         // TODO Check that form is part of referrer page for security
         $this->getFormDesc();
         $this->getFormData();
      }
      else $this->attrib = array();
      $this->state = 100;
   }

   /**
    * Clear error of an attribute
    *
    * @param string attribute name
    * @param integer record number
    * @return boolean true - attribute error has been cleared
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    */
   protected function clearError($attrib, $rec = 1) {
      if ($this->checkAttrib($attrib, $rec)) {
         if ($this->attrib[$attrib][$rec]["ERROR_B"] == "Y") {
            unset($this->attrib[$attrib][$rec]["ERROR_TEXT"]);
            $this->errorCt--;
         }
         $this->attrib[$attrib][$rec]["ERROR_B"] = 'N';
         if ($this->errorCt == 0) $this->page->setFormError('N');
      }

      return true;
   }

   /**
    * Set the text error of an attribute
    *
    * @param string attribute name
    * @param string error text
    * @param integer record number
    * @return boolean true - error has been set
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    * @throws -241, Error text must be 1-255 characters long.
    */
   protected function setError($attrib, $text, $rec = 1) {
      if ($this->checkAttrib($attrib, $rec)) {
         $text = trim($text);
         if (is_null($text) || strlen($text) < 1 || 255 < strlen($text))
            throw new Exception("Error text must be 1-255 characters long.", -204);
         else {
            if ($this->attrib[$attrib][$rec]["ERROR_B"] != "Y") $this->errorCt++;

            $this->attrib[$attrib][$rec]["ERROR_B"] = "Y";
            $this->attrib[$attrib][$rec]["ERROR_TEXT"] = $text;
            $this->page->setFormError('Y');
         }
      }

      return true;
   }

   /**
    * Get the text error of an attribute
    *
    * @param string attribute name
    * @param integer record number
    * @return string error or null if no error exists:
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    */
   protected function getError($attrib, $rec = 1) {
      $retValue = null;
      if ($this->checkAttrib($attrib, $rec)) {
         if ($this->attrib[$attrib][$rec]["ERROR_B"] == "Y")
            $retValue = $this->attrib[$attrib][$rec]["ERROR_TEXT"];
      }
      return $retValue;
   }

   /**
    * Inquire whether the form or an attribute of the form has an outstanding error
    *
    * <code>
    * # Form level error inquirey
    * $this->isError();
    * # Attribute level error inquirey
    * $this->isError('acme-AQuantity');
    * # Attribute in second record level error inquirey
    * $this->isError('acme-AQuantity', 2);
    * </code>
    *
    * @param string attribute name
    * @param integer record number
    * @return string
    * <ul>
    * <li> 'Y' - Yes an outstanding error exists
    * <li> 'N' - No outstanding error exists
    * </ul>
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    */
   protected function isError($attrib = null, $rec = 1) {
      $retValue = null;

      if (is_null($attrib)) // Check for form error
         $retValue = $this->page->setFormError();
      else {                // Check for attrib error
         if ($this->checkAttrib($attrib, $rec))
            $retValue = $this->attrib[$attrib][$rec]["ERROR_B"];
      }

      return $retValue;
   }

   /**
    * Inquire how many records exist in form
    *
    * @return integer number of records in the form
    *
    * @throws -201, Form [Form Name] is not a record form.
    */
   protected function recCount() {
      if ($this->property['TYPE'] != 'R')
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' is not a record form.", -201);

      return $this->recTotalNew;
   }

   /**
    * Inquire whether a record in a form has been deleted
    *
    * @param integer $rec record number
    * @return string
    * <ul>
    * <li> 'Y' - Yes the record has been deleted
    * <li> 'N' - No the record has not been deleted
    * </ul>
    *
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    */
   protected function isDelRec($rec) {
      if ($this->property['TYPE'] != 'R')
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' is not a record form.", -201);
      elseif ($rec < 1 || $rec > $this->recTotalNew)
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' does not have a record number $rec.", -202);

      return $this->delRecs[$rec];
   }

   /**
    * Delete a record in a form
    *
    * @param integer $rec record number
    * @return boolean true - $rec record number deleted
    *
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    */
   protected function delRec($rec) {
      if ($this->property['TYPE'] != 'R')
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' is not a record form.", -201);
      elseif ($rec < 1 || $rec > $this->recTotalNew)
         throw new Exception("Form '" . $this->property["FORM_NAME"] . "' does not have a record number $rec.", -202);

      if ($this->delRecs[$rec] != "Y") {
         $this->delRecs[$rec] = "Y";
         $this->recTotalDel++;
      }

      return true;
   }

   /**
    * Get a form attribute value
    *
    * @param string attribute name
    * @param integer record number
    * @param string
    * <ul>
    * <li> 'NEW' - the new user entered value
    * <li> 'OLD' - the old attribute value
    * </ul>
    * @return string - attribute value
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    */
   protected function getAttrib($attrib, $rec = 1, $ver = 'NEW') {
      if ($this->checkAttrib($attrib, $rec))
         return $this->attrib[$attrib][$rec][$ver];
   }
   
   /**
    * Set a form attribute value
    *
    * A record may be added to a form by specifying <b>$rec</b> as one greater than the value of {@link recCount()}
    *
    * @param string attribute name
    * @param string value assigned to attribute
    * @param integer record number
    * @return boolean true - form attribute has been set
    * @throws -201, Form [Form Name] is not a record form.
    * @throws -202, Form [Form Name] does not have a record number [$rec].
    * @throws -203, Form [Form Name] does not contain the attribute [Attrib Name].
    * @throws -204, Attribute [Attrib Name] in form [Form Name] must be less than 256 characters long.
    */
   protected function setAttrib($attrib, $value, $rec = 1) {
      try {
         $this->checkAttrib($attrib, $rec);
      }
      catch (Exception $e) {
         if ($e->getCode() == -202 && $rec == $this->recCount() + 1) {
            $this->recTotalNew++;
            $this->delRecs[$rec] = 'N';
            foreach($this->attrib as $name => $val) {
               $val[$rec]["OLD"] = "";
               if ($name != $attrib) $val[$rec]["NEW"] = "";
            }
         }
         else throw $e;
      }

      $text = trim(strval($value));
      if (strlen($text) > 255)
         throw new Exception("Attribute '" . $attrib . "' in form '" . $this->property["FORM_NAME"] . "' must be less than 256 characters long.", -204);
      else $this->attrib[$attrib][$rec]['NEW'] = $text;

      return true;
   }

   /**
    * Get the form attribute names
    *
    * @return array array of strings containing the form attribute names
    */
   protected function getAttribNames() {
      $retValue = array();

      foreach ($this->attrib as $attribName => $value)
         array_push($retValue, $attribName);

      return $retValue;
   }

   /**
    * Get a form properity
    *
    * @param string property name, one of:
    * <ul>
    * <li> 'FORM_NAME' - name of form being processed
    * <li> 'TYPE' - the type of form
    * <li> 'TRAP_ON_ERR_TYPE' - whether the form traps the user until all errors are corrected
    * <li> 'R_SAVE_TYPE' - if the form is of record type how the attributes are saved at {@link commit()}
    * <li> 'R_AUDIT_TYPE' - if the form is of record type how the attributes are audited at {@link commit()}
    * </ul>
    * @return string
    * <ul>
    * <li> <b>$propName</b> is 'FORM_NAME' - name of form being processed
    * <li> <b>$propName</b> is 'TYPE'
    *    <ul>
    *    <li> 'S' (string) - standard form
    *    <li> 'R' (string) - record form
    *    </ul>
    * <li> <b>$propName</b> is 'TRAP_ON_ERR_TYPE'
    *    <ul>
    *    <li> 'N' (string) - no trapping is performed on this form
    *    <li> 'S' (string) - this form traps for the duration of the session
    *    <li> 'U' (string) - this form traps for the current user and any new login under the current user name
    *    </ul>
    * <li> <b>$propName</b> is 'R_SAVE_TYPE'
    *    <ul>
    *    <li> 'N' (string) - no value saving for these records
    *    <li> 'S' (string) - record values are saved for the duration of the session
    *    <li> 'U' (string) - record values are saved for the life of the use
    *    </ul>
    * <li> <b>$propName</b> is 'R_AUDIT_TYPE'
    *    <ul>
    *    <li> 'N' (string) - no value auditing for these records
    *    <li> 'S' (string) - record values are audited for the duration of the session
    *    <li> 'U' (string) - record values are audited for the life of the use
    *    </ul>
    * </ul>
    * @throws -211, Invalid property name [Property Name] requested.
    */
   protected function getProperty($propName) {
      if (! isset($this->property[$propName]))
         throw new Exception("Invalid property name '" . $propName . "' requested.", -211);

      return $this->property[$propName];
   }

   /**
    * Commit form attributes and errors to session/user.
    *
    * @return boolean true - commit completed
    * @throws -222, {@link commitAttribs()} called out of order must be called after {@link processRules()}
    */
   protected function commitAttribs() {
      if ($this->state != 200)
         throw new Exception("commitAttribs() called out of order must be called after processRules()", -222);

      $this->page->clearErrors();
      if ($this->property["TRAP_ON_ERR_TYPE"] == 'U')
         $this->page->clearErrors($this->page->getUserId());

      if (   $this->page->getMember('loginApp') == 'dze'
          || $this->page->getMember("config['log_level']") >= 5)
         $this->page->setVpi('attrib', print_r($this->attrib, true));

      if (! is_null($this->attrib)) {
         foreach ($this->attrib as $attribName => $value) {
            for ($recCt = 1; $recCt <= $this->recTotalNew; $recCt++) {
               // TRICKY is_null test is required
               // a null and an empty string evaluate as equal in PHP
               // The only time 'OLD' is NULL is on the initial set/insert
               // Do not use PHP's '!==' this causes problems in other
               // scenarios
               if ((   is_null($value[$recCt]["OLD"])
                    || $value[$recCt]["OLD"] != $value[$recCt]["NEW"]
                   )
                   && $this->delRecs[$recCt] != "Y") {
                  $this->auditFormAttrib($attribName, $value[$recCt]["NEW"], $value["AUDIT_TYPE"], $recCt);
                  $this->setFormAttrib($attribName, $value[$recCt]["NEW"], $value["SAVE_TYPE"], $recCt);
               }

               if ($value[$recCt]['ERROR_B'] == "Y") {
                  $this->page->setSesAttribError($attribName, $value[$recCt]['ERROR_TEXT'], $recCt);
                  if ($this->property["TRAP_ON_ERR_TYPE"] == 'U')
                     $this->page->setUserAttribError($attribName, $value[$recCt]['ERROR_TEXT'], $recCt);
               }
            }

            // TRICKY Delete is seperate loop.  Do not delete in the update loop
            // TRICKY Delete must be performed in descending order
            for ($recCt = $this->recTotalOld; $recCt >= 1; $recCt--)
               if ($this->delRecs[$recCt] == "Y") {
                  $this->auditDelFormAttrib($attribName, $value["AUDIT_TYPE"], $recCt);
                  $this->delFormAttrib($attribName, $value["SAVE_TYPE"], $recCt);
               }
         }

         if ($this->property['TYPE'] == 'R') {
            $this->recTotalNew -= $this->recTotalDel;
            if ($this->recTotalNew != $this->recTotalOld)
               $this->setFormAttrib($this->recCtName, $this->recTotalNew, $this->property["R_SAVE_TYPE"]);
            $this->recTotalOld -= $this->recTotalDel;
         }
      }

      $this->page->setSesAttrib("common-SESSION-PREVIOUS-FORM_ERR",
         $this->isError());
      $this->page->setSesAttrib("common-SESSION-PREVIOUS-FORM_NAME",
         $this->property["FORM_NAME"]);

      if (   $this->property["TRAP_ON_ERR_TYPE"] == 'U'
          && $this->isError() == 'Y') {
         $this->page->setUserAttrib("common-SESSION-PREVIOUS-FORM_ERR",
            $this->isError());
         $this->page->setUserAttrib("common-SESSION-PREVIOUS-FORM_NAME",
            $this->property["FORM_NAME"]);
         $this->page->setUserAttrib("common-SESSION-PREVIOUS-URL",
            $this->page->previousUrl);
      }
      $this->state = 300;

      return true;
   }

   /**
    * Process the form attribute rules
    *
    * @return boolean true - processing completed
    * @throws -221, {@link processRules()} called out of order must be called after {@link commitAttribs()}
    */
   protected function processRules() {
      if ($this->state != 100)
         throw new Exception("processRules() called out of order must be called after commitAttribs()", -221);

      if (! is_null($this->attrib)) {
         $this->sql->pushResult();

         foreach ($this->attrib as $attribName => $values) {
            // TODO Handle each Attribute TYPE seperately
            $this->sql->select(
               "DZE_ATTRIB_RULE",
               array("RULE", "FIRE_ORDER", "RULE_TYPE", "ERR_TXT"),
               array("ATTRIB_NAME" => $attribName),
               "ORDER BY FIRE_ORDER"
            );

            while ($rule = $this->sql->fetchAssoc()) {
               for ($recCt = 1; $recCt <= $this->recTotalNew; $recCt++) {
                  if (   $this->delRecs[$recCt] != "Y"
                      && $this->attrib[$attribName][$recCt]['ERROR_B'] != "Y") {
                     // TODO currently there is a 255 character limit
                     //      on all data entry
                     // TODO this 255 limit may/will cause problems  
                     //      if it chops a multi-select
                     $maxLen = $this->attrib[$attribName]["T_FORM_LEN_MAX"];
                     if ($maxLen > 255 ) $maxLen = 255;
                     if (strlen($values[$recCt]["NEW"]) > $maxLen) {
                        $this->attrib[$attribName][$recCt]["NEW"] =
                           substr($values[$recCt]["NEW"], 0, $maxLen);
                        $this->setError(
                           $attribName,
                           "maximum length exceeded ...",
                           $recCt
                        );
                     }
                     elseif (   $this->tryRule($rule, $values[$recCt]["NEW"])
                             != "Y") {
                        $this->setError(
                           $attribName,
                           $rule["ERR_TXT"],
                           $recCt
                        );
                     }
                  }
               }
            }

            $this->sql->freeResult();
         }

         $this->sql->popResult();
      }
      $this->state = 200;

      return true;
   }
}
?>
Return current item: dizzyPages