Jump to content

Returning repeater pages getForPage unless it's in trash?


a-ok
 Share

Recommended Posts

I'm a bit stuck with this search result setup.

$fieldsToSearch = 'title|text|textA|textarea|projectsCategories.title|projectsClients.title|aboutPressCategories.title|aboutPressClients.title';
$templatesToSearch = 'projectsSingle|shopSingle|typeSingle|typeCustomSingle|typeCustomSingleB|aboutPressSingle|repeater_modulesA';

$results = $pages->find("$fieldsToSearch%=$searchQuery, template=$templatesToSearch, sort=sort, check_access=0");

It should search all those templates (including the repeater). If the result is a repeater then it returns the `getForPage()`

foreach ($results as $result) {
	if ($result->template->name == 'repeater_modulesA') $result = $result->getForPage();
}

This is pretty straightforward. I just have an issue...

1. If the getForPage() is in the trash it's still getting returned (it shouldn't) but I guess that's because the repeater isn't in the trash.

Is there anything I can apply to the selector to avoid this? Or before I loop through $results should I do a check to remove any $result where status is trash?

$results = $pages->find("$fieldsToSearch%=$searchQuery, template=$templatesToSearch, sort=sort, check_access=0");
$results = $results->not("status<" . Page::statusTrash);

Thoughts? I guess the issue with the above is that it'll be checking the repeater for trash, not the getForPage().

Link to comment
Share on other sites

$results = $pages->find("$fieldsToSearch%=$searchQuery, template=$templatesToSearch, sort=sort, check_access=0");

$resultsToRemove = new PageArray();
foreach ($results as $result) {
	if ($result->template->name == 'repeater_modulesA' && ($result->getForPage()->is('unpublished') || $result->getForPage()->is('trash'))) {
		$resultsToRemove->add($result);
	}
}
$results = $results->not($resultsToRemove);

I had to end up doing the above. Maybe this is correct but seems a bit crazy.

Link to comment
Share on other sites

The normal way to match content in a Repeater is by searching the subfields of the Repeater.

Instead of...

my_field%=foo, template=repeater_my_repeater_field

...you would do...

my_repeater_field.my_field%=foo

That way you are matching the pages that contain the repeater field so you don't need getForPage(), plus you don't have to deal with the access restrictions on the Repeater template, unpublished repeater items, sorting of the container pages, etc.

 

10 hours ago, a-ok said:

$fieldsToSearch = 'title|text|textA|textarea|projectsCategories.title|projectsClients.title|aboutPressCategories.title|aboutPressClients.title';

Have you considered merging the text of all the fields you want to search into a hidden "index" textarea field? It's not too difficult to do this with a Pages::saveReady hook, but to make it really easy you can use the SearchEngine module which takes this approach. Doing this has the potential to solve the other issues you raised here and here (you could strip apostrophes from text that is saved to the index field).

  • Like 1
Link to comment
Share on other sites

14 hours ago, Robin S said:

That way you are matching the pages that contain the repeater field so you don't need getForPage(), plus you don't have to deal with the access restrictions on the Repeater template, unpublished repeater items, sorting of the container pages, etc.

 

Of course! That makes perfect sense. Doh.

Your method of merging all the relevant text to one field makes sense, also. Thanks and nice work! The only issue is if someone searched 'Kettle's' it wouldn't return, would it, as the text it's returning doesn't have the apostrophe?

Also, while I'm on the subject, has anyone attempted to implement a fuzzy search with PW?

Link to comment
Share on other sites

9 hours ago, a-ok said:

The only issue is if someone searched 'Kettle's' it wouldn't return, would it, as the text it's returning doesn't have the apostrophe?

You would strip apostrophes from the search input also. The general idea is you strip out any characters that shouldn't affect the search from both the input and the stored index.

9 hours ago, a-ok said:

Also, while I'm on the subject, has anyone attempted to implement a fuzzy search with PW?

There is discussion in this topic:

On one site I've implemented a fuzzy search that uses the Levenshtein distance with the approach described here, but it was done with plain SQL and searched only the title field. Using it on multiple fields has the potential to generate a huge number of queries so performance could become an issue.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...