From ff0a66821d2f0966772168f0394c4dbe9a69d32b Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Wed, 19 May 2021 08:57:13 -0400 Subject: [PATCH] Optimizations to WireArray::get(), plus add support for get('a|b|c') where it returns value for first matching key, consistently with WireData. This also provides a solution for PR #109 @bernhardbaumrock --- wire/core/WireArray.php | 50 ++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/wire/core/WireArray.php b/wire/core/WireArray.php index 3b00c874..0b215569 100644 --- a/wire/core/WireArray.php +++ b/wire/core/WireArray.php @@ -539,6 +539,7 @@ class WireArray extends Wire implements \IteratorAggregate, \ArrayAccess, \Count * */ public function get($key) { + $match = null; // if an object was provided, get its key if(is_object($key)) { @@ -566,28 +567,45 @@ class WireArray extends Wire implements \IteratorAggregate, \ArrayAccess, \Count } // check if the index is set and return it if so - if(isset($this->data[$key])) return $this->data[$key]; + if(isset($this->data[$key])) return $this->data[$key]; - // check if key contains a selector - if(Selectors::stringHasSelector($key)) { - $item = $this->findOne($key); - if($item === false) $item = null; - return $item; - } + // check if key contains something other than numbers, letters, underscores, hyphens + if(!ctype_alnum("$key") && !ctype_alnum(strtr("$key", '-_', 'ab'))) { + + // check if key contains a selector + if(Selectors::stringHasSelector($key)) { + $item = $this->findOne($key); + if($item === false) $item = null; + return $item; + } + + if(strpos($key, '{') !== false && strpos($key, '}')) { + // populate a formatted string with {tag} vars + return wirePopulateStringTags($key, $this); + } + + // check if key is requesting a property array: i.e. "name[]" + if(strpos($key, '[]') !== false && substr($key, -2) == '[]') { + return $this->explode(substr($key, 0, -2)); + } - if(strpos($key, '{') !== false && strpos($key, '}')) { - // populate a formatted string with {tag} vars - return wirePopulateStringTags($key, $this); - } - - // check if key is requesting a property array: i.e. "name[]" - if(strpos($key, '[]') !== false && substr($key, -2) == '[]') { - return $this->explode(substr($key, 0, -2)); + // check if key is asking for first match in "a|b|c" + if(strpos($key, '|') !== false) { + $numericKeys = $this->usesNumericKeys(); + foreach(explode('|', $key) as $k) { + if(isset($this->data[$k])) { + $match = $this->data[$k]; + } else if($numericKeys) { + $match = $this->getItemThatMatches('name', $k); + } + if($match) break; + } + return $match; + } } // if the WireArray uses numeric keys, then it's okay to // match a 'name' field if the provided key is a string - $match = null; if(is_string($key) && $this->usesNumericKeys()) { $match = $this->getItemThatMatches('name', $key); }