<?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'));
?>