summaryrefslogtreecommitdiff
path: root/src/Model
diff options
context:
space:
mode:
Diffstat (limited to 'src/Model')
-rw-r--r--src/Model/Collection.php85
-rw-r--r--src/Model/Menu.php38
-rw-r--r--src/Model/Model.php2
-rw-r--r--src/Model/Vendor.php126
4 files changed, 232 insertions, 19 deletions
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 <phil@pgburton.com>
+ * @author Phil Burton <phil@pgburton.com>"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 <phil@pgburton.com>
- * @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 <phil@pgburton.com>
- * @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 @@
+<?php
+
+namespace App\Model;
+
+use App\Model\Model;
+
+/**
+ * Menu Model
+ */
+class Menu extends Model
+{
+ protected $name;
+ protected $allergies;
+ protected $advanceTime;
+
+
+ public function __construct($name, $allergies, $advanceTime)
+ {
+ $this->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 <phil@pgburton.com>
- * @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;
}
}