From 213cf4b12be7c96f4c5416445517405dfb03acbb Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 02:31:46 +0200 Subject: [PATCH 01/10] extrated commands from ConsoleUI --- src/ConsoleUI.php | 102 +++++++++++++----------- src/VendingMachine.php | 11 +++ src/models/commands/AddCoinCommand.php | 18 +++++ src/models/commands/BaseCommand.php | 20 +++++ src/models/commands/CommandInteface.php | 11 +++ src/models/commands/GetCommand.php | 19 +++++ src/models/commands/ReturnCommand.php | 14 ++++ src/models/generic/Collection.php | 5 ++ 8 files changed, 153 insertions(+), 47 deletions(-) create mode 100644 src/models/commands/AddCoinCommand.php create mode 100644 src/models/commands/BaseCommand.php create mode 100644 src/models/commands/CommandInteface.php create mode 100644 src/models/commands/GetCommand.php create mode 100644 src/models/commands/ReturnCommand.php diff --git a/src/ConsoleUI.php b/src/ConsoleUI.php index 761dd3b..b6d3a96 100644 --- a/src/ConsoleUI.php +++ b/src/ConsoleUI.php @@ -9,20 +9,22 @@ use vending\models\Coins; use vending\models\Product; use vending\models\Products; +use vending\ui\BaseCommand; class ConsoleUI { private $coinManager; private $products; private $vendingMachine; - private $commands = ['RETURN-COIN', 'GET-']; - + public function start() { + echo "\n"; + $this->productsHeader(); while (true) { $line = readline($this->status()); $commands = $this->parse($line); - echo ' -> ' . $this->execute(...$commands) . PHP_EOL . PHP_EOL; + $this->processCommands(...$commands); } } @@ -32,61 +34,67 @@ public function status():string return " $insertedAmount$ >"; } - public function parse($line): array + public function productsHeader() { - $sanitized = str_replace(' ', '', $line); - return explode(',', $sanitized); + $productHeader = array_reduce( + $this->products->toArray(), + function ($initial, $product) { + return $initial .= " ".$product->hash()."(".$product->count()."): ".(string)$product->getValue(); + }, + '' + ); + + echo ' PRODUCTS: '.$productHeader . PHP_EOL; } - public function execute(...$commands):string + public function parse($line): array { - $result = []; - $invalidCoins = []; - foreach ($commands as $command) { - $command = strtoupper($command); - $spltCommand = explode('-', $command); - - switch ($spltCommand[0]) { - case 'GET': - try { - list($product, $coins) = $this->vendingMachine->sellProduct($spltCommand[1]); - } catch (\Exception $e) { - return $e->getMessage(); - } - return "SOLD $product RETURN: ".implode(', ', $coins); - break; - case 'RETURN': - if ($command == 'RETURN-COIN') { - return "RETURN: ". implode(', ', $this->vendingMachine->returnCoins()); - } - break; - default: - - } - - - - $fltValue = floatval($command); + $sanitized = trim(str_replace(' ', ' ', $line)); + $commands = []; + foreach (explode(',', $sanitized) as $part) { + $commands[] = trim(str_replace('-', ' ', $part)); + } + return $commands; + } + private function processCommands(...$commands) + { + foreach ($commands as $fullCommand) { + $args = explode(' ', $fullCommand); + $command = array_shift($args); - if ($fltValue != 0) { - if ($fltValue < 0) { - // no negative money in coins - $fltValue *= -1; + if ($command) { + $command = ucfirst(strtolower($command)); + if (is_numeric($command)) { + $args = [$command]; + $command = 'AddCoin'; } - $invalid = $this->vendingMachine->insertCoin($fltValue); - if ($invalid != 0) { - $invalidCoins[] = $invalid; - } - continue; + $this->execute($command, ...$args); } } + } - if (count($invalidCoins) > 0) { - $result[] = "RETURN INVALID COINS: ".implode(', ', $invalidCoins); + private function execute($command, ...$args):string + { + $commandInstance = $this->initializeCommand($command); + if ($commandInstance) { + $result = $commandInstance->execute(...$args); + if (!empty($result)) { + echo ' -> ' . $result . PHP_EOL . PHP_EOL; + } + } + return "Error on introduced request"; + } + + + private function initializeCommand(string $command) + { + try { + $class = new \ReflectionClass('vending\ui\\'.ucfirst($command).'Command'); + return $class->newInstanceArgs([$this->vendingMachine]); + } catch (\ReflectionException $e) { + return false; } - - return implode(', ', $result); } public function setDefaultValues() diff --git a/src/VendingMachine.php b/src/VendingMachine.php index 6ab656e..221f23c 100644 --- a/src/VendingMachine.php +++ b/src/VendingMachine.php @@ -11,6 +11,7 @@ class VendingMachine private $insertedCoins = []; private $products = null; private $checkout; + private $service = false; public function __construct(CoinManager $coinManager, Products $products) @@ -53,4 +54,14 @@ public function sellProduct(string $productCode) : array return [$product, $this->returnCoins()]; } + + public function setService(bool $status) + { + $this->service = $status; + } + + public function inService(): bool + { + return $this->service; + } } diff --git a/src/models/commands/AddCoinCommand.php b/src/models/commands/AddCoinCommand.php new file mode 100644 index 0000000..996c53b --- /dev/null +++ b/src/models/commands/AddCoinCommand.php @@ -0,0 +1,18 @@ + 0 && is_numeric($args[0])) { + $fvalue = $this->vendingMachine->insertCoin((float)$args[0]); + if ($fvalue != 0) { + return 'Invalid Coin to add! RETURN: '.$fvalue; + } + } + #we should throw error + return ''; + } +} diff --git a/src/models/commands/BaseCommand.php b/src/models/commands/BaseCommand.php new file mode 100644 index 0000000..e604c80 --- /dev/null +++ b/src/models/commands/BaseCommand.php @@ -0,0 +1,20 @@ +vendingMachine = $vendingMachine; + } + + public function execute(...$args):string + { + } +} diff --git a/src/models/commands/CommandInteface.php b/src/models/commands/CommandInteface.php new file mode 100644 index 0000000..d69c17c --- /dev/null +++ b/src/models/commands/CommandInteface.php @@ -0,0 +1,11 @@ + 0) { + try { + list($product, $coins) = $this->vendingMachine->sellProduct($args[0]); + } catch (\Exception $e) { + return $e->getMessage(); + } + return "SOLD $product RETURN: ".implode(', ', $coins); + } + return ''; + } +} diff --git a/src/models/commands/ReturnCommand.php b/src/models/commands/ReturnCommand.php new file mode 100644 index 0000000..c290224 --- /dev/null +++ b/src/models/commands/ReturnCommand.php @@ -0,0 +1,14 @@ + 0 &&strtoupper($args[0]) == 'COIN') { + return "RETURN: ". implode(', ', $this->vendingMachine->returnCoins()); + } + return 'Can only return coins'; + } +} diff --git a/src/models/generic/Collection.php b/src/models/generic/Collection.php index dbe7d8d..6d20d4a 100644 --- a/src/models/generic/Collection.php +++ b/src/models/generic/Collection.php @@ -38,6 +38,11 @@ public function getIterator() return new \ArrayIterator($this->items->toArray()); } + public function toArray() + { + return $this->items->toArray(); + } + private function internalSort() { $this->items->sort(function ($a, $b) { From 889be525693780c59490d34fb4069be1400a64c4 Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 02:58:05 +0200 Subject: [PATCH 02/10] some ordering and small bug --- src/Checkout.php | 2 +- src/{ => ui}/ConsoleUI.php | 6 ++++-- src/{models => ui}/commands/AddCoinCommand.php | 2 +- src/{models => ui}/commands/BaseCommand.php | 3 +-- src/{models => ui}/commands/CommandInteface.php | 2 +- src/{models => ui}/commands/GetCommand.php | 2 +- src/{models => ui}/commands/ReturnCommand.php | 2 +- 7 files changed, 10 insertions(+), 9 deletions(-) rename src/{ => ui}/ConsoleUI.php (93%) rename src/{models => ui}/commands/AddCoinCommand.php (93%) rename src/{models => ui}/commands/BaseCommand.php (86%) rename src/{models => ui}/commands/CommandInteface.php (87%) rename src/{models => ui}/commands/GetCommand.php (93%) rename src/{models => ui}/commands/ReturnCommand.php (91%) diff --git a/src/Checkout.php b/src/Checkout.php index 6427e70..88560c9 100644 --- a/src/Checkout.php +++ b/src/Checkout.php @@ -18,7 +18,7 @@ public function __construct(CoinManager $coinManager, Products $products) public function sell(string $productCode, array &$money) { $product = $this->products->find($productCode); - if (!$product->any()) { + if ($product == null || !$product->any()) { throw new \Exception("Product $productCode not available", 11); } diff --git a/src/ConsoleUI.php b/src/ui/ConsoleUI.php similarity index 93% rename from src/ConsoleUI.php rename to src/ui/ConsoleUI.php index b6d3a96..cb6a4d1 100644 --- a/src/ConsoleUI.php +++ b/src/ui/ConsoleUI.php @@ -22,7 +22,9 @@ public function start() echo "\n"; $this->productsHeader(); while (true) { - $line = readline($this->status()); + // fwrite(STDOUT, $this->status()); + print($this->status()); + $line = readline(); $commands = $this->parse($line); $this->processCommands(...$commands); } @@ -90,7 +92,7 @@ private function execute($command, ...$args):string private function initializeCommand(string $command) { try { - $class = new \ReflectionClass('vending\ui\\'.ucfirst($command).'Command'); + $class = new \ReflectionClass('vending\ui\commands\\'.ucfirst($command).'Command'); return $class->newInstanceArgs([$this->vendingMachine]); } catch (\ReflectionException $e) { return false; diff --git a/src/models/commands/AddCoinCommand.php b/src/ui/commands/AddCoinCommand.php similarity index 93% rename from src/models/commands/AddCoinCommand.php rename to src/ui/commands/AddCoinCommand.php index 996c53b..6a9737c 100644 --- a/src/models/commands/AddCoinCommand.php +++ b/src/ui/commands/AddCoinCommand.php @@ -1,6 +1,6 @@ Date: Tue, 13 Oct 2020 03:17:19 +0200 Subject: [PATCH 03/10] starting to give better format --- src/ui/ConsoleUI.php | 20 +++++++++++++------- src/ui/commands/BaseCommand.php | 5 ++++- src/ui/commands/CommandInteface.php | 3 ++- src/ui/output/ConsoleOutput.php | 16 ++++++++++++++++ src/ui/output/OutputInterface.php | 9 +++++++++ 5 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 src/ui/output/ConsoleOutput.php create mode 100644 src/ui/output/OutputInterface.php diff --git a/src/ui/ConsoleUI.php b/src/ui/ConsoleUI.php index cb6a4d1..ff96e70 100644 --- a/src/ui/ConsoleUI.php +++ b/src/ui/ConsoleUI.php @@ -10,20 +10,26 @@ use vending\models\Product; use vending\models\Products; use vending\ui\BaseCommand; +use vending\ui\output\ConsoleOutput; -class ConsoleUI +final class ConsoleUI { private $coinManager; private $products; private $vendingMachine; + private $consoleOutput; + + public function __construct() + { + $this->consoleOutput = new ConsoleOutput(); + } public function start() { - echo "\n"; + $this->consoleOutput->writeln(''); $this->productsHeader(); while (true) { - // fwrite(STDOUT, $this->status()); - print($this->status()); + $this->consoleOutput->write($this->status()); $line = readline(); $commands = $this->parse($line); $this->processCommands(...$commands); @@ -46,7 +52,7 @@ function ($initial, $product) { '' ); - echo ' PRODUCTS: '.$productHeader . PHP_EOL; + $this->consoleOutput->writeln(' PRODUCTS: '.$productHeader); } public function parse($line): array @@ -82,7 +88,7 @@ private function execute($command, ...$args):string if ($commandInstance) { $result = $commandInstance->execute(...$args); if (!empty($result)) { - echo ' -> ' . $result . PHP_EOL . PHP_EOL; + $this->consoleOutput->writeln(' -> ' . $result . PHP_EOL); } } return "Error on introduced request"; @@ -93,7 +99,7 @@ private function initializeCommand(string $command) { try { $class = new \ReflectionClass('vending\ui\commands\\'.ucfirst($command).'Command'); - return $class->newInstanceArgs([$this->vendingMachine]); + return $class->newInstanceArgs([$this->vendingMachine, $this->consoleOutput]); } catch (\ReflectionException $e) { return false; } diff --git a/src/ui/commands/BaseCommand.php b/src/ui/commands/BaseCommand.php index c25f190..1f999a7 100644 --- a/src/ui/commands/BaseCommand.php +++ b/src/ui/commands/BaseCommand.php @@ -3,14 +3,17 @@ namespace vending\ui\commands; use vending\VendingMachine; +use vending\ui\output\OutputInterface; class BaseCommand implements CommandInterface { protected $vendingMachine; + protected $consoleOutput; - public function __construct(\vending\VendingMachine $vendingMachine) + public function __construct(VendingMachine $vendingMachine, OutputInterface $consoleOutput) { $this->vendingMachine = $vendingMachine; + $this->consoleOutput = $consoleOutput; } public function execute(...$args):string diff --git a/src/ui/commands/CommandInteface.php b/src/ui/commands/CommandInteface.php index 5d0fb6f..f0844d8 100644 --- a/src/ui/commands/CommandInteface.php +++ b/src/ui/commands/CommandInteface.php @@ -3,9 +3,10 @@ namespace vending\ui\commands; use vending\VendingMachine; +use vending\ui\output\OutputInterface; interface CommandInterface { - public function __construct(\vending\VendingMachine $vendingMachine); + public function __construct(VendingMachine $vendingMachine, OutputInterface $consoleOutput); public function execute(...$args):string; } diff --git a/src/ui/output/ConsoleOutput.php b/src/ui/output/ConsoleOutput.php new file mode 100644 index 0000000..90d85f0 --- /dev/null +++ b/src/ui/output/ConsoleOutput.php @@ -0,0 +1,16 @@ +write($message . PHP_EOL); + } +} diff --git a/src/ui/output/OutputInterface.php b/src/ui/output/OutputInterface.php new file mode 100644 index 0000000..cd245a0 --- /dev/null +++ b/src/ui/output/OutputInterface.php @@ -0,0 +1,9 @@ + Date: Tue, 13 Oct 2020 04:17:44 +0200 Subject: [PATCH 04/10] removing complexity from consoleUI --- src/VendingMachine.php | 10 ++++++++++ src/prompt.php | 26 ++++++++++++++++++++++++-- src/ui/ConsoleUI.php | 36 ++++-------------------------------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/src/VendingMachine.php b/src/VendingMachine.php index 221f23c..1c9408f 100644 --- a/src/VendingMachine.php +++ b/src/VendingMachine.php @@ -64,4 +64,14 @@ public function inService(): bool { return $this->service; } + + public function getCoinManager() + { + return $this->coinManager; + } + + public function getProducts() + { + return $this->products; + } } diff --git a/src/prompt.php b/src/prompt.php index 29dbb0b..246b9ba 100644 --- a/src/prompt.php +++ b/src/prompt.php @@ -3,7 +3,29 @@ require_once './vendor/autoload.php'; use vending\ui\ConsoleUI; +use vending\models\Coins; +use vending\models\Coin; +use vending\models\Product; -$console = new ConsoleUI(); -$console->setDefaultValues(); +function defaultValues() +{ + $coinManager = new vending\CoinManager( + new Coins( + new Coin(0.05, 10), + new Coin(0.1, 10), + new Coin(0.25, 10), + new Coin(1, 10) + ) + ); + + $products = new vending\models\Products( + new Product('WATER', 0.65, 10), + new Product('JUICE', 1.00, 10), + new Product('SODA', 1.50, 10) + ); + + return new \vending\VendingMachine($coinManager, $products); +} + +$console = new ConsoleUI(defaultValues()); $console->start(); diff --git a/src/ui/ConsoleUI.php b/src/ui/ConsoleUI.php index ff96e70..c5b15ec 100644 --- a/src/ui/ConsoleUI.php +++ b/src/ui/ConsoleUI.php @@ -2,26 +2,18 @@ namespace vending\ui; -use vending\Checkout; -use vending\CoinManager; -use vending\VendingMachine; -use vending\models\Coin; -use vending\models\Coins; -use vending\models\Product; -use vending\models\Products; use vending\ui\BaseCommand; use vending\ui\output\ConsoleOutput; final class ConsoleUI { - private $coinManager; - private $products; private $vendingMachine; private $consoleOutput; - public function __construct() + public function __construct(\vending\VendingMachine $vendingMachine) { $this->consoleOutput = new ConsoleOutput(); + $this->vendingMachine = $vendingMachine; } public function start() @@ -36,7 +28,7 @@ public function start() } } - public function status():string + public function prompt():string { $insertedAmount = number_format($this->vendingMachine->getInsertedAmount(), 2, '.', ','); return " $insertedAmount$ >"; @@ -45,7 +37,7 @@ public function status():string public function productsHeader() { $productHeader = array_reduce( - $this->products->toArray(), + $this->vendingMachine->getProducts()->toArray(), function ($initial, $product) { return $initial .= " ".$product->hash()."(".$product->count()."): ".(string)$product->getValue(); }, @@ -104,24 +96,4 @@ private function initializeCommand(string $command) return false; } } - - public function setDefaultValues() - { - $this->coinManager = new CoinManager( - new Coins( - new Coin(0.05, 10), - new Coin(0.1, 10), - new Coin(0.25, 10), - new Coin(1, 10) - ) - ); - - $this->products = new Products( - new Product('WATER', 0.65, 10), - new Product('JUICE', 1.00, 10), - new Product('SODA', 1.50, 10) - ); - - $this->vendingMachine = new VendingMachine($this->coinManager, $this->products); - } } From dda1dd86e23e12757c6f672363082f27e18675ae Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 04:19:25 +0200 Subject: [PATCH 05/10] BaseShell refactored from ConsoleUI --- src/ui/BaseShell.php | 86 ++++++++++++++++++++++++++++++ src/ui/ConsoleUI.php | 77 ++------------------------ src/ui/commands/AddCoinCommand.php | 2 +- 3 files changed, 90 insertions(+), 75 deletions(-) create mode 100644 src/ui/BaseShell.php diff --git a/src/ui/BaseShell.php b/src/ui/BaseShell.php new file mode 100644 index 0000000..f29c3ac --- /dev/null +++ b/src/ui/BaseShell.php @@ -0,0 +1,86 @@ +consoleOutput = new ConsoleOutput(); + $this->vendingMachine = $vendingMachine; + } + + public function start() + { + $this->consoleOutput->writeln(''); + $this->consoleOutput->writeln($this->header()); + + while (true) { + $this->consoleOutput->write($this->prompt()); + $line = readline(); + $commands = $this->parse($line); + $this->processCommands(...$commands); + } + } + + public function prompt():string + { + return ">"; + } + + public function parse($line): array + { + $sanitized = trim(str_replace(' ', ' ', $line)); + $commands = []; + foreach (explode(',', $sanitized) as $part) { + $commands[] = trim(str_replace('-', ' ', $part)); + } + return $commands; + } + + private function processCommands(...$commands) + { + foreach ($commands as $fullCommand) { + $args = explode(' ', $fullCommand); + $command = array_shift($args); + + if ($command) { + $command = ucfirst(strtolower($command)); + if (is_numeric($command)) { + $args = [$command]; + $command = 'AddCoin'; + } + $this->execute($command, ...$args); + } + } + } + + private function execute($command, ...$args) + { + $commandInstance = $this->initializeCommand($command); + if ($commandInstance) { + $result = $commandInstance->execute(...$args); + // print_r([empty($result)]); + if (!empty($result)) { + $this->consoleOutput->writeln(' -> ' . $result . PHP_EOL); + } + } + } + + + private function initializeCommand(string $command) + { + try { + $class = new \ReflectionClass("vending\\ui\\commands\\{$command}Command"); + return $class->newInstanceArgs([$this->vendingMachine, $this->consoleOutput]); + } catch (\ReflectionException $e) { + return false; + } + } +} diff --git a/src/ui/ConsoleUI.php b/src/ui/ConsoleUI.php index c5b15ec..b8afe85 100644 --- a/src/ui/ConsoleUI.php +++ b/src/ui/ConsoleUI.php @@ -5,36 +5,15 @@ use vending\ui\BaseCommand; use vending\ui\output\ConsoleOutput; -final class ConsoleUI +final class ConsoleUI extends BaseShell { - private $vendingMachine; - private $consoleOutput; - - public function __construct(\vending\VendingMachine $vendingMachine) - { - $this->consoleOutput = new ConsoleOutput(); - $this->vendingMachine = $vendingMachine; - } - - public function start() - { - $this->consoleOutput->writeln(''); - $this->productsHeader(); - while (true) { - $this->consoleOutput->write($this->status()); - $line = readline(); - $commands = $this->parse($line); - $this->processCommands(...$commands); - } - } - public function prompt():string { $insertedAmount = number_format($this->vendingMachine->getInsertedAmount(), 2, '.', ','); return " $insertedAmount$ >"; } - public function productsHeader() + public function header() { $productHeader = array_reduce( $this->vendingMachine->getProducts()->toArray(), @@ -44,56 +23,6 @@ function ($initial, $product) { '' ); - $this->consoleOutput->writeln(' PRODUCTS: '.$productHeader); - } - - public function parse($line): array - { - $sanitized = trim(str_replace(' ', ' ', $line)); - $commands = []; - foreach (explode(',', $sanitized) as $part) { - $commands[] = trim(str_replace('-', ' ', $part)); - } - return $commands; - } - - private function processCommands(...$commands) - { - foreach ($commands as $fullCommand) { - $args = explode(' ', $fullCommand); - $command = array_shift($args); - - if ($command) { - $command = ucfirst(strtolower($command)); - if (is_numeric($command)) { - $args = [$command]; - $command = 'AddCoin'; - } - $this->execute($command, ...$args); - } - } - } - - private function execute($command, ...$args):string - { - $commandInstance = $this->initializeCommand($command); - if ($commandInstance) { - $result = $commandInstance->execute(...$args); - if (!empty($result)) { - $this->consoleOutput->writeln(' -> ' . $result . PHP_EOL); - } - } - return "Error on introduced request"; - } - - - private function initializeCommand(string $command) - { - try { - $class = new \ReflectionClass('vending\ui\commands\\'.ucfirst($command).'Command'); - return $class->newInstanceArgs([$this->vendingMachine, $this->consoleOutput]); - } catch (\ReflectionException $e) { - return false; - } + return ' PRODUCTS: '.$productHeader; } } diff --git a/src/ui/commands/AddCoinCommand.php b/src/ui/commands/AddCoinCommand.php index 6a9737c..8b810c1 100644 --- a/src/ui/commands/AddCoinCommand.php +++ b/src/ui/commands/AddCoinCommand.php @@ -13,6 +13,6 @@ public function execute(...$args):string } } #we should throw error - return ''; + return ""; } } From b20115667b8528a3ed43e3e4de8c0db829c9ef47 Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 04:58:53 +0200 Subject: [PATCH 06/10] Service shell working first command implemented --- src/CoinManager.php | 5 +++ src/ui/BaseShell.php | 17 ++++++---- src/ui/commands/ServiceCommand.php | 16 ++++++++++ src/ui/service/ServiceConsole.php | 30 ++++++++++++++++++ src/ui/service/commands/InfoCommand.php | 41 +++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 src/ui/commands/ServiceCommand.php create mode 100644 src/ui/service/ServiceConsole.php create mode 100644 src/ui/service/commands/InfoCommand.php diff --git a/src/CoinManager.php b/src/CoinManager.php index 17222c1..535c5e4 100644 --- a/src/CoinManager.php +++ b/src/CoinManager.php @@ -51,4 +51,9 @@ public function add(...$coins) return true; } + + public function getCoins() + { + return $this->coinDrawers; + } } diff --git a/src/ui/BaseShell.php b/src/ui/BaseShell.php index f29c3ac..724ce71 100644 --- a/src/ui/BaseShell.php +++ b/src/ui/BaseShell.php @@ -9,6 +9,7 @@ class BaseShell { protected $vendingMachine; protected $consoleOutput; + protected $running = true; public function __construct(\vending\VendingMachine $vendingMachine) { @@ -21,7 +22,7 @@ public function start() $this->consoleOutput->writeln(''); $this->consoleOutput->writeln($this->header()); - while (true) { + while ($this->running) { $this->consoleOutput->write($this->prompt()); $line = readline(); $commands = $this->parse($line); @@ -34,7 +35,7 @@ public function prompt():string return ">"; } - public function parse($line): array + protected function parse($line): array { $sanitized = trim(str_replace(' ', ' ', $line)); $commands = []; @@ -44,12 +45,17 @@ public function parse($line): array return $commands; } - private function processCommands(...$commands) + protected function processCommands(...$commands) { foreach ($commands as $fullCommand) { $args = explode(' ', $fullCommand); $command = array_shift($args); + if (strtoupper($command) == 'EXIT') { + $this->running = false; + return; + } + if ($command) { $command = ucfirst(strtolower($command)); if (is_numeric($command)) { @@ -61,12 +67,11 @@ private function processCommands(...$commands) } } - private function execute($command, ...$args) + protected function execute($command, ...$args) { $commandInstance = $this->initializeCommand($command); if ($commandInstance) { $result = $commandInstance->execute(...$args); - // print_r([empty($result)]); if (!empty($result)) { $this->consoleOutput->writeln(' -> ' . $result . PHP_EOL); } @@ -74,7 +79,7 @@ private function execute($command, ...$args) } - private function initializeCommand(string $command) + protected function initializeCommand(string $command) { try { $class = new \ReflectionClass("vending\\ui\\commands\\{$command}Command"); diff --git a/src/ui/commands/ServiceCommand.php b/src/ui/commands/ServiceCommand.php new file mode 100644 index 0000000..08c7f23 --- /dev/null +++ b/src/ui/commands/ServiceCommand.php @@ -0,0 +1,16 @@ +vendingMachine); + $console->start(); + + return ''; + } +} diff --git a/src/ui/service/ServiceConsole.php b/src/ui/service/ServiceConsole.php new file mode 100644 index 0000000..16b7d31 --- /dev/null +++ b/src/ui/service/ServiceConsole.php @@ -0,0 +1,30 @@ +"; + } + + public function header() + { + return ''; + } + + protected function initializeCommand(string $command) + { + try { + $class = new \ReflectionClass("vending\\ui\\service\\commands\\{$command}Command"); + return $class->newInstanceArgs([$this->vendingMachine, $this->consoleOutput]); + } catch (\ReflectionException $e) { + return false; + } + } +} diff --git a/src/ui/service/commands/InfoCommand.php b/src/ui/service/commands/InfoCommand.php new file mode 100644 index 0000000..4e1f817 --- /dev/null +++ b/src/ui/service/commands/InfoCommand.php @@ -0,0 +1,41 @@ +getProductsInfo(); + $this->getCoinsInfo(); + return ""; + } + + public function getProductsInfo() + { + $productHeader = array_reduce( + $this->vendingMachine->getProducts()->toArray(), + function ($initial, $product) { + return $initial .= " ".$product->hash()."(".$product->count()."): ".(string)$product->getValue()."\t"; + }, + '' + ); + + $this->consoleOutput->writeln(' PRODUCTS: '.$productHeader); + } + + public function getCoinsInfo() + { + $coinsHeader = array_reduce( + $this->vendingMachine->getCoinManager()->getCoins()->toArray(), + function ($initial, $coin) { + return $initial .= " ".(string)$coin->getValue()."(".$coin->count().")\t"; + }, + '' + ); + + $this->consoleOutput->writeln(' COINS: '.$coinsHeader); + } +} From ad71540c33a693430c81de041ec246df49e0d986 Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 05:01:31 +0200 Subject: [PATCH 07/10] udpated readme some more info on service commands --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a90a09a..bc1f07d 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,7 @@ Lets start with an simple version implementation and grow from it. php src/prompt.php ``` - -___With Docker ___ +***With Docker*** ```bash docker run --rm -ti -v $(pwd):/app -w /app composer:latest /app/scripts/run_in_docker.sh @@ -46,6 +45,13 @@ I think the code and git log will give a lot of insight of why/how i did X in th - Normally in large code bases i work using the git-flow approach but for small repos/projects, working alone and in the begin of the project i dont use it to remove the overhead of it, that is why in most of this project i didn't use it. - I have use PHPUnit for some time, but i dont really like the way the testing API is done, that is why i use atoum, which i found more expresive, and easy to understand at first look +# Info + +The SERVICE option has been implemented as a different shell with its own commands the commands so far are + +- Info +- exit + # Extras @@ -78,7 +84,6 @@ Setup a VendingMachine class with the basic funcionality I/O (Simple version to - [ ] Cleaning tests - ### Interfaces #### Terminal UI From 60f431eb637052417787ecf9519286f2d5a814e1 Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 05:30:01 +0200 Subject: [PATCH 08/10] ner SERVICE command Update Coin/Product count (for now) --- src/models/generic/Item.php | 5 +++ src/ui/service/commands/UpdateCommand.php | 45 +++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 src/ui/service/commands/UpdateCommand.php diff --git a/src/models/generic/Item.php b/src/models/generic/Item.php index fa0f9d4..7e59d58 100644 --- a/src/models/generic/Item.php +++ b/src/models/generic/Item.php @@ -53,4 +53,9 @@ public function any(): bool { return $this->count() > 0; } + + public function updateCount(int $count) + { + $this->count = $count; + } } diff --git a/src/ui/service/commands/UpdateCommand.php b/src/ui/service/commands/UpdateCommand.php new file mode 100644 index 0000000..b2adf76 --- /dev/null +++ b/src/ui/service/commands/UpdateCommand.php @@ -0,0 +1,45 @@ +updateCoin($args[1], (int)$args[2]); + break; + + case 'PRODUCT': + $this->updateProduct($args[1], (int)$args[2]); + break; + } + + return ""; + } + + private function updateCoin($coin, int $amount) + { + $coinManager = $this->vendingMachine->getCoinManager(); + $coin = $coinManager->getCoin((float)$coin); + if ($coin) { + $coin->updateCount($amount); + } + } + + private function updateProduct($product, int $amount) + { + $product = $this->vendingMachine->getProducts()->find($product); + + if ($product) { + $product->updateCount($amount); + } + } +} From 5a1490965e39610c40541790a2d5165423bd0a2b Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 05:30:27 +0200 Subject: [PATCH 09/10] improvement on the info output --- src/ui/service/commands/InfoCommand.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/service/commands/InfoCommand.php b/src/ui/service/commands/InfoCommand.php index 4e1f817..9f77c25 100644 --- a/src/ui/service/commands/InfoCommand.php +++ b/src/ui/service/commands/InfoCommand.php @@ -18,12 +18,12 @@ public function getProductsInfo() $productHeader = array_reduce( $this->vendingMachine->getProducts()->toArray(), function ($initial, $product) { - return $initial .= " ".$product->hash()."(".$product->count()."): ".(string)$product->getValue()."\t"; + return $initial .= str_pad(" ".$product->hash().": ".$product->count()."\t", 15, ' ', STR_PAD_LEFT); }, '' ); - $this->consoleOutput->writeln(' PRODUCTS: '.$productHeader); + $this->consoleOutput->writeln(" PRODUCTS: $productHeader"); } public function getCoinsInfo() @@ -31,11 +31,11 @@ public function getCoinsInfo() $coinsHeader = array_reduce( $this->vendingMachine->getCoinManager()->getCoins()->toArray(), function ($initial, $coin) { - return $initial .= " ".(string)$coin->getValue()."(".$coin->count().")\t"; + return $initial .= str_pad(" ".(string)$coin->getValue().": ".$coin->count()."\t", 15, ' ', STR_PAD_LEFT); }, '' ); - $this->consoleOutput->writeln(' COINS: '.$coinsHeader); + $this->consoleOutput->writeln(" COINS: $coinsHeader"); } } From 3eb63808e54beef0ed618acd672efce0cc955392 Mon Sep 17 00:00:00 2001 From: Gamaliel Toro Date: Tue, 13 Oct 2020 14:19:08 +0200 Subject: [PATCH 10/10] avoiding the backspace error for now --- src/ui/BaseShell.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/BaseShell.php b/src/ui/BaseShell.php index 724ce71..d76f301 100644 --- a/src/ui/BaseShell.php +++ b/src/ui/BaseShell.php @@ -23,8 +23,8 @@ public function start() $this->consoleOutput->writeln($this->header()); while ($this->running) { - $this->consoleOutput->write($this->prompt()); - $line = readline(); + // $this->consoleOutput->write(); + $line = readline($this->prompt()); $commands = $this->parse($line); $this->processCommands(...$commands); }