1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-14 02:34:24 +02:00

Update Selectors class to support altOperators (alternate fallback operators for when first does not match)

This commit is contained in:
Ryan Cramer
2020-06-26 09:41:17 -04:00
parent 26710f262e
commit ac18dad59c

View File

@@ -241,10 +241,11 @@ class Selectors extends WireArray {
}
$group = $this->extractGroup($str);
$field = $this->extractField($str);
$operator = $this->extractOperator($str, self::getOperatorChars());
$operators = $this->extractOperators($str);
$operator = array_shift($operators);
$value = $this->extractValue($str, $quote);
if($this->parseVars && $quote == '[' && $this->valueHasVar($value)) {
if($this->parseVars && $quote === '[' && $this->valueHasVar($value)) {
// parse an API variable property to a string value
$v = $this->parseValue($value);
if($v !== null) {
@@ -258,6 +259,7 @@ class Selectors extends WireArray {
if(!is_null($group)) $selector->group = $group;
if($quote) $selector->quote = $quote;
if($not) $selector->not = true;
if(count($operators)) $selector->altOperators = $operators;
$this->add($selector);
}
}
@@ -323,6 +325,8 @@ class Selectors extends WireArray {
* @param string $str
* @param array $operatorChars
* @return string
* @deprecated Replaced by extractOperators()
* @todo this method can be removed once confirmed nothing else uses it
*
*/
protected function extractOperator(&$str, array $operatorChars) {
@@ -343,6 +347,52 @@ class Selectors extends WireArray {
return $operator;
}
/**
* Given a string starting with an operator, return that operator, and remove it from $str.
*
* @param string $str
* @return array
*
*/
protected function extractOperators(&$str) {
$n = 0;
$operator = '';
$lastOperator = '';
$operators = array();
$operatorChars = self::getOperatorChars();
while(isset($str[$n]) && isset($operatorChars[$str[$n]])) {
$operator .= $str[$n];
if(self::isOperator($operator)) {
$lastOperator = $operator;
} else if($lastOperator) {
$operators[$lastOperator] = $lastOperator;
$lastOperator = '';
$operator = $str[$n];
}
$n++;
}
if($lastOperator) {
$operators[$lastOperator] = $lastOperator;
}
if(count($operators)) {
$str = substr($str, $n);
}
if($operator && !isset($operators[$lastOperator])) {
if(self::isOperator($operator)) {
$operators[$operator] = $operator;
} else {
throw new WireException("Unrecognized operator: $operator");
}
}
return $operators;
}
/**
* Early-exit optimizations for extractValue
*
@@ -710,7 +760,17 @@ class Selectors extends WireArray {
}
if(!$selector->matches($value)) {
$matches = false;
break;
// attempt any alternate operators, if present
foreach($selector->altOperators as $altOperator) {
$altSelector = self::getSelectorByOperator($altOperator);
if(!$altSelector) continue;
$this->wire($altSelector);
$selector->copyTo($altSelector);
$matches = $altSelector->matches($value);
if($matches) break;
}
// if neither selector nor altSelectors match then stop
if(!$matches) break;
}
}