From f2b7874edd21a324b8d00f8153ad60eccd82614d Mon Sep 17 00:00:00 2001 From: Vassilis Kanellopoulos Date: Fri, 19 Feb 2016 13:47:04 +0200 Subject: [PATCH] application form submission completed --- config/settings/acl.global.php | 1 + config/settings/nav.global.php | 8 +- module/application/bootstrap.php | 5 +- module/application_form/bootstrap.php | 24 ++++-- module/application_form/data/schema.mysql.sql | 63 ++++++++++++++ .../public/js/application_form/index.js | 34 +++++--- .../src/Action/ApplicationForm.php | 39 +++++++-- .../src/Action/SubmitSuccess.php | 48 +++++++++++ .../src/Service/ApplicationFormService.php | 4 +- .../templates/application_form/form.twig | 75 +++++++++------- .../application_form/submit_success.twig | 86 +++++++++++++++++++ 11 files changed, 325 insertions(+), 62 deletions(-) create mode 100644 module/application_form/data/schema.mysql.sql create mode 100644 module/application_form/src/Action/SubmitSuccess.php create mode 100644 module/application_form/templates/application_form/submit_success.twig diff --git a/config/settings/acl.global.php b/config/settings/acl.global.php index 74f6fa9..7f63af1 100644 --- a/config/settings/acl.global.php +++ b/config/settings/acl.global.php @@ -28,6 +28,7 @@ return [ ['/school/assets', ['school'], ['get', 'post', 'delete']], ['/school/labs/attachment', ['school'], ['get', 'delete']], ['/application-form', ['school'], ['get', 'post']], + ['/application-form/submit-success', ['school'], ['get']], ], ], ], diff --git a/config/settings/nav.global.php b/config/settings/nav.global.php index c665293..15565ec 100644 --- a/config/settings/nav.global.php +++ b/config/settings/nav.global.php @@ -42,10 +42,10 @@ return [ ], ], ], - // 'app-form' => [ - // 'label' => 'Αίτηση', - // 'route' => 'app-form', - // ], + 'app-form' => [ + 'label' => 'Αίτηση', + 'route' => 'application_form', + ], ], ], diff --git a/module/application/bootstrap.php b/module/application/bootstrap.php index 817d27d..0d0abb9 100644 --- a/module/application/bootstrap.php +++ b/module/application/bootstrap.php @@ -26,10 +26,9 @@ return function (Slim\App $app) { RedBeanPHP\R::setup( $container['settings']['db']['dsn'], $container['settings']['db']['user'], - $container['settings']['db']['pass'] + $container['settings']['db']['pass'], + isset($container['settings']['db']['freeze']) ? $container['settings']['db']['freeze'] : true ); - RedBeanPHP\R::freeze(); -// RedBeanPHP\R::debug( true ); $container['view'] = function ($c) { $settings = $c['settings']; diff --git a/module/application_form/bootstrap.php b/module/application_form/bootstrap.php index 0cdf619..5a69114 100644 --- a/module/application_form/bootstrap.php +++ b/module/application_form/bootstrap.php @@ -47,9 +47,18 @@ return function (Slim\App $app) { return new GrEduLabs\ApplicationForm\Action\ApplicationForm( $c->get('view'), $c->get(GrEduLabs\Schools\Service\AssetServiceInterface::class), + $c->get(GrEduLabs\Schools\Service\LabServiceInterface::class), $c->get(GrEduLabs\ApplicationForm\Service\ApplicationFormServiceInterface::class), $c->get(GrEduLabs\ApplicationForm\InputFilter\ApplicationForm::class), - $c->get('authentication_service') + $c->get('authentication_service'), + $c->get('router')->pathFor('application_form.submit_success') + ); + }; + + $container[GrEduLabs\ApplicationForm\Action\SubmitSuccess::class] = function ($c) { + return new GrEduLabs\ApplicationForm\Action\SubmitSuccess( + $c->get('view'), + $c->get('router')->pathFor('application_form') ); }; }); @@ -57,10 +66,13 @@ return function (Slim\App $app) { $events('on', 'app.bootstrap', function ($stop, $app, $container) { $container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates'); - $app->map(['get', 'post'], '/application-form', GrEduLabs\ApplicationForm\Action\ApplicationForm::class) - ->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class) - ->add(GrEduLabs\Application\Middleware\AddCsrfToView::class) - ->add('csrf') - ->setName('application_form'); + $app->group('/application-form', function () { + $this->map(['get', 'post'], '', GrEduLabs\ApplicationForm\Action\ApplicationForm::class) + ->add(GrEduLabs\Application\Middleware\AddCsrfToView::class) + ->add('csrf') + ->setName('application_form'); + $this->get('/submit-success', GrEduLabs\ApplicationForm\Action\SubmitSuccess::class) + ->setName('application_form.submit_success'); + })->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class); }); }; diff --git a/module/application_form/data/schema.mysql.sql b/module/application_form/data/schema.mysql.sql new file mode 100644 index 0000000..6fb1b0e --- /dev/null +++ b/module/application_form/data/schema.mysql.sql @@ -0,0 +1,63 @@ +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `applicationform` +-- + +DROP TABLE IF EXISTS `applicationform`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `applicationform` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `school_id` int(11) unsigned NOT NULL, + `apply_for` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + `new_lab_perspective` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `comments` TEXT COLLATE utf8mb4_unicode_ci, + `submitted` int(11) unsigned NOT NULL, + `submitted_by` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, + PRIMARY KEY (`id`), + KEY `index_foreignkey_applicationform_school` (`school_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + + +-- +-- Table structure for table `applicationformitem` +-- + +DROP TABLE IF EXISTS `applicationformitem`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `applicationformitem` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `itemcategory_id` int(11) unsigned NOT NULL, + `qty` int(11) unsigned NOT NULL, + `reasons` TEXT COLLATE utf8mb4_unicode_ci NOT NULL, + `applicationform_id` int(11) unsigned NOT NULL, + `lab_id` int(11) unsigned NOT NULL, + PRIMARY KEY (`id`), + KEY `index_foreignkey_applicationformitem_itemcategory` (`itemcategory_id`), + KEY `index_foreignkey_applicationformitem_applicationform` (`applicationform_id`), + KEY `index_foreignkey_applicationformitem_lab` (`lab_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + diff --git a/module/application_form/public/js/application_form/index.js b/module/application_form/public/js/application_form/index.js index 08b6bf1..599c4f5 100644 --- a/module/application_form/public/js/application_form/index.js +++ b/module/application_form/public/js/application_form/index.js @@ -1,19 +1,16 @@ -(function () { +(function ($, _, utils) { 'use strict'; var ItemsView, - ItemRowView, - itemCount = 0; - + ItemRowView; ItemRowView = Backbone.View.extend({ tagName: 'tr', render: function (index) { - this.$el.html(this.constructor.template({ index: index | 0})); + this.$el.html(this.template({ index: index | 0})); return this; - } - }, { + }, template: _.template($('#app-form-item-row-template').html()) }); @@ -26,9 +23,6 @@ }, initialize: function () { this.itemCount = this.$el.find('tbody tr').length; - if (this.itemCount === 0) { - this.addRow(); - } }, addRow: function () { var index = this.itemCount; @@ -45,4 +39,22 @@ }); new ItemsView(); -}()); \ No newline at end of file + + (function () { + var form = $('#app-form form'), + messages = (function (messages) { + var itemMessages = {}; + _.each(messages.items || [], function (message, idx){ + var name = 'items[' + idx + ']'; + _.each(_.keys(message), function (prop) { + itemMessages[name + '[' + prop + ']'] = message[prop]; + }); + }); + delete messages.items; + _.extend(messages, itemMessages); + return messages; + }(form.data('messages'))); + utils.formMessages.render(form, messages); + }()); + +}(window.jQuery, _, window.EDULABS.utils)); \ No newline at end of file diff --git a/module/application_form/src/Action/ApplicationForm.php b/module/application_form/src/Action/ApplicationForm.php index b97f2c1..1ef4193 100644 --- a/module/application_form/src/Action/ApplicationForm.php +++ b/module/application_form/src/Action/ApplicationForm.php @@ -12,6 +12,7 @@ namespace GrEduLabs\ApplicationForm\Action; use GrEduLabs\ApplicationForm\Service\ApplicationFormServiceInterface; use GrEduLabs\Schools\Service\AssetServiceInterface; +use GrEduLabs\Schools\Service\LabServiceInterface; use Slim\Http\Request; use Slim\Http\Response; use Slim\Views\Twig; @@ -31,6 +32,12 @@ class ApplicationForm */ protected $assetsService; + /** + * + * @var LabServiceInterface + */ + protected $labService; + /** * * @var ApplicationFormServiceInterface @@ -49,19 +56,28 @@ class ApplicationForm */ protected $authService; + /** + * + * @var string + */ + protected $successUrl; public function __construct( Twig $view, AssetServiceInterface $assetsService, + LabServiceInterface $labService, ApplicationFormServiceInterface $appFormService, InputFilterInterface $appFormInputFilter, - AuthenticationServiceInterface $authService + AuthenticationServiceInterface $authService, + $successUrl ) { $this->view = $view; $this->assetsService = $assetsService; + $this->labService = $labService; $this->appFormService = $appFormService; $this->appFormInputFilter = $appFormInputFilter; $this->authService = $authService; + $this->successUrl = $successUrl; } public function __invoke(Request $req, Response $res) @@ -75,10 +91,12 @@ class ApplicationForm ])); $isValid = $this->appFormInputFilter->isValid(); if ($isValid) { - $data = $this->appFormInputFilter->getValues(); - $appForm = $this->appFormService->submit($data); - var_dump($appForm); - die(); + $data = $this->appFormInputFilter->getValues(); + $appForm = $this->appFormService->submit($data); + $_SESSION['applicationForm']['appForm'] = $appForm; + $res = $res->withRedirect($this->successUrl); + + return $res; } $this->view['form'] = [ @@ -87,10 +105,19 @@ class ApplicationForm 'raw_values' => $this->appFormInputFilter->getRawValues(), 'messages' => $this->appFormInputFilter->getMessages(), ]; - var_dump($this->view['form']); } + // todo replace with labs from service + $labs = array_map(function ($bean) { + return $bean->export(); + }, \RedBeanPHP\R::findAll('lab', ' school_id = ? ', [$school->id])); + +// $labs = $this->labService->getLabsBySchoolId($school->id); + $res = $this->view->render($res, 'application_form/form.twig', [ + 'lab_choices' => array_map(function ($lab) { + return ['value' => $lab['id'], 'label' => $lab['name']]; + }, $labs), 'type_choices' => array_map(function ($category) { return ['value' => $category['id'], 'label' => $category['name']]; }, $this->assetsService->getAllItemCategories()), diff --git a/module/application_form/src/Action/SubmitSuccess.php b/module/application_form/src/Action/SubmitSuccess.php new file mode 100644 index 0000000..b367005 --- /dev/null +++ b/module/application_form/src/Action/SubmitSuccess.php @@ -0,0 +1,48 @@ +view = $view; + $this->formUrl = $formUrl; + } + + public function __invoke(Request $req, Response $res) + { + $school = $req->getAttribute('school'); + + if (!isset($_SESSION['applicationForm']['appForm'])) { + $res = $res->withRedirect($this->formUrl); + + return $res; + } + $appForm = $_SESSION['applicationForm']['appForm']; + + $_SESSION['applicationForm']['appForm'] = null; + unset($_SESSION['applicationForm']['appForm']); + + return $this->view->render($res, 'application_form/submit_success.twig', [ + 'school' => $school, + 'appForm' => $appForm, + ]); + } +} diff --git a/module/application_form/src/Service/ApplicationFormService.php b/module/application_form/src/Service/ApplicationFormService.php index b2e8c32..9fd5be7 100644 --- a/module/application_form/src/Service/ApplicationFormService.php +++ b/module/application_form/src/Service/ApplicationFormService.php @@ -36,8 +36,8 @@ class ApplicationFormService implements ApplicationFormServiceInterface $appForm->submitted_by = $data['submitted_by']; $items = []; foreach ($data['items'] as $itemData) { - $item = R::dispense('applicationformitem'); -// $item->lab_id = $itemData['lab_id']; + $item = R::dispense('applicationformitem'); + $item->lab_id = $itemData['lab_id']; $item->itemcategory_id = $itemData['itemcategory_id']; $item->qty = $itemData['qty']; $item->reasons = $itemData['reasons']; diff --git a/module/application_form/templates/application_form/form.twig b/module/application_form/templates/application_form/form.twig index 4980665..2681329 100644 --- a/module/application_form/templates/application_form/form.twig +++ b/module/application_form/templates/application_form/form.twig @@ -1,25 +1,35 @@ {% extends "layout.twig" %} {% macro itemSelect(name, label, options, selected, index) %} - +
+ +
{% endmacro %} {% macro itemCount(name, label, value, index) %}
+ type="number" name="items[{{ index | default('<%= index %>') | raw }}][{{ name }}]" value="{{ value|default('')|raw }}">
{% endmacro %} +{% macro itemReasons(name, label, value, index) %} +
+ +
+{% endmacro %} + {% macro select(name, label, options, selected) %}
@@ -48,7 +58,9 @@ {% macro text(name, label, value) %}
- +
{% endmacro %} @@ -61,7 +73,8 @@ Αίτηση για νέο εξοπλισμό {% endblock %} -
+

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent pulvinar tincidunt odio, vel pretium mauris imperdiet at. In tempor fermentum enim, euismod posuere @@ -106,35 +119,39 @@

Νέος εξοπλισμός -
+
- - + + - {% for item in form.values.items %} + {% for itemIndex,item in form.values.items %} - - + + + - + {% else %} + + + + + + + {% endfor %} @@ -168,12 +185,10 @@ +{% endblock %} \ No newline at end of file -- GitLab
ΧώροςΤύπος ΠλήθοςΤύποςΧώρος Αιτιολογία χρήσης
{{ macros.itemSelect('lab_id', 'Χώρος', lab_choices, item.lab_id, loop.index0 ) }}{{ macros.itemSelect('itemcategory_id', 'Τύπος', type_choices, item.itemcategory_id, loop.index0) }} {{ macros.itemCount('qty', 'Πλήθος', item.qty, loop.index0) }}{{ macros.itemSelect('itemcategory_id', 'Τύπος', type_choices, item.itemcategory_id, loop.index0) }}{{ macros.itemSelect('lab_id', 'Χώρος', lab_choices, item.lab_id, loop.index0 ) }}{{ macros.itemReasons('reasons', 'Αιτιολογία χρήσης', item.reasons, loop.index0) }} - -
{{ macros.itemCount('qty', 'Πλήθος', '', 0) }}{{ macros.itemSelect('itemcategory_id', 'Τύπος', type_choices, '', 0) }}{{ macros.itemSelect('lab_id', 'Χώρος', lab_choices, '', 0 ) }}{{ macros.itemReasons('reasons', 'Αιτιολογία χρήσης', '', 0) }}