<?php

class BaseCriteria    {

    
/**
     *    sanitize incoming db data
     *    @param    string sql stuff
     *    @return    string sanitized sql stuff
     *    @access    private
     **/
    
    
function _sanitize($string)    {
        return 
trim(addslashes($string) );
    }    
    
    
/**
     *    escape fields
     *    @param    string field
     *    @return    string escaped field
     *    @access    private
     **/
    
    
function _escape($field)    {
        
$field    =    str_replace('.''`.`'$field);
        
$field    =    "`{$field}`";
        return 
$field;
    }
}


class 
Criteria extends BaseCriteria    {

    
/**
     *    Constructor
     *    @param    string field
     *    @param    mixed value
     *    @param    string operator
     *    @access    protected
     **/
    
function Criteria($field$value$operator)    {
        
$this->field    =    $field;
        
$this->value    =    $value;
        
$this->operator    =    $operator;
    }

    
/**
     *    build a search statement
     *    @param    string field
     *    @param    mixed value
     *    @return    object SearchCriteria
     *    @access    static
     **/
    
    
function &isLike($field$value)    {
        return new 
SearchCriteria($field$value);
    }

    
/**
     *    Build an equality statement
     *    @param    string field
     *    @param    mixed value
     *    @return    object Criteria 
     *    @access    static
     **/
    
    
function &isEqualTo($field$value)    {
        return new 
Criteria($field$value'=');
    }     
    
    
/**
     *    Build an inequality statement
     *    @param    string field
     *    @param    mixed value
     *    @return    object Criteria 
     *    @access    static
     **/
    
    
function &isNotEqualTo($field$value)    {
        return new 
Criteria($field$value'!=');
    }     

    
/**
     *    Build a less than statement
     *    @param    string field
     *    @param    string value
     *    @return    object Criteria 
     *    @access    static
     **/
    
    
function &isLessThan($field$value)    {
        return new 
Criteria($field$value'<');
    }
    
    
/**
     *    Build a greater than statement
     *    @param    string field
     *    @param    string value
     *    @return    object Criteria 
     *    @access    static
     **/
    
    
function &isGreaterThan($field$value)    {
        return new 
Criteria($field$value'>');
    }

    
/**
     *    Build an order by statement
     *    @param    string field
     *    @param    string direction
     *    @return    object OrderByCriteria
     *    @access    static
     **/
    
    
function &orderBy($field$direction)    {
        return new 
OrderByCriteria($field$direction);
    }

    
/**
     *    Build field / value pairs for insert/update operations
     *    @param    array field/value pairs
     *    @return    object SetFieldsCriteria
     *    @access    static
     **/
    
    
function &setFields($array)    {
        return new 
SetFieldsCriteria($array);
    }

    
/**
     *    handle generation of SQL from an array
     *    @param    array SQL fragments
     *    @return    string SQL fragment
     *    @access    private
     **/
    
    
function _generateSqlFromArray($array)    {
        
$query    =    "(";
        foreach(
$array as $value)    {
            
$query    .=    $this->_escape($this->field)." {$this->operator} '".$this->_sanitize($value)."' OR ";
        }
        
$query    =    substr($query0, -4);
        
$query    .=    ")";
        return 
$query;
    }
    
    
/**
     *    Generate the SQL required
     *    @return    string SQL snippet
     *    @access    public
     **/
    
    
function generateSql()    {
        if (
is_array($this->value) )    {
            return 
$this->_generateSqlFromArray($this->value);
        } else {
            
$query    =    $this->_escape($this->field)." {$this->operator} '".$this->_sanitize($this->value)."'";
            return 
$query;
        }
    }

}


class 
SearchCriteria extends BaseCriteria    {

    
/**
     *    Constructor
     *    @param    string field
     *    @param    string search phrase
     *    @access    protected
     **/
    
    
function SearchCriteria($field$value)    {
        
$this->field    =    trim($field);
        
$this->value    =    $value;
    }

    
/**
     *    generate the required SQL
     *    @return    string SQL snippet
     *    @access    public
     **/
    
    
function generateSql()    {
        if (
is_array($this->value) )    {
            
$query    =    "(";
            foreach(
$this->value as $term)    {
                
$query    .=    $this->_escape($this->field)." LIKE '%".$this->_sanitize($term)."%' OR ";
            }
            
$query    =    substr($query0, -4);
            
$query    .=    ")";
        }
        return 
$query;
    }

}


class 
OrderByCriteria extends BaseCriteria    {

    
/**
     *    Constructor
     *    @param    string field
     *    @param    string direction
     *    @access    protected
     **/
    
    
function OrderByCriteria($field$direction)    {
        
$this->field    =    trim($field);

        if (
strtoupper(trim($direction) ) == 'DESC')    {
            
$this->direction    =    'DESC';
        } else {
            
$this->direction    =    'ASC';
        }
    }
    
    
/**
     *    Generate the SQL required
     *    @return    string SQL snippet
     *    @access    public
     **/
     
    
function generateSql()    {
        return 
$this->_escape($this->field)." {$this->direction}";
    }
}



class 
SetFieldsCriteria extends BaseCriteria    {

    
/**
     *    Constructor
     *    @param    array field/value key pairs
     *    @access    protected
     **/
    
    
function SetFieldsCriteria($array)    {
        
$this->data    =    $array;
    }
    
    
/**
     *    Generate the SQL required for SET
     *    @return    string SQL snippet
     *    @access    public
     **/
    
    
function generateSql()    {
        
$sql    =    '';
        
$pcre    =    '/^%s\s?[\+|\-|\*|\/]\s?[0-9]+$/';
        foreach(
$this->data as $field=>$value)    {
            if (
preg_match(sprintf($pcre$field), $value) )    {
                
$sql    .=    $this->_handleMathSet($field$value);
            } else {
                
$sql    .=    $this->_handleDefaultSet($field$value);
            }
        }
        return 
substr($sql0, -2);
    }
    
    
/**
     *    handle a match operation
     *    @param    string field
     *    @param    string value
     *    @access    private
     **/
    
    
function _handleMathSet($field$value)    {
        
$value    =    str_replace($field$this->_escape($field), $value);
        return 
$this->_escape($field)." = {$value}, ";
    }
    
    
/**
     *    handle typical set operation
     *    @param    string field
     *    @param    string value
     *    @access    private
     **/
    
    
function _handleDefaultSet($field$value)    {
        return 
$this->_escape($field)." = '".$this->_sanitize($value)."', ";
    }
}

?>