cnizzardini / cakephp-datatable

CakePHP Component for interoperability between CakePHP 2.x and jQuery DataTables plugin.
62 stars 49 forks source link

Filtering on belongsTo fields in containable #13

Open drjaydenm opened 10 years ago

drjaydenm commented 10 years ago

I have found that this component does not correctly allow you to search on containable belongsTo fields as it adds the search conditions to the conditions of the model in the containable. I have fixed this as below

// check for WHERE statement in GET request
    if(isset($httpGet) && !empty($httpGet['sSearch'])){
        $conditions = $this->getWhereConditions();
        //debug($conditions);

        $this->controller->paginate = array_merge_recursive($this->controller->paginate, array('conditions'=>$conditions));

        if( !empty($this->controller->paginate['contain']) ){
            // Apply the conditions to the root model fields
            $fields = !empty($this->fields) ? $this->fields : $this->controller->paginate['fields'];

            $modelConditions = array();
            foreach($fields as $x => $column){
                // Check that the field is searchable
                if( $this->controller->request->query['bSearchable_'.$x] == 'true'){
                    list($table, $field) = explode('.', $column);

                    // Check that the field is part of the root model with or without the model name appended
                    if (($table == $this->model->name && in_array($field, $this->controller->paginate['fields'])) || in_array($column, $this->controller->paginate['fields'])){
                        $modelConditions[] = $column.' LIKE "%'.$this->controller->request->query['sSearch'].'%"';
                    }
                }
            }

            $this->controller->paginate = array_merge_recursive($this->controller->paginate, array('conditions'=>array("OR" => $modelConditions)));
        }
        else{
            $this->controller->paginate = array_merge_recursive($this->controller->paginate, array('conditions'=>$conditions));
        }
        //debug($this->controller->paginate);
        $isFiltered = true;
    }

It was also not adding the conditions for the base model when using containable which was fixed as below in the getWhereConditions() function

// only create conditions on bSearchable fields
        if( $this->controller->request->query['bSearchable_'.$x] == 'true' ){

            list($table, $field) = explode('.', $column);

            // attempt using definitions in $model->validate to build intelligent conditions
            if( $this->conditionsByValidate == 1 && array_key_exists($column,$this->model->validate) ){

                if( !empty($this->controller->paginate['contain']) ){
                    if(array_key_exists($table, $this->controller->paginate['contain']) && in_array($field, $this->controller->paginate['contain'][$table]['fields'])){
                        $conditions['OR'][] = $this->conditionByDataType($column);
                    }
                }
                else{
                    $conditions['OR'][] = $this->conditionByDataType($column);
                }
            }
            else{

                if( !empty($this->controller->paginate['contain']) ){
                    // Check if the table and field are in the contain
                    if(array_key_exists($table, $this->controller->paginate['contain']) && in_array($field, $this->controller->paginate['contain'][$table]['fields'])){
                        $conditions['OR'][] = $column.' LIKE "%'.$this->controller->request->query['sSearch'].'%"';
                    }
                }
                else{
                    $conditions['OR'][] = array(
                        $column.' LIKE' => '%'.$this->controller->request->query['sSearch'].'%'
                    );
                }
            }
        }
cnizzardini commented 10 years ago

Nice work, I'll have to test this out at some time. You could always do a pull request or whatever as well. I didn't work too hard on containable because containable frankly sucks. It's very slow. It accesses the databases the way a novice programmer would IMO.

aurelioth commented 8 years ago

Have to fix this for containable search.

// Check that the field is searchable if(isset($this->controller->request->query['bSearchable'.$x]) and $this->controller->request->query['bSearchable'.$x] == 'true')

Also notice that model fields must be at this version like ModelName.field, otherwise there is an error.

fr0z3nfyr commented 7 years ago

Closely related issue #35