[SOLVED] FOC Search plugin : howto use callback to modify filter

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

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 :slight_smile:

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.