For anyone interested, I ended up doing the following:
- Add a new
SearchController
on my Plugin with ashow
-view, which is an adapted version of the search-View on theNodesController
. - Override the
search/*
route with my new view.
In order to search in the translated fields, I came with 2 possible approaches:
1) If using only the paginate for this, then there would be necessary to join the node and the i18n tables, first And then look for the string additionally on the joined fields.
2) Or, first find all distinct nodes with matching content on the i18n table through a query. And then use this list of nodes to add condition of "OR Node.id in (list_of_nodes)
"
I ended up with alternative 2, and this is how the show-view looks like:
public function show() {
if (!isset($this->request->params['named']['q'])) {
$this->redirect('/');
}
App::uses('Sanitize', 'Utility');
$q = Sanitize::clean($this->request->params['named']['q']);
$results = $this->Node->query(
"SELECT DISTINCT(foreign_key) FROM `i18n` " .
"WHERE content LIKE '%" . $q . "%';");
$node_ids = array();
foreach($results as $res) {
$node_ids[] = $res['i18n']['foreign_key'];
}
$this->paginate['Node']['order'] = 'Node.created DESC';
$this->paginate['Node']['limit'] = Configure::read('Reading.nodes_per_page');
$this->paginate['Node']['conditions'] = array(
'Node.status' => 1,
'AND' => array(
array(
'OR' => array(
'Node.title LIKE' => '%' . $q . '%',
'Node.excerpt LIKE' => '%' . $q . '%',
'Node.body LIKE' => '%' . $q . '%',
'Node.id' => $node_ids,
),
),
array(
'OR' => array(
'Node.visibility_roles' => '',
'Node.visibility_roles LIKE' => '%"' . $this->Croogo->roleId . '"%',
),
),
),
);
// some more stuff ...
}