protectDest = $params["protect_dest"] ?? static::PROTECT_DEST; $this->mapNames = $params["map_names"] ?? static::MAP_NAMES; $this->_setName($name); $this->_setDest($dest); $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } protected bool $protectDest; protected ?object $dest; protected bool $mapNames; protected ?string $name; protected ?ReflectionProperty $property; private function _getName(string $key): string { return $this->mapNames? str::us2camel($key): $key; } private function _setName(?string $name): void { if ($name !== null) $name = $this->_getName($name); $this->name = $name; } private function _getProperty(?string $name, ?ReflectionClass $class, ?object $object=null): ?ReflectionProperty { $property = null; if ($class === null && $object !== null) { $class = new ReflectionClass($object); } if ($class !== null && $name !== null) { try { $property = $class->getProperty($name); $property->setAccessible(true); } catch (ReflectionException $e) { } } return $property; } private function _setDest(?object $dest): void { $this->dest = $dest; $this->property = $this->_getProperty($this->name, null, $dest); } function reset(?object $dest, ?string $name=null): self { $this->_setName($name); $this->_setDest($dest); return $this; } function resetKey($name=null): self { $this->_setName($name); return $this; } protected bool $allowNull; protected bool $allowFalse; function exists(): bool { $name = $this->name; if ($this->dest === null) return false; return $name === null || $this->property !== null || property_exists($this->dest, $name); } protected function _get($default=null) { $name = $this->name; $property = $this->property; if ($this->dest === null) { return $default; } elseif ($name === null) { return $this->dest; } elseif ($property !== null) { return $property->getValue($this->dest); } elseif (property_exists($this->dest, $name)) { return $this->dest->$name; } else { return $default; } } function available(): bool { if (!$this->exists()) return false; $value = $this->_get(); if ($value === "") return $this->allowEmpty; if ($value === null) return $this->allowNull; if ($value === false) return $this->allowFalse; return true; } function get($default=null) { if (!$this->exists()) return $default; $value = $this->_get(); if ($value === "" && !$this->allowEmpty) return $default; if ($value === null && !$this->allowNull) return $default; if ($value === false && !$this->allowFalse) return $default; return $value; } protected function _set($value): void { $name = $this->name; $property = $this->property; if ($this->dest === null) { throw StateException::unexpected_state("dest is null"); } elseif ($name === null) { if (!$this->protectDest) $this->_setDest($value); } elseif ($property !== null) { $property->setValue($this->dest, $value); } else { $this->dest->$name = $value; } } function set($value): void { $this->_set($value); } function del(): void { $this->_set(null); } function addKey($key): IAccess { if ($key === null) return $this; return new ChainAccess($this, $key); } function ensureAssoc(array $keys, ?array $params=null): void { # NOP } function ensureKeys(array $defaults, ?array $params=null): void { $dest = $this->dest; if ($dest === null) { # comme ne connait pas la classe de l'objet destination, on n'essaie pas # de le créer return; } $class = new ReflectionClass($dest); $keys = array_keys($defaults); $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; foreach ($keys as $key) { $name = $this->_getName("$prefix$key$suffix"); $property = $this->_getProperty($name, $class); if ($property !== null) { $type = $property->getType(); if ($type !== null && !$property->isInitialized($dest) && $type->allowsNull()) { # initialiser avec null au lieu de $defaults[$key] pour respecter le # type de la propriété $property->setValue($dest, null); } } elseif (!property_exists($dest, $name)) { $dest->$name = $defaults[$key]; } } } function ensureOrder(array $keys, ?array $params=null): void { # NOP } }