$cdef } */ protected function COMMANDS(): array { return static::COMMANDS; } const COMMANDS = null; private $commands; private $dcommands; private $aliases; protected function buildCommands(): void { if ($this->commands !== null) return; $commands = []; $dcommands = []; $aliases = []; $index = 0; foreach ($this->COMMANDS() as $key => $cdef) { if ($key === $index) { $index++; [$cnames, $assoc] = A::split_assoc($cdef); $cname = $cnames[0]; if ($cname === null) { # commande complètement dynamique $dcommands[] = $cnames[2]; if ($cnames[1] === null) continue; $cdef = [null, $cnames[1]]; $cname = $cnames[1][0]; $cnames = []; } } else { $cname = $key; $cnames = [$cname]; [$seq, $assoc] = A::split_assoc($cdef); A::merge($cnames, $seq); A::merge_assoc($cdef, $cnames, $assoc, true); } $commands[$cname] = $cdef; foreach ($cnames as $key) { $aliases[$key] = $cname; } } $this->commands = $commands; $this->dcommands = $dcommands; $this->aliases = $aliases; } function getCommands(): ?array { $this->buildCommands(); return array_keys($this->commands); } function getCommandDefs(string $command, bool $virtual): ?array { $this->buildCommands(); $command = A::get($this->aliases, $command, $command); $cdef = A::get($this->commands, $command); if ($cdef !== null) { if ($cdef[0] === null) { if ($virtual) $cdef = $cdef[1]; else return null; } return $cdef !== null? [$cdef]: null; } # tester les commandes complètement dynamiques foreach ($this->dcommands as $func) { $cdef = func::call($func, $command); if ($cdef !== null) return [$cdef]; } return null; } }