mirror of
https://github.com/processwire/processwire.git
synced 2025-08-16 11:44:42 +02:00
Add PageFinder support for partial match operator on parent.path selectors like: parent.path%=something
This commit is contained in:
@@ -169,6 +169,7 @@ class PageFinder extends Wire {
|
|||||||
protected $sortsAfter = array(); // apply these sorts after pages loaded
|
protected $sortsAfter = array(); // apply these sorts after pages loaded
|
||||||
protected $reverseAfter = false; // reverse order after load?
|
protected $reverseAfter = false; // reverse order after load?
|
||||||
protected $pageArrayData = array(); // any additional data that should be populated back to any resulting PageArray objects
|
protected $pageArrayData = array(); // any additional data that should be populated back to any resulting PageArray objects
|
||||||
|
protected $partialMatchOperators = array('%=', '^=', '$=', '%^=', '%$=', '*=');
|
||||||
protected $singlesFields = array( // fields that can only be used by themselves (not OR'd with other fields)
|
protected $singlesFields = array( // fields that can only be used by themselves (not OR'd with other fields)
|
||||||
'has_parent',
|
'has_parent',
|
||||||
'hasParent',
|
'hasParent',
|
||||||
@@ -2048,6 +2049,7 @@ class PageFinder extends Wire {
|
|||||||
// the following fields are defined in each iteration here because they may be modified in the loop
|
// the following fields are defined in each iteration here because they may be modified in the loop
|
||||||
$table = "pages";
|
$table = "pages";
|
||||||
$operator = $selector->operator;
|
$operator = $selector->operator;
|
||||||
|
$isPartialOperator = in_array($operator, $this->partialMatchOperators);
|
||||||
$subfield = '';
|
$subfield = '';
|
||||||
$IDs = array(); // populated in special cases where we can just match parent IDs
|
$IDs = array(); // populated in special cases where we can just match parent IDs
|
||||||
$sql = '';
|
$sql = '';
|
||||||
@@ -2073,7 +2075,7 @@ class PageFinder extends Wire {
|
|||||||
if($isParent || $isChildren || $isPages) {
|
if($isParent || $isChildren || $isPages) {
|
||||||
// parent, children, pages
|
// parent, children, pages
|
||||||
|
|
||||||
if(($isPages || $isParent) && (!$subfield || in_array($subfield, array('id', 'path', 'url')))) {
|
if(($isPages || $isParent) && !$isPartialOperator && (!$subfield || in_array($subfield, array('id', 'path', 'url')))) {
|
||||||
// match by location (id or path)
|
// match by location (id or path)
|
||||||
// convert parent fields like '/about/company/history' to the equivalent ID
|
// convert parent fields like '/about/company/history' to the equivalent ID
|
||||||
foreach($values as $k => $v) {
|
foreach($values as $k => $v) {
|
||||||
@@ -2104,11 +2106,7 @@ class PageFinder extends Wire {
|
|||||||
$s = '';
|
$s = '';
|
||||||
if($field === 'children') $finderMethod = 'findParentIDs';
|
if($field === 'children') $finderMethod = 'findParentIDs';
|
||||||
// inherit include mode from main selector
|
// inherit include mode from main selector
|
||||||
$includeSelector = trim(
|
$includeSelector = $this->getIncludeSelector($selectors);
|
||||||
$selectors->getSelectorByField('include') . ',' .
|
|
||||||
$selectors->getSelectorByField('status') . ',' .
|
|
||||||
$selectors->getSelectorByField('check_access'), ','
|
|
||||||
);
|
|
||||||
} else if($field === 'children') {
|
} else if($field === 'children') {
|
||||||
$s = 'children.id';
|
$s = 'children.id';
|
||||||
} else {
|
} else {
|
||||||
@@ -2174,6 +2172,7 @@ class PageFinder extends Wire {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$isName = $field === 'name' || strpos($field, 'name') === 0;
|
$isName = $field === 'name' || strpos($field, 'name') === 0;
|
||||||
|
$isPath = $field === 'path' || $field === 'url';
|
||||||
|
|
||||||
if($isName && $operator == '~=') {
|
if($isName && $operator == '~=') {
|
||||||
// handle one or more space-separated full words match to 'name' field in any order
|
// handle one or more space-separated full words match to 'name' field in any order
|
||||||
@@ -2183,7 +2182,7 @@ class PageFinder extends Wire {
|
|||||||
$s .= ($s ? ' AND ' : '') . "$table.$field RLIKE '" . '[[:<:]]' . $word . '[[:>:]]' . "'";
|
$s .= ($s ? ' AND ' : '') . "$table.$field RLIKE '" . '[[:<:]]' . $word . '[[:>:]]' . "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if($isName && in_array($operator, array('%=', '^=', '$=', '%^=', '%$=', '*='))) {
|
} else if($isName && $isPartialOperator) {
|
||||||
// handle partial match to 'name' field
|
// handle partial match to 'name' field
|
||||||
$value = $database->escapeStr($sanitizer->pageName($value, Sanitizer::toAscii));
|
$value = $database->escapeStr($sanitizer->pageName($value, Sanitizer::toAscii));
|
||||||
if($operator == '^=' || $operator == '%^=') $value = "$value%";
|
if($operator == '^=' || $operator == '%^=') $value = "$value%";
|
||||||
@@ -2191,6 +2190,16 @@ class PageFinder extends Wire {
|
|||||||
else $value = "%$value%";
|
else $value = "%$value%";
|
||||||
$s = "$table.$field LIKE '$value'";
|
$s = "$table.$field LIKE '$value'";
|
||||||
|
|
||||||
|
} else if($isPath && $isPartialOperator) {
|
||||||
|
// partial match of path (used when original selector is parent.path%=...)
|
||||||
|
$tempSelector = trim($this->getIncludeSelector($selectors) . ", $field$operator" . $sanitizer->selectorValue($value), ',');
|
||||||
|
$tempIDs = $sanitizer->intArray($this->wire('pages')->findIDs($tempSelector));
|
||||||
|
if(count($tempIDs)) {
|
||||||
|
$s = "$table.id IN(" . implode(',', $tempIDs) . ')';
|
||||||
|
} else {
|
||||||
|
$s = "$table.id=-1"; // force non-match
|
||||||
|
}
|
||||||
|
|
||||||
} else if(!$database->isOperator($operator)) {
|
} else if(!$database->isOperator($operator)) {
|
||||||
throw new PageFinderSyntaxException("Operator '{$operator}' is not supported for '$field'.");
|
throw new PageFinderSyntaxException("Operator '{$operator}' is not supported for '$field'.");
|
||||||
|
|
||||||
@@ -2229,6 +2238,22 @@ class PageFinder extends Wire {
|
|||||||
//$this->nativeWheres[] = $SQL;
|
//$this->nativeWheres[] = $SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the include|status|check_access portions from given Selectors and return selector string for them
|
||||||
|
*
|
||||||
|
* @param Selectors|string $selectors
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function getIncludeSelector($selectors) {
|
||||||
|
if(!$selectors instanceof Selectors) $selectors = new Selectors($selectors);
|
||||||
|
return trim(
|
||||||
|
$selectors->getSelectorByField('include') . ',' .
|
||||||
|
$selectors->getSelectorByField('status') . ',' .
|
||||||
|
$selectors->getSelectorByField('check_access'), ','
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the query specific to all pages below a certain parent (children, grandchildren, great grandchildren, etc.)
|
* Make the query specific to all pages below a certain parent (children, grandchildren, great grandchildren, etc.)
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user