Location: PHPKode > projects > Anahita Social Engine > dependencies/plg_system_socialengine/socialengine/domain/query/query.php
<?php
/**
 * @version		1.0.0
 * @category	Anahita Social Engine™
 * @copyright	Copyright (C) 2008 - 2010 rmdStudio Inc. and Peerglobe Technology Inc. All rights reserved.
 * @license		GNU GPLv2 <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
 * @link     	http://www.anahitapolis.com
 */

class AnDomainQuery extends KDatabaseQuery implements KMixinInterface
{				
	protected $_mapper;
	
	protected $_unique_conditions = array();
	
	protected $_fields_map;
	
	protected $_raw_query;
		
	public function __construct($options = array())
	{						
		$this->_mapper		= $options['mapper'];
		
		parent::__construct(array('adapter'=>$this->getMapper()->getAdapter()));
		
		$this->_raw_query = $this->getMapper()->rawQuery();
		
		$this->from 	  = $this->_raw_query->from;	
				
		$this->update($this->_raw_query, array('join','where','group','order'));
				
		$this->_fields_map  = $this->_mapper->attrKeyPathsToField();
	}
	
	public function getMapper()
	{
		return $this->_mapper;	
	}
	
	public function getModel()
	{
		return $this->getMapper()->getModel();
	}
	
    public function join($type, $table, $condition)
    {    
		$conditions = array();
		
		if ( is_array($condition) ) {	
		
			foreach($condition as $key => $value) {
				if ( is_numeric($key) ) {
					$conditions[] = $value;
					continue;
				} else if ( isset($this->_fields_map[$key]) ) {
					$key = $this->_fields_map[$key];
				}
				$conditions[] = $key.' = '.$value;
			}
		} else {
			
			$conditions	= $condition;
		}
		
		parent::join($type, $table, $conditions);
          
        return $this;
    }
	
	public function uniqueConditions()
	{		 
		return $this->_unique_conditions;
	}

	/**
	 * 
	 * @return 
	 * @param $property Object
	 * @param $constraint Object
	 * @param $value Object[optional]
	 * @param $condition Object[optional]
	 */	
	 
	protected $_where_statements = array();
	
	public function where( $key, $constraint, $value = null, $condition = 'AND' )
	{				
		//is query being used to find a unique entity
		$unique_keys = $this->getMapper()->getUniqueKeys();

		if ( isset($unique_keys[$key]) && $constraint != 'IN' ) {
			$this->_unique_conditions[$key] = $value;
		}
		
		$property = $this->getMapper()->getProperty($key);

		if ( isset($this->_fields_map[$key]) || !$property ) {
			$key = isset($this->_fields_map[$key]) ? $this->_fields_map[$key] : $key;
			if ( $value === false ) {
				$value = 0;
			} else if ( is_null($value) ) {
				$value = '';	
			}
			return parent::where($key, $constraint, $value, $condition);
		}
		
		if ( $property->getIdentifier()->name == 'manytomany' ) {
			$property->mergeQueryWithTargetQuery($this, $key, array(
				'where'=> array(
					'constraint' => $constraint,
					'value'		 => $value,
					'condition'  => $condition
				)
			) );
			return $this;
		}
		


		$table_fields = $property->getTableFields();
		
		if ( (is_array($value) || $value instanceof KObjectArray)) {
						
			$values 	  = $value;
			
			$constraint   = 'IN';
			
			$field_array  = array();
			
			foreach($table_fields as $table_field) 	
				$field_array[$table_field] = array();
	
			foreach($values as $value) {
				
				$table_values = $property->getTableValues( $value );
				
				foreach($table_values as $index => $table_value) {
					$table_field = $table_fields[$index];
					$field_array[ $table_field ][] = $table_value;
				}
			}
			
			foreach($field_array as $field => $values) {
				$this->where($field,'IN', array_unique($values), $condition);
			}
	
		} else {

			$table_fields = $property->getTableFields();
			
			$table_values = $property->getTableValues( $value );
			
			foreach($table_fields as $index => $field)  {
				$value = $table_values[$index];
				$this->where($field, $constraint, $value, $condition);
			}
		}	
		
		return $this;			
	}		

	public function group($keys)
	{
		settype($keys, 'array');
		
		foreach($keys as $key) 
		{
			$property = $this->getMapper()->getProperty($key);

			if ( !$property ) {
				$key = isset($this->_fields_map[$key]) ? $this->_fields_map[$key] : $key;
				parent::group($key);
				continue;
			}
			
			$fields = $property->getTableFields();
			
			foreach($fields as $field) {
				parent::group($field);
			}
		}

		return $this;		
	}
	public function order( $keys, $direction = 'ASC' )
	{		
		settype($keys, 'array');
		
		foreach($keys as $key) 
		{
			$property = $this->getMapper()->getProperty($key);

			if ( !$property ) {
				$key = isset($this->_fields_map[$key]) ? $this->_fields_map[$key] : $key;
				parent::where($key, $direction);
				continue;
			}
			
			$fields = $property->getTableFields();
			
			foreach($fields as $field) {
				parent::order($field, $direction);
			}
		}

		return $this;
	}
		
	/**
	 * 
	 * @return 
	 * @param $query Object
	 */
	public function update($query, array $keys = array('join','where'))
	{
		foreach($keys as $key) {
			if ( $key == 'where' && count($query->where) && count($this->where) ) {
				$this->where[] = 'AND';
			}
			$this->$key = is_array($this->$key) ?
					array_merge($this->$key, $query->$key) :
				    $query->$key;
		}
		
		return $this;
	}
	
	public function merge($query)
	{	
		if ( count($query->where) && count($this->where) ) {
				$this->where[] = 'AND';	
		}
		
		$this->operation  = $query->operation;
		$this->order = array_merge($this->order, $query->order);
		$this->where = array_merge($this->where, $query->where);
		$this->limit = $query->limit;
		return $this;
	}
	
	public function getOffset()
	{	
		return $this->offset;
	}
	
	public function getLimit()
	{
		return $this->limit;
	}
	
	/**
	 * Return min of the property
	 * @return Integer
	 * @param $name String
	 */
	public function min($property)
	{
		$query 			   = clone $this;
		$query->columns    = array();		
		$attribute 		   = $this->getMapper()->getAttribute($property);
		$query->limit(null);		
		$query->operation  = 'SELECT min('.$attribute.')';
		$min			   = $this->getAdapter()->fetchResult($query);
		return $min;
	}
	
	/**
	 * Return max of the property
	 * @return Integer
	 * @param $property String
	 */
	public function max($property)
	{	
		$query 			  = clone $this;
		$query->columns   = array();		
		$attribute 		  = $this->getMapper()->getAttribute($property);
		$query->limit(null);		
		$query->operation = 'SELECT max('.$attribute.')';
		$max			  = $this->getAdapter()->fetchResult($query);
		return $max;
	}
	
	/**
	 * Count total number of entities
	 * @return Integer
	 */
	public function count()
	{	
		$query = clone $this;
		$query->operation = 'SELECT count(*)';
		$query->columns   = array();
		$query->limit(null);
		$count = $this->getAdapter()->fetchResult($query);
		return $count;
	}
	
	/**
	 * Fetch an entity
	 * @return Entity
	 */	
	public function fetch()
	{
		return $this->getMapper()->getRepository()->fetch($this);
	}
	
	/**
	 * Fetch a collection of entities
	 * @return Collection
	 */
	public function fetchAll()
	{
		return $this->getMapper()->getRepository()->fetchAll($this);
	}
	
	/**
	 * Get the methods that are available for mixin. 
	 * 
	 * @return array An array of methods
	 */
	public function getMixableMethods()
	{
		$remove  = array('__construct', '__destruct');
        $methods = array_diff(get_class_methods($this), $remove);
        return $methods;
	}
			
	protected $_selected_properties = array();
	
	public function getSelectedProperties()
	{
		return array_unique($this->_selected_properties);	
	}
	
	public function select($name)
	{	
		if ( is_array($name) )
			foreach($name as $onename) 
				$this->select($onename);
		else if ( $property = $this->_mapper->getProperty($name) ) {
			if ( !$property->isSelectable() ) return;
			$this->_selected_properties[] = $property->getName();
			$fields = $property->getTableFields();
			foreach($fields as $field) 
			{
				if ( strpos($field, '(') ) // a mysql function
				{
					$this->columns[] = $field;
				} else parent::select( $field.' AS '.str_replace('.','_',$field) );
			}
		} else {
			parent::select($name);
		}
		
		return $this;
	}
	
	/**
	 * 
	 */
	static $_default_columns = array();
		
	/**
	 * what is that ???
	 * @return 
	 */
	public function __toString()
	{		
		if ( !$this->operation ) 
			$this->operation = 'SELECT';
		
		$operation = $this->operation;
		
		if ( $this->operation == 'SELECT' || $this->operation == 'SELECT DISTINCT ') {
			
			if ( !count($this->_selected_properties) ) {
				//cache the default columns for future queries
				$model	   = $this->getMapper()->getModel();
				
				if ( !isset(self::$_default_columns[ $model ]) ) {
					$properies = $this->getMapper()->getProperties();
					foreach($properies as $property) {
						$this->select($property->getName());
					}
					self::$_default_columns[$model] = $this->columns;
				}
				$this->columns = self::$_default_columns[$model];
			} else {
				$keys = array_keys($this->getMapper()->getUniqueKeys());
				$this->select( $keys );
			}
		}
		
		$query = '';
						
		$query .= $operation.PHP_EOL;

		if (!empty($this->columns)) {
			$query .= implode(' , ', $this->columns).PHP_EOL;
		}

		if (!empty($this->from)) {
			$query .= ' FROM '.implode(' , ', $this->from).PHP_EOL;
		}
		
		if (!empty($this->join))
		{
			$joins = array();
            foreach ($this->join as $join) 
            {
            	$tmp = '';
                
            	if (! empty($join['type'])) {
                    $tmp .= $join['type'] . ' ';
                }
               
                $tmp .= 'JOIN ' . $join['table'];
                $tmp .= ' ON ' . implode(' AND ', $join['condition']);
           
                $joins[] = $tmp;
            }
            
            $query .= implode(PHP_EOL, $joins) .PHP_EOL;
		}

		if (!empty($this->where)) {
			//print implode(' ', $this->_where_statements);
			$where  = implode(' ', $this->where);
			$query .= ' WHERE '.$where.PHP_EOL;
		}

		if (!empty($this->group)) {
			$query .= ' GROUP BY '.implode(' , ', $this->group).PHP_EOL;
		}

		if (!empty($this->having)) {
			$query .= ' HAVING '.implode(' , ', $this->having).PHP_EOL;
		}
		
		if (!empty($this->order) ) 
		{
			$query .= 'ORDER BY ';
			
			$list = array();
            foreach ($this->order as $order) {
            	$list[] = $order['column'].' '.$order['direction'];
            }
            
            $query .= implode(' , ', $list) . PHP_EOL;
		}
		
		if (!empty($this->limit)) {
			$query .= ' LIMIT '.$this->offset.' , '.$this->limit.PHP_EOL;
		}
		
		$query = $this->getAdapter()->replaceTablePrefix( $query );
		
		return $query;
	}
}
Return current item: Anahita Social Engine