private function searchSingleContentType($query, $contenttype, $fields, array $filter = null, $implode = false)
{
// This could be even more configurable
// (see also Content->getFieldWeights)
$searchableTypes = ['text', 'textarea', 'html', 'markdown'];
$table = $this->getContenttypeTablename($contenttype);
if ($implode) {
$query['words'] = [implode(' ', $query['words'])];
}
// Build fields 'WHERE'
$fieldsWhere = [];
foreach ($fields as $field => $fieldconfig) {
if (in_array($fieldconfig['type'], $searchableTypes)) {
foreach ($query['words'] as $word) {
$fieldsWhere[] = sprintf('%s.%s LIKE %s', $table, $field, $this->app['db']->quote('%' . $word . '%'));
}
}
}
// make taxonomies work
$taxonomytable = $this->getTablename('taxonomy');
$taxonomies = $this->getContentTypeTaxonomy($contenttype);
$tagsWhere = [];
$tagsQuery = '';
foreach ($taxonomies as $taxonomy) {
if ($taxonomy['behaves_like'] == 'tags') {
foreach ($query['words'] as $word) {
$tagsWhere[] = sprintf('%s.slug LIKE %s', $taxonomytable, $this->app['db']->quote('%' . $word . '%'));
}
}
}
// only add taxonomies if they exist
if (!empty($taxonomies) && !empty($tagsWhere)) {
$tagsQueryA = sprintf("%s.contenttype = '%s'", $taxonomytable, $contenttype);
$tagsQueryB = implode(' OR ', $tagsWhere);
$tagsQuery = sprintf(' OR (%s AND (%s))', $tagsQueryA, $tagsQueryB);
}
// Build filter 'WHERE"
// @todo make relations work as well
$filterWhere = [];
if (!is_null($filter)) {
foreach ($fields as $field => $fieldconfig) {
if (isset($filter[$field])) {
$filterWhere[] = $this->parseWhereParameter($table . '.' . $field, $filter[$field]);
}
}
}
// Build actual where
$where = [];
$where[] = sprintf("%s.status = 'published'", $table);
$where[] = '(( ' . implode(' OR ', $fieldsWhere) . ' ) ' . $tagsQuery . ' )';
$where = array_merge($where, $filterWhere);
// Build SQL query
$select = sprintf('SELECT %s.id FROM %s LEFT JOIN %s ON %s.id = %s.content_id WHERE %s GROUP BY %s.id', $table, $table, $taxonomytable, $table, $taxonomytable, implode(' AND ', $where), $table);
// Run Query
$results = $this->app['db']->fetchAll($select);
if (!empty($results)) {
$ids = implode(' || ', array_column($results, 'id'));
$results = $this->getContent($contenttype, ['id' => $ids, 'returnsingle' => false]);
// Convert and weight
foreach ($results as $result) {
$result->weighSearchResult($query);
}
}
return $results;
}