Jump to content

Searching for numbers throws Exception: Operator '~=' is not implemented


joe_ma
 Share

Recommended Posts

Hi

I have the following code in search.php (modified from the original one):

<?php
// look for a GET variable named 'q' and sanitize it
$q = $sanitizer->text($input->get->q); 
// did $q have anything in it?
if($q) { 
	$input->whitelist('q', $q); 
	$q = $sanitizer->selectorValue($q); 

	// Search the given fields for our query text.
	// Limit the results to 50 pages. 
	$selector = "headline|title|body|sidebar|untertitel|mitwirkende|moderator~=$q, limit=50, template=event|basic-page|kontakt"; 
	if($user->isLoggedin()) $selector .= ", has_parent!=2"; 

	// Find pages that match the selector
	$matches = $pages->find($selector); 

	// did we find any matches?
	if($matches->count) {
		// yes we did: output a headline indicating how many were found.
		// note how we handle singular vs. plural for multi-language, with the _n() function
		$content = "<h2>$matches->count Seite(n) gefunden, die Ihren Suchkriterien entspricht/entsprechen:</h2>";
	
		// create dt-list with results
		$content .= "<dl>";
		foreach ($matches as $m){
					$content .= "<dt><a href='{$m->url}?searched={$q}'>$m->title</a></dt>";
							if(strlen($m->body) > 250) { //Limit text to 250 signs and whole words
							 $m->body = substr($m->body,0,250).'…';
						     $string_ende = strrchr($m->body, ' ');
	        				 $m->body = str_replace($string_ende," …", $m->body); //
							}
							$content .= "<dd><span><a href='{$m->url}?searched={$q}'>URL: $m->url</a></span><br>" . strip_tags($m->body) . "</dd>";		
		}
		$content .= "</dl>";

	} else {
		// we didn't find any
		$content = "<h2>" . __('Sorry, no results were found.') . "</h2>";
	}
} else {
	// no search terms provided
	$content = "<h2>" . __('Please enter a search term in the search box (upper right corner)') . "</h2>";
}

Now everything works fine with any search terms, except numbers. When I search for numbers, I get the following error:

  Quote

Error: Exception: Operator '~=' is not implemented in (in /…/wire/modules/Fieldtype/FieldtypePage.module line 590)

Expand  

Thanks for your help.

 

Link to comment
Share on other sites

  On 9/7/2016 at 10:45 AM, joe_ma said:

$selector = "headline|title|body|sidebar|untertitel|mitwirkende|moderator~=$q, limit=50, template=event|basic-page|kontakt";

Expand  

One or more of these fields in your selector must be Page fields. If you are trying to match the title of the selected page(s) in your search then use a subfield selector for the page title. For example, instead of...

$selector = "my_page_field~=$q";

...do...

$selector = "my_page_field.title~=$q";

I suspect that otherwise PW thinks that you might be trying to match the page ID to the number in your search query, which doesn't allow a ~= operator.

  • Like 3
Link to comment
Share on other sites

So the structure of the site is like this:

- event (template: event)

      - event date (template: event_date)

      - event date (template: event_date)

     …

Each child of event has a unique event number that is also its title. But the children are not viewable, because they are listed in a table. I like the titles (i.e. the event numbers) of the children also to be searchable. So I tried this

	$selector = "headline|title|body|sidebar|untertitel|mitwirkende.title|moderator.title~=$q, limit=50, template=event|basic-page|kontakt"; 
	
	$eventNr = $pages->get("title~=$q, template=event_date");  //Subpage that has title equal to query (not viewable)
	$eventParent = $eventNr->parent;  // Get the parent (viewable) of this subpage
	if($user->isLoggedin()) $selector .= ", has_parent!=2"; 

	// Find pages that match the selector
	$matches = $pages->find($selector); 
	if($eventParent){ 
	$matches->add($eventParent);
	}
    // rest see original post

That works fine, but lists also pages from the trash.

How can I exclude the trash?

Link to comment
Share on other sites

The reason you are seeing pages from the trash is because you are using $pages->get() which returns a page regardless of access or status.

Besides Adrian's suggestion you could use $pages->findOne() instead of $pages->get().

But I think the way you are adding a match to your $pages->find() result is going to cause a problem with your pagination - the additional match will appear on every page of results. The only way I can think of getting around this is to make the child page titles a property of the parent page so that parent page can be matched directly in your selector. Unfortunately there isn't a "has_child" feature similar to "has_parent". So perhaps make a page field in your event template and automatically add and remove child pages from it with hooks. Or use a PageTable or Repeater field for your event_date pages and only add event dates via this field.

  • Like 2
Link to comment
Share on other sites

OK, thank you very much for these clarifications.

I think in this case pagination won't be a problem, because there will not be more than up to ten results anyway. So I probably stick with my solution.

Thank you both for your help.

Link to comment
Share on other sites

  • 1 year later...

This is an older thread, but since I have a problem that's related to this I figured I'd post in here. I am having the same problem with search. I want the search field to include the names of authors, but this causes an error when you type in a number. Here's part of the selector I use:

$selector .= ", title|subtitle|summary|body|product_isbn|authors.authors_name%=$q_word";

The problem is with authors.authors_name -- this is a repeater field (authors) and authors_name is a PageArray. Now, when you type in a number, ProcessWire gets confused and thinks you might be asking for an ID (as explained earlier in this thread). Obviously, this is not what I want -- people should be able to e.g. search for an ISBN (as you can see in the list) or something similar.

How can I ensure that ProcessWire searches through the proper fields of authors_name? Ideally, it would be the fields title, name_first, or name_last. I tried doing this:

$selector .= ", title|subtitle|summary|body|product_isbn|authors.authors_name.title%=$q_word";

But that didn't work. Any ideas? Thank you!

Link to comment
Share on other sites

  On 11/3/2017 at 8:25 AM, JoshoB said:

authors_name is a PageArray

Expand  

What sort of field is authors_name? A Page Reference field? If so you should be able to match against the title of the referenced page with:

authors.authors_name.title%=$q_word

I'm curious about the setup of the authors field. The authors field is a Repeater, and then inside that Repeater is a Page Reference field, and the selectable pages of that field contain name fields for the author? Why so complex? Wouldn't it be possible to remove one of these levels and use either a Repeater or a Page Reference field for author?

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  On 11/3/2017 at 8:03 PM, Robin S said:

I'm curious about the setup of the authors field. The authors field is a Repeater, and then inside that Repeater is a Page Reference field, and the selectable pages of that field contain name fields for the author? Why so complex? Wouldn't it be possible to remove one of these levels and use either a Repeater or a Page Reference field for author?

Expand  

Hi Robin. It's complex because there's no other way to do this, I think. Here's an overview of the structure:

  • The page in question is a book (template=product) with a repeater field called "authors".
  • Each element of the repeater field is a block: a PageArray that lists all authors (with template=author) under /authors, plus three checkboxes (to indicate that the author is actually an editor and/or a translator and/or writer of the book's introduction).
  • Since a book often has more than one writer (and/or editor, translator, etc.) I need the ability to add multiple instances of this block, hence the repeater field.

In addition, because the author is a page, I can load that author's page and then list all books associated with that author on his/her page (using $pages->find). I find that advantageous. I also dislike having to re-enter data twice, so by using a PageArray I can (a) see if the author is already in the database and (b) if so, add him/her to the field or (c) otherwise create a page for that author. This has the added benefit of making sure that author names are consistent across the site (e.g. no "J. Smith", "John Smith", "John J. Smith", etc. that are actually all the same writer).

Link to comment
Share on other sites

  On 11/12/2017 at 2:03 PM, JoshoB said:

It's complex because there's no other way to do this, I think.

Expand  

Got it.

If you have ProFields then Table could be a good alternative to a Repeater that avoids the overhead of extra pages.

  On 11/12/2017 at 2:03 PM, JoshoB said:

a PageArray that lists all authors

Expand  

A PageArray is not a type of field, but several fieldtypes return their value as a PageArray. Repeater, PageTable and "multiple" Page Reference fields all return PageArrays. I think you are meaning a Page Reference field. If so, did you manage to get it working? I tested it and you should be able to match the title of a page inside a Page Reference field inside a Repeater with:

authors.authors_name.title%=$q_word

 

  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...
  On 11/12/2017 at 8:05 PM, Robin S said:

I think you are meaning a Page Reference field.

Expand  

Yes, that's what I mean; sorry! I didn't get the chance yet to test it. I have to tinker with the website next Tuesday anyway (add a newsletter page), so I'll try it then and see if it works (and post an update here).

Thanks! :-)

Link to comment
Share on other sites

  • 2 weeks later...

Hello again!

Sorry for the delay. I finally got around to trying this:

authors.authors_name.title%=$q_word

But get an error: Error: Exception: Multi-dot 'a.b.c' type selectors may not be used with OR '|' fields

Guess it's a bit too complex the way that it is now, with pipes (OR) between the different fields. The way it is now (see above) works, even though I have PHP skip numbers that the user may have entered (since I don't think that will be too much of a problem).

I should probably buy the ProFields module at some point: the Table Fieldtype looks extremely useful.

Link to comment
Share on other sites

  • 2 years later...

@Robin S

Sorry to bring this back up.

$fieldsToSearch = 'name|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");

I am getting a `Operator '%=' is not implemented in FieldtypePage` error when searching for numbers, also. However, my Page Reference Fields should all be searching `.title`?

Link to comment
Share on other sites

It would appear `name` was throwing this off.

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

Works fine.

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...