Search with two fields not mandatory

落爺英雄遲暮 提交于 2019-12-24 21:57:58

问题


I'd like to do a search function in my website. This research will show products based on product's name and seller's location. My view :

<?php echo $this->Form->create('Product', array('type' => 'GET')); ?>

<div class="col col-sm-4">
    <?php echo $this->Form->input('search', array('label' => false, 'div' => false, 'class' => 'form-control', 'autocomplete' => 'off', 'value' => $search)); ?>
</div>
    <div class="col col-sm-2">
        <?php echo $this->Form->input('searchCity', array('label' => false, 'div' => false, 'class' => 'form-control', 'autocomplete' => 'off')); ?>
    </div>
<div class="col col-sm-3">
    <?php echo $this->Form->button('Search', array('div' => false, 'class' => 'btn btn-sm btn-primary')); ?>
</div>

<?php echo $this->Form->end(); ?>

Two search fields : one for the name and the second for location.

My controller (worked for only one search field) :

if(!empty($this->request->query['search']) || !empty($this->request->data['name'])) {
        $search = empty($this->request->query['search']) ? $this->request->data['name'] : $this->request->query['search'];
        $search = preg_replace('/[^a-zA-Z0-9 ]/', '', $search);
        $terms = explode(' ', trim($search));
        $terms = array_diff($terms, array(''));
        $conditions = array(
            'Brand.active' => 1,
            'Product.active' => 1,
            'Product.date_discount >' => date('Y-m-d H:i:s')
        );
        foreach($terms as $term) {
            $terms1[] = preg_replace('/[^a-zA-Z0-9]/', '', $term);
            $conditions[] = array(
                'OR' => array(
                    array('Product.name LIKE' => '%' . $term . '%'),
                    //array('Brand.city LIKE' => '%' . $this->request->query['searchCity'] . '%')
                )
            );
        }
        $products = $this->Product->find('all', array(
            'recursive' => -1,
            'contain' => array(
                'Brand'
            ),
            'conditions' => $conditions,
            'limit' => 200,
        ));
        if(count($products) == 1) {
            return $this->redirect(array('controller' => 'products', 'action' => 'view', 'slug' => $products[0]['Product']['slug']));
        }
        $terms1 = array_diff($terms1, array(''));
        $this->set(compact('products', 'terms1'));
    }

No search fields are mandatory. If only name search field, it will show all products based on product's name whatever the location. If only city search field, it will show all products in location. If both, it will show all products based on name and location.

I don't know what to modify to do it. I tried to do another if(!empty($this->request->query['searchCity']) under the if I posted above but it didn't work (copy paste the first if and I changed conditions). What should I do?

Thanks.


回答1:


You can use this CakeDC Search plugin

First include the plugin in your app

CakePlugin::load('Search');

Then in your model include the behavior

public $actsAs = array(
   'Search.Searchable'
);

and

public $filterArgs = array(
    'search' => array(
        'type' => 'like'
    ),
    'searchcity' => array(
        'type' => 'like'
    )
);

and in your controller

public $components = array(
    'Search.Prg','Paginator'
);

public function find() {
    $this->Prg->commonProcess();
    $this->Paginator->settings['conditions'] = $this-> Product->parseCriteria($this->passedArgs);
    $this->set('products', $this->Paginator->paginate());
}

For complete example visit here




回答2:


I'm unable to understand exactly what is being asked but from what I understand, the OR condition didn't work as expected and that is because there is a small problem with the syntax used in your $conditions. Additional arrays used for each field in conditions are not required, which is causing the problem. So,

instead of:

$conditions[] = array(
    'OR' => array(
        array('Product.name LIKE' => '%' . $term . '%'),
        array('Brand.city LIKE' => '%' . $this->request->query['searchCity'] . '%')
    )
);

use:

$conditions[] = array(
    'OR' => array(
        'Product.name LIKE' => '%' . $term . '%',
        'Brand.city LIKE' => '%' . $this->request->query['searchCity'] . '%'
    )
);

Also, use two different variables for static conditions and dynamic conditions(with $terms in foreach()) and then combine them using array_combine like this:

$conditions_st = array(
    'Brand.active' => 1,
    'Product.active' => 1,
    'Product.date_discount >' => date('Y-m-d H:i:s')
);


foreach($terms as $term) {
    $terms1[] = preg_replace('/[^a-zA-Z0-9]/', '', $term);
    $conditions_dy = array(
        'OR' => array(
            'Product.name LIKE' => '%' . $term . '%',
            'Brand.city LIKE' => '%' . $this->request->query['searchCity'] . '%'
        )
    );
}

$conditions = array_combine($conditions_st, $conditions_dy);

P.S: i just scanned through your code, and couldn't quite understand what you are trying to do. I just highlighted the problems I noticed.



来源:https://stackoverflow.com/questions/33495110/search-with-two-fields-not-mandatory

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!