function isValid()
 {
     #echo "checking field $this->name\n";
     #print_r($this);
     $this->error = '';
     $no_errors = TRUE;
     if (!empty($this->value)) {
         if ($this->preg_rule == '') {
             switch ($this->value_type) {
                 case FORMFIELD_EMAIL_TYPE:
                     $no_errors = xox_check_email($this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_EMAIL_TYPE';
                     }
                     break;
                 case FORMFIELD_URI_TYPE:
                     $no_errors = xox_check_url($this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_URI_TYPE';
                     }
                     break;
                 case FORMFIELD_INTEGER_TYPE:
                     $no_errors = is_integer($this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_INTEGER_TYPE';
                     }
                     break;
                 case FORMFIELD_NUMERIC_TYPE:
                 case FORMFIELD_CURRENCY_TYPE:
                     $no_errors = is_numeric($this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_NUMERIC_TYPE';
                     }
                     break;
                 case FORMFIELD_DATE_TYPE:
                     $no_errors = preg_match('/^[1-9][0-9][0-9][0-9]-[0-1]?[0-9]-[0-3]?[0-9]$/', $this->value) || preg_match('/^[0-3]?[0-9]\\.[0-1]?[0-9].[1-9][0-9][0-9][0-9]$/', $this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_DATE_TYPE';
                     }
                     break;
                 case FORMFIELD_SHORTDATE_TYPE:
                     $no_errors = preg_match('/^[0-1]?[0-9]-[0-3]?[0-9]$/', $this->value) || preg_match('/^[0-3]?[0-9]\\.[0-1]?[0-9]$/', $this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_SHORTDATE_TYPE';
                     }
                     break;
                 case FORMFIELD_TIME_TYPE:
                     $no_errors = preg_match('/[0-2]?[0-9]:[0-9][0-9]:[0-9][0-9]/', $this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_TIME_TYPE';
                     }
                     break;
                 case FORMFIELD_SHORTTIME_TYPE:
                     $no_errors = preg_match('/[0-2]?[0-9]:[0-9][0-9]/', $this->value);
                     if (!$no_errors) {
                         $this->error = 'INVALID_SHORTTIME_TYPE';
                     }
                     break;
             }
         } else {
             $no_errors = preg_match($this->preg_rule, $this->value);
             if (!$no_errors) {
                 $this->error = 'INVALID_BREAKS_RULE';
             }
         }
         if ($no_errors && !($this->min_val == 0 && $this->max_val == 0)) {
             $no_errors = $this->value >= $this->min_val && $this->value <= $this->max_val;
             if (!$no_errors) {
                 $this->error = 'INVALID_VALUE';
             }
         }
         if ($no_errors && !($this->min_len == 0 && $this->max_len == 0)) {
             $no_errors = strlen($this->value) >= $this->min_len && strlen($this->value) <= $this->max_len;
             if (!$no_errors) {
                 $this->error = 'INVALID_LENGTH';
             }
         }
     } elseif ($this->mandatory) {
         $no_errors = FALSE;
         if (!$no_errors) {
             $this->error = 'INVALID_EMPTY';
         }
     }
     #if (!$no_errors) echo '=== '.$this->error.' ===';
     return $no_errors;
 }
 /**
  * validate contents of field
  * @return true if field is valid
  */
 function validate()
 {
     // optimistic approach
     $this->validated = true;
     // get length of value
     $len = $this->value == DCO_DATA_NULL ? 0 : is_array($this->value) ? count($this->value) : strlen($this->value);
     // check mandatory
     if ($this->mandatory && $len < 1) {
         $this->validated = false;
         $this->reason = DCO_DATA_ERR_EMPTY;
         return false;
     }
     // check length
     if ($this->checklength && $len > 0 && ($this->minlength != DCO_DATA_NULL && $len < $this->minlength) || $this->maxlength != DCO_DATA_NULL && $len > $this->maxlength) {
         $this->validated = false;
         $this->reason = DCO_DATA_ERR_LENGTH;
         return false;
     }
     // check range
     if ($this->checkrange && $len > 0 && ($this->minvalue != DCO_DATA_NULL && $this->value < $this->minvalue) || $this->maxvalue != DCO_DATA_NULL && $this->value > $this->maxvalue) {
         $this->validated = false;
         $this->reason = DCO_DATA_ERR_RANGE;
         return false;
     }
     // only check formats when a value is set
     if ($len > 0) {
         // regular expression has precedence to default regex for email and url
         if ($this->regex != DCO_DATA_NULL && !empty($this->regex)) {
             $this->validated = preg_match($this->regex, $this->value);
             // check default regex for email field
         } elseif ($this->type == DCO_DATA_EMAIL) {
             $this->validated = xox_check_email($this->value);
             // check default regex for url field
         } elseif ($this->type == DCO_DATA_URL) {
             $this->validated = xox_check_url($this->value);
             // check default regex for url field
         } elseif ($this->type == DCO_DATA_DATE) {
             $this->validated = xox_check_date($this->value);
         }
         // if validation failed here, then it was a format error
         if (!$this->validated) {
             $this->reason = DCO_DATA_ERR_FORMAT;
         }
     }
     // default exit
     return $this->validated;
 }