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

Optimizations in PageLoader class plus fix issue processwire/processwire-issues#1021

This commit is contained in:
Ryan Cramer
2019-11-05 07:35:22 -05:00
parent b3337d0110
commit 76943ac192

View File

@@ -116,41 +116,55 @@ class PagesLoader extends Wire {
$value = false; $value = false;
$filter = empty($options['findAll']); $filter = empty($options['findAll']);
if(is_array($selector)) { if(is_string($selector)) {
$selector = trim($selector, ', ');
if(ctype_digit($selector)) {
// normalize to page ID (int)
$selector = (int) $selector;
} else if($selector === '/' || $selector === 'path=/') {
// normalize selectors that indicate homepage to just be ID 1
$selector = (int) $this->wire('config')->rootPageID;
} else if($selector[0] == '/') {
// if selector begins with a slash, it is referring to a path
$selector = "path=$selector";
}
}
if(is_array($selector)) {
// array that is .... not associative .................. not selector array ........ consists of only numbers
if(ctype_digit(implode('', array_keys($selector))) && !is_array(reset($selector)) && ctype_digit(implode('', $selector))) { if(ctype_digit(implode('', array_keys($selector))) && !is_array(reset($selector)) && ctype_digit(implode('', $selector))) {
// if given a regular array of page IDs, we delegate that to getById() method, but with access/visibility control // regular array of page IDs, we delegate that to getById() method, but with access/visibility control
foreach($selector as $k => $v) $selector[$k] = (int) $v;
$value = $this->getById($selector, $loadOptions); $value = $this->getById($selector, $loadOptions);
$filter = true; $filter = true;
} }
} else if(is_int($selector)) { } else if(is_int($selector)) {
// page ID integer
$value = $this->getById(array($selector), $loadOptions); $value = $this->getById(array($selector), $loadOptions);
} else if(is_string($selector) || is_int($selector)) { } else if(is_string($selector) && strpos($selector, ',') === false) {
// there is just one “key=value” or “value” selector
// normalize selectors that indicate homepage to just be ID 1 if(strpos($selector, 'id=') === 0) {
if($selector === '/' || $selector === 'path=/') $selector = 1; // string like id=123 or id=123|456|789
$s = substr($selector, 3); // skip over 'id='
// if selector begins with a slash, then we'll assume it's referring to a path if(ctype_digit($s)) {
if($selector[0] == '/') $selector = "path=$selector"; // id=123
$value = $this->getById((int) $s, $loadOptions);
if(strpos($selector, ",") === false && strpos($selector, "|") === false) { } else if(strpos($selector, '|') && ctype_digit(str_replace('|', '', $s))) {
// there is just one param. Lets see if we can find a shortcut. // id=123|456|789
if(ctype_digit("$selector") || strpos($selector, "id=") === 0) { $a = explode('|', $s);
// if selector is just a number, or a string like "id=123" then we're going to do a shortcut foreach($a as $k => $v) $a[$k] = (int) $v;
$s = str_replace("id=", '', $selector); $value = $this->getById($a, $loadOptions);
if(ctype_digit(str_replace('|', '', "$s"))) { }
$a = explode('|', $s); } else if(!Selectors::stringHasOperator($selector)) {
foreach($a as $k => $v) $a[$k] = (int) $v; // no operator indicates this is just referring to a page name
$value = $this->getById($a, $loadOptions); $sanitizer = $this->wire('sanitizer');
} if($sanitizer->pageNameUTF8($selector) === $selector) {
} else if(!Selectors::stringHasOperator($selector)) { // sanitized value consistent with a page name
if($this->wire('sanitizer')->pageNameUTF8($selector) === $selector) { // optimize selector rather than determining value here
$selector = "name=$selector"; $selector = 'name=' . $sanitizer->selectorValue($selector);
}
} }
} }
} }
@@ -500,7 +514,7 @@ class PagesLoader extends Wire {
* - Specify false for 'findTemplates' so this method doesn't have to look them up. Potential speed optimization if you have few autojoin fields globally. * - Specify false for 'findTemplates' so this method doesn't have to look them up. Potential speed optimization if you have few autojoin fields globally.
* - Note that if you specify false for 'findTemplates' the pageClass is assumed to be 'Page' unless you specify something different for the 'pageClass' option. * - Note that if you specify false for 'findTemplates' the pageClass is assumed to be 'Page' unless you specify something different for the 'pageClass' option.
* *
* @param array|WireArray|string $_ids Array of IDs or CSV string of IDs * @param array|WireArray|string|int $_ids Array of page IDs, comma or pipe-separated string of IDs, or single page ID (string or int)
* @param Template|array|null $template Specify a template to make the load faster, because it won't have to attempt to join all possible fields... just those used by the template. * @param Template|array|null $template Specify a template to make the load faster, because it won't have to attempt to join all possible fields... just those used by the template.
* Optionally specify an $options array instead, see the method notes above. * Optionally specify an $options array instead, see the method notes above.
* @param int|null $parent_id Specify a parent to make the load faster, as it reduces the possibility for full table scans. * @param int|null $parent_id Specify a parent to make the load faster, as it reduces the possibility for full table scans.
@@ -552,8 +566,16 @@ class PagesLoader extends Wire {
if(is_string($_ids)) { if(is_string($_ids)) {
// convert string of IDs to array // convert string of IDs to array
if(strpos($_ids, '|') !== false) $_ids = explode('|', $_ids); $_ids = trim($_ids, '|, ');
else $_ids = explode(",", $_ids); if(ctype_digit($_ids)) {
$_ids = array((int) $_ids); // single ID: "123"
} else if(strpos($_ids, '|')) {
$_ids = explode('|', $_ids); // pipe-separated IDs: "123|456|789"
} else if(strpos($_ids, ',')) {
$_ids = explode(',', $_ids); // comma-separated IDs: "123,456,789"
} else {
$_ids = array(); // unrecognized ID string: fail
}
} else if(is_int($_ids)) { } else if(is_int($_ids)) {
$_ids = array($_ids); $_ids = array($_ids);
} }
@@ -571,10 +593,16 @@ class PagesLoader extends Wire {
// sanitize ids and determine which pages we can pull from cache // sanitize ids and determine which pages we can pull from cache
foreach($_ids as $key => $id) { foreach($_ids as $key => $id) {
$key = (int) $key; if(!is_int($id)) {
$id = (int) $id; $id = trim($id);
if(!ctype_digit($id)) continue;
$id = (int) $id;
}
if($id < 1) continue; if($id < 1) continue;
$key = (int) $key;
if($options['getOne'] && is_object($options['page'])) { if($options['getOne'] && is_object($options['page'])) {
// single page that will be populated directly // single page that will be populated directly
$loaded[$id] = ''; $loaded[$id] = '';