diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/File/Handler.php | 56 | ||||
-rw-r--r-- | src/Model/Collection.php | 193 | ||||
-rw-r--r-- | src/Model/Menu.php | 0 | ||||
-rw-r--r-- | src/Model/Model.php | 19 | ||||
-rw-r--r-- | src/Model/Vendor.php | 49 | ||||
-rw-r--r-- | src/Script/Console.php | 52 | ||||
-rw-r--r-- | src/Script/Input.php | 87 | ||||
-rw-r--r-- | src/Script/Output.php | 0 |
8 files changed, 456 insertions, 0 deletions
diff --git a/src/File/Handler.php b/src/File/Handler.php new file mode 100644 index 0000000..61c78a8 --- /dev/null +++ b/src/File/Handler.php @@ -0,0 +1,56 @@ +<?php + +namespace App\File\Handler; + +use Exception; + +/** + * File handler + */ +class Handler +{ + protected $filename; + protected $file; + protected $array; + + /** + * Check file can be read + * Read and parse file into array + * + * @author Phil Burton <phil@pgburton.com> + * @param string $filename [description] + */ + public function __construct(string $filename) + { + $this->filename = $filename; + if (!is_readable($filename)) { + throw new Exception('Cannot read from file: ' . $filename); + } + $this->load; + } + + /** + * Load the file + * + * @author Phil Burton <phil@pgburton.com> + */ + public function load() + { + $this->file = file_get_contents($this->filename); + } + + /** + * Parse file and return array + * + * @author Phil Burton <phil@pgburton.com> + * @return array + */ + public function getVendorArray(): array + { + if (!$this->array) { + $this->array = []; + } + + return $this->array; + } +} diff --git a/src/Model/Collection.php b/src/Model/Collection.php new file mode 100644 index 0000000..8715f07 --- /dev/null +++ b/src/Model/Collection.php @@ -0,0 +1,193 @@ +<?php + +namespace App\Model; + +use App\Model\Model; +use ArrayAccess; +use Countable; +use Exception; +use Iterator; + +/** + * A collection of models + * + * @author Phil Burton <phil@pgburton.com> + */ +class Collection implements ArrayAccess, Iterator, Countable +{ + /** + * Raw array of models + * + * @var Model[] + */ + protected $models; + + /** + * Current index of array + * + * @var int + */ + protected $position; + + /** + * Initalise the collection + * + * @author Phil Burton <phil@pgburton.com> + * @param $array + */ + public function __construct($array = []) + { + // Initalise Index + $this->position = 0; + + // Initalise empty array + $this->setFromArray($array); + } + + /** + * Reset array to a new array of models + * + * @author Phil Burton <phil@pgburton.com> + * @param array $array + */ + public function setFromArray(array $array) + { + $this->models = []; + foreach ($array as $model) { + $this->models[] = $model; + } + } + + /** + * Set the offset + * Only allow values that are an instance of User + * + * @author Phil Burton <phil@pgburton.com> + * @param mixed $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + if (!$value instanceof Model) { + throw new Exception( + 'Collection expects a value of type ' . Model::class . ', ' . gettype($value) . ' given' + ); + } + if (is_null($offset)) { + $this->models[] = $value; + } else { + $this->models[$offset] = $value; + } + } + + /** + * Return true if the given offset exists + * Otherwise return false + * + * @author Phil Burton <phil@pgburton.com> + * @param mixed $offset + */ + public function offsetExists($offset) + { + return isset($this->models[$offset]); + } + + /** + * Unset a given offset + * + * @author Phil Burton <phil@pgburton.com> + * @param mixed $offset + */ + public function offsetUnset($offset) + { + unset($this->models[$offset]); + } + + /** + * Get the value at a given offset + * + * @author Phil Burton <phil@pgburton.com> + * @param mixed $offset + */ + public function offsetGet($offset) + { + return isset($this->models[$offset]) ? $this->models[$offset] : null; + } + + /** + * Return current user + * + * @author Phil Burton <phil@pgburton.com> + * @return Model + */ + public function current() + { + return $this->models[$this->position]; + } + + /** + * Return true if the current index exists in user array + * Otherwise return false + * + * @author Phil Burton <phil@pgburton.com> + * @return bool + */ + public function valid() + { + return isset($this->models[$this->position]); + } + + /** + * Reset index back to 0 + * + * @author Phil Burton <phil@pgburton.com> + */ + public function rewind() + { + $this->position = 0; + } + + /** + * Return the current index + * + * @author Phil Burton <phil@pgburton.com> + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * Increment index by 1 + * + * @author Phil Burton <phil@pgburton.com> + */ + public function next() + { + ++$this->position; + } + + /** + * Create and return new collection of the merged arrays from thsi and a given collection + * + * @author Phil Burton <phil@pgburton.com> + * @param Collection $collection + * @return Collection + */ + public function merge(Collection $collection): Collection + { + return new Collection(array_merge($collection->toArray(), $this->toArray())); + } + + /** + * Return count of users + * + * @author Phil Burton <phil@pgburton.com> + * @return int + */ + public function count(): int + { + return count($this->models); + } +} diff --git a/src/Model/Menu.php b/src/Model/Menu.php new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/Model/Menu.php diff --git a/src/Model/Model.php b/src/Model/Model.php new file mode 100644 index 0000000..99847f9 --- /dev/null +++ b/src/Model/Model.php @@ -0,0 +1,19 @@ +<?php + +namespace App\Model; + +/** + * Base model class + */ +class Model +{ + /** + * Init + * + * @author Phil Burton <phil@pgburton.com> + */ + public function __construct() + { + // initalise Model + } +} diff --git a/src/Model/Vendor.php b/src/Model/Vendor.php new file mode 100644 index 0000000..99a95dd --- /dev/null +++ b/src/Model/Vendor.php @@ -0,0 +1,49 @@ +<?php + +namespace App\Model; + +use App\File\Handler as FileHandler; +use App\Model\Collection; +use App\Model\Model; +use App\Script\Input; + +/** + * Vendor Model + */ +class Vendor extends Model +{ + protected $name; + protected $postcode; + protected $maxCovers; + protected $menus; + + /** + * Load vendors from file, parse them into a model collection and Return + * + * @author Phil Burton <phil@pgburton.com> + * @param FileHandler $handler + * @return Collection + */ + public function loadFromFile(FileHandler $handler): Collection + { + // initalise a Vendor Collection + $collection = new Collection; + + foreach ($handler->getVendorArray() as $vendorRaw) { + $collection[] = new Vendor($vendorRaw); + } + + return $collection; + } + + /** + * Filter by input + * + * @author Phil Burton <phil@pgburton.com> + * @param Input $input + */ + public function filterByInput(Input $input) + { + // Amend the colletion so we've filtered by the input + } +} diff --git a/src/Script/Console.php b/src/Script/Console.php new file mode 100644 index 0000000..bedbc1d --- /dev/null +++ b/src/Script/Console.php @@ -0,0 +1,52 @@ +<?php + +namespace App\Script; + +// use App\Model\Vendor; +use App\Script\Input; +// use App\Script\Output; + +/** + * Main application class + * + * @author Phil Burton <phil@pgburton.com> + */ +class Console +{ + /** + * Create symfony application and add commands + * + * @author Phil Burton <phil@pgburton.com> + */ + public function __construct() + { + $this->init(); + } + + /** + * Initalise + * + * @author Phil Burton <phil@pgburton.com> + */ + protected function init() + { + // Define the root of the application + define('APP_ROOT', realpath(dirname(__FILE__) . '/../../') . '/'); + } + + /** + * Run main application code + * + * @author Phil Burton <phil@pgburton.com> + */ + public function exec() + { + $vendors = Vendor::loadAll(); + $input = new Input; + + $vendors->filterByInput($input); + // $output = new Output; + // + // $output->printCollection($vendors); + } +} diff --git a/src/Script/Input.php b/src/Script/Input.php new file mode 100644 index 0000000..6b15c51 --- /dev/null +++ b/src/Script/Input.php @@ -0,0 +1,87 @@ +<?php + +namespace App\Script; + +use Exception; + +/** + * Input handler for CLI arugments and options + */ +class Input +{ + /** + * Available CLI options + * f filename - input file with the vendors data + * d day - delivery day (dd/mm/yy) + * t time - delivery time in 24h format (hh:mm) + * l location - delivery location (postcode without spaces, e.g. NW43QB) + * c covers - number of people to feed + * + * @var string + */ + protected $availableOptions = 'fdtlc::'; + + /** + * The loaded CLI options + * + * @var string + */ + protected $options; + + /** + * Parse arguments and options + * + * @author Phil Burton <phil@pgburton.com> + */ + public function __construct() + { + $this->loadOptions(); + } + + /** + * Load options, make sure required options are set + * + * @author Phil Burton <phil@pgburton.com> + */ + protected function loadOptions() + { + $this->options = getopt($this->getOptionString()); + + if (!array_key_exists('f', $this->options)) { + throw new Exception('Filename Option `-f` is required'); + } + + // If only a day or a time is given, we throw exception as we need neither or both + if ((array_key_exists('d', $this->options) <=> array_key_exists('t', $this->options)) !== 0) { + throw new Exception('Both day and time options (`-d` and `-t`) are required for time based filtering'); + } + } + + /** + * Return the option string for the options we want to load + * + * @author Phil Burton <phil@pgburton.com> + * @return string + */ + public function getOptionString(): string + { + return $this->availableOptions; + } + + /** + * Return an option value + * In it doesn't exist return false + * + * @author Phil Burton <phil@pgburton.com> + * @param string $key + * @return mixed + */ + public function getOption(string $key) + { + if (!array_key_exists($key, $this->options)) { + return false; + } + + return $this->options[$key]; + } +} diff --git a/src/Script/Output.php b/src/Script/Output.php new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/Script/Output.php |