eachEnsureSchema($keys); $namedkeys = []; $pkeys = null; foreach ($keys as $key) { $namedkeys[$key["name"]] = $key; if ($key["primary"]) $pkeys[] = $key; } $this->kinfos[$channel] = ["keys" => $namedkeys, "pkeys" => $pkeys]; } private static function get_kvalues(array $keys, $item): array { $item = A::with($item); $kvalues = []; foreach ($keys as $kname => $key) { $kvalues[$kname] = A::get($item, $key["name"]); } return $kvalues; } private static function compute_itemkey(array $pkvalues): string { return implode("-", $pkvalues); } private static function get_itemkey(?array $kinfos, $item): ?string { if ($kinfos === null) return null; $pkeys = $kinfos["pkeys"]; if ($pkeys === null) return null; $pkvalues = self::get_kvalues($pkeys, $item); return self::compute_itemkey($pkvalues); } /** @var array */ protected $data; /** * trier les données selon les clés spécifiées. NB: cette implémentation * autorise qu'on utilise des clés qui n'ont pas été déclarées avec * {@link setKeys()} * * @see ICapacitor::sort() */ function sort(?array $keys=null, ?string $channel=null): void { $kinfos = A::get($this->kinfos, $channel); $asort = $kinfos !== null && $kinfos["pkeys"] !== null; $defaultKeys = $kinfos !== null? $kinfos["keys"]: null; if ($keys !== null) { self::sort_md()->eachEnsureSchema($keys); } else { $keys = $defaultKeys; if ($keys === null) return; } foreach ($keys as $kname => &$key) { if ($key["reverse"] === null && $defaultKeys !== null && array_key_exists($kname, $defaultKeys)) { $key["reverse"] = $defaultKeys[$kname]["reverse"]; } if ($key["reverse"] === null) $key["reverse"] = false; }; unset($key); $sortfunc = function ($a, $b) use ($keys) { $akvs = self::get_kvalues($keys, $a); $bkvs = self::get_kvalues($keys, $b); foreach ($keys as $kname => $key) { $akv = $akvs[$kname]; $bkv = $bkvs[$kname]; if ($akv == $bkv) continue; if ($akv < $bkv) { return $key["reverse"] ? 1 : -1; } else { return $key["reverse"] ? -1 : 1; } } return 0; }; if ($asort) uasort($this->data[$channel], $sortfunc); else usort($this->data[$channel], $sortfunc); } function charge($item, ?string $channel=null, $pkvalues=null): void { $kinfos = A::get($this->kinfos, $channel); $itemkey = self::get_itemkey($kinfos, $item); if ($itemkey === null && $item === null) { if ($pkvalues === null) return; $itemkey = self::compute_itemkey($pkvalues); } A::set($this->data[$channel], $itemkey, $item); } function getItem($pkvalues, ?string $channel=null, $default=null) { if (is_array($pkvalues)) { $itemkey = self::compute_itemkey($pkvalues); } else { $itemkey = $pkvalues; } return A::_pget($this->data, [$channel, $itemkey], $default); } function discharge(?string $channel=null, bool $remove=true): iterable { $items = A::get($this->data, $channel, []); if ($remove) A::del($this->data, $channel); return $items; } }