private function _checkExpressions(Kwf_Model_Select_Expr_Interface $expr, $data)
 {
     if ($expr instanceof Kwf_Model_Select_Expr_Equal) {
         $v = $this->_rowValue($expr->getField(), $data);
         $values = $expr->getValue();
         if ($values instanceof Kwf_Model_Select_Expr_Interface) {
             $values = $this->getExprValue($data, $values);
         }
         if (!is_array($values)) {
             $values = array($values);
         }
         if (!in_array($v, $values)) {
             return false;
         }
     } else {
         if ($expr instanceof Kwf_Model_Select_Expr_NotEquals) {
             $v = $this->_rowValue($expr->getField(), $data);
             $values = $expr->getValue();
             if (!is_array($values)) {
                 $values = array($values);
             }
             if (in_array($v, $values)) {
                 return false;
             }
         } else {
             if ($expr instanceof Kwf_Model_Select_Expr_IsNull) {
                 $v = $this->_rowValue($expr->getField(), $data);
                 if (!is_null($v)) {
                     return false;
                 }
             } else {
                 if ($expr instanceof Kwf_Model_Select_Expr_Higher) {
                     $v = $this->_rowValue($expr->getField(), $data);
                     $exprValue = $expr->getValue();
                     if ($exprValue instanceof Kwf_Date) {
                         $exprValue = $exprValue->getTimestamp();
                         $v = strtotime($v);
                     }
                     if (!(!is_null($v) && $v > $exprValue)) {
                         return false;
                     }
                 } else {
                     if ($expr instanceof Kwf_Model_Select_Expr_Lower) {
                         $v = $this->_rowValue($expr->getField(), $data);
                         $exprValue = $expr->getValue();
                         if ($exprValue instanceof Kwf_Date) {
                             $exprValue = $exprValue->getTimestamp();
                             $v = strtotime($v);
                         }
                         if (!(!is_null($v) && $v < $exprValue)) {
                             return false;
                         }
                     } else {
                         if ($expr instanceof Kwf_Model_Select_Expr_HigherEqual) {
                             $v = $this->_rowValue($expr->getField(), $data);
                             $exprValue = $expr->getValue();
                             if ($exprValue instanceof Kwf_Date) {
                                 $exprValue = $exprValue->getTimestamp();
                                 $v = strtotime($v);
                             }
                             if (!(!is_null($v) && $v >= $exprValue)) {
                                 return false;
                             }
                         } else {
                             if ($expr instanceof Kwf_Model_Select_Expr_LowerEqual) {
                                 $v = $this->_rowValue($expr->getField(), $data);
                                 $exprValue = $expr->getValue();
                                 if ($exprValue instanceof Kwf_Date) {
                                     $exprValue = $exprValue->getTimestamp();
                                     $v = strtotime($v);
                                 }
                                 if (!(!is_null($v) && $v <= $exprValue)) {
                                     return false;
                                 }
                             } else {
                                 if ($expr instanceof Kwf_Model_Select_Expr_HigherEqualDate) {
                                     $v = $this->_rowValue($expr->getField(), $data);
                                     if (!is_null($v)) {
                                         $fieldTime = strtotime($v);
                                         $exprTime = strtotime($expr->getValue());
                                         if ($fieldTime >= $exprTime) {
                                             return true;
                                         } else {
                                             return false;
                                         }
                                     } else {
                                         return false;
                                     }
                                 } else {
                                     if ($expr instanceof Kwf_Model_Select_Expr_SmallerEqualDate) {
                                         $v = $this->_rowValue($expr->getField(), $data);
                                         if (!is_null($v)) {
                                             $fieldTime = strtotime($v);
                                             $exprTime = strtotime($expr->getValue());
                                             if ($fieldTime <= $exprTime) {
                                                 return true;
                                             } else {
                                                 return false;
                                             }
                                         } else {
                                             return false;
                                         }
                                     } else {
                                         if ($expr instanceof Kwf_Model_Select_Expr_Contains) {
                                             $v = $this->_rowValue($expr->getField(), $data);
                                             if (!($v && strpos(strtolower($v), strtolower($expr->getValue())) !== false)) {
                                                 return false;
                                             }
                                         } else {
                                             if ($expr instanceof Kwf_Model_Select_Expr_Like) {
                                                 $v = $this->_rowValue($expr->getField(), $data);
                                                 if (!is_null($v)) {
                                                     $reg = $expr->getValue();
                                                     $partsToEscape = array('\\', '(', ')', '_', '*', '.', '^', '$');
                                                     foreach ($partsToEscape as $part) {
                                                         $reg = str_replace($part, '\\' . $part, $reg);
                                                     }
                                                     $reg = str_replace('%', '(.*)', $reg);
                                                     $reg = "/^{$reg}\$/i";
                                                     return preg_match($reg, $v);
                                                 }
                                                 return false;
                                             } else {
                                                 if ($expr instanceof Kwf_Model_Select_Expr_RegExp) {
                                                     $v = $this->_rowValue($expr->getField(), $data);
                                                     if (!is_null($v)) {
                                                         $reg = $expr->getValue();
                                                         return preg_match('/' . $reg . '/', $v);
                                                     }
                                                     return false;
                                                 } else {
                                                     if ($expr instanceof Kwf_Model_Select_Expr_StartsWith) {
                                                         $v = $this->_rowValue($expr->getField(), $data);
                                                         if (!($v && substr($v, 0, strlen($expr->getValue())) == $expr->getValue())) {
                                                             return false;
                                                         }
                                                     } else {
                                                         if ($expr instanceof Kwf_Model_Select_Expr_Area) {
                                                             // TODO: Umkreissuche
                                                             throw new Kwf_Exception_NotYetImplemented();
                                                         } else {
                                                             if ($expr instanceof Kwf_Model_Select_Expr_Not) {
                                                                 if ($this->_checkExpressions($expr->getExpression(), $data)) {
                                                                     return false;
                                                                 }
                                                             } else {
                                                                 if ($expr instanceof Kwf_Model_Select_Expr_Or) {
                                                                     foreach ($expr->getExpressions() as $orExpr) {
                                                                         if ($this->_checkExpressions($orExpr, $data)) {
                                                                             return true;
                                                                         }
                                                                     }
                                                                     return false;
                                                                 } else {
                                                                     if ($expr instanceof Kwf_Model_Select_Expr_And) {
                                                                         foreach ($expr->getExpressions() as $andExpr) {
                                                                             if (!$this->_checkExpressions($andExpr, $data)) {
                                                                                 return false;
                                                                             }
                                                                         }
                                                                         return true;
                                                                     } else {
                                                                         if ($expr instanceof Kwf_Model_Select_Expr_Add) {
                                                                             $ret = 0;
                                                                             foreach ($expr->getExpressions() as $andExpr) {
                                                                                 $ret += $this->_checkExpressions($andExpr, $data);
                                                                             }
                                                                             return $ret;
                                                                         } else {
                                                                             if ($expr instanceof Kwf_Model_Select_Expr_Subtract) {
                                                                                 $ret = 0;
                                                                                 foreach ($expr->getExpressions() as $andExpr) {
                                                                                     $ret -= $this->_checkExpressions($andExpr, $data);
                                                                                 }
                                                                                 if ($expr->lowerNullAllowed && $ret < 0) {
                                                                                     $ret = 0;
                                                                                 }
                                                                                 return $ret;
                                                                             } else {
                                                                                 if ($expr instanceof Kwf_Model_Select_Expr_Divide) {
                                                                                     foreach ($expr->getExpressions() as $e) {
                                                                                         $value = $this->_checkExpressions($e, $data);
                                                                                         if ($ret == null) {
                                                                                             $ret = $value;
                                                                                         } else {
                                                                                             if ($value == 0) {
                                                                                                 //throw new Kwf_Exception('division by 0 not possible, check you expressions');
                                                                                             } else {
                                                                                                 $ret = $ret / $value;
                                                                                             }
                                                                                         }
                                                                                     }
                                                                                     if (!$ret) {
                                                                                         $ret = 0;
                                                                                     }
                                                                                     return $ret;
                                                                                 } else {
                                                                                     if ($expr instanceof Kwf_Model_Select_Expr_Multiply) {
                                                                                         $ret = null;
                                                                                         foreach ($expr->getExpressions() as $e) {
                                                                                             $value = $this->getExprValue($row, $e);
                                                                                             if ($ret == null) {
                                                                                                 $ret = $value;
                                                                                             } else {
                                                                                                 $ret *= $value;
                                                                                             }
                                                                                         }
                                                                                         if (!$ret) {
                                                                                             $ret = 0;
                                                                                         }
                                                                                         return $ret;
                                                                                     } else {
                                                                                         if ($expr instanceof Kwf_Model_Select_Expr_SearchLike) {
                                                                                             $e = $expr->getQueryExpr($this);
                                                                                             if (!$e) {
                                                                                                 return true;
                                                                                             }
                                                                                             return $this->_checkExpressions($e, $data);
                                                                                         } else {
                                                                                             return (bool) $this->getExprValue($data, $expr);
                                                                                         }
                                                                                     }
                                                                                 }
                                                                             }
                                                                         }
                                                                     }
                                                                 }
                                                             }
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return true;
 }
 private static function _evaluateExprForRowset($rowset, Kwf_Model_Select_Expr_Interface $expr)
 {
     if ($expr instanceof Kwf_Model_Select_Expr_Count) {
         if ($expr->getField() != '*') {
             $f = $expr->getField();
             $values = array();
             foreach ($rowset as $r) {
                 if (!is_null($r->{$f})) {
                     $values[] = $r->{$f};
                 }
             }
             if ($expr->getDistinct()) {
                 $values = array_unique($values);
             }
             return count($values);
         } else {
             return $rowset->count();
         }
     } else {
         if ($expr instanceof Kwf_Model_Select_Expr_Sum) {
             $f = $expr->getField();
             $ret = 0;
             foreach ($rowset as $r) {
                 $ret += $r->{$f};
             }
             return $ret;
         } else {
             if ($expr instanceof Kwf_Model_Select_Expr_Max) {
                 $f = $expr->getField();
                 $ret = $rowset->current()->{$f};
                 foreach ($rowset as $r) {
                     $ret = max($ret, $r->{$f});
                 }
                 return $ret;
             } else {
                 if ($expr instanceof Kwf_Model_Select_Expr_Min) {
                     $f = $expr->getField();
                     $ret = $rowset->current()->{$f};
                     foreach ($rowset as $r) {
                         $ret = min($ret, $r->{$f});
                     }
                     return $ret;
                 } else {
                     if ($expr instanceof Kwf_Model_Select_Expr_GroupConcat) {
                         $f = $expr->getField();
                         $ret = array();
                         foreach ($rowset as $r) {
                             $ret[] = $r->{$f};
                         }
                         return implode($expr->getSeparator(), $ret);
                     } else {
                         if ($expr instanceof Kwf_Model_Select_Expr_Field) {
                             if (!count($rowset)) {
                                 return null;
                             }
                             $f = $expr->getField();
                             return $rowset->current()->{$f};
                         } else {
                             throw new Kwf_Exception_NotYetImplemented("support for " . get_class($expr) . " is not yet implemented");
                         }
                     }
                 }
             }
         }
     }
 }
 private static function _evaluateExprForRowset($rowset, Kwf_Model_Select_Expr_Interface $expr)
 {
     if ($expr instanceof Kwf_Model_Select_Expr_Count) {
         if ($expr->getField() != '*') {
             $f = $expr->getField();
             $values = array();
             foreach ($rowset as $r) {
                 if (!is_null($r->{$f})) {
                     $values[] = $r->{$f};
                 }
             }
             if ($expr->getDistinct()) {
                 $values = array_unique($values);
             }
             return count($values);
         } else {
             return $rowset->count();
         }
     } else {
         if ($expr instanceof Kwf_Model_Select_Expr_Sum) {
             $f = $expr->getField();
             $ret = 0;
             foreach ($rowset as $r) {
                 $ret += $r->{$f};
             }
             return $ret;
         } else {
             if ($expr instanceof Kwf_Model_Select_Expr_Max) {
                 $f = $expr->getField();
                 if (!count($rowset)) {
                     return null;
                 }
                 $ret = $rowset->current()->{$f};
                 foreach ($rowset as $r) {
                     $ret = max($ret, $r->{$f});
                 }
                 return $ret;
             } else {
                 if ($expr instanceof Kwf_Model_Select_Expr_Min) {
                     $f = $expr->getField();
                     if (!count($rowset)) {
                         return null;
                     }
                     $ret = $rowset->current()->{$f};
                     foreach ($rowset as $r) {
                         $ret = min($ret, $r->{$f});
                     }
                     return $ret;
                 } else {
                     if ($expr instanceof Kwf_Model_Select_Expr_GroupConcat) {
                         $f = $expr->getField();
                         $orderField = $expr->getOrderField();
                         $ret = array();
                         if ($orderField) {
                             $orderFieldValue = $orderField['field'];
                             $orderFieldDirection = $orderField['direction'] == 'DESC' ? SORT_DESC : SORT_ASC;
                             $rowData = array();
                             foreach ($rowset as $r) {
                                 $rowData[] = array($f => $r->{$f}, $orderFieldValue => $r->{$orderFieldValue});
                             }
                             $orderFieldValues = array();
                             foreach ($rowData as $key => $data) {
                                 $orderFieldValues[$key] = $data[$orderFieldValue];
                             }
                             array_multisort($orderFieldValues, $orderFieldDirection, $rowData);
                             foreach ($rowData as $r) {
                                 $ret[] = $r[$f];
                             }
                         } else {
                             foreach ($rowset as $r) {
                                 $ret[] = $r->{$f};
                             }
                         }
                         return implode($expr->getSeparator(), $ret);
                     } else {
                         if ($expr instanceof Kwf_Model_Select_Expr_Field) {
                             if (!count($rowset)) {
                                 return null;
                             }
                             $f = $expr->getField();
                             return $rowset->current()->{$f};
                         } else {
                             throw new Kwf_Exception_NotYetImplemented("support for " . get_class($expr) . " is not yet implemented");
                         }
                     }
                 }
             }
         }
     }
 }