From: Roland Häder Date: Mon, 2 Nov 2020 15:29:50 +0000 (+0100) Subject: Continued: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=b4a83b1583b9b3947633bbaf62b25883bfc3f9ea;p=core.git Continued: - re-implemented initIterator(), current() and valid() Signed-off-by: Roland Häder --- diff --git a/framework/main/classes/iterator/registry/class_RegistryIterator.php b/framework/main/classes/iterator/registry/class_RegistryIterator.php index 74d8908c..916f6faa 100644 --- a/framework/main/classes/iterator/registry/class_RegistryIterator.php +++ b/framework/main/classes/iterator/registry/class_RegistryIterator.php @@ -11,10 +11,11 @@ use Org\Mxchange\CoreFramework\Registry\Registerable; use Org\Mxchange\CoreFramework\Registry\Sub\SubRegistry; // Import SPL stuff +use \BadMethodCallException; use \LogicException; /** - * A Registry iterator + * A registry iterator * * @author Roland Haeder * @version 0.0.0 @@ -42,14 +43,15 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { private $registryKeys = []; /** - * Current array key + * An array containing keys ob sub-registries which keys should only be + * included in the iterator. */ - private $key = NULL; + private $onlyRegistries = []; /** - * Valid status (default: not valid) + * Current array key */ - private $valid = FALSE; + private $key = NULL; /** * Protected constructor @@ -59,6 +61,14 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { protected function __construct () { // Call parent constructor parent::__construct(__CLASS__); + + // Init registry keys array + $this->registryKeys = [ + // Generic registry + 'generic' => [], + // Instance registry + 'instance' => [], + ]; } /** @@ -78,109 +88,103 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { return $iteratorInstance; } + /** + * Setter for only-registries array + * + * @param $onlyRegistries Array with keys only being iterated over + * @return void + */ + private function setOnlyRegistries (array $onlyRegistries) { + $this->onlyRegistries = $onlyRegistries; + } + /** * Initializes this iterator by scanning over the registry for all keys. * - * @param $callbackInstance An instance of a FrameworkInterface class to call back (optional) - * @param $criteriaKey Criteria key (optional) - * @param $criteriaMethod Method to call back (optional) + * @param $onlyRegistries Only iterate on these sub-registry keys, default is all * @return void * @throws LogicException If a registry entry does not implement Registerable * @throws NullPointerException If criteriaKey or criteriaMethod is not set but a call-back instance is set */ - public function initIterator (FrameworkInterface $callbackInstance = NULL, $criteriaKey = NULL, $criteriaMethod = NULL) { - // Is the call-back instance set? - if ($callbackInstance instanceof FrameworkInterface) { - // Then also criteria key and method name must be given - if (is_null($criteriaKey)) { - // Throw NPE - throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); - } elseif (is_null($criteriaMethod)) { - // Throw NPE - throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); - } - - // Set all - $iteratorInstance->setCallbackInstance($callbackInstance); - $iteratorInstance->setCriteriaKey($criteriaKey); - } // END - if + public function initIterator (array $onlyRegistries = []) { + // Set it in this registry + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR: onlyRegistries()=%d - CALLED!', count($onlyRegistries))); + $this->setOnlyRegistries($onlyRegistries); // Get generic registry entries from it $entries = $this->getRegistryInstance()->getGenericRegistry(); - // Init registry keys array - $this->registryKeys['generic'] = []; - // Anything in there? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[generic]: entries()=%d', count($entries))); if (count($entries) > 0) { // Debugging: - /* DEBUG-DIE: */ die(sprintf('[%s:%d]: entries=%s', __METHOD__, __LINE__, print_r($entries, TRUE))); + /* DEBUG-DIE: */ die(sprintf('[%s:%d]: UNFINISHED: entries=%s', __METHOD__, __LINE__, print_r($entries, TRUE))); } // END - if // Get instance registry entries from it $entries = $this->getRegistryInstance()->getInstanceRegistry(); - // Init registry keys array - $this->registryKeys['instance'] = []; - // Anything in there? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: entries()=%d', count($entries))); if (count($entries) > 0) { // Then run over all foreach ($entries as $key => $entry) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s,entry[]=%s', $key, gettype($entry))); - - // Is it 'socket_registry' ? - if ($key == 'socket_registry') { - // Skip this entry + // Is an unwanted registry found? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s,entry[]=%s', $key, gettype($entry))); + if (substr($key, -8, 8) == 'registry') { + // Skip this! + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s is a registry key, skipping ...', $key)); continue; - } // END - if + } // Is it an instance of a sub-registry? - if ($entry instanceof SubRegistry) { + if (count($onlyRegistries) > 0 && !in_array($key, $onlyRegistries, TRUE)) { + // Not in requested registries + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s is not wanted, skipping ...', $key)); + continue; + } elseif ($entry instanceof SubRegistry) { // Get iterator from this instance - $iteratorInstance = $entry->getIterator(); - - // Debugging: - //* DEBUG-DIE: */ die(sprintf('[%s:%d]: key=%s,iteratorInstance=%s', __METHOD__, __LINE__, $key, print_r($iteratorInstance, TRUE))); - - // Get all keys - $keys = $iteratorInstance->getRegistryKeys(); - - // Should be there - if (!isset($keys['instance'])) { - // Should not happen - throw new LogicException(sprintf('key=%s,keys[instance] is not set.', $key)); - } // END - if + $subRegistryInstances = $entry->getInstanceRegistry(); // Add all sub-registry keys to this registry keys array - $this->registryKeys['instance'][$key] = $keys['instance']; - - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s,keys=%s', $key, print_r($this->registryKeys['instance'][$key], TRUE))); + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: subRegistryInstances()=%d', count($subRegistryInstances))); + //* DEBUG-DIE: */ die(sprintf('[%s:%d]: key=%s,subRegistryInstances=%s', __METHOD__, __LINE__, $key, print_r($subRegistryInstances, TRUE))); + foreach (array_keys($subRegistryInstances) as $subKey) { + // Add it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: Adding key=%s,subKey=%s ...', $key, $subKey)); + array_push($this->registryKeys['instance'], $subKey); + + // Is the current key set? + if (is_null($this->key)) { + // Init key + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: Setting subKey=%s as first key ...', $subKey)); + $this->key = $subKey; + } + } // Skip below code continue; } elseif (!($entry instanceof Registerable)) { // Not registerable?! throw new LogicException(sprintf('entry[]=%s does not implement Registerable.', gettype($entry))); - } elseif (is_null($this->key)) { - // Debug message - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: Setting key=%s ...', $key)); + } - // Init key/valid + // Is the current key set? + if (is_null($this->key)) { + // Init key + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: Setting key=%s as first key ...', $key)); $this->key = $key; - $this->valid = TRUE; } - // Debugging: - //* DEBUG-DIE: */ die(sprintf('[%s:%d]: key=%s,entry=%s', __METHOD__, __LINE__, $key, print_r($entry, TRUE))); - //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s,entry[]=%s - Adding ...', $key, gettype($entry))); - // Add key to array - $this->registryKeys['instance'][$key] = []; + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[instance]: key=%s - Adding ...', $key)); + //* DEBUG-DIE: */ die(sprintf('[%s:%d]: key=%s,entry=%s', __METHOD__, __LINE__, $key, print_r($entry, TRUE))); + array_push($this->registryKeys['instance'], $key); } // END - foreach } // END - if + + // Trace message + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('REGISTRY-ITERATOR: EXIT!'); } /** @@ -197,14 +201,51 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { * Getter for current value from group or generic * * @return $current Current value in iteration + * @throws NullPointerException If current key points to a non-existing entry in searched registries */ public function current () { // Default is null - $current = null; + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: CALLED!', $this->key())); + //* DEBUG-DIE: */ die(sprintf('[%s:%d]: this->key(%d)[%s]=%s,this->valid=%d,this->registryKeys=%s', __METHOD__, __LINE__, strlen($this->key()), gettype($this->key()), $this->key(), intval($this->valid()), print_r($this->registryKeys, TRUE))); + $current = NULL; + $entries = []; + + // Get all registries + $allRegistries = $this->getRegistryInstance()->getInstanceRegistry(); + + // Loop through all sub-sets + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: allRegistries()=%d', $this->key(), count($allRegistries))); + foreach ($allRegistries as $registryKey => $registryInstance) { + // Is this key wanted? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: registryKey=%s', $this->key(), $registryKey)); + if (count($this->onlyRegistries) == 0 || in_array($registryKey, $this->onlyRegistries)) { + // Yes, then loop through them only + $instances = $registryInstance->getInstanceRegistry(); + + // The key should be there + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: Handling registryKey=%s ...', $this->key(), $registryKey)); + //* DEBUG-DIE: */ die(sprintf('[%s:%d]: instances=%s', __METHOD__, __LINE__, print_r($instances, TRUE))); + if (!isset($instances[$this->key()])) { + // Skip below code + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: registryKey=%s has no this->key=%s, skipping ...', $this->key(), $registryKey)); + continue; + } + + // Set as current element and leave loop + $current = $instances[$this->key()]; + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: registryKey=%s,current=%s found. - BREAK!', $this->key(), $registryKey, $current->__toString())); + break; + } + } - $this->partialStub('Please implement this method.'); + // Is current still NULL? + if (is_null($current)) { + // This cannot happen and indicates a logic error + throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER); + } // Return it + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: current[%s]=%s - EXIT!', $this->key(), gettype($current), $current)); return $current; } @@ -222,25 +263,32 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { * Advances to the next entry * * @return void + * @throws BadMethodCallException If $this->valid() returns FALSE */ public function next () { - $this->partialStub('Please implement this method.'); + // Is valid() still TRUE? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: CALLED!', $this->key())); + /* DEBUG-DIE: */ die(sprintf('[%s:%d]: this->key(%d)[%s]=%s,this->valid=%d,this->registryKeys=%s', __METHOD__, __LINE__, strlen($this->key()), gettype($this->key()), $this->key(), intval($this->valid()), print_r($this->registryKeys, TRUE))); + if (!$this->valid()) { + // Bad method call! + throw new BadMethodCallException(sprintf('this->key[%s]=%s is no longer valid, but method was called.', gettype($this->key()), $this->key())); + } } /** * Rewinds to the beginning of the iteration * * @return void + * @throws BadMethodCallException If $this->key is already the first element */ public function rewind () { - // Is the registry empty? - if (count($this->registryKeys) == 0) { - // Then no need to continue - return; - } // END - if - - // Debugging: + // Is current key first key? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: CALLED!', $this->key())); /* DEBUG-DIE: */ die(sprintf('[%s:%d]: this->key(%d)[%s]=%s,this->valid=%d,this->registryKeys=%s', __METHOD__, __LINE__, strlen($this->key()), gettype($this->key()), $this->key(), intval($this->valid()), print_r($this->registryKeys, TRUE))); + if (array_search($this->key(), $this->getRegistryKeys()) === 0) { + // rewind() cannot rewind first entry! + throw new BadMethodCallException(sprintf('this->key=%s is already first element, but method was called.', $this->key())); + } } /** @@ -249,8 +297,14 @@ class RegistryIterator extends BaseIterator implements IteratableRegistry { * @return $valid Whether the current key is still valid */ public function valid () { + // Is the element there? + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: CALLED!', $this->key())); + //* DEBUG-DIE: */ die(sprintf('[%s:%d]: this->key(%d)[%s]=%s,this->registryKeys=%s', __METHOD__, __LINE__, strlen($this->key()), gettype($this->key()), $this->key(), print_r($this->registryKeys, TRUE))); + $valid = (in_array($this->key(), $this->registryKeys['instance']) || in_array($this->key(), $this->registryKeys['generic'])); + // Return flag - return $this->valid; + /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugOutput(sprintf('REGISTRY-ITERATOR[%s]: valid=%d - EXIT!', $this->key(), intval($valid))); + return $valid; } } diff --git a/framework/main/classes/registry/class_BaseRegistry.php b/framework/main/classes/registry/class_BaseRegistry.php index 4364d25a..26fe8f9d 100644 --- a/framework/main/classes/registry/class_BaseRegistry.php +++ b/framework/main/classes/registry/class_BaseRegistry.php @@ -61,9 +61,10 @@ abstract class BaseRegistry extends BaseFrameworkSystem implements Register, Reg /** * Returns an iterator for this whole registry. * + * @param $onlyRegistries Only iterate on these sub-registry keys, default is all * @return $iteratorInstance An instance of a Iterator class */ - public function getIterator () { + public function getIterator (array $onlyRegistries = []) { // Is it set? if (is_null($this->getIteratorInstance())) { // Then instance it @@ -76,6 +77,9 @@ abstract class BaseRegistry extends BaseFrameworkSystem implements Register, Reg $iteratorInstance = $this->getIteratorInstance(); } + // Init iterator instance + $iteratorInstance->initIterator($onlyRegistries); + // Return it return $iteratorInstance; } diff --git a/framework/main/interfaces/iterator/registry/class_IteratableRegistry.php b/framework/main/interfaces/iterator/registry/class_IteratableRegistry.php index 7bfbb5c2..9e9d602a 100644 --- a/framework/main/interfaces/iterator/registry/class_IteratableRegistry.php +++ b/framework/main/interfaces/iterator/registry/class_IteratableRegistry.php @@ -35,10 +35,11 @@ interface IteratableRegistry extends FrameworkInterface, Iterator { /** * Initializes this iterator by scanning over the registry for all keys. * + * @param $onlyRegistries Only iterate on these sub-registry keys, default is all * @return void * @throws LogicException If a registry entry does not implement Registerable * @throws NullPointerException If criteriaKey or criteriaMethod is not set but a call-back instance is set */ - function initIterator (FrameworkInterface $callbackInstance = NULL, $criteriaKey = NULL, $criteriaMethod = NULL); + function initIterator (array $onlyRegistries = []); }