soySearch->getCriteria($criteria=array()); * 3. $results = $this->Model->findAll($criteria); * * @author Russell Austin (soytuny) * @version 0.1.0 * @license MIT */ class soySearchComponent extends Object { function startup(&$controller) { $this->controller =& $controller; } function init($searchConfig = null) { } function getCriteria($criteria=null) { $newSearch = 1; if(isset($_GET['newSearch']) && $_GET['newSearch'] == 0) { $newSearch = 0; } // get the models and fields from the $uses array foreach($this->controller->modelNames as $modelName) { foreach($this->controller->{$modelName}->_tableInfo->value as $col) { $searchFields[$modelName][$col['name']] = $col; } // get extra models and fields from the associations foreach($this->controller->{$modelName}->hasAndBelongsToMany as $instanceName => $relatedModel) { $searchFields[$modelName][$relatedModel['associationForeignKey']] = array('type'=>'multi', 'joinTable'=>$relatedModel['joinTable'], 'foreignKey'=>$relatedModel['foreignKey']); } } if(isset($this->controller->data['Search'])) { foreach($this->controller->data['Search'] as $name => $value) { list($model, $field) = explode('.', $name); $savedSearch = array(); if(!empty($searchFields[$model][$field])) { switch($searchFields[$model][$field]['type']) { case 'string': case 'text': $savedSearch[$name] = 'LIKE %'.$value.'%'; break; case 'integer': case 'float': // This logic allows for ranged searches. If the field is present and the field name with "__from" and/or "__to" extensions // the search will be limited to that range if(!empty($this->controller->data['Search'][$name]) && is_numeric($this->controller->data['Search'][$name])) $this->controller->data['Search'][$name.'__from'] = $this->controller->data['Search'][$name]; if(empty($this->controller->data['Search'][$name.'__from']) || !is_numeric($this->controller->data['Search'][$name.'__from'])) $this->controller->data['Search'][$name.'__from'] = 0; else $this->controller->data['Search'][$name.'__from'] = $this->controller->data['Search'][$name.'__from']; if(empty($this->controller->data['Search'][$name.'__to'])) $this->controller->data['Search'][$name.'__to'] = 9999999999; $savedSearch[$name.'__from'] = '>= '.$this->controller->data['Search'][$name.'__from']; $savedSearch[$name.'__to'] = '<= '.$this->controller->data['Search'][$name.'__to']; break; case 'boolean': $savedSearch[$name] = $value; break; case 'date': case 'datetime': // Allow for ranged searches. if(!empty($this->controller->data['Search'][$name]) && is_numeric(strtotime($this->controller->data['Search'][$name]))) $this->controller->data['Search'][$name.'__from'] = $this->controller->data['Search'][$name]; if(empty($this->controller->data['Search'][$name.'__from']) || !is_numeric(strtotime($this->controller->data['Search'][$name.'__from']))) $this->data['Search'][$name.'__from'] = '1979-01-01 00:00:00'; else $this->controller->data['Search'][$name.'__from'] = $this->controller->data['Search'][$name.'__from']; if(empty($this->controller->data['Search'][$name.'__to'])) $this->controller->data['Search'][$name.'__to'] = date('Y-m-d 23:59:59', strtotime('20 years')); $savedSearch[$name."__from"] = ">= ".$this->controller->data['Search'][$name.'__from']; $savedSearch[$name."__to"] = "<= ".$this->controller->data['Search'][$name.'__to']; break; case 'multi': $savedSearch[$name] = $model.'.id IN (SELECT '.$searchFields[$model][$field]['foreignKey'].' FROM '.$searchFields[$model][$field]['joinTable'].' WHERE '.$name.' IN ('.implode(',',$value).'))'; break; } // at this piont I have collected the criteria for that field // now I save it and add it to the overall criteria string if($mode = 'session') { foreach($savedSearch as $n => $v) { $this->controller->Session->write('Search.'.$n.'.criteria', $v); if(substr($n, -4) == '__to') $n = substr($n, 0, -4); if(substr($n, -6) == '__from') $n = substr($n, 0, -6); $criteria[] = array($n=>$v); if(isset($this->controller->data['Search'][$n])) { $this->controller->Session->write('Search.'.$n.'.value', $this->controller->data['Search'][$n]); } } } } else { // clear any fields they did not fill out if($this->controller->Session->check("Search.$name")) { $this->controller->Session->del("Search.$name"); } } } } elseif(!$newSearch) { if($this->controller->Session->check('Search')) { $savedSessionSearch = $this->controller->Session->read('Search'); foreach($savedSessionSearch as $model => $fields) { foreach($fields as $field => $value) { $criteria[] = $value['criteria']; $this->controller->data['Search']["$model.$field"] = $value['value']; } } } } return $criteria; } } ?>