diff --git a/.gitignore b/.gitignore index 164d0d4..927573b 100644 --- a/.gitignore +++ b/.gitignore @@ -49,9 +49,10 @@ phpunit.phar /rest/web/assets/** !/rest/web/assets/.gitkeep +/customerapi/web/assets/** +!/customerapi/web/assets/.gitkeep + /customerapi/config/*-local.php /customerapi/runtime/logs/** !/customerapi/runtime/.gitkeep -/customerapi/web/assets/** -!/customerapi/assets/.gitkeep diff --git a/backend/controllers/EventRegistrationController.php b/backend/controllers/EventRegistrationController.php index c109950..a76285b 100644 --- a/backend/controllers/EventRegistrationController.php +++ b/backend/controllers/EventRegistrationController.php @@ -81,6 +81,7 @@ class EventRegistrationController extends Controller * If update is successful, the browser will be redirected to the 'view' page. * @param integer $id * @return mixed + * @throws NotFoundHttpException */ public function actionUpdate($id) { diff --git a/common/components/HttpStatus.php b/common/components/HttpStatus.php new file mode 100644 index 0000000..74bfc72 --- /dev/null +++ b/common/components/HttpStatus.php @@ -0,0 +1,131 @@ + "CARD_NOT_FOUND", - self::CUSTOMER_NOT_FOUND => "CUSTOMER_NOT_FOUND", - self::TICKET_NOT_FOUND => "TICKET_NOT_FOUND", - self::NO_FREE_SEATS => "NO_FREE_SEATS", - self::EVENT_TYPE_NOT_FOUND => "EVENT_TYPE_NOT_FOUND", - self::TICKET_INSUFFICIENT => "TICKET_INSUFFICIENT", - self::UNKNOWN_ERROR => "UNKNOWN_ERROR", - self::MAX_SEAT_COUNT_EXCEEDED => "MAX_SEAT_COUNT_EXCEEDED", - self::EVENT_UNAVAILABLE => "EVENT_UNAVAILABLE", + self::CARD_NOT_FOUND => 'CARD_NOT_FOUND', + self::CUSTOMER_NOT_FOUND => 'CUSTOMER_NOT_FOUND', + self::TICKET_NOT_FOUND => 'TICKET_NOT_FOUND', + self::NO_FREE_SEATS => 'NO_FREE_SEATS', + self::EVENT_TYPE_NOT_FOUND => 'EVENT_TYPE_NOT_FOUND', + self::TICKET_INSUFFICIENT => 'TICKET_INSUFFICIENT', + self::UNKNOWN_ERROR => 'UNKNOWN_ERROR', + self::MAX_SEAT_COUNT_EXCEEDED => 'MAX_SEAT_COUNT_EXCEEDED', + self::EVENT_UNAVAILABLE => 'EVENT_UNAVAILABLE', ]; /** - * @param \common\models\CardEventRegistrationForm $cardEventForm - * @throws \yii\db\Exception + * @param CardEventRegistrationForm $cardEventForm + * @throws Exception */ public function registerCard($cardEventForm) { - $db = \Yii::$app->db; + $db = Yii::$app->db; $tx = $db->beginTransaction(); try { if ($cardEventForm->validate()) { - /** @var \common\models\Card $card */ + /** @var Card $card */ $card = Card::readCard($cardEventForm->card_number, false); if (!isset($card)) { - throw new NotFoundHttpException("Card not found: " . $cardEventForm->card_number, self::CARD_NOT_FOUND); + throw new NotFoundHttpException('Card not found: ' . $cardEventForm->card_number, self::CARD_NOT_FOUND); } if ($card->isFree()) { - throw new NotFoundHttpException("Customer not found", self::CUSTOMER_NOT_FOUND); + throw new NotFoundHttpException('Customer not found', self::CUSTOMER_NOT_FOUND); } $activeTickets = $card->getActiveTickets(); - if (sizeof($activeTickets) == 0) { - throw new NotFoundHttpException("Ticket not found", self::TICKET_NOT_FOUND); + if (count($activeTickets) === 0) { + throw new NotFoundHttpException('Ticket not found', self::TICKET_NOT_FOUND); } - /** @var \common\models\Event $event */ + /** @var Event $event */ $event = Event::find()->andWhere(['id' => $cardEventForm->event_id])->one(); if (!isset($event)) { - throw new NotFoundHttpException("Event not found: " . $cardEventForm->event_id); + throw new NotFoundHttpException('Event not found: ' . $cardEventForm->event_id); } if ( isset($event->deleted_at)){ - throw new BadRequestHttpException("Event deleted", self::EVENT_UNAVAILABLE); + throw new BadRequestHttpException('Event deleted', self::EVENT_UNAVAILABLE); } if (!$event->hasFreeSeats()) { - throw new BadRequestHttpException("No free seats", self::NO_FREE_SEATS); + throw new BadRequestHttpException('No free seats', self::NO_FREE_SEATS); } $eventType = $event->eventType; if (!isset($eventType)) { - throw new ServerErrorHttpException("Event type not found", self::EVENT_TYPE_NOT_FOUND); + throw new ServerErrorHttpException('Event type not found', self::EVENT_TYPE_NOT_FOUND); } $selectedTicket = $eventType->findTicketAllowingEventType($activeTickets); if (!isset($selectedTicket)) { - throw new NotFoundHttpException("Ticket not found", self::TICKET_INSUFFICIENT); + throw new NotFoundHttpException('Ticket not found', self::TICKET_INSUFFICIENT); } if ($selectedTicket->hasOpenReservationCount()) { @@ -106,16 +112,17 @@ class EventRegistrationManager extends \yii\base\Object $registration->id_event = $event->id; $registration->id_card = $card->id_card; $registration->id_ticket = $selectedTicket->id_ticket; + $registration->id_customer = $card->customer->id_customer; try { $registration->save(false); - } catch (\Throwable $exception) { - throw new ServerErrorHttpException("Failed to save", self::UNKNOWN_ERROR); + } catch (Throwable $exception) { + throw new ServerErrorHttpException('Failed to save', self::UNKNOWN_ERROR); } $cardEventForm->registration = $registration; } $tx->commit(); - } catch (\Exception $exception) { + } catch (Exception $exception) { $tx->rollBack(); throw $exception; } @@ -126,21 +133,21 @@ class EventRegistrationManager extends \yii\base\Object { $query = new Query(); $query->select([ - "event_registration.id as event_registration_id", - "event_registration.created_at as event_registration_created_at", - "event_registration.canceled_at as event_registration_canceled_at", - "event_registration.deleted_at as event_registration_deleted_at", - "card.id_card as card_id_card", - "card.number as card_number", - "customer.id_customer as customer_id_customer", - "customer.name as customer_name", - "customer.email as customer_email", + 'event_registration.id as event_registration_id', + 'event_registration.created_at as event_registration_created_at', + 'event_registration.canceled_at as event_registration_canceled_at', + 'event_registration.deleted_at as event_registration_deleted_at', + 'card.id_card as card_id_card', + 'card.number as card_number', + 'customer.id_customer as customer_id_customer', + 'customer.name as customer_name', + 'customer.email as customer_email', ]); $query->from(EventRegistration::tableName()); - $query->innerJoin(Event::tableName(), "event_registration.id_event = event.id"); - $query->innerJoin(Card::tableName(), "event_registration.id_card = card.id_card"); - $query->innerJoin(Customer::tableName(), "customer.id_customer_card = card.id_card"); - $query->andWhere(["event_registration.id_event" => $idEvent]); + $query->innerJoin(Event::tableName(), 'event_registration.id_event = event.id'); + $query->innerJoin(Card::tableName(), 'event_registration.id_card = card.id_card'); + $query->innerJoin(Customer::tableName(), 'customer.id_customer_card = card.id_card'); + $query->andWhere(['event_registration.id_event' => $idEvent]); return $query; } @@ -148,21 +155,21 @@ class EventRegistrationManager extends \yii\base\Object /** * @param $idRegistration - * @return array|EventRegistration|\yii\db\ActiveRecord|null + * @return array|EventRegistration|ActiveRecord|null * @throws NotFoundHttpException */ public function loadRegistration($idRegistration) { $registration = EventRegistration::find()->andWhere(['id' => $idRegistration])->one(); - if ($registration == null) { + if ( $registration === null) { throw new NotFoundHttpException('The requested registration does not exist.'); } return $registration; } /** - * @param \common\models\EventRegistration $registration + * @param EventRegistration $registration * @throws ServerErrorHttpException */ public function cancelRegistration($registration) @@ -181,7 +188,7 @@ class EventRegistrationManager extends \yii\base\Object } /** - * @param \common\models\EventRegistration $registration + * @param EventRegistration $registration * @throws ServerErrorHttpException */ public function deleteRegistration($registration) @@ -202,13 +209,13 @@ class EventRegistrationManager extends \yii\base\Object /** * Delete an event - * @param \common\models\Event $event - * @throws \yii\db\Exception - * @throws \Exception + * @param Event $event + * @throws Exception + * @throws Throwable */ public function deleteEvent($event) { - $db = \Yii::$app->db; + $db = Yii::$app->db; $tx = $db->beginTransaction(); try { @@ -217,20 +224,20 @@ class EventRegistrationManager extends \yii\base\Object // if even has no registrations // we can simply delete it from db // //////////////////////////////// - if (count($registrations) == 0) { + if ( count($registrations) === 0 ) { $event->delete(); } else { $event->deleted_at = date('Y-m-d H:i:s'); $event->save(false); foreach ($registrations as $registration) { if (!isset($registration->deleted_at)) { - /** @var \common\models\EventRegistration $registration */ + /** @var EventRegistration $registration */ $this->deleteRegistration($registration); } } } $tx->commit(); - } catch (\Exception $e) { + } catch (Exception $e) { $tx->rollBack(); throw $e; } diff --git a/common/models/CardEventRegistrationForm.php b/common/models/CardEventRegistrationForm.php index 1022169..a1f65a9 100644 --- a/common/models/CardEventRegistrationForm.php +++ b/common/models/CardEventRegistrationForm.php @@ -1,6 +1,7 @@ $id]); } /** diff --git a/common/models/Event.php b/common/models/Event.php index 6ba4829..0d5791a 100644 --- a/common/models/Event.php +++ b/common/models/Event.php @@ -111,18 +111,18 @@ class Event extends \yii\db\ActiveRecord } public function getEventType(){ - return $this->hasOne(EventType::className(),['id' => 'id_event_type']); + return $this->hasOne($this->getEventTypeClass(),['id' => 'id_event_type']); } public function getTrainer(){ - return $this->hasOne(Trainer::className(),['id' => 'id_trainer']); + return $this->hasOne($this->getTrainerClass(),['id' => 'id_trainer']); } /** * @return Room|\yii\db\ActiveQuery */ public function getRoom() { - return $this->hasOne(Room::className(),['id' => 'id_room']); + return $this->hasOne($this->getRoomClass(),['id' => 'id_room']); } /** @@ -139,16 +139,24 @@ class Event extends \yii\db\ActiveRecord return $this->hasMany(EventRegistration::className(),['id_event' => 'id']); } + + /** + * @return \common\models\EventRegistration[]|\yii\db\ActiveQuery + */ + public function getActiveEventRegistrations(){ + return $this->hasMany(EventRegistration::className(),['id_event' => 'id'])->andWhere( + [ + 'event_registration.canceled_at' => null, + 'event_registration.deleted_at' => null, + ] + ); + } + /** * @return \common\models\EventRegistration[]|\yii\db\ActiveQuery */ public function getEventRegistrationCount(){ - return sizeof($this->getEventRegistrations() - ->andWhere( [ - 'canceled_at' => null, - 'deleted_at' => null, - ]) - ->all()); + return sizeof($this->getActiveEventRegistrations()->all()); } public function getOpenSeatCount(){ @@ -183,4 +191,16 @@ class Event extends \yii\db\ActiveRecord return true; } + + protected function getTrainerClass(){ + return Trainer::class; + } + protected function getEventTypeClass(){ + return EventType::class; + } + + protected function getRoomClass(){ + return Room::class; + } + } diff --git a/common/models/EventRegistration.php b/common/models/EventRegistration.php index 2b23453..b750052 100644 --- a/common/models/EventRegistration.php +++ b/common/models/EventRegistration.php @@ -65,4 +65,14 @@ class EventRegistration extends \yii\db\ActiveRecord ], parent::behaviors()); } + + + public function getEvent(){ + return $this->hasOne(Event::class,['id' => 'id_event']); + } + + public function getCustomer(){ + return $this->hasOne(Customer::class,['id' => 'id_customer']); + } + } diff --git a/composer.json b/composer.json index cc65f10..a24d3fa 100644 --- a/composer.json +++ b/composer.json @@ -14,8 +14,8 @@ }, "minimum-stability": "stable", "require": { - "php": ">=5.4.0", - "yiisoft/yii2": "2.0.6", + "php": ">=5.6.0", + "yiisoft/yii2": "~2.0.10", "yiisoft/yii2-bootstrap": "*", "yiisoft/yii2-swiftmailer": "*", "kartik-v/yii2-widgets": "^3.4", @@ -31,7 +31,10 @@ "os/php-excel": "^2.1", "phpoffice/phpexcel": "^1.8", "2amigos/yii2-tinymce-widget": "~1.1", - "iisns/yii2-assets-compress": "*" + "iisns/yii2-assets-compress": "*", + "yiisoft/yii2-composer": "2.0.4", + "sizeg/yii2-jwt": "^2.0", + "fxp/composer-asset-plugin": "dev-master" }, "require-dev": { "yiisoft/yii2-codeception": "*", diff --git a/composer.lock b/composer.lock index def3bce..f9ed977 100644 --- a/composer.lock +++ b/composer.lock @@ -1,11 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "hash": "6f107bd4aac24595297e9f71bfd031f3", - "content-hash": "42a9442876f84ea41b6767df22460fcf", + "content-hash": "62617dd27b81a8c6428c875f01cf0dd8", "packages": [ { "name": "2amigos/yii2-tinymce-widget", @@ -65,19 +64,19 @@ "yii 2", "yii2" ], - "time": "2015-03-28 21:53:43" + "time": "2015-03-28T21:53:43+00:00" }, { "name": "almasaeed2010/adminlte", "version": "v2.3.2", "source": { "type": "git", - "url": "https://github.com/almasaeed2010/AdminLTE.git", + "url": "https://github.com/ColorlibHQ/AdminLTE.git", "reference": "1ee281b3b99e8d8cccdc72fb8437c6888149cb46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/almasaeed2010/AdminLTE/zipball/1ee281b3b99e8d8cccdc72fb8437c6888149cb46", + "url": "https://api.github.com/repos/ColorlibHQ/AdminLTE/zipball/1ee281b3b99e8d8cccdc72fb8437c6888149cb46", "reference": "1ee281b3b99e8d8cccdc72fb8437c6888149cb46", "shasum": "" }, @@ -105,7 +104,7 @@ "theme", "web" ], - "time": "2015-10-23 14:50:49" + "time": "2015-10-23T14:50:49+00:00" }, { "name": "bassjobsen/bootstrap-3-typeahead", @@ -141,7 +140,7 @@ } ], "description": "Bootstrap 3 Typeahead", - "time": "2015-11-14 22:02:27" + "time": "2015-11-14T22:02:27+00:00" }, { "name": "bower-asset/accounting", @@ -245,6 +244,66 @@ ], "description": "Font Awesome" }, + { + "name": "bower-asset/inputmask", + "version": "3.3.11", + "source": { + "type": "git", + "url": "https://github.com/RobinHerbots/Inputmask.git", + "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/RobinHerbots/Inputmask/zipball/5e670ad62f50c738388d4dcec78d2888505ad77b", + "reference": "5e670ad62f50c738388d4dcec78d2888505ad77b", + "shasum": "" + }, + "require": { + "bower-asset/jquery": ">=1.7" + }, + "type": "bower-asset-library", + "extra": { + "bower-asset-main": [ + "./dist/inputmask/inputmask.js", + "./dist/inputmask/inputmask.extensions.js", + "./dist/inputmask/inputmask.date.extensions.js", + "./dist/inputmask/inputmask.numeric.extensions.js", + "./dist/inputmask/inputmask.phone.extensions.js", + "./dist/inputmask/jquery.inputmask.js", + "./dist/inputmask/global/document.js", + "./dist/inputmask/global/window.js", + "./dist/inputmask/phone-codes/phone.js", + "./dist/inputmask/phone-codes/phone-be.js", + "./dist/inputmask/phone-codes/phone-nl.js", + "./dist/inputmask/phone-codes/phone-ru.js", + "./dist/inputmask/phone-codes/phone-uk.js", + "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.jqlite.js", + "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.jquery.js", + "./dist/inputmask/dependencyLibs/inputmask.dependencyLib.js", + "./dist/inputmask/bindings/inputmask.binding.js" + ], + "bower-asset-ignore": [ + "**/*", + "!dist/*", + "!dist/inputmask/*", + "!dist/min/*", + "!dist/min/inputmask/*" + ] + }, + "license": [ + "http://opensource.org/licenses/mit-license.php" + ], + "description": "Inputmask is a javascript library which creates an input mask. Inputmask can run against vanilla javascript, jQuery and jqlite.", + "keywords": [ + "form", + "input", + "inputmask", + "jquery", + "mask", + "plugins" + ], + "time": "2017-11-21T11:46:23+00:00" + }, { "name": "bower-asset/jquery", "version": "2.1.4", @@ -314,58 +373,6 @@ "bower-asset-ignore": [] } }, - { - "name": "bower-asset/jquery.inputmask", - "version": "3.1.63", - "source": { - "type": "git", - "url": "https://github.com/RobinHerbots/jquery.inputmask.git", - "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/c40c7287eadc31e341ebbf0c02352eb55b9cbc48", - "reference": "c40c7287eadc31e341ebbf0c02352eb55b9cbc48", - "shasum": "" - }, - "require": { - "bower-asset/jquery": ">=1.7" - }, - "type": "bower-asset-library", - "extra": { - "bower-asset-main": [ - "./dist/inputmask/jquery.inputmask.js", - "./dist/inputmask/jquery.inputmask.extensions.js", - "./dist/inputmask/jquery.inputmask.date.extensions.js", - "./dist/inputmask/jquery.inputmask.numeric.extensions.js", - "./dist/inputmask/jquery.inputmask.phone.extensions.js", - "./dist/inputmask/jquery.inputmask.regex.extensions.js" - ], - "bower-asset-ignore": [ - "**/.*", - "qunit/", - "nuget/", - "tools/", - "js/", - "*.md", - "build.properties", - "build.xml", - "jquery.inputmask.jquery.json" - ] - }, - "license": [ - "http://opensource.org/licenses/mit-license.php" - ], - "description": "jquery.inputmask is a jquery plugin which create an input mask.", - "keywords": [ - "form", - "input", - "inputmask", - "jquery", - "mask", - "plugins" - ] - }, { "name": "bower-asset/moment", "version": "2.10.6", @@ -541,16 +548,16 @@ }, { "name": "cebe/markdown", - "version": "1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/cebe/markdown.git", - "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2" + "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2", - "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2", + "url": "https://api.github.com/repos/cebe/markdown/zipball/9bac5e971dd391e2802dca5400bbeacbaea9eb86", + "reference": "9bac5e971dd391e2802dca5400bbeacbaea9eb86", "shasum": "" }, "require": { @@ -568,7 +575,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -597,7 +604,7 @@ "markdown", "markdown-extra" ], - "time": "2015-03-06 05:28:07" + "time": "2018-03-26T11:24:36+00:00" }, { "name": "cebe/yii2-gravatar", @@ -640,7 +647,7 @@ "gravatar", "yii" ], - "time": "2013-12-10 17:49:58" + "time": "2013-12-10T17:49:58+00:00" }, { "name": "dmstr/yii2-adminlte-asset", @@ -694,25 +701,28 @@ "extension", "yii2" ], - "time": "2015-11-06 10:35:36" + "time": "2015-11-06T10:35:36+00:00" }, { "name": "ezyang/htmlpurifier", - "version": "v4.6.0", + "version": "v4.11.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd" + "reference": "83ab08bc1af7d808a9e0fbf024f1c24bfd73c0a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd", - "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/83ab08bc1af7d808a9e0fbf024f1c24bfd73c0a7", + "reference": "83ab08bc1af7d808a9e0fbf024f1c24bfd73c0a7", "shasum": "" }, "require": { "php": ">=5.2" }, + "require-dev": { + "simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd" + }, "type": "library", "autoload": { "psr-0": { @@ -724,7 +734,7 @@ }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL" + "LGPL-2.1-or-later" ], "authors": [ { @@ -738,7 +748,66 @@ "keywords": [ "html" ], - "time": "2013-11-30 08:25:19" + "time": "2019-07-14T18:58:38+00:00" + }, + { + "name": "fxp/composer-asset-plugin", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/fxpio/composer-asset-plugin.git", + "reference": "886ece037849d3935c5a34cdcd984e46f2de5fae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fxpio/composer-asset-plugin/zipball/886ece037849d3935c5a34cdcd984e46f2de5fae", + "reference": "886ece037849d3935c5a34cdcd984e46f2de5fae", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "composer/composer": "^1.6.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Fxp\\Composer\\AssetPlugin\\FxpAssetPlugin", + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Fxp\\Composer\\AssetPlugin\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Pluchino", + "email": "francois.pluchino@gmail.com" + } + ], + "description": "NPM/Bower Dependency Manager for Composer", + "homepage": "https://github.com/fxpio/composer-asset-plugin", + "keywords": [ + "asset", + "bower", + "composer", + "dependency manager", + "nodejs", + "npm", + "package" + ], + "time": "2019-08-08T18:36:07+00:00" }, { "name": "iisns/yii2-assets-compress", @@ -785,7 +854,7 @@ "iisns", "yii2" ], - "time": "2016-02-12 14:59:50" + "time": "2016-02-12T14:59:50+00:00" }, { "name": "kartik-v/bootstrap-fileinput", @@ -833,7 +902,7 @@ "progress", "upload" ], - "time": "2015-09-13 17:39:44" + "time": "2015-09-13T17:39:44+00:00" }, { "name": "kartik-v/bootstrap-star-rating", @@ -874,7 +943,7 @@ "jquery", "star" ], - "time": "2015-09-21 09:06:33" + "time": "2015-09-21T09:06:33+00:00" }, { "name": "kartik-v/dependent-dropdown", @@ -916,7 +985,7 @@ "option", "select" ], - "time": "2015-07-14 09:54:25" + "time": "2015-07-14T09:54:25+00:00" }, { "name": "kartik-v/yii2-krajee-base", @@ -962,7 +1031,7 @@ "widget", "yii2" ], - "time": "2015-06-16 05:19:57" + "time": "2015-06-16T05:19:57+00:00" }, { "name": "kartik-v/yii2-widget-activeform", @@ -1009,7 +1078,7 @@ "widget", "yii2" ], - "time": "2015-10-22 14:36:24" + "time": "2015-10-22T14:36:24+00:00" }, { "name": "kartik-v/yii2-widget-affix", @@ -1058,7 +1127,7 @@ "widget", "yii2" ], - "time": "2014-11-09 04:56:27" + "time": "2014-11-09T04:56:27+00:00" }, { "name": "kartik-v/yii2-widget-alert", @@ -1108,7 +1177,7 @@ "widget", "yii2" ], - "time": "2014-11-19 06:44:12" + "time": "2014-11-19T06:44:12+00:00" }, { "name": "kartik-v/yii2-widget-colorinput", @@ -1157,7 +1226,7 @@ "widget", "yii2" ], - "time": "2014-11-08 21:10:18" + "time": "2014-11-08T21:10:18+00:00" }, { "name": "kartik-v/yii2-widget-datepicker", @@ -1206,7 +1275,7 @@ "widget", "yii2" ], - "time": "2015-07-19 04:49:03" + "time": "2015-07-19T04:49:03+00:00" }, { "name": "kartik-v/yii2-widget-datetimepicker", @@ -1255,7 +1324,7 @@ "widget", "yii2" ], - "time": "2015-01-25 16:36:55" + "time": "2015-01-25T16:36:55+00:00" }, { "name": "kartik-v/yii2-widget-depdrop", @@ -1304,7 +1373,7 @@ "widget", "yii2" ], - "time": "2015-06-26 20:20:32" + "time": "2015-06-26T20:20:32+00:00" }, { "name": "kartik-v/yii2-widget-fileinput", @@ -1354,7 +1423,7 @@ "widget", "yii2" ], - "time": "2015-06-26 20:23:24" + "time": "2015-06-26T20:23:24+00:00" }, { "name": "kartik-v/yii2-widget-growl", @@ -1403,7 +1472,7 @@ "widget", "yii2" ], - "time": "2015-05-03 08:23:04" + "time": "2015-05-03T08:23:04+00:00" }, { "name": "kartik-v/yii2-widget-rangeinput", @@ -1452,7 +1521,7 @@ "widget", "yii2" ], - "time": "2014-11-08 21:15:27" + "time": "2014-11-08T21:15:27+00:00" }, { "name": "kartik-v/yii2-widget-rating", @@ -1503,7 +1572,7 @@ "widget", "yii2" ], - "time": "2014-11-08 19:30:37" + "time": "2014-11-08T19:30:37+00:00" }, { "name": "kartik-v/yii2-widget-select2", @@ -1551,7 +1620,7 @@ "widget", "yii2" ], - "time": "2015-09-12 19:56:48" + "time": "2015-09-12T19:56:48+00:00" }, { "name": "kartik-v/yii2-widget-sidenav", @@ -1600,7 +1669,7 @@ "widget", "yii2" ], - "time": "2014-11-09 08:07:23" + "time": "2014-11-09T08:07:23+00:00" }, { "name": "kartik-v/yii2-widget-spinner", @@ -1648,7 +1717,7 @@ "widget", "yii2" ], - "time": "2014-11-09 05:02:05" + "time": "2014-11-09T05:02:05+00:00" }, { "name": "kartik-v/yii2-widget-switchinput", @@ -1698,7 +1767,7 @@ "widget", "yii2" ], - "time": "2015-01-14 16:27:26" + "time": "2015-01-14T16:27:26+00:00" }, { "name": "kartik-v/yii2-widget-timepicker", @@ -1747,7 +1816,7 @@ "widget", "yii2" ], - "time": "2014-11-08 20:01:29" + "time": "2014-11-08T20:01:29+00:00" }, { "name": "kartik-v/yii2-widget-touchspin", @@ -1797,7 +1866,7 @@ "widget", "yii2" ], - "time": "2014-12-04 12:53:04" + "time": "2014-12-04T12:53:04+00:00" }, { "name": "kartik-v/yii2-widget-typeahead", @@ -1845,7 +1914,7 @@ "widget", "yii2" ], - "time": "2015-06-28 18:05:41" + "time": "2015-06-28T18:05:41+00:00" }, { "name": "kartik-v/yii2-widgets", @@ -1907,7 +1976,62 @@ "widget", "yii2" ], - "time": "2014-11-09 19:54:17" + "time": "2014-11-09T19:54:17+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "3.3.1", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", + "reference": "a11ec5f4b4d75d1fcd04e133dede4c317aac9e18", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-openssl": "*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "mikey179/vfsstream": "~1.5", + "phpmd/phpmd": "~2.2", + "phpunit/php-invoker": "~1.1", + "phpunit/phpunit": "^5.7 || ^7.3", + "squizlabs/php_codesniffer": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Otávio Cobucci Oblonczyk", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "time": "2019-05-24T18:30:49+00:00" }, { "name": "mpdf/mpdf", @@ -1950,7 +2074,7 @@ "php", "utf-8" ], - "time": "2015-03-01 10:27:49" + "time": "2015-03-01T10:27:49+00:00" }, { "name": "mrclay/minify", @@ -1995,7 +2119,7 @@ ], "description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers", "homepage": "http://code.google.com/p/minify/", - "time": "2016-03-08 11:49:57" + "time": "2016-03-08T11:49:57+00:00" }, { "name": "natxet/CssMin", @@ -2042,7 +2166,7 @@ "css", "minify" ], - "time": "2015-09-25 11:13:11" + "time": "2015-09-25T11:13:11+00:00" }, { "name": "os/php-excel", @@ -2079,7 +2203,7 @@ "keywords": [ "excel" ], - "time": "2012-05-02 20:42:37" + "time": "2012-05-02T20:42:37+00:00" }, { "name": "phpoffice/phpexcel", @@ -2136,7 +2260,8 @@ "xls", "xlsx" ], - "time": "2015-05-01 07:00:55" + "abandoned": "phpoffice/phpspreadsheet", + "time": "2015-05-01T07:00:55+00:00" }, { "name": "rmrevin/yii2-fontawesome", @@ -2188,7 +2313,51 @@ "font", "yii" ], - "time": "2015-11-20 09:17:45" + "time": "2015-11-20T09:17:45+00:00" + }, + { + "name": "sizeg/yii2-jwt", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sizeg/yii2-jwt.git", + "reference": "28830a6eaa66e8b0b08c392d180fc361559de56e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sizeg/yii2-jwt/zipball/28830a6eaa66e8b0b08c392d180fc361559de56e", + "reference": "28830a6eaa66e8b0b08c392d180fc361559de56e", + "shasum": "" + }, + "require": { + "lcobucci/jwt": "~3.3.0", + "php": ">=5.6.0", + "yiisoft/yii2": "~2.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8" + }, + "type": "yii2-extension", + "autoload": { + "psr-4": { + "sizeg\\jwt\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "authors": [ + { + "name": "Dmitriy Demin", + "email": "sizemail@gmail.com", + "homepage": "https://sizeg.tk" + } + ], + "description": "JWT based on Icobucci", + "keywords": [ + "jwt", + "yii 2", + "yii2" + ], + "time": "2019-09-21T06:50:31+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -2241,7 +2410,7 @@ "mail", "mailer" ], - "time": "2015-06-06 14:19:39" + "time": "2015-06-06T14:19:39+00:00" }, { "name": "tedivm/jshrink", @@ -2287,7 +2456,7 @@ "javascript", "minifier" ], - "time": "2015-07-04 07:35:09" + "time": "2015-07-04T07:35:09+00:00" }, { "name": "tinymce/tinymce", @@ -2333,33 +2502,34 @@ "tinymce", "wysiwyg" ], - "time": "2016-05-10 11:15:05" + "time": "2016-05-10T11:15:05+00:00" }, { "name": "yiisoft/yii2", - "version": "2.0.6", + "version": "2.0.27", "source": { "type": "git", "url": "https://github.com/yiisoft/yii2-framework.git", - "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38" + "reference": "6793f8f9b4cd891dbf475cfbb88cf480f74eaa85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f42b2eb80f61992438661b01d0d74c6738e2ff38", - "reference": "f42b2eb80f61992438661b01d0d74c6738e2ff38", + "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/6793f8f9b4cd891dbf475cfbb88cf480f74eaa85", + "reference": "6793f8f9b4cd891dbf475cfbb88cf480f74eaa85", "shasum": "" }, "require": { - "bower-asset/jquery": "2.1.*@stable | 1.11.*@stable", - "bower-asset/jquery.inputmask": "3.1.*", + "bower-asset/inputmask": "~3.2.2 | ~3.3.5", + "bower-asset/jquery": "3.4.*@stable | 3.3.*@stable | 3.2.*@stable | 3.1.*@stable | 2.2.*@stable | 2.1.*@stable | 1.11.*@stable | 1.12.*@stable", "bower-asset/punycode": "1.3.*", - "bower-asset/yii2-pjax": ">=2.0.1", - "cebe/markdown": "~1.0.0 | ~1.1.0", + "bower-asset/yii2-pjax": "~2.0.1", + "cebe/markdown": "~1.0.0 | ~1.1.0 | ~1.2.0", + "ext-ctype": "*", "ext-mbstring": "*", - "ezyang/htmlpurifier": "4.6.*", + "ezyang/htmlpurifier": "~4.6", "lib-pcre": "*", "php": ">=5.4.0", - "yiisoft/yii2-composer": "*" + "yiisoft/yii2-composer": "~2.0.4" }, "bin": [ "yii" @@ -2413,6 +2583,17 @@ "name": "Paul Klimov", "email": "klimov.paul@gmail.com", "role": "Core framework development" + }, + { + "name": "Dmitry Naumenko", + "email": "d.naumenko.a@gmail.com", + "role": "Core framework development" + }, + { + "name": "Boudewijn Vahrmeijer", + "email": "info@dynasource.eu", + "homepage": "http://dynasource.eu", + "role": "Core framework development" } ], "description": "Yii PHP Framework Version 2", @@ -2421,7 +2602,7 @@ "framework", "yii2" ], - "time": "2015-08-05 22:00:30" + "time": "2019-09-18T13:04:16+00:00" }, { "name": "yiisoft/yii2-bootstrap", @@ -2471,24 +2652,24 @@ "bootstrap", "yii2" ], - "time": "2015-09-23 17:48:24" + "time": "2015-09-23T17:48:24+00:00" }, { "name": "yiisoft/yii2-composer", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/yiisoft/yii2-composer.git", - "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be" + "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/ca8d23707ae47d20b0454e4b135c156f6da6d7be", - "reference": "ca8d23707ae47d20b0454e4b135c156f6da6d7be", + "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464", + "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464", "shasum": "" }, "require": { - "composer-plugin-api": "1.0.0" + "composer-plugin-api": "^1.0" }, "type": "composer-plugin", "extra": { @@ -2518,7 +2699,7 @@ "extension installer", "yii2" ], - "time": "2015-03-01 06:22:44" + "time": "2016-02-06T00:49:24+00:00" }, { "name": "yiisoft/yii2-jui", @@ -2568,7 +2749,7 @@ "jQuery UI", "yii2" ], - "time": "2015-05-10 22:09:43" + "time": "2015-05-10T22:09:43+00:00" }, { "name": "yiisoft/yii2-swiftmailer", @@ -2618,7 +2799,7 @@ "swiftmailer", "yii2" ], - "time": "2015-05-10 22:12:32" + "time": "2015-05-10T22:12:32+00:00" } ], "packages-dev": [ @@ -2699,7 +2880,7 @@ "faker", "fixtures" ], - "time": "2015-05-29 06:29:14" + "time": "2015-05-29T06:29:14+00:00" }, { "name": "phpspec/php-diff", @@ -2733,7 +2914,7 @@ } ], "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", - "time": "2013-11-01 13:02:21" + "time": "2013-11-01T13:02:21+00:00" }, { "name": "yiisoft/yii2-codeception", @@ -2778,7 +2959,8 @@ "codeception", "yii2" ], - "time": "2015-05-10 22:08:30" + "abandoned": "codeception/codeception", + "time": "2015-05-10T22:08:30+00:00" }, { "name": "yiisoft/yii2-debug", @@ -2825,7 +3007,7 @@ "debugger", "yii2" ], - "time": "2015-08-06 16:14:06" + "time": "2015-08-06T16:14:06+00:00" }, { "name": "yiisoft/yii2-faker", @@ -2872,7 +3054,7 @@ "faker", "yii2" ], - "time": "2015-03-01 06:22:44" + "time": "2015-03-01T06:22:44+00:00" }, { "name": "yiisoft/yii2-gii", @@ -2925,16 +3107,18 @@ "gii", "yii2" ], - "time": "2015-05-10 22:09:31" + "time": "2015-05-10T22:09:31+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "fxp/composer-asset-plugin": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4.0" + "php": ">=5.6.0" }, "platform-dev": [] } diff --git a/customer/app/src/app/app.module.ts b/customer/app/src/app/app.module.ts index 5430b2f..4683ff8 100644 --- a/customer/app/src/app/app.module.ts +++ b/customer/app/src/app/app.module.ts @@ -67,7 +67,7 @@ registerLocaleData(localeHu, 'hu'); { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, // provider used to create fake backend - fakeBackendProvider + // fakeBackendProvider ], bootstrap: [AppComponent] }) diff --git a/customer/app/src/app/services/authentication.service.ts b/customer/app/src/app/services/authentication.service.ts index e1cfc68..476ccc0 100644 --- a/customer/app/src/app/services/authentication.service.ts +++ b/customer/app/src/app/services/authentication.service.ts @@ -18,7 +18,7 @@ export class AuthenticationService { // login login(username: string, password:string){ - return this.http.post(Endpoints.POST_USERS_AUTHENTICATE(), {username,password}) + return this.http.post(Endpoints.POST_USERS_AUTHENTICATE(), {username:username,password:password}) .pipe( // the backend service sends an instance of the user // user: any (because .post) diff --git a/customer/app/src/app/services/endpoints.ts b/customer/app/src/app/services/endpoints.ts index 1caefe1..c3dbe10 100644 --- a/customer/app/src/app/services/endpoints.ts +++ b/customer/app/src/app/services/endpoints.ts @@ -2,11 +2,11 @@ import {Observable} from "rxjs"; import {EventType} from "./event.service"; export class Endpoints { - private static contextPath = "http://localhost/api"; - private static baseUrl: string = Endpoints.contextPath + "/rest/web/index.php?r="; + private static contextPath = "http://localhost:86/fitness_web"; + private static baseUrl: string = Endpoints.contextPath + "/customerapi/web/index.php?r="; public static POST_USERS_AUTHENTICATE(){ - return `${this.baseUrl}/users/authenticate`; + return `${this.baseUrl}user/login`; } public static GET_EVENTS( ){ diff --git a/customer/app/src/app/services/event.service.ts b/customer/app/src/app/services/event.service.ts index e793606..a2b7a36 100644 --- a/customer/app/src/app/services/event.service.ts +++ b/customer/app/src/app/services/event.service.ts @@ -53,15 +53,21 @@ export interface Event { reservationCount: number; eventType: EventType; reservedAt: number; + room: Room; } +export interface Room { + id: number; + name: string; + seat_count: number; +} export interface EventType { id: number; name: string; } export interface DayToDisplay { - date: number; + date: number; //seconds active: true; events: Event[]; } diff --git a/customerapi/components/JwtValidationData.php b/customerapi/components/JwtValidationData.php new file mode 100644 index 0000000..889e6f9 --- /dev/null +++ b/customerapi/components/JwtValidationData.php @@ -0,0 +1,18 @@ +validationData->setIssuer('customerapi'); + $this->validationData->setAudience('customer'); + $this->validationData->setId('A989C57D19E2AF756BA9585AC4CFAF7974AE3D2BCA7CCA7307B39AB28CC7C2C8'); + + parent::init(); + } +} diff --git a/customerapi/config/main.php b/customerapi/config/main.php index b540ef6..1bfb925 100644 --- a/customerapi/config/main.php +++ b/customerapi/config/main.php @@ -1,4 +1,8 @@ [ 'errorAction' => 'site/error', ], + 'jwt' => [ + 'class' => Jwt::class, + 'key' => 'secret', + // You have to configure ValidationData informing all claims you want to validate the token. + 'jwtValidationData' => JwtValidationData::class, + ], ], 'params' => $params, ]; diff --git a/customerapi/controllers/CustomerController.php b/customerapi/controllers/CustomerApiController.php similarity index 84% rename from customerapi/controllers/CustomerController.php rename to customerapi/controllers/CustomerApiController.php index 2e975e8..a0eccc5 100644 --- a/customerapi/controllers/CustomerController.php +++ b/customerapi/controllers/CustomerApiController.php @@ -15,7 +15,7 @@ use common\models\Ticket; use yii\web\BadRequestHttpException; use yii\web\NotFoundHttpException; -class CustomerController extends CustomerapiController +class CustomerApiController extends RestController { diff --git a/customerapi/controllers/EventController.php b/customerapi/controllers/EventController.php index 185276b..fc5b7db 100644 --- a/customerapi/controllers/EventController.php +++ b/customerapi/controllers/EventController.php @@ -9,20 +9,84 @@ namespace customerapi\controllers; -use common\components\Helper; -use common\models\Card; -use common\models\Ticket; -use yii\web\BadRequestHttpException; -use yii\web\NotFoundHttpException; +use common\models\Event; +use customerapi\models\available\EventInterval; +use customerapi\models\available\EventAvailable; +use customerapi\models\DayToDisplay; +use DateTime; +use Exception; -class EventController extends CustomerapiController +/** @noinspection PhpUnused */ + +class EventController extends CustomerApiController { - + /** @noinspection PhpUnused */ /** + * interface EventsAvailableResponse { + * days: DayToDisplay[]; + * events: Event[]; + * } + * @throws Exception */ - public function actionEvent( ) + public function actionAvailable() { + $interval = EventInterval::createInterval(); + + // compose day objects + $dates = []; + for ($i = 0; $i < $interval->daysToDisplay; $i++) { + $day = clone $interval->firstDisplayDate; + $day->modify('+' . $i . ' day'); + $dayToDisplay = new DayToDisplay(); + $dayToDisplay->date = $day->getTimestamp(); + $afterFirstActiveDay = $interval->firstActiveDate < $day || $interval->firstActiveDate == $day; + $beforeLastActiveDay = $interval->lastActiveDate > $day || $interval->lastActiveDate == $day; + + $dayToDisplay->active = ($afterFirstActiveDay && $beforeLastActiveDay); + $dayToDisplay->comment = '#' . idate('W', $day->getTimestamp()) . ' - ' . $day->format('Y-m-d H:i:s'); + $dayToDisplay->events = []; + $dates[] = $dayToDisplay; + } + + // get events between active dates + $query = EventAvailable::find(); + $query = $query->select( + [ + '{{event}}.*', +// 'COUNT({{event_registration}}.id) AS reservationCount' + ]); + + $events = $query + ->innerJoinWith('trainer') + ->innerJoinWith('eventType') + ->innerJoinWith('room') + ->joinWith('activeEventRegistrations') + ->andWhere(['>=', 'event.start', $interval->firstActiveDate->getTimestamp()]) + ->andWhere(['<', 'event.start', (clone $interval->lastActiveDate)->modify('+1 day')->getTimestamp()]) + ->andWhere(['event.active' => '1']) + ->all(); + + // set events per day + /** @var Event $event */ + foreach ($events as $event) { + $eventDay = new DateTime(); + $eventDay->setTimestamp($event->start); + $eventDay->setTime(0, 0); + + /** @var DayToDisplay $date */ + foreach ($dates as $date) { + if ($date->date === $eventDay->getTimestamp()) { + $date->events[] = $event; + break; + } + } + } + + return + $this->asJson([ + 'interval' => $interval, + 'dates' => $dates + ]); } - } diff --git a/customerapi/controllers/EventRegistrationController.php b/customerapi/controllers/EventRegistrationController.php new file mode 100644 index 0000000..6df9baf --- /dev/null +++ b/customerapi/controllers/EventRegistrationController.php @@ -0,0 +1,67 @@ +innerJoinWith('event') + ->andWhere(['and', + ['>=', 'event.start', $interval->firstActiveDate->getTimestamp()], + ['<', 'event.start', $interval->lastActiveDate->getTimestamp()], + ['id_customer' => Yii::$app->user->getId()] + ])->all(); + + return $this->asJson( + + $registrations + ); + + } + + /** + * @noinspection PhpUnused + * @param $idEvent + * @throws Throwable + */ + public function actionRegister($idEvent) { + /** @var Customer $customer */ + $customer = Yii::$app->user->getIdentity(); + $card =$customer->card; + + $form = new CardEventRegistrationForm(); + $form->event_id = $idEvent; + $form->card_number = $card->number; + + $manager = new EventRegistrationManager(); + $manager->registerCard($form); + + return $form->registration; + + } + + +} diff --git a/customerapi/controllers/PingController.php b/customerapi/controllers/PingController.php new file mode 100644 index 0000000..45a28b6 --- /dev/null +++ b/customerapi/controllers/PingController.php @@ -0,0 +1,28 @@ +response->setStatusCode( HttpStatus::NO_CONTENT ); + } + + +} diff --git a/customerapi/controllers/RestController.php b/customerapi/controllers/RestController.php index fc9a1fd..87203c7 100644 --- a/customerapi/controllers/RestController.php +++ b/customerapi/controllers/RestController.php @@ -3,44 +3,58 @@ namespace customerapi\controllers; -use common\components\Helper; -use common\models\Card; use common\models\Customer; -use yii\filters\auth\HttpBasicAuth; +use Exception; +use Lcobucci\JWT\Token; +use sizeg\jwt\JwtHttpBearerAuth; +use Yii; +use yii\filters\auth\AuthMethod; +use yii\rest\Controller; -class RestController extends \yii\web\Controller +class RestController extends Controller { public function behaviors() { $behaviors = parent::behaviors(); $behaviors['authenticator'] = [ - 'class' => HttpBasicAuth::className(), - 'auth' => [$this, 'auth'] + 'class' => JwtHttpBearerAuth::class, + 'auth' => [$this, 'auth'], + 'optional' => $this->getOptionalActions(), ]; return $behaviors; } - public function auth($username, $password) + /** + * This method will check the token + * @param Token $token + * @return Customer|null + */ + public function auth($token) { + if ( !isset($token ) ) { + return null; + } try { -// $query = Card::find(); -// Card::addCardNumberCondition($query, Helper::fixAsciiChars($username)); -// $card = $query->one(); - - $customer = Customer::findOne(['email' => $username]); - - + $uid = (string) $token->getClaim('uid'); + $customer = Customer::findOne(['id_customer' => $uid]); if (isset($customer)) { - if ($customer->validatePassword($password)) { + \Yii::$app->user->setIdentity($customer); return $customer; - } } - } catch (\Exception $e) { - \Yii::error("Failed to load user: " . $e->getMessage()); + } catch (Exception $e) { + Yii::error('Failed to load customer: ' . $e->getMessage()); } return null; } + /** + * @see AuthMethod::$optional + * @return array + */ + protected function getOptionalActions(){ + return []; + } + } diff --git a/customerapi/controllers/UserController.php b/customerapi/controllers/UserController.php index 6be590a..31a20ee 100644 --- a/customerapi/controllers/UserController.php +++ b/customerapi/controllers/UserController.php @@ -8,21 +8,61 @@ namespace customerapi\controllers; +use common\models\Customer; +use customerapi\models\LoginForm; +use sizeg\jwt\Jwt; +use sizeg\jwt\JwtHttpBearerAuth; +use Yii; -use common\components\Helper; -use common\models\Card; -use common\models\Ticket; -use yii\web\BadRequestHttpException; -use yii\web\NotFoundHttpException; +/** @noinspection PhpUnused */ class UserController extends RestController { - /** - */ + + /** @noinspection PhpUnused */ public function actionLogin( ) { - \Yii::$app->response->setStatusCode(204); + + $form = new LoginForm(); + + $form->load(\Yii::$app->request->post( ), ''); + + if ( $form->validate() ){ + + + /** @var Jwt $jwt */ + $jwt = Yii::$app->jwt; + $signer = $jwt->getSigner('HS256'); + $key = $jwt->getKey(); + $time = time(); + + // Adoption for lcobucci/jwt ^4.0 version + $token = $jwt->getBuilder() + ->issuedBy('customerapi')// Configures the issuer (iss claim) + ->permittedFor('customer')// Configures the audience (aud claim) + ->identifiedBy('A989C57D19E2AF756BA9585AC4CFAF7974AE3D2BCA7CCA7307B39AB28CC7C2C8', true)// Configures the id (jti claim), replicating as a header item + ->issuedAt($time)// Configures the time that the token was issue (iat claim) + ->expiresAt($time + 3600)// Configures the expiration time of the token (exp claim) + ->withClaim('uid', $form->getCustomer()->getId())// Configures a new claim, called "uid" + ->getToken($signer, $key); // Retrieves the generated token + + return $this->asJson([ + 'token' => (string)$token, + ]); + } else { + return $this->asJson( + [ + 'errors' => $form->getErrors() + ] + ); + } + + } + + protected function getOptionalActions() + { + return ['login']; } diff --git a/customerapi/models/DayToDisplay.php b/customerapi/models/DayToDisplay.php new file mode 100644 index 0000000..180bc9a --- /dev/null +++ b/customerapi/models/DayToDisplay.php @@ -0,0 +1,13 @@ +Yii::t('common/site', 'Username'), + 'password' =>Yii::t('common/site', 'Password'), + ]; + } + + /** + * Validates the password. + * This method serves as the inline validation for password. + * + * @param string $attribute the attribute currently being validated + * @param array $params the additional name-value pairs given in the rule + * @throws \yii\base\InvalidConfigException + */ + public function validatePassword($attribute, $params) + { + if (!$this->hasErrors()) { + /** @var \common\models\Customer $user */ + $customer = $this->getCustomer(); + if (!$customer || !$customer->validatePassword($this->password)) { + $this->addError($attribute, 'Incorrect username or password.'); + } + } + } + + + /** + * Finds user by [[username]] + * + * @return Customer|null + */ + public function getCustomer() + { + if ( $this->customer === null ){ + $this->customer = Customer::findIdentity( $this->username ); + } + return $this->customer; + } +} diff --git a/customerapi/models/available/EventAvailable.php b/customerapi/models/available/EventAvailable.php new file mode 100644 index 0000000..330860f --- /dev/null +++ b/customerapi/models/available/EventAvailable.php @@ -0,0 +1,58 @@ + "id", + "start" => "start", + "end" => "end", + "seat_count" => "seat_count", + "active" => "active", +// "reservationCount" => "reservationCount" + ]; + $fields['trainer'] = 'trainer'; + $fields['eventType'] = 'eventType'; + $fields['room'] = 'room'; + return $fields; + } + + + function extraFields() + { + $extra= parent::extraFields(); + $extra[] = 'trainer'; + return $extra; + } + +} diff --git a/customerapi/models/available/EventInterval.php b/customerapi/models/available/EventInterval.php new file mode 100644 index 0000000..2c100c2 --- /dev/null +++ b/customerapi/models/available/EventInterval.php @@ -0,0 +1,56 @@ +setTime(0, 0); + $this->firstActiveDate = $firstActiveDay; + + $lastActiveDay = new DateTime(); + $lastActiveDay->setTime(0, 0); + $lastActiveDay->modify('+' . $this->countOfActiveDays . ' day'); + $this->lastActiveDate = $lastActiveDay; + + $firstDisplayDate = new DateTime(); + $firstDisplayDate->modify('this week'); + $firstDisplayDate->setTime(0, 0); + $this->firstDisplayDate = $firstDisplayDate; + + $lastDisplayDate = clone $firstDisplayDate; + $lastDisplayDate->setTime(0, 0); + $lastDisplayDate->modify('+' . $this->daysToDisplay . ' day'); + $this->lastDisplayDate = $lastDisplayDate; + + } + + public static function createInterval(){ + return new EventInterval(); +} +} diff --git a/customerapi/models/available/EventRegistrationAvailable.php b/customerapi/models/available/EventRegistrationAvailable.php new file mode 100644 index 0000000..1ed7f40 --- /dev/null +++ b/customerapi/models/available/EventRegistrationAvailable.php @@ -0,0 +1,13 @@ + 'id', + 'name' => 'name' + ]; + } + +} diff --git a/customerapi/models/available/RoomAvailable.php b/customerapi/models/available/RoomAvailable.php new file mode 100644 index 0000000..01a58a1 --- /dev/null +++ b/customerapi/models/available/RoomAvailable.php @@ -0,0 +1,19 @@ + 'id', + 'name' => 'name', + 'seat_count' => 'seat_count' + ]; + } +} diff --git a/customerapi/models/available/TrainerAvailable.php b/customerapi/models/available/TrainerAvailable.php new file mode 100644 index 0000000..e4ae5cf --- /dev/null +++ b/customerapi/models/available/TrainerAvailable.php @@ -0,0 +1,20 @@ + 'id', + 'name' => 'name' + ]; + } + +} diff --git a/customerapi/web/assets/.gitkeep b/customerapi/web/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/doc/upgrade.txt b/doc/upgrade.txt new file mode 100644 index 0000000..cdb5d08 --- /dev/null +++ b/doc/upgrade.txt @@ -0,0 +1,23 @@ +composer self-update + +## composer --version +## Do not run Composer as root/super user! See https://getcomposer.org/root for details +## Composer version 1.9.0 2019-08-02 20:55:32 + + +composer config -g github-oauth.github.com 4fe4faf52ce29b298d02c6473a1ee7e10047ed7c + +#token: 4fe4faf52ce29b298d02c6473a1ee7e10047ed7c + +composer require "fxp/composer-asset-plugin:^1.1.3" + +composer require "fxp/composer-asset-plugin:dev-master" + +# composer require "yiisoft/yii2":"2.0.7" + +# sometimes it works only, if we first update to this version and then to the higher version +composer require "yiisoft/yii2":"2.0.5" + +composer require "yiisoft/yii2:~2.0.10" --update-with-dependencies + +