From 33f00442f1667d57f94433834e0da4985670025b Mon Sep 17 00:00:00 2001 From: Fbenas Date: Mon, 7 May 2018 14:42:15 +0100 Subject: Get filtering working with output --- src/Model/Collection.php | 85 ++++++++++++++++++++++++++------ src/Model/Menu.php | 38 ++++++++++++++ src/Model/Model.php | 2 + src/Model/Vendor.php | 126 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 232 insertions(+), 19 deletions(-) (limited to 'src/Model') diff --git a/src/Model/Collection.php b/src/Model/Collection.php index 8715f07..803e777 100644 --- a/src/Model/Collection.php +++ b/src/Model/Collection.php @@ -4,9 +4,12 @@ namespace App\Model; use App\Model\Model; use ArrayAccess; -use Countable; use Exception; use Iterator; +use App\Script\Input; +use DateTime; +use DateTimeZone; +use Countable; /** * A collection of models @@ -129,7 +132,7 @@ class Collection implements ArrayAccess, Iterator, Countable * Return true if the current index exists in user array * Otherwise return false * - * @author Phil Burton + * @author Phil Burton "dump" * @return bool */ public function valid() @@ -169,24 +172,78 @@ class Collection implements ArrayAccess, Iterator, Countable } /** - * Create and return new collection of the merged arrays from thsi and a given collection + * Filter by input * * @author Phil Burton - * @param Collection $collection - * @return Collection + * @param Input $input */ - public function merge(Collection $collection): Collection + public function filterByInput(Input $input) { - return new Collection(array_merge($collection->toArray(), $this->toArray())); + // filter by time + if ($time = $input->getOption('t')) { + $day = $input->getOption('d'); + $this->filterByDateTime($day, $time); + } + + if ($location = $input->getOption('l')) { + $this->filterByLocation($location); + } + + if ($covers = (int) $input->getOption('c')) { + $this->filterByCovers($covers); + } + + + // day - delivery day (dd/mm/yy) + // time - delivery time in 24h format (hh:mm) + // location - delivery location (postcode without spaces, e.g. NW43QB) + // covers - number of people to feed } - /** - * Return count of users - * - * @author Phil Burton - * @return int - */ - public function count(): int + public function filterByDateTime(string $date, string $time) + { + $dateTime = DateTime::createFromFormat('d/m/y G:i', $date . ' ' . $time); + $dateTime->setTImezone(new DateTImeZone('Europe/London')); + + $out = []; + foreach ($this->models as $model) { + if ($model->checkDate($dateTime)) { + $out[] = $model; + } + } + + $this->models = $out; + } + + public function filterByLocation(string $location) + { + $location = substr($location, 0, 2); + + $out = []; + + foreach ($this->models as $model) { + if ($model->checkLocation($location)) { + $out[] = $model; + } + } + + $this->models = $out; + } + + public function filterByCovers(int $covers) + { + $out = []; + + foreach ($this->models as $model) { + if ($model->checkMaxCovers($covers)) { + $out[] = $model; + } + } + + $this->models = $out; + } + + public function count() { return count($this->models); } diff --git a/src/Model/Menu.php b/src/Model/Menu.php index e69de29..d0a281e 100644 --- a/src/Model/Menu.php +++ b/src/Model/Menu.php @@ -0,0 +1,38 @@ +name = $name; + $this->allergies = $allergies; + $this->setTime($advanceTime); + } + + public function setTime($time) + { + $this->advanceTime = str_replace('h', '', $time); + } + + public function getAdvanceTime(): int + { + return $this->advanceTime; + } + + public function toString() + { + return $this->name . ';' . $this->allergies; + } +} diff --git a/src/Model/Model.php b/src/Model/Model.php index 99847f9..f59ab0e 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -7,6 +7,8 @@ namespace App\Model; */ class Model { + protected static $inputFile = APP_ROOT . 'data/input.txt'; + /** * Init * diff --git a/src/Model/Vendor.php b/src/Model/Vendor.php index 99a95dd..6b98704 100644 --- a/src/Model/Vendor.php +++ b/src/Model/Vendor.php @@ -4,8 +4,10 @@ namespace App\Model; use App\File\Handler as FileHandler; use App\Model\Collection; +use App\Model\Menu; use App\Model\Model; -use App\Script\Input; +use DateTime; +use DateInterval; /** * Vendor Model @@ -17,6 +19,19 @@ class Vendor extends Model protected $maxCovers; protected $menus; + public function __construct($name, $postcode, $maxCovers) + { + $this->name = $name; + $this->postcode = $postcode; + $this->maxCovers = $maxCovers; + $this->menus = []; + } + + public function addMenu(Menu $menu) + { + $this->menus[] = $menu; + } + /** * Load vendors from file, parse them into a model collection and Return * @@ -36,14 +51,115 @@ class Vendor extends Model return $collection; } + public static function loadAll(string $filename): Collection + { + $fileHandler = new FileHandler($filename); + + $fileContents = $fileHandler->getFileContents(); + + return static::parseVendors($fileContents); + } + + /** - * Filter by input + * Parse file and return array * * @author Phil Burton - * @param Input $input + * @return array */ - public function filterByInput(Input $input) + public static function parseVendors($fileContents): Collection + { + $collection = new Collection; + + // split the various vendor data out + $array = explode("\n\n", $fileContents); + + // For each vendor + foreach ($array as $value) { + $rawVendor = explode("\n", $value); + // Split off the vendor data + $vendorHead = explode(";", $rawVendor[0]); + + $vendor = new Vendor($vendorHead[0], $vendorHead[1], $vendorHead[2]); + + // Remove the head + unset($rawVendor[0]); + // Reset the keys + $rawVendor = array_values($rawVendor); + + // Now parse menus + foreach ($rawVendor as $item) { + // Ignore empty line (usually last line of file) + if ($item === "") { + continue; + } + $rawMenu = explode(";", $item); + $menu = new Menu($rawMenu[0], $rawMenu[1], $rawMenu[2]); + $vendor->addMenu($menu); + } + + $collection[] = $vendor; + } + + return $collection; + } + + public function checkDate(DateTime $date) { - // Amend the colletion so we've filtered by the input + $out = []; + $now = new DateTime(); + + foreach ($this->menus as $menu) { + $earliestDelivery = $now->add(new DateInterval('PT' . $menu->getAdvanceTime() . 'H')); + + if ($earliestDelivery <= $date) { + $out[] = $menu; + } + } + + $this->menus = $out; + + if (!$this->menus) { + return false; + } + + return true; + } + + public function checkLocation(string $location) + { + $postPrefix = ''; + + foreach (str_split($this->postcode) as $char) { + if (is_numeric($char)) { + break; + } + + $postPrefix .= $char; + } + + return strtoupper($postPrefix) === strtoupper($location); + } + + public function checkMaxCovers(int $covers) + { + if ($this->maxCovers >= $covers) { + return true; + } + + return false; + } + + public function toString() + { + $out = [ + $this->name . ';' . $this->postcode . ';' . $this->maxCovers + ]; + + foreach ($this->menus as $menu) { + $out[] = $menu->toString(); + } + + return $out; } } -- cgit v1.2.3