Search code examples
phpcakephpmodels

The correct way to set a default search value in CakePHP


I have a CakePHP Application with many many screens using data from a specific model. Most of the time, I need a specific field to be checked against (like the "user_active=>1" example in the cookbook), however I'd still like to be able to specify that field as a condition and override the default. My code works, but is this the best way to do this?

Also, the $queryData field is mixed — what are the possibilities other than array? just NULL?

<?php public function beforeFind($queryData) {
    if(is_array($queryData)) {
        //query data was an array
        if(!is_array($queryData['conditions'])) {
            $queryData['conditions'] = array('Course.semester_id'=>SEMESTER_ID);
        } else if (!isset($queryData['conditions']['Course.semester_id'])) {
            $queryData['conditions']['Course.semester_id'] = SEMESTER_ID;
        }
    }
} ?>

Solution

  • I would recommend making a custom findCourses($options) function in your model. That way, you can just set all the default conditions, and override any that were passed in $options.

    Here's an example:

    //Article model
    
    public function articles($opts = null) {
    
        //initialize
        $params = array();
        $findType = 'all';
        $params['conditions'] = array();
    
        //status
        if(!empty($opts['status'])) {
            array_push($params['conditions'], array('Article.status'=>$opts['status']));
        } else {
            array_push($params['conditions'], array('Article.status'=>1));
        }
    
        //id
        if(!empty($opts['id'])) {
            $params['limit'] = 1;
            $findType = 'first';
            array_push($params['conditions'], array('Article.id'=>$opts['id']));
        }
    
        //slug
        if(!empty($opts['slug'])) {
            $params['limit'] = 1;
            $findType = 'first';
            array_push($params['conditions'], array('Article.slug'=>$opts['slug']));
        }
    
        //limit (and find type)
        if(!empty($opts['limit'])) {
            $params['limit'] = $opts['limit'];
            if($opts['limit'] == 1) $findType = 'first';
        }
    
        //order by
        $params['order'] = array('Article.created DESC');
        if(!empty($opts['order'])) {
            $params['order'] = $opts['order'];
        }
    
        //type
        if(!empty($opts['type'])) {
            array_push($params['conditions'], array('type'=>$opts['type']));
        }
    
        //find type
        if(!empty($opts['find_type'])) $findType = $opts['find_type'];
    
        //slug
        if(!empty($opts['slug'])) {
            array_push($params['conditions'], array('slug'=>$opts['slug']));
        }
    
        //search
        if(!empty($opts['search'])) {
            array_push($params['conditions'], array('Article.title LIKE' => '%'.$opts['search'].'%'));
        }
    
        //contain
        $params['contain'] = array('MetaData', 'Tag', 'Upload');
    
        //paginate options or results
        if(!empty($opts['paginate'])) {
            return $params;
        } else {
            return $this->find($findType, $params);
        }
    
    }
    

    In my controller, I can just do this:

    $opts = array('limit'=>6, 'type'=>'gaming');
    $articles = $this->Article->articles($opts);