Here is the initialize function in my table “ForumPostsTable”:
$this->addBehavior('Search.Search'); //FriendsOfCakePlugin
$this->searchManager()
->value('user_id')
// Here we will alias the 'keywords' query param to search the `ForumPost.subject`
// field and the `ForumPost.body` field, using a LIKE match, with `%`
// both before and after.
->add('keywords', 'Search.Like', [
'before' => true,
'after' => true,
'fieldMode' => 'OR',
'comparison' => 'LIKE',
'wildcardAny' => '*',
'wildcardOne' => '?',
'field' => ['subject', 'body']
]);
The ‘field’ value is actually to be defined by the ‘keywordsOption’ of my querystring.
I am trying to use the ‘Search.Callback’ filter to do so, but I did not succeed so far.
Here is how my querystring looks like:
http://compte.sandbox.com/forum/search?keywords=bin&keywordsOption=1&periodStart=6&periodDirection=1
How to use ‘callback’:
->add('keywordsOption', 'Search.Callback', [
'callback' => function ($query, $args, $filter) {
if($args['keywordsOption'] == 1) {
$fields = ['subject'];
} else {
$fields = ['subject', 'body'];
}
// Modify $query as required
//$what to write here?
return $what;
}
]);
Thankyou
raul338
February 18, 2018, 3:35pm
2
I didn’t found a way to mix filters with conditionals in callback, so I forced a simple where
$manager->callback('cotizacion', [
'callback' => function (Query $query, $args, $filter) {
$busqueda = $args['cotizacion'];
if ($busqueda == -1) {
$query
->leftJoinWith('Cotizaciones')
->where([
'Cotizaciones.id IS' => null,
]);
return true;
}
$query
->innerJoinWith('Cotizaciones')
->where([
'Cotizaciones.estado_id' => $busqueda,
]);
return true;
}
]);
NOTE : Table names are in spanish, I use special inflector rules to do it, it does not always work by default
Thanks raul338 for your answer - I made it through the spanish words
I did something close to it:
In initialize()
$this->addBehavior(‘Search.Search’); //FriendsOfCakePlugin
$this->searchManager()
->value(‘author’, [
‘field’ => ‘user_id’])
->add('keywordsOption', 'Search.Callback', [
'callback' => function ($query, $args, $manager) {
$options = $query->getOptions();
$criteria = $options['search'];
$conditions = $this->getConditions($criteria);
return $query->applyOptions([
'conditions' => $conditions
]);
}
]);
My getConditions Method in the ForumPostsTable.php:
public function getConditions($criteria = null) {
$conditions = [];
//Début - Recherche sur un ou plusieurs mots clés
if(isset($criteria['keywords']) && ($criteria['keywords'] !== '')) {
//explode la string
$searchTerms = explode(" ", $criteria['keywords']);
$myQuery = [];
if($criteria['keywordsOption'] == 2) { //uniquement dans le titre
foreach ($searchTerms as $key => $searchTerm) {
$myQuery[] = ['ForumPosts.subject LIKE' => '%' . $searchTerm . '%'];
}
} else {
foreach ($searchTerms as $key => $searchTerm) {
$myQuery[] = ['OR' =>
['ForumPosts.subject LIKE' => '%' . $searchTerm . '%',
'ForumPosts.body LIKE' => '%' . $searchTerm . '%'],
];
}
}
$myQuery = [
'AND' => $myQuery
];
$conditions[] = $myQuery;
}
// Fin - Recherche sur un ou plusieurs mots clés
//Début - Recherche sur une période
if($criteria['periodStart'] != 7) {
$options['periodMatrix'] = [
1 => '-1 day',
2 => '-7 days',
3 => '-1 month',
4 => '-3 months',
5 => '-6 months',
6 => '-12 months',
];
if($criteria['periodDirection'] == 1) {
//et aprés
$conditions[] = ['ForumPosts.modified >=' => New Time($options['periodMatrix'][$criteria['periodStart']])];
} else {
//et avant
$conditions[] = ['ForumPosts.modified <=' => New Time($options['periodMatrix'][$criteria['periodStart']])];
}
}
//Début - Recherche sur une période
//Début - Recherche sur une ou plusieurs catégories
if(isset($criteria['category']) && is_array($criteria['category'])) {
$conditions[] = ['ForumPosts.forum_category_id IN' => $criteria['category']];
}
//Fin - Recherche sur une ou plusieurs catégories
return $conditions;
}
I hope this could help someone.