2019-05-20 15:08:41 +10:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace pointybeard\Helpers\Cli\Input;
|
|
|
|
|
|
|
|
|
|
use pointybeard\Helpers\Functions\Flags;
|
|
|
|
|
|
|
|
|
|
abstract class AbstractInputHandler implements Interfaces\InputHandlerInterface
|
|
|
|
|
{
|
2019-05-24 17:16:49 +10:00
|
|
|
protected $input = [];
|
2019-05-20 15:08:41 +10:00
|
|
|
protected $collection = null;
|
|
|
|
|
|
|
|
|
|
abstract protected function parse(): bool;
|
|
|
|
|
|
|
|
|
|
public function bind(InputCollection $inputCollection, bool $skipValidation = false): bool
|
|
|
|
|
{
|
|
|
|
|
// Do the binding stuff here
|
2019-05-24 17:16:49 +10:00
|
|
|
$this->input = [];
|
2019-05-20 15:08:41 +10:00
|
|
|
$this->collection = $inputCollection;
|
|
|
|
|
|
|
|
|
|
$this->parse();
|
|
|
|
|
|
|
|
|
|
if (true !== $skipValidation) {
|
|
|
|
|
$this->validate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static function checkRequiredAndRequiredValue(AbstractInputType $input, array $context): void
|
|
|
|
|
{
|
|
|
|
|
if (!isset($context[$input->name()])) {
|
|
|
|
|
if (Flags\is_flag_set($input->flags(), AbstractInputType::FLAG_REQUIRED)) {
|
|
|
|
|
throw new Exceptions\RequiredInputMissingException($input);
|
|
|
|
|
}
|
|
|
|
|
} elseif (Flags\is_flag_set($input->flags(), AbstractInputType::FLAG_VALUE_REQUIRED) && (null == $context[$input->name()] || true === $context[$input->name()])) {
|
|
|
|
|
throw new Exceptions\RequiredInputMissingValueException($input);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function validate(): void
|
|
|
|
|
{
|
2019-05-24 17:16:49 +10:00
|
|
|
foreach ($this->collection->getItems() as $type => $items) {
|
|
|
|
|
foreach($items as $input) {
|
|
|
|
|
self::checkRequiredAndRequiredValue($input, $this->input);
|
|
|
|
|
|
|
|
|
|
if(
|
|
|
|
|
null !== $input->default() &&
|
|
|
|
|
null === $this->find($input->name()) &&
|
|
|
|
|
null === $input->validator()
|
|
|
|
|
) {
|
|
|
|
|
$result = $input->default();
|
|
|
|
|
} elseif(null !== $input->validator()) {
|
|
|
|
|
$validator = $input->validator();
|
|
|
|
|
|
|
|
|
|
if ($validator instanceof \Closure) {
|
|
|
|
|
$validator = new Validator($validator);
|
|
|
|
|
} elseif (!($validator instanceof Validator)) {
|
|
|
|
|
throw new \Exception("Validator for '{$input->name()}' must be NULL or an instance of either Closure or Input\Validator.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result = $validator->validate($input, $this);
|
2019-05-20 15:08:41 +10:00
|
|
|
} else {
|
2019-05-24 17:16:49 +10:00
|
|
|
$result = $this->find($input->name());
|
2019-05-20 15:08:41 +10:00
|
|
|
}
|
|
|
|
|
|
2019-05-24 17:16:49 +10:00
|
|
|
$this->input[$input->name()] = $result;
|
2019-05-20 15:08:41 +10:00
|
|
|
}
|
|
|
|
|
}
|
2019-05-24 17:16:49 +10:00
|
|
|
}
|
2019-05-20 15:08:41 +10:00
|
|
|
|
2019-05-24 17:16:49 +10:00
|
|
|
public function find(string $name)
|
|
|
|
|
{
|
|
|
|
|
if(isset($this->input[$name])) {
|
|
|
|
|
return $this->input[$name];
|
|
|
|
|
}
|
2019-05-20 15:08:41 +10:00
|
|
|
|
2019-05-24 17:16:49 +10:00
|
|
|
// Check the collection to see if anything responds to $name
|
|
|
|
|
foreach($this->collection->getItems() as $type => $items) {
|
|
|
|
|
foreach($items as $ii) {
|
|
|
|
|
if($ii->respondsTo($name) && isset($this->input[$ii->name()])) {
|
|
|
|
|
return $this->input[$ii->name()];
|
2019-05-20 15:08:41 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-24 17:16:49 +10:00
|
|
|
throw new Exceptions\InputNotFoundException($name);
|
2019-05-20 15:08:41 +10:00
|
|
|
}
|
|
|
|
|
|
2019-05-24 17:16:49 +10:00
|
|
|
public function getInput(): array
|
2019-05-20 15:08:41 +10:00
|
|
|
{
|
2019-05-24 17:16:49 +10:00
|
|
|
return $this->input;
|
2019-05-20 15:08:41 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getCollection(): ?InputCollection
|
|
|
|
|
{
|
|
|
|
|
return $this->collection;
|
|
|
|
|
}
|
|
|
|
|
}
|