Location: PHPKode > projects > Porte > porte-0.2.2/src/plugins/Index.php
<?php

/**
 * Copyright (c) 2008, SARL Adaltas. All rights reserved.
 * Code licensed under the BSD License:
 * http://porte.adaltas.com/en/developer/license.html
 */

/**
 * PorteJson
 *
 * Add CSV import and export support to records or list of records by registering two new method "fromJson"
 * and "toJson" to each record.
 * 
 * @package    Porte
 * @subpackage plugin
 * @author     David Worms info(at)adaltas.com
 * @copyright  2008 Adaltas
 */
class PorteIndex{
	
	public static function loadByUnique(Porte $porte,$type,array $params,$options=array()){
		$model = $porte->models->$type;
		$uniques = PorteModel::getUniques($model);
		// Sanitize params
		//if(isset($params[$model['primary_key']]))
		//	unset($params[$model['primary_key']]);
		$query = array();
		foreach($uniques as $k=>$v){
			if(is_array($v)){
				// Ok, we just dont rely on primary key
				if(in_array($model['primary_key'], $v)) continue
				$subquery = array();
				foreach($v as $p){
					if(!isset($params[$p])) continue 2;
					$subquery[] = $model['properties'][$p]['field'].'=:'.$p;
				}
				$query[] = '('.implode(') AND (',$subquery).')';
			}else{
				// Skip if param does not exists or if it is equals to null
				if(!isset($params[$k])) continue;
				$query[] = $model['properties'][$k]['field'].' = :'.$k;
			}
		}
		if(empty($query)) return null;
		$query = '('.implode(') OR (',$query).')';
		$records = $porte->tables->{$type}->find($query,$params,$options);
		if($records instanceof PorteIterator){
			if(count($records)===1){
				return $records->current();
			}
			return null;
		}else{
			return $records;
		}
	}
	
	public static function _modelTableBefore(PorteModels $models,$type){
		foreach(array('index','unique') as $key){
			if(!empty($models->{$type}[$key])){
				if(!is_array($models->{$type}[$key])) throw new PorteException(PorteUtils::camelize($key).' is expected to be an array in model type: "'.$type.'"');
				foreach($models->{$type}[$key] as $k=>$v){
					unset($models->{$type}[$key][$k]);
					if($v===true&&is_string($k)){
						$v = explode(',',$k);
						$k = $v[0];
					}else if(is_array($v)){
						$v = array_keys($v);
					}
					if(is_string($v)) $v = explode(',',$v);
					else if(!is_array($v)) throw new Exception(PorteUtils::camelize($key).' are expected to be a string list or an array');
					if(is_int($k)) $k = $v[0];
					if(count($v)==1){
						if($key=='unique'&&isset($models->{$type}['index'][$v[0]])&&is_array($models->{$type}['index'][$v[0]])){
							// bypass since it is already sanitized
						}else if(isset($models->{$type}['properties'][$v[0]])){
							$models->{$type}['properties'][$v[0]][$key] = $k;
						}else{
							throw new PorteException(PorteUtils::camelize($key).' map to non existing property or index: "'.PorteUtils::toString($v[0]).'" in type "'.$type.'"');
						}
					}else{
						$models->{$type}[$key][$k] = ($key=='index')?array():true;
						if($key=='unique'&&!isset($models->{$type}['index'][$k])) $models->{$type}['index'][$k] = array();
						foreach($v as $property){
							if(!isset($models->{$type}['properties'][$property])) throw new PorteException(PorteUtils::camelize($key).' map to non existing property: '.PorteUtils::toString($property));
							$models->{$type}['index'][$k][] = $property;
						}
					}
				}
			}else{
				$models->{$type}[$key] = array();
			}
		}
		$properties = $models->{$type}['properties'];
		foreach($properties as $property=>$config){
			// Sanitixe unique & index
			if(!empty($config['unique'])){
				if(empty($config['index'])||$config['index']===true) $config['index'] = $config['unique'];
				$config['unique'] = true;
			}
			if(!empty($config['index'])){
				$config['index'] = is_string($config['index'])?$config['index']:$config['field'];
			}
			$models->{$type}['properties'][$property] = $config;
		}
	}
	
	public static function _tableUpdateAfter(PorteTable $table,array $existingFields){
		$model = $table->porte->models->{$table->type};
		$dbRawIndexes = $table->indexes();
		$dbFormatedIndexes = array();
		foreach($dbRawIndexes as $dbRawIndex){
			$dbFormatedIndexes[$dbRawIndex['Key_name']][] = $dbRawIndex['Column_name'];
		}
		unset($dbRawIndexes);
		foreach($model['index'] as $k=>$v){
			foreach($v as $vk=>$vv){
				$v[$vk] = $model['properties'][$vv]['field'];
			}
			if(isset($dbFormatedIndexes[$k])&&$dbFormatedIndexes[$k]==$v){
				// Index already exists and it din't change
				continue;
			}
			if(isset($dbFormatedIndexes[$k])&&$dbFormatedIndexes[$k]!=$v){
				// Index already exists but we need to update it
				$query = 'ALTER TABLE `'.$model['database'].'`.`'.$model['table'].'` DROP INDEX `'.$k.'`;';
				$table->porte->connection->exec($query);
			}
			$query = 'ALTER TABLE `'.$model['database'].'`.`'.$model['table'].'` ADD '.(isset($model['unique'][$k])?'UNIQUE':'INDEX').' `'.$k.'` (`'.implode('`,`',$v).'`);';
			$table->porte->connection->exec($query);
		}
	}
	
}

PorteEvents::connect('model_table_after',array('PorteIndex','_modelTableBefore'));
PorteEvents::connect('table_update_after',array('PorteIndex','_tableUpdateAfter'));

?>
Return current item: Porte