protectDest = $params["protect_dest"] ?? static::PROTECT_DEST; $this->dest =& $dest; $this->key = $key; $this->allowNull = $params["allow_null"] ?? static::ALLOW_NULL; $this->allowFalse = $params["allow_false"] ?? static::ALLOW_FALSE; } protected bool $protectDest; /** @var mixed|array|ArrayAccess */ protected $dest; /** @var null|int|string|array */ protected $key; function reset(&$dest, $key=null): self { $this->dest =& $dest; $this->key = $key; return $this; } function resetKey($key=null): self { $this->key = $key; return $this; } protected ?bool $allowNull; protected function isAllowNull(): bool { $allowNull = $this->allowNull; if ($allowNull !== null) return $allowNull; return $this->key !== null; } protected ?bool $allowFalse; protected function isAllowFalse(): bool { $allowFalse = $this->allowFalse; if ($allowFalse !== null) return $allowFalse; return $this->key === null; } function exists(): bool { $key = $this->key; if ($key === null) { return $this->isAllowNull() || $this->dest !== null; } else { return cl::phas($this->dest, $key); } } function available(): bool { if (!$this->exists()) return false; $key = $this->key; if ($key === null) $value = $this->dest; else $value = cl::pget($this->dest, $key); if ($value === "") return $this->allowEmpty; if ($value === null) return $this->isAllowNull(); if ($value === false) return $this->isAllowFalse(); return true; } function get($default=null) { $key = $this->key; if ($key === null) $value = $this->dest; else $value = cl::pget($this->dest, $key, $default); if ($value === "" && !$this->allowEmpty) return $default; if ($value === null && !$this->isAllowNull()) return $default; if ($value === false && !$this->isAllowFalse()) return $default; return $value; } function set($value): void { $key = $this->key; if ($key === null) { if (!$this->protectDest) $this->dest = $value; } else { cl::pset($this->dest, $key, $value); } } function del(): void { $key = $this->key; if ($key === null) { if (!$this->protectDest) $this->dest = null; } else { cl::pdel($this->dest, $key); } } function addKey($key): self { if ($key === null) return $this; if ($this->key !== null) $key = cl::merge($this->key, $key); return new KeyAccess($this->dest, $key, [ "allow_empty" => $this->allowEmpty, "allow_null" => $this->allowNull, "allow_false" => $this->allowFalse, "protect_dest" => $this->protectDest, ]); } function ensureAssoc(array $keys, ?array $params=null): void { $dest =& $this->dest; $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; $index = 0; foreach ($keys as $key) { if ($prefix !== null || $suffix !== null) { $destKey = "$prefix$key$suffix"; } else { # préserver les clés numériques $destKey = $key; } if ($dest !== null && array_key_exists($destKey, $dest)) continue; while (in_array($index, $keys, true)) { $index++; } if ($dest !== null && array_key_exists($index, $dest)) { $dest[$destKey] = $dest[$index]; unset($dest[$index]); $index++; } } } function ensureKeys(array $defaults, ?array $missings, ?array $params=null): void { $dest =& $this->dest; $keys = array_keys($defaults); $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; foreach ($keys as $key) { $destKey = "$prefix$key$suffix"; $haveMissing = $missings !== null && array_key_exists($key, $missings); if ($dest === null || !array_key_exists($destKey, $dest)) { $dest[$destKey] = $defaults[$key]; } elseif ($haveMissing && $dest[$destKey] === $missings[$key]) { $dest[$destKey] = $defaults[$key]; } } } function deleteMissings(array $missings, ?array $params=null): void { $dest =& $this->dest; $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; foreach ($missings as $key => $missing) { $destKey = "$prefix$key$suffix"; if (array_key_exists($destKey, $dest) && $dest[$destKey] === $missing) { unset($dest[$destKey]); } } } function ensureOrder(array $keys, ?array $params=null): void { $dest =& $this->dest; if ($dest === null) return; $prefix = $params["key_prefix"] ?? null; $suffix = $params["key_suffix"] ?? null; if ($prefix !== null || $suffix !== null) { foreach ($keys as &$key) { $key = "$prefix$key$suffix"; }; unset($key); } $destKeys = array_keys($dest); $keyCount = count($keys); if (array_slice($destKeys, 0, $keyCount) === $keys) { # si le tableau a déjà les bonnes clés dans le bon ordre, rien à faire return; } $ordered = []; foreach ($keys as $key) { if (array_key_exists($key, $dest)) { $ordered[$key] = $dest[$key]; unset($dest[$key]); } } $preserveKeys = $params["preserve_keys"] ?? false; if ($preserveKeys) $dest = cl::merge2($ordered, $dest); else $dest = array_merge($ordered, $dest); } }