Reputation: 466
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.
Upvotes: 0
Views: 92
Reputation: 1290
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
Upvotes: 1
Reputation: 1939
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.
Upvotes: 0