getTypePrefix() : ''; if (static::$type) { return $type . static::$type; } $class = get_class($this); return $type . strtolower(substr($class, strrpos($class, '\\') + 1)); } /** * @return string */ public function getKey() { return $this->_key ?: $this->getType() . '@@' . spl_object_hash($this); } /** * @return bool */ public function hasKey() { return !empty($this->_key); } /** * @param string $property Object property name. * @return bool[] True if property has been defined (can be null). */ public function hasProperty($property) { return $this->doHasProperty($property); } /** * @param string $property Object property to be fetched. * @param mixed $default Default value if property has not been set. * @return mixed[] Property values. */ public function getProperty($property, $default = null) { return $this->doGetProperty($property, $default); } /** * @param string $property Object property to be updated. * @param mixed $value New value. * @return $this */ public function setProperty($property, $value) { $this->doSetProperty($property, $value); return $this; } /** * @param string $property Object property to be unset. * @return $this */ public function unsetProperty($property) { $this->doUnsetProperty($property); return $this; } /** * @param string $property Object property to be defined. * @param mixed $default Default value. * @return $this */ public function defProperty($property, $default) { if (!$this->hasProperty($property)) { $this->setProperty($property, $default); } return $this; } /** * @return array */ final public function __serialize(): array { return $this->doSerialize(); } /** * @param array $data * @return void */ final public function __unserialize(array $data): void { if (method_exists($this, 'initObjectProperties')) { $this->initObjectProperties(); } $this->doUnserialize($data); } /** * @return array */ protected function doSerialize() { return [ 'key' => $this->getKey(), 'type' => $this->getType(), 'elements' => $this->getElements() ]; } /** * @param array $data * @return void */ protected function doUnserialize(array $data) { if (!isset($data['key'], $data['type'], $data['elements']) || $data['type'] !== $this->getType()) { throw new InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); } $this->setKey($data['key']); $this->setElements($data['elements']); } /** * Implements JsonSerializable interface. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->doSerialize(); } /** * Returns a string representation of this object. * * @return string */ #[\ReturnTypeWillChange] public function __toString() { return $this->getKey(); } /** * @param string $key * @return $this */ public function setKey($key) { $this->_key = (string) $key; return $this; } /** * Create a copy from this collection by cloning all objects in the collection. * * @return static */ public function copy() { $list = []; foreach ($this->getIterator() as $key => $value) { /** @phpstan-ignore-next-line */ $list[$key] = is_object($value) ? clone $value : $value; } /** @phpstan-var static */ return $this->createFrom($list); } /** * @return string[] */ public function getObjectKeys() { return $this->call('getKey'); } /** * @param string $property Object property to be matched. * @return bool[] Key/Value pairs of the properties. */ public function doHasProperty($property) { $list = []; /** @var ObjectInterface $element */ foreach ($this->getIterator() as $id => $element) { $list[$id] = (bool)$element->hasProperty($property); } return $list; } /** * @param string $property Object property to be fetched. * @param mixed $default Default value if not set. * @param bool $doCreate Not being used. * @return mixed[] Key/Value pairs of the properties. */ public function &doGetProperty($property, $default = null, $doCreate = false) { $list = []; /** @var ObjectInterface $element */ foreach ($this->getIterator() as $id => $element) { $list[$id] = $element->getProperty($property, $default); } return $list; } /** * @param string $property Object property to be updated. * @param mixed $value New value. * @return $this */ public function doSetProperty($property, $value) { /** @var ObjectInterface $element */ foreach ($this->getIterator() as $element) { $element->setProperty($property, $value); } return $this; } /** * @param string $property Object property to be updated. * @return $this */ public function doUnsetProperty($property) { /** @var ObjectInterface $element */ foreach ($this->getIterator() as $element) { $element->unsetProperty($property); } return $this; } /** * @param string $property Object property to be updated. * @param mixed $default Default value. * @return $this */ public function doDefProperty($property, $default) { /** @var ObjectInterface $element */ foreach ($this->getIterator() as $element) { $element->defProperty($property, $default); } return $this; } /** * @param string $method Method name. * @param array $arguments List of arguments passed to the function. * @return mixed[] Return values. */ public function call($method, array $arguments = []) { $list = []; /** * @var string|int $id * @var ObjectInterface $element */ foreach ($this->getIterator() as $id => $element) { $callable = [$element, $method]; $list[$id] = is_callable($callable) ? call_user_func_array($callable, $arguments) : null; } return $list; } /** * Group items in the collection by a field and return them as associated array. * * @param string $property * @return array * @phpstan-return array */ public function group($property) { $list = []; /** @var ObjectInterface $element */ foreach ($this->getIterator() as $element) { $list[(string) $element->getProperty($property)][] = $element; } return $list; } /** * Group items in the collection by a field and return them as associated array of collections. * * @param string $property * @return static[] * @phpstan-return array> */ public function collectionGroup($property) { $collections = []; foreach ($this->group($property) as $id => $elements) { /** @phpstan-var static $collection */ $collection = $this->createFrom($elements); $collections[$id] = $collection; } return $collections; } }