Jump to content

Return validated & cleaned selector string.


Martijn Geerts
 Share

Recommended Posts

In a page I have a field that i want to use as a selector string. 

I want the dirty string to be cleaned ( strip out all invalid parts ).

So processWire will never throw an error.

This is what I came-up with, but there must be a better way.

/**
 * Clean a Dirty selector string
 * @param (string) $string, Dirty ProcessWire selector string.
 * @return (string) Cleaned ProcessWire selector string.
 */
function returnValidSelector( $string ) {

	$out = '';

	if(strlen($string)) {

		$exclude = array();
		$explode = explode(",", $string);
		
		foreach ($explode as $value) {

			$value = trim($value);

			if(!Selectors::stringHasSelector($value)) continue;

			// string or array
			if(preg_match('/^(!?[_|.a-zA-Z0-9]+)(.*)/', $value, $matches)) {
				$field = trim($matches[1], '|');
				$field = strpos($field, '|') ? explode('|', $field) : $field;
			}

			if(is_string($field)) {
				if(wire('fields')->get($field)->id) $exclude[] = $value;
				continue;
			}

			if(count($field)) {
				foreach($field as $f) {
					$goodField = wire('fields')->get($f)->id;
					if(!$goodField) break;
				}
				if($goodField) $exclude[] = $value;
			}	
		}

		$out .= implode(", ", array_filter($exclude));
	}

	return $out;
}
Link to comment
Share on other sites

yep:

Dirty:

not#$#%=tralala, body=soma, title|headline%=start, also_not_available=test

Cleaned:

body=soma, title|headline%=start

You could use it like:

$dirty = 'not#$#%=tralala, also_not_available=test';
$cleaned = returnValidSelector( $dirty ); // empty string
if($cleaned) $pages->find($cleaned); // never executed 

---

$dirty = 'not#$#%=tralala, also_not_available=test, title=Soma';
$cleaned = returnValidSelector( $dirty ); // title=Soma
if($cleaned) $pages->find($cleaned); // no errors, valid selector, search pages
Link to comment
Share on other sites

And what is wrong with your code, why must there be a better way?

I just think you may not do it in template but after saving the page, it's also not kind of validation but a cleaning. So you wouldn't end with selectors being "false" saved to DB.

ProcessWire hasn't some other way to do what you want/doing here, possibly also because of performance - it doesn't attempt to check for each selector if it's really valid/field exists. Technically there's also a way to add a runtime value to a pages that is used in selector on page arrays.

  • Like 1
Link to comment
Share on other sites

Cool, tnx for the response. I Can imagine I gonna build some kinds of fieldtype from this. Because you've got some valid points about this.

The lastline "Technically there's also a way to add a runtime value to a pages that is used in selector on page arrays." I don't fully understand.

Link to comment
Share on other sites

That means

$pa = $pages->find("template=basic-page");
foreach($pa as $p){
     $p->price_total = $p->amount * $p->price;
}

foreach($pa->find("sort=price_total") as $p){
     echo "<p>$p->title $p->price_total</p>";
}
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...