Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
21.74% |
5 / 23 |
CRAP | |
7.34% |
8 / 109 |
| Senh\Lib\Prices\KortingFactory | |
0.00% |
0 / 1 |
|
21.74% |
5 / 23 |
2550.94 | |
7.34% |
8 / 109 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| init | |
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 13 |
|||
| getAllowedProductIds | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| setAllowedProductIds | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| setAvailableKortingModels | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| getAvailableKortingModels | |
0.00% |
0 / 1 |
30 | |
0.00% |
0 / 8 |
|||
| getModelByKortingsCode | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 2 |
|||
| hasModel | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| hasModelWithAllowedProductId | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
| getModel | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| setModelByParameters | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 13 |
|||
| getModelByParameters | |
0.00% |
0 / 1 |
90 | |
0.00% |
0 / 24 |
|||
| getModelBySession | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 3 |
|||
| getSessionSaleId | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 1 |
|||
| getModelByCookies | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 7 |
|||
| getSpecificModelFromCookies | |
0.00% |
0 / 1 |
12 | |
0.00% |
0 / 6 |
|||
| setModel | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| calcDatumStop | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 8 |
|||
| hasKortingsCodeParameters | |
0.00% |
0 / 1 |
6 | |
0.00% |
0 / 1 |
|||
| hasKortingsCodeCookie | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| getCookieName | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 1 |
|||
| getCookie | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 4 |
|||
| setCookie | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
| <?php | |
| namespace Senh\Lib\Prices; | |
| use Senh\Lib\Prices\PricesHelper; | |
| use Senh\Lib\Managers\InternalProductManager; | |
| use Senh\Lib\Prices\KortingModel; | |
| use DateTime; | |
| use DateInterval; | |
| use DateTimeZone; | |
| class KortingFactory | |
| { | |
| const COOKIE_NAME_PREFIX = 'kc_'; | |
| const COOKIE_LIFETIME = 31536000; // 1 year | |
| const SESSION_NAME_ACTIVE_ACTION = 'kortings_actie'; | |
| /** | |
| * @var InternalProductManager; | |
| */ | |
| protected $internalProductManager; | |
| /** | |
| * @var KortingModel: use setModel to set, session info is set as well | |
| */ | |
| protected $model; | |
| /** | |
| * @var array | |
| */ | |
| protected $allowedProductIds; | |
| /** | |
| * @var KortingModel[] | |
| */ | |
| protected $availableKortingModels; | |
| /** | |
| * @param InternalProductManager $internalProductManager | |
| */ | |
| public function __construct(InternalProductManager $internalProductManager) | |
| { | |
| $this->internalProductManager = $internalProductManager; | |
| } | |
| public function init() | |
| { | |
| if (session_id() == '') { | |
| session_start(); | |
| } | |
| $this->internalProductManager = InternalProductManager::getInstance(); | |
| $model = $this->getModelByParameters(); | |
| // get from session | |
| if (!$model instanceof KortingModel) { | |
| $model = $this->getModelBySession(); | |
| // if the model's date from the parameter is not valid, we still use it, since it is a specific request. | |
| // however, from the session we do not want to indefinitely show an 0 0 0 0 timer | |
| if ($model instanceof KortingModel && !$model->isFutureDatumStop()) { | |
| $model = null; | |
| } | |
| } | |
| // get from cookies | |
| if (!$model instanceof KortingModel) { | |
| $model = $this->getModelByCookies(); // only returns models that have valid dates | |
| } | |
| if ($model instanceof KortingModel) { | |
| $this->setModel($model); | |
| } | |
| return $this; | |
| } | |
| /** | |
| * @return array | |
| */ | |
| public function getAllowedProductIds() | |
| { | |
| return $this->allowedProductIds; | |
| } | |
| /** | |
| * @param $allowedProductIds | |
| * @return $this | |
| */ | |
| public function setAllowedProductIds($allowedProductIds) | |
| { | |
| $this->allowedProductIds = $allowedProductIds; | |
| return $this; | |
| } | |
| /** | |
| * @param KortingModel[]|null $availableKortingModels | |
| */ | |
| public function setAvailableKortingModels($availableKortingModels) | |
| { | |
| $this->availableKortingModels = $availableKortingModels; | |
| } | |
| /** | |
| * @param $allowedProductIds: if provided, limit to those ids | |
| * @return KortingModel[] | |
| */ | |
| public function getAvailableKortingModels($allowedProductIds = null) | |
| { | |
| /** | |
| * @var KortingModel[] $availableModels | |
| */ | |
| if (!$allowedProductIds) { | |
| return $this->availableKortingModels; | |
| } | |
| $allowedModels = array(); | |
| foreach ($allowedProductIds as $allowedProductId) { | |
| foreach ($this->availableKortingModels as $availableModel) { | |
| if ($availableModel->hasAllowedProductId($allowedProductId)) { | |
| $allowedModels[$availableModel->getCode()] = $availableModel; | |
| } | |
| } | |
| } | |
| return $allowedModels; | |
| } | |
| /** | |
| * @param $kortingsCode | |
| * | |
| * @return KortingModel|null | |
| */ | |
| public function getModelByKortingsCode($kortingsCode, $allowedProductIds = null) | |
| { | |
| $availableKortingsModels = $this->getAvailableKortingModels($allowedProductIds); | |
| return isset($availableKortingsModels[$kortingsCode]) ? $availableKortingsModels[$kortingsCode] : null; | |
| } | |
| /** | |
| * @return bool | |
| */ | |
| public function hasModel() | |
| { | |
| return $this->model instanceof KortingModel; | |
| } | |
| public function hasModelWithAllowedProductId($productId) | |
| { | |
| return $this->hasModel() && $this->model->hasAllowedProductId($productId); | |
| } | |
| /** | |
| * @return KortingModel | |
| */ | |
| public function getModel() | |
| { | |
| return $this->model; | |
| } | |
| /** | |
| * This forces the model to be set by the code. | |
| * It checks the cookies first to get the datumStop, if not aivailable, the parameter datumStop will be used instead | |
| * | |
| * @param string $kortingsCode | |
| * @param DateTime $datumVerstuurd | |
| * @return null|KortingModel | |
| */ | |
| public function setModelByParameters($kortingsCode, $datumVerstuurd, $dagNummer, $ignoreCookie = false) | |
| { | |
| if (!$ignoreCookie) { | |
| $model = $this->getSpecificModelFromCookies($kortingsCode); | |
| if ($model instanceof KortingModel) { | |
| $this->setModel($model); | |
| return $model; | |
| } | |
| } | |
| $model = $this->getModelByKortingsCode($kortingsCode, $this->allowedProductIds); | |
| if (!$model instanceof KortingModel) { | |
| return null; | |
| } | |
| $datumStop = $this->calcDatumStop($kortingsCode, $datumVerstuurd, $dagNummer); | |
| $model->setDatumStop($datumStop); | |
| $this->setModel($model); | |
| $this->setCookie($model); | |
| return $model; | |
| } | |
| /** | |
| * @return KortingModel|null | |
| */ | |
| protected function getModelByParameters() | |
| { | |
| if (!$this->hasKortingsCodeParameters()) { | |
| return null; | |
| } | |
| $kortingsCode = $_GET['kc']; | |
| $kortingModel = $this->getModelByKortingsCode($kortingsCode, $this->allowedProductIds); | |
| if ($kortingModel instanceof KortingModel) { | |
| $dagNummer = isset($_GET['dg']) ? $_GET['dg'] : 1; | |
| $datumVerstuurd = isset($_GET['dt']) ? $_GET['dt'] : null; | |
| if ($datumVerstuurd) { | |
| $datumVerstuurd .= ' 00:00:00'; | |
| // we try to keep everything UTC | |
| $datumVerstuurd = DateTime::createFromFormat('d/m/Y H:i:s', $datumVerstuurd,new DateTimeZone('UTC')); | |
| if (!$datumVerstuurd instanceof DateTime) { | |
| return null; | |
| } | |
| // correct for local timezone difference (timer should stop at midnight locallay) | |
| $localTimeZone = new DateTimeZone('Europe/Amsterdam'); | |
| $datumVerstuurd->sub(new DateInterval('PT'.$localTimeZone->getOffset($datumVerstuurd).'S')); | |
| } else { | |
| $datumVerstuurd = new DateTime(null,new DateTimeZone('UTC')); | |
| } | |
| $datumStop = $this->calcDatumStop($kortingsCode, $datumVerstuurd, $dagNummer); | |
| $kortingModel->setDatumStop($datumStop); | |
| if ($this->hasKortingsCodeCookie($kortingsCode)) { | |
| // overschrijf datumStop eventueel met de cookie data | |
| $datumStop = $this->getCookie($kortingsCode); | |
| } elseif ($kortingModel->isFutureDatumStop()) { | |
| // set cookie | |
| $this->setCookie($kortingModel); | |
| } | |
| // als is de datum in het verleden is, dan moet 'actie verlopen' getoond worden | |
| $kortingModel->setDatumStop($datumStop); | |
| return $kortingModel; | |
| } | |
| return null; | |
| } | |
| /** | |
| * @return KortingModel|null | |
| */ | |
| protected function getModelBySession() | |
| { | |
| if (!isset($_SESSION[self::SESSION_NAME_ACTIVE_ACTION])) { | |
| return null; | |
| } | |
| return $this->getSpecificModelFromCookies($_SESSION[self::SESSION_NAME_ACTIVE_ACTION]); | |
| } | |
| /** | |
| * @return null | float | |
| */ | |
| protected function getSessionSaleId() | |
| { | |
| return isset($_SESSION['sale_id']) ? $_SESSION['sale_id'] : null; | |
| } | |
| /** | |
| * Loop through available kortingscodes to see if any of these is set in the cookies and return the first valid one | |
| * @return KortingModel|null | |
| */ | |
| protected function getModelByCookies() | |
| { | |
| foreach ($this->getAvailableKortingModels($this->allowedProductIds) as $kortingsCode => $kortingModel) { | |
| if ($this->hasKortingsCodeCookie($kortingsCode)) { | |
| $datumStop = $this->getCookie($kortingsCode); | |
| $kortingModel->setDatumStop($datumStop); | |
| if ($kortingModel->isFutureDatumStop()) { | |
| return $kortingModel; | |
| } | |
| }; | |
| } | |
| return null; | |
| } | |
| /** | |
| * Return the KortingModel that matches $kortingsCode if it is an available action AND if the kortingsCode is set in | |
| * the cookies, and the model is allowed for the current product even if the datumStop is not valid. | |
| * | |
| * @param $kortingsCode | |
| * @return null | KortingModel | |
| */ | |
| protected function getSpecificModelFromCookies($kortingsCode) | |
| { | |
| $kortingModel = $this->getModelByKortingsCode($kortingsCode, $this->allowedProductIds); | |
| if (!$kortingModel instanceof KortingModel || !$this->hasKortingsCodeCookie($kortingsCode)) { | |
| return null; | |
| } | |
| $datumStop = $this->getCookie($kortingsCode); | |
| $kortingModel->setDatumStop($datumStop); | |
| return $kortingModel; | |
| } | |
| /** | |
| * @param KortingModel|null $kortingModel | |
| */ | |
| public function setModel($kortingModel) | |
| { | |
| $this->model = $kortingModel; | |
| $_SESSION[self::SESSION_NAME_ACTIVE_ACTION] = $kortingModel ? $kortingModel->getCode() : null;; | |
| } | |
| /** | |
| * @param string $kortingsCode | |
| * @param DateTime $datumVerstuurd | |
| * @param int $dagNummer | |
| * | |
| * @return DateTime | |
| */ | |
| protected function calcDatumStop($kortingsCode, $datumVerstuurd, $dagNummer) | |
| { | |
| $model = $this->getModelByKortingsCode($kortingsCode); | |
| $urenOver = $model->getDuur() - ($dagNummer - 1) * 24; | |
| if ($urenOver < 0) { | |
| $datumStop = $datumVerstuurd->sub(new DateInterval("PT1H")); | |
| } else { | |
| $minutenOver = round(($urenOver - floor($urenOver)) * 60); | |
| $urenOver = floor($urenOver); | |
| $datumStop = $datumVerstuurd->add(new DateInterval("PT{$urenOver}H{$minutenOver}M")); | |
| } | |
| return $datumStop; | |
| } | |
| protected function hasKortingsCodeParameters() | |
| { | |
| return (isset($_GET['kc']) && isset($_GET['pn'])); | |
| } | |
| protected function hasKortingsCodeCookie($kortingsCode) | |
| { | |
| $cookieName = $this->getCookieName($kortingsCode); | |
| return isset($_COOKIE[$cookieName]); | |
| } | |
| protected function getCookieName($kortingsCode) | |
| { | |
| return self::COOKIE_NAME_PREFIX.$kortingsCode; | |
| } | |
| /** | |
| * @return DateTime: datumStop | |
| */ | |
| protected function getCookie($kortingsCode) | |
| { | |
| $cookieName = $this->getCookieName($kortingsCode); | |
| $dateTime = new DateTime(date('Y-m-d H:i:s', $_COOKIE[$cookieName]), new \DateTimeZone(SERVER_TIME_ZONE)); | |
| $dateTime->setTimezone(new DateTimeZone('UTC')); | |
| return $dateTime; | |
| } | |
| /** | |
| * @param KortingModel $model | |
| */ | |
| protected function setCookie($model) | |
| { | |
| $cookieName = $this->getCookieName($model->getCode()); | |
| // note: DateTime->getTimeStamp() returns the time that corresponds with the server's time zone. This is corrected in getCookie. | |
| setcookie($cookieName, $model->getDatumStop()->getTimestamp(), time() + self::COOKIE_LIFETIME, '/'); | |
| } | |
| } |