mirror of
https://github.com/n3w/helpers-cli-input.git
synced 2025-12-19 12:43:23 +00:00
InputCollection now implements Iterator and Countable (implementing required methods). Removed use of $type. Added getItemsExcludeByType(). getItemsByType() and getItems() now returns an Iterator. Renamed append() to add() and added $position flag. Added POSITION_APPEND and POSITION_PREPEND flags.
This commit is contained in:
parent
90db5c2047
commit
05d283b6d2
1 changed files with 92 additions and 38 deletions
|
|
@ -4,96 +4,150 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace pointybeard\Helpers\Cli\Input;
|
namespace pointybeard\Helpers\Cli\Input;
|
||||||
|
|
||||||
class InputCollection
|
class InputCollection implements \Iterator, \Countable
|
||||||
{
|
{
|
||||||
private $items = [];
|
private $items = [];
|
||||||
|
private $position = 0;
|
||||||
|
|
||||||
|
public const POSITION_APPEND = 0x0001;
|
||||||
|
public const POSITION_PREPEND = 0x0002;
|
||||||
|
|
||||||
// Prevents the class from being instanciated
|
// Prevents the class from being instanciated
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
$this->position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function append(Interfaces\InputTypeInterface $input, bool $replace = false): self
|
public function current(): mixed
|
||||||
{
|
{
|
||||||
$class = new \ReflectionClass($input);
|
return $this->items[$this->position];
|
||||||
|
}
|
||||||
|
|
||||||
if (null !== $this->find($input->name(), null, null, $type, $index) && !$replace) {
|
public function key(): scalar
|
||||||
throw new \Exception("{$class->getShortName()} '{$input->name()}' already exists in this collection");
|
{
|
||||||
|
return $this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function next(): void
|
||||||
|
{
|
||||||
|
++$this->position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind(): void
|
||||||
|
{
|
||||||
|
$this->position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function valid(): bool
|
||||||
|
{
|
||||||
|
return isset($this->items[$this->position]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function count() : int {
|
||||||
|
return count($this->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exists(string $name, &$index=null): bool {
|
||||||
|
return (null !== $this->find($name, null, null, $index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove(string $name): self {
|
||||||
|
if(!$this->exists($name, $index)) {
|
||||||
|
throw new \Exception("Input '{$name}' does not exist in this collection");
|
||||||
|
}
|
||||||
|
unset($this->items[$index]);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add(Interfaces\InputTypeInterface $input, bool $replace = false, int $position=self::POSITION_APPEND): self
|
||||||
|
{
|
||||||
|
if($this->exists($input->name(), $index) && !$replace) {
|
||||||
|
throw new \Exception(
|
||||||
|
(new \ReflectionClass($input))->getShortName()." '{$input->name()}' already exists in this collection"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true == $replace && null !== $index) {
|
if (true == $replace && null !== $index) {
|
||||||
$this->items[$class->getShortName()][$index] = $input;
|
$this->items[$index] = $input;
|
||||||
} else {
|
} else {
|
||||||
$this->items[$class->getShortName()][] = $input;
|
if($position == self::POSITION_PREPEND) {
|
||||||
|
array_unshift($this->items, $input);
|
||||||
|
} else {
|
||||||
|
array_push($this->items, $input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function find(string $name, array $restrictToType = null, array $excludeType = null, &$type = null, &$index = null): ?AbstractInputType
|
public function find(string $name, array $restrictToType = null, array $excludeType = null, &$index = null): ?AbstractInputType
|
||||||
{
|
{
|
||||||
foreach ($this->items as $type => $items) {
|
foreach ($this->items as $index => $input) {
|
||||||
// Check if we're restricting to or excluding specific types
|
// Check if we're restricting to or excluding specific types
|
||||||
if (null !== $restrictToType && !in_array($type, $restrictToType)) {
|
if (null !== $restrictToType && !in_array($input->getType(), $restrictToType)) {
|
||||||
continue;
|
continue;
|
||||||
} elseif (null !== $excludeType && in_array($type, $excludeType)) {
|
} elseif (null !== $excludeType && in_array($input->getType(), $excludeType)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($items as $index => $item) {
|
if ($input->respondsTo($name)) {
|
||||||
if ($item->respondsTo($name)) {
|
return $input;
|
||||||
return $item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
$type = null;
|
|
||||||
$index = null;
|
$index = null;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTypes(): array
|
public function getTypes(): array
|
||||||
{
|
{
|
||||||
return array_keys($this->items);
|
$types = [];
|
||||||
|
foreach($this->items as $input) {
|
||||||
|
$types[] = $input->getType();
|
||||||
|
}
|
||||||
|
return array_unique($types);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItems(): array
|
public function getItems(): \Iterator
|
||||||
{
|
{
|
||||||
return $this->items;
|
return (new \ArrayObject($this->items))->getIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItemsByType(string $type): array
|
public function getItemsByType(string $type): \Iterator
|
||||||
{
|
{
|
||||||
return $this->items[$type] ?? [];
|
return new InputTypeFilterIterator(
|
||||||
|
$this->getItems(),
|
||||||
|
[$type],
|
||||||
|
InputTypeFilterIterator::FILTER_INCLUDE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getItemByIndex(string $type, int $index): ?AbstractInputType
|
public function getItemsExcludeByType(string $type): \Iterator
|
||||||
{
|
{
|
||||||
return $this->items[$type][$index] ?? null;
|
return new InputTypeFilterIterator(
|
||||||
|
$this->getItems(),
|
||||||
|
[$type],
|
||||||
|
InputTypeFilterIterator::FILTER_EXCLUDE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemByIndex(int $index): ?AbstractInputType
|
||||||
|
{
|
||||||
|
return $this->items[$index] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function merge(self ...$collections): self
|
public static function merge(self ...$collections): self
|
||||||
{
|
{
|
||||||
$inputs = [];
|
|
||||||
|
|
||||||
|
$iterator = new \AppendIterator;
|
||||||
foreach ($collections as $c) {
|
foreach ($collections as $c) {
|
||||||
foreach ($c->getItems() as $type => $items) {
|
$iterator->append($c->getItems());
|
||||||
foreach ($items as $item) {
|
|
||||||
$inputs[] = $item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$mergedCollection = new self();
|
$mergedCollection = new self();
|
||||||
|
foreach ($iterator as $input) {
|
||||||
foreach ($inputs as $input) {
|
$mergedCollection->add($input, true);
|
||||||
try {
|
|
||||||
$mergedCollection->append($input, true);
|
|
||||||
} catch (\Exception $ex) {
|
|
||||||
// Already exists, so skip it.
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $mergedCollection;
|
return $mergedCollection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue