Skip to content
Snippets Groups Projects
Commit 9725a14b authored by Benoit Socias's avatar Benoit Socias
Browse files

[FIX] website: apply page search on most specific pages only

Since [1] when the fuzzy search was introduced on website pages, the
filtering on most specific pages only happens at the end of the search
operation. Because of this, the search happens on pages that would be
excluded anyway, the limit might be wrongly applied and the count might
be wrong.

This commit makes the page search begin by keeping only the most
specific pages, then performing the actual search within those pages.

Steps to reproduce:
- Install `website` only and drop a search snippet.
- Search "ax".

=> No results found, but the "All results" link is displayed.

[1]: https://github.com/odoo/odoo/commit/7559626c54e34b41e1549e28276a650accec6986



task-3203794

closes odoo/odoo#120881

X-original-commit: 5ad049f5
Signed-off-by: default avatarArthur Detroux (ard) <ard@odoo.com>
parent a3cc14e4
No related branches found
No related tags found
No related merge requests found
......@@ -226,39 +226,51 @@ class Page(models.Model):
@api.model
def _search_fetch(self, search_detail, search, limit, order):
with_description = 'description' in search_detail['mapping']
results, count = super()._search_fetch(search_detail, search, limit, order)
# Cannot rely on the super's _search_fetch because the search must be
# performed among the most specific pages only.
fields = search_detail['search_fields']
base_domain = search_detail['base_domain']
domain = self._search_build_domain(base_domain, search, fields, search_detail.get('search_extra'))
most_specific_pages = self.env['website']._get_website_pages(
domain=expression.AND(base_domain), order=order
)
results = most_specific_pages.filtered_domain(domain) # already sudo
if with_description and search:
# Perform search in translations
# TODO Remove when domains will support xml_translate fields
query = sql.SQL("""
SELECT {table}.id
SELECT DISTINCT {table}.id
FROM {table}
LEFT JOIN ir_ui_view v ON {table}.view_id = v.id
WHERE v.name ILIKE {search}
OR COALESCE(v.arch_db->>{lang}, v.arch_db->>'en_US') ILIKE {search}
WHERE (v.name ILIKE {search}
OR COALESCE(v.arch_db->>{lang}, v.arch_db->>'en_US') ILIKE {search})
AND {table}.id IN {ids}
LIMIT {limit}
""").format(
table=sql.Identifier(self._table),
search=sql.Placeholder('search'),
lang=sql.Literal(self.env.lang or 'en_US'),
ids=sql.Placeholder('ids'),
limit=sql.Placeholder('limit'),
)
self.env.cr.execute(query, {
'search': '%%%s%%' % escape_psql(search),
'limit': limit,
'ids': tuple(most_specific_pages.ids),
'limit': len(most_specific_pages.ids),
})
ids = {row[0] for row in self.env.cr.fetchall()}
ids.update(results.ids)
domains = search_detail['base_domain'].copy()
domains.append([('id', 'in', list(ids))])
domain = expression.AND(domains)
model = self.sudo() if search_detail.get('requires_sudo') else self
results = model.search(
domain,
limit=limit,
order=search_detail.get('order', order)
)
count = max(count, len(results))
if ids:
ids.update(results.ids)
domains = search_detail['base_domain'].copy()
domains.append([('id', 'in', list(ids))])
domain = expression.AND(domains)
model = self.sudo() if search_detail.get('requires_sudo') else self
results = model.search(
domain,
limit=len(ids),
order=search_detail.get('order', order)
)
def filter_page(search, page, all_pages):
# Search might have matched words in the xml tags and parameters therefore we make
......@@ -266,11 +278,9 @@ class Page(models.Model):
text = '%s %s %s' % (page.name, page.url, text_from_html(page.arch))
pattern = '|'.join([re.escape(search_term) for search_term in search.split()])
return re.findall('(%s)' % pattern, text, flags=re.I) if pattern else False
if 'url' not in order:
results = results._get_most_specific_pages()
if search and with_description:
results = results.filtered(lambda result: filter_page(search, result, results))
return results, count
return results[:limit], len(results)
def action_page_debug_view(self):
return {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment