diff --git a/.gitignore b/.gitignore index bb1fd07d34de2e225287802d3c945cc432884f34..7012e249e08d4a3cf16f9f9df12648ff2863c7a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .phpintel -vendor \ No newline at end of file +vendor +/nbproject/private/ \ No newline at end of file diff --git a/composer.json b/composer.json index fbbdf3a2face7873102b6e6d523ab379f9090f71..d319d1aa782af9d9b0015b5a8b110b4bb78b7e68 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "zendframework/zend-crypt": "^2.0", "zendframework/zend-eventmanager": "^3.0", "zendframework/zend-ldap": "^2.0", - "zendframework/zend-permissions-acl": "^2.0" + "zendframework/zend-permissions-acl": "^2.0", + "zendframework/zend-inputfilter": "^2.0" }, "require-dev": { "fabpot/php-cs-fixer": "1.*", diff --git a/composer.lock b/composer.lock index 1fe2ad227a1515008c5b31f69aead1492d6e2776..945931447c715198d6a25e7563954f3468d157e8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "2b6ef5eafbeda796b77abd927e9e74b2", - "content-hash": "b76fa7640686792f43397a7ff0ded352", + "hash": "059041460fb8d23eee6eeb857572b920", + "content-hash": "bd78bc722c9d002c5e0c6c4a04df5ac3", "packages": [ { "name": "container-interop/container-interop", @@ -1183,6 +1183,62 @@ ], "time": "2016-01-12 23:27:48" }, + { + "name": "zendframework/zend-filter", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-filter.git", + "reference": "202014ee64e2aae23140a1719f6d362a602713ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/202014ee64e2aae23140a1719f6d362a602713ed", + "reference": "202014ee64e2aae23140a1719f6d362a602713ed", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "zendframework/zend-stdlib": "^2.7 || ^3.0" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "pear/archive_tar": "^1.4", + "phpunit/phpunit": "~4.0", + "zendframework/zend-crypt": "^2.6", + "zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3", + "zendframework/zend-uri": "^2.5" + }, + "suggest": { + "zendframework/zend-crypt": "Zend\\Crypt component, for encryption filters", + "zendframework/zend-i18n": "Zend\\I18n component for filters depending on i18n functionality", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component, for using the filter chain functionality", + "zendframework/zend-uri": "Zend\\Uri component, for the UriNormalize filter" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Filter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed data filters", + "homepage": "https://github.com/zendframework/zend-filter", + "keywords": [ + "filter", + "zf2" + ], + "time": "2016-02-08 18:02:37" + }, { "name": "zendframework/zend-hydrator", "version": "1.0.0", @@ -1239,27 +1295,80 @@ ], "time": "2015-09-17 14:06:43" }, + { + "name": "zendframework/zend-inputfilter", + "version": "2.5.5", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-inputfilter.git", + "reference": "3208cddbb92df029230cde676a5c8e5a22b531c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/3208cddbb92df029230cde676a5c8e5a22b531c6", + "reference": "3208cddbb92df029230cde676a5c8e5a22b531c6", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-stdlib": "~2.5", + "zendframework/zend-validator": "^2.5.3" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "^4.5", + "zendframework/zend-i18n": "~2.5", + "zendframework/zend-servicemanager": "~2.5" + }, + "suggest": { + "zendframework/zend-servicemanager": "To support plugin manager support" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\InputFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zend-inputfilter", + "keywords": [ + "inputfilter", + "zf2" + ], + "time": "2015-09-03 22:31:38" + }, { "name": "zendframework/zend-ldap", - "version": "2.5.1", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-ldap.git", - "reference": "c647a86224030543401634dbafd514074b49b2b6" + "reference": "920863c447f167f7f1e90f982bdc2532e7a8bf24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-ldap/zipball/c647a86224030543401634dbafd514074b49b2b6", - "reference": "c647a86224030543401634dbafd514074b49b2b6", + "url": "https://api.github.com/repos/zendframework/zend-ldap/zipball/920863c447f167f7f1e90f982bdc2532e7a8bf24", + "reference": "920863c447f167f7f1e90f982bdc2532e7a8bf24", "shasum": "" }, "require": { "ext-ldap": "*", - "php": ">=5.3.23", + "php": ">=5.5", "zendframework/zend-stdlib": "~2.5" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", + "php-mock/php-mock-phpunit": "~0.3", "phpunit/phpunit": "~4.0", "zendframework/zend-config": "~2.5", "zendframework/zend-eventmanager": "~2.5" @@ -1289,7 +1398,7 @@ "ldap", "zf2" ], - "time": "2015-06-03 15:32:02" + "time": "2016-02-11 15:17:45" }, { "name": "zendframework/zend-math", @@ -1447,6 +1556,72 @@ "zf2" ], "time": "2015-10-15 15:57:32" + }, + { + "name": "zendframework/zend-validator", + "version": "2.5.3", + "source": { + "type": "git", + "url": "https://github.com/zendframework/zend-validator.git", + "reference": "53e567a58c8952a03da0b8edf0f075303a5ac5d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/53e567a58c8952a03da0b8edf0f075303a5ac5d1", + "reference": "53e567a58c8952a03da0b8edf0f075303a5ac5d1", + "shasum": "" + }, + "require": { + "php": ">=5.5", + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-cache": "~2.5", + "zendframework/zend-config": "~2.5", + "zendframework/zend-db": "~2.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-http": "~2.5", + "zendframework/zend-i18n": "~2.5", + "zendframework/zend-math": "~2.5", + "zendframework/zend-servicemanager": "~2.5", + "zendframework/zend-session": "~2.5", + "zendframework/zend-uri": "~2.5" + }, + "suggest": { + "zendframework/zend-db": "Zend\\Db component", + "zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator", + "zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages as well as to use the various Date validators", + "zendframework/zend-i18n-resources": "Translations of validator messages", + "zendframework/zend-math": "Zend\\Math component", + "zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", + "zendframework/zend-session": "Zend\\Session component", + "zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Validator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides a set of commonly needed validators", + "homepage": "https://github.com/zendframework/zend-validator", + "keywords": [ + "validator", + "zf2" + ], + "time": "2015-09-03 19:06:11" } ], "packages-dev": [ @@ -1609,22 +1784,24 @@ }, { "name": "phpspec/prophecy", - "version": "v1.5.0", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7" + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4745ded9307786b730d7a60df5cb5a6c43cf95f7", - "reference": "4745ded9307786b730d7a60df5cb5a6c43cf95f7", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972", + "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" + "sebastian/comparator": "~1.1", + "sebastian/recursion-context": "~1.0" }, "require-dev": { "phpspec/phpspec": "~2.0" @@ -1632,7 +1809,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -1665,7 +1842,7 @@ "spy", "stub" ], - "time": "2015-08-13 10:07:40" + "time": "2016-02-15 07:46:21" }, { "name": "phpunit/php-code-coverage", @@ -1961,16 +2138,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.22", + "version": "4.8.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "dfb11aa5236376b4fc63853cf746af39fe780e72" + "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/dfb11aa5236376b4fc63853cf746af39fe780e72", - "reference": "dfb11aa5236376b4fc63853cf746af39fe780e72", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e351261f9cd33daf205a131a1ba61c6d33bd483", + "reference": "6e351261f9cd33daf205a131a1ba61c6d33bd483", "shasum": "" }, "require": { @@ -2029,7 +2206,7 @@ "testing", "xunit" ], - "time": "2016-02-02 09:01:21" + "time": "2016-02-11 14:56:33" }, { "name": "phpunit/phpunit-mock-objects", diff --git a/config/settings/schools.global.php b/config/settings/schools.global.php index f1ec440483a909bb6ffcee3e8dd5360238e56aae..7dff83f911e3e12a5ae48516441a893ac4ac2490 100644 --- a/config/settings/schools.global.php +++ b/config/settings/schools.global.php @@ -14,6 +14,7 @@ return [ ['/school', ['school'], ['get']], ['/school/labs', ['school'], ['get']], ['/school/staff', ['school'], ['get', 'post']], + ['/school/staff/{id:[1-9][0-9]*}', ['school'], ['delete']], ['/school/assets', ['school'], ['get']], ], ], diff --git a/module/application/bootstrap.php b/module/application/bootstrap.php index 1b4d44fff6b33947eed2f2c2ba00e954761e9594..cdd7cfbcc2e4b01c6f5b74d357ee015525f9195a 100644 --- a/module/application/bootstrap.php +++ b/module/application/bootstrap.php @@ -28,7 +28,7 @@ return function (Slim\App $app) { $container['settings']['db']['user'], $container['settings']['db']['pass'] ); - RedBeanPHP\R::freeze(); + // RedBeanPHP\R::freeze(); $container['view'] = function ($c) { $settings = $c['settings']; diff --git a/module/sch_sync/src/Middleware/CreateLabs.php b/module/sch_sync/src/Middleware/CreateLabs.php new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/module/schools/bootstrap.php b/module/schools/bootstrap.php index df386d8a48c400b0fd4596c394ced63c483e53a3..acb976eb54f258722f5ffe81ad84d2f9c07afcef 100644 --- a/module/schools/bootstrap.php +++ b/module/schools/bootstrap.php @@ -25,16 +25,22 @@ return function (Slim\App $app) { ); }; - $container[GrEduLabs\Schools\Action\Staff::class] = function ($c) { - return new GrEduLabs\Schools\Action\Staff( + $container[GrEduLabs\Schools\Action\Staff\ListAll::class] = function ($c) { + return new GrEduLabs\Schools\Action\Staff\ListAll( $c->get('view'), - $c->get('staffservice') + $c->get(GrEduLabs\Schools\Service\StaffService::class) ); }; - $container[GrEduLabs\Schools\Action\StaffCreate::class] = function ($c) { - return new GrEduLabs\Schools\Action\StaffCreate( - $c->get('staffservice') + $container[GrEduLabs\Schools\Action\Staff\PersistTeacher::class] = function ($c) { + return new GrEduLabs\Schools\Action\Staff\PersistTeacher( + $c->get(GrEduLabs\Schools\Service\StaffService::class) + ); + }; + + $container[GrEduLabs\Schools\Action\Staff\DeleteTeacher::class] = function ($c) { + return new GrEduLabs\Schools\Action\Staff\DeleteTeacher( + $c->get(GrEduLabs\Schools\Service\StaffService::class) ); }; @@ -58,9 +64,17 @@ return function (Slim\App $app) { return new GrEduLabs\Schools\Service\SchoolService(); }; - $container['staffservice'] = function ($c) { - return new GrEduLabs\Schools\Service\StaffService( - new GrEduLabs\Schools\Filter\Teacher() + $container[GrEduLabs\Schools\InputFilter\Teacher::class] = function ($c) { + return new GrEduLabs\Schools\InputFilter\Teacher(); + }; + + $container[GrEduLabs\Schools\Service\StaffService::class] = function ($c) { + return new GrEduLabs\Schools\Service\StaffService(); + }; + + $container[GrEduLabs\Schools\Middleware\InputFilterTeacher::class] = function ($c) { + return new GrEduLabs\Schools\Middleware\InputFilterTeacher( + $c->get(GrEduLabs\Schools\InputFilter\Teacher::class) ); }; @@ -89,8 +103,13 @@ return function (Slim\App $app) { $app->group('/school', function () { $this->get('', GrEduLabs\Schools\Action\Index::class)->setName('school'); - $this->get('/staff', GrEduLabs\Schools\Action\Staff::class)->setName('school.staff'); - $this->post('/staff', GrEduLabs\Schools\Action\StaffCreate::class)->setName('school.staffcreate'); + $this->get('/staff', GrEduLabs\Schools\Action\Staff\ListAll::class)->setName('school.staff'); + $this->post('/staff', GrEduLabs\Schools\Action\Staff\PersistTeacher::class) + ->add(GrEduLabs\Schools\Middleware\InputFilterTeacher::class) + ->setName('school.staffcreate'); + $this->delete('/staff/{id:[1-9][0-9]*}', GrEduLabs\Schools\Action\Staff\DeleteTeacher::class) + ->setName('school.staffdelete'); + $this->get('/labs', GrEduLabs\Schools\Action\Labs::class)->setName('school.labs'); $this->post('/labs', GrEduLabs\Schools\Action\LabCreate::class)->setName('school.labcreate'); $this->get('/assets', GrEduLabs\Schools\Action\Assets::class)->setName('school.assets'); diff --git a/module/schools/data/schema.mysql.sql b/module/schools/data/schema.mysql.sql index e18fe97ee67153f3f623baea26ed0192135b7dc0..a13240cd8fefaeab2655273ca0b2fdfba8feb5ed 100644 --- a/module/schools/data/schema.mysql.sql +++ b/module/schools/data/schema.mysql.sql @@ -178,6 +178,26 @@ INSERT INTO `schooltype` VALUES (1,'ΝΗΠΙΑΓΩΓΕΙΟ',1),(2,'ΔΗΜΟΤΙ /*!40000 ALTER TABLE `schooltype` ENABLE KEYS */; UNLOCK TABLES; +DROP TABLE IF EXISTS `teacher`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `teacher` ( + `id` int(11) unsigned NOT NULL AUTO_INCREMENT, + `school_id` int(11) unsigned NOT NULL, + `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `surname` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `telephone` int(11) unsigned NOT NULL, + `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, + `branch_id` int(11) unsigned NOT NULL, + `is_principle` tinyint(1) unsigned DEFAULT '0', + `is_responsible` tinyint(1) unsigned DEFAULT '0', + PRIMARY KEY (`id`), + KEY `index_foreignkey_teacher_school` (`school_id`), + KEY `index_foreignkey_teacher_branch` (`branch_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 */; diff --git a/module/schools/public/js/schools/staff.js b/module/schools/public/js/schools/staff.js index 37f4e0e22a1ffc7fd92b0b199575b7186dd08726..dee1d8355dfbec07783e63bb1ee854f03446cf44 100644 --- a/module/schools/public/js/schools/staff.js +++ b/module/schools/public/js/schools/staff.js @@ -2,100 +2,112 @@ 'use strict'; var Staff, - Employee, - EmployeeView, + Teacher, + StaffRow, StaffView, - ModalView, - employeeTemplate; + TeacherView, + teacherTemplate; - Employee = Backbone.Model.extend({ idAttribute: 'id' }); + Teacher = Backbone.Model.extend({ idAttribute: 'id' }); Staff = Backbone.Collection.extend({ - model: Employee, + model: Teacher, comparator: 'surname' }); - EmployeeView = Backbone.View.extend({ + StaffRow = Backbone.View.extend({ tagName: 'tr', template: (function () { - if (typeof employeeTemplate === 'undefined') { - employeeTemplate = _.template($('#employee-row').html()); + if (typeof teacherTemplate === 'undefined') { + teacherTemplate = _.template($('#teacher-row').html()); } - return employeeTemplate; + return teacherTemplate; }()), initialize: function () { this.model.on('change', this.render, this); + this.model.on('remove', this.remove, this); }, render: function () { - this.$el.html(this.template({ employee: this.model.attributes })); + this.$el.html(this.template({ teacher: this.model.attributes })); this.$el.attr('data-id', this.model.get('id')); return this; + }, + remove: function () { + this.$el.remove(); } }); StaffView = Backbone.View.extend({ el: '#school', - modal: null, + teacherView: null, events: { - 'click .btn-add-employee': 'addEmployee', + 'click .btn-add-teacher': 'addEmployee', 'click tbody tr': 'editEmployee' }, initialize: function () { var that = this; - this.modal = new ModalView(); + this.teacherView = new TeacherView({model: this.model}); _.each(this.$el.find('tbody tr'), function (tr) { - var data = $(tr).data('employee'), - employee = new Employee(data); - that.model.add(employee); - new EmployeeView({ model: employee, el: tr }); - $(tr).attr('data-employee', null); + var data = $(tr).data('teacher'), + teacher = new Teacher(data); + that.model.add(teacher); + new StaffRow({ model: teacher, el: tr }); + $(tr).attr('data-teacher', null); }); this.model.on('add', this.renderEmployee, this); }, addEmployee: function (evt) { - var that = this; evt.preventDefault(); - this.modal.render(function (data) { - that.model.add(data); - that.$el.find('.no-records').remove(); - }); + this.teacherView.render(); return this; }, editEmployee: function (evt) { - var employee = this.model.get($(evt.target).closest('tr').data('id')); + var teacherId; if ($(evt.target).is('a')) return; - if (!employee) return; - this.modal.render(function (data) { - employee.set(data); - }, employee.attributes); + teacherId = $(evt.target).closest('tr').data('id'); + this.teacherView.render(teacherId); return this; }, - renderEmployee: function (employee) { - this.$el.find('tbody').append(new EmployeeView({ - model: employee + renderEmployee: function (teacher) { + this.$el.find('tbody').append(new StaffRow({ + model: teacher }).render().el); return this; } }); - ModalView = Backbone.View.extend({ - el: '#employee-form-modal', + TeacherView = Backbone.View.extend({ + el: '#teacher-form-modal', form: null, + teacher: null, + url: null, events: { - 'submit form': 'submit', + 'submit form': 'persistTeacher', + 'click button.remove': 'removeTeacher', }, initialize: function () { this.form = this.$el.find('form'); + this.url = this.form.data('url'); }, - render: function (done, employee) { - this.form.data('done', done); + render: function (teacherId) { + var teacherAttributes; this.form[0].reset(); this.form.find('input[type="hidden"]').val(''); - employee = employee || {}; + if (!teacherId) { + this.$el.find('.modal-footer button.remove').addClass('hidden'); + } else { + this.$el.find('.modal-footer button.remove').removeClass('hidden'); + } + this.teacher = teacherId && this.model.get(teacherId) || null; + teacherAttributes = this.teacher && this.teacher.attributes || {}; _.each(this.form[0].elements, function (element) { var element = $(element), name = element.attr('name'); - element.val(employee[name] || ''); + if ('checkbox' === element.attr('type')) { + element.prop('checked', parseInt(teacherAttributes[name], 10)); + } else { + element.val(teacherAttributes[name] || ''); + } }); this.show(); }, @@ -105,21 +117,40 @@ hide: function () { this.$el.modal('hide'); }, - submit: function (evt) { + persistTeacher: function (evt) { var data = _.reduce(this.form.serializeArray(), function (hash, pair) { hash[pair.name] = pair.value; return hash; }, {}); var that = this; evt.preventDefault(); - $.post("", data). + $.post(this.url, data). done(function(response){ - that.form.data('done')(response); - that.form.data('done', undefined); + if (that.teacher) { + that.teacher.set(response); + } else{ + that.model.add(response); + } that.hide(); }).fail(function (xhr, err) { alert(xhr.statusText); }); + }, + removeTeacher: function () { + var that = this; + if (!confirm('Να διαγραφεί ο εκπαιδευτικός;')) { + return; + } + $.ajax({ + url: this.url + '/' + this.teacher.get('id'), + type: 'delete', + dataType: 'json' + }).done(function () { + that.model.remove(that.teacher.get('id')); + that.hide(); + }).fail(function (xhr, err) { + alert(xhr.statusText); + }); } }); diff --git a/module/schools/src/Action/Staff/DeleteTeacher.php b/module/schools/src/Action/Staff/DeleteTeacher.php new file mode 100644 index 0000000000000000000000000000000000000000..29bf599c10f05b53bdf17c1990b9492bc8165afd --- /dev/null +++ b/module/schools/src/Action/Staff/DeleteTeacher.php @@ -0,0 +1,61 @@ +staffService = $staffService; + } + + public function __invoke(Request $req, Response $res, array $args = []) + { + $school = $req->getAttribute('school', false); + if (!$school->id) { + return $res->withStatus(403, 'No school'); + } + $id = isset($args['id']) ? $args['id'] : false; + + if (!$id) { + $res = $res->withStatus(404); + + return $res; + } + + $teacher = $this->staffService->getTeacherById($id); + if ($teacher['school_id'] != $school->id) { + $res = $res->withStatus(403, 'Schools not match'); + + return $res; + } + + try { + $this->staffService->removeTeacher($id); + $res = $res->withStatus(204); + } catch (Exception $ex) { + $res = $res->withStatus(500, $ex->getMessage()); + } + + return $res; + } +} diff --git a/module/schools/src/Action/Staff.php b/module/schools/src/Action/Staff/ListAll.php similarity index 53% rename from module/schools/src/Action/Staff.php rename to module/schools/src/Action/Staff/ListAll.php index 5c29bd99e679d29b43d997f318d57d4daac4626b..138a1efb8609e7cc6f16bc95f832a61523a6a3ec 100644 --- a/module/schools/src/Action/Staff.php +++ b/module/schools/src/Action/Staff/ListAll.php @@ -8,31 +8,37 @@ * @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html */ -namespace GrEduLabs\Schools\Action; +namespace GrEduLabs\Schools\Action\Staff; +use GrEduLabs\Schools\Service\StaffServiceInterface; use Slim\Http\Request; use Slim\Http\Response; use Slim\Views\Twig; -class Staff +class ListAll { - protected $view; + private $view; + private $staffService; - public function __construct(Twig $view, $staffservice) + public function __construct(Twig $view, StaffServiceInterface $staffService) { $this->view = $view; - $this->staffservice = $staffservice; + $this->staffService = $staffService; } public function __invoke(Request $req, Response $res, array $args = []) { - $staff = $this->staffservice->getTeachersBySchoolId(1); + $school = $req->getAttribute('school', false); + if (!$school) { + return $res->withStatus(403, 'No school'); + } + $staff = $this->staffService->getTeachersBySchoolId($school->id); return $this->view->render($res, 'schools/staff.twig', [ 'staff' => $staff, - 'branches' => array_map(function ($branch) { + 'branches' => array_map(function ($branch) { return ['value' => $branch['id'], 'label' => $branch['name']]; - }, $this->staffservice->getBranches()), + }, $this->staffService->getBranches()), ]); } } diff --git a/module/schools/src/Action/Staff/PersistTeacher.php b/module/schools/src/Action/Staff/PersistTeacher.php new file mode 100644 index 0000000000000000000000000000000000000000..e0c8c3170e91e6105e2cdcdb7cf50eec53b20a2b --- /dev/null +++ b/module/schools/src/Action/Staff/PersistTeacher.php @@ -0,0 +1,57 @@ +staffService = $staffService; + } + + public function __invoke(Request $req, Response $res, array $args = []) + { + $school = $req->getAttribute('school', false); + if (!$school) { + return $res->withStatus(403, 'No school'); + } + $params = $req->getParams(); + $params['school_id'] = $school->id; + $id = $params['id']; + unset($params['id']); + + try { + if ($id) { + $teacher = $this->staffService->updateTeacher($params, $id); + $res = $res->withStatus(200); + } else { + $teacher = $this->staffService->createTeacher($params); + $res = $res->withStatus(201); + } + $res = $res->withJson($teacher); + } catch (Exception $ex) { + $res = $res->withStatus(500, $ex->getMessage()); + } + + return $res; + } +} diff --git a/module/schools/src/Action/StaffCreate.php b/module/schools/src/Action/StaffCreate.php deleted file mode 100644 index a442e09dd9d302ee7df55ec71ea0b0805c55ee67..0000000000000000000000000000000000000000 --- a/module/schools/src/Action/StaffCreate.php +++ /dev/null @@ -1,52 +0,0 @@ -staffservice = $staffservice; - } - - public function __invoke(Request $req, Response $res, array $args = []) - { - $school = $req->getAttribute('school', false); - if (!$school) { - return $res->withStatus(403, 'No school'); - } - $params = $req->getParams(); - $id = $params['id']; - unset($params['id']); - $params['school_id'] = $school->id; - if ($id > 0) { - $id = $this->staffservice->updateTeacher($params, $id); - $teacher = $this->staffservice->getTeacherById($id); - } else { - $id = $this->staffservice->createTeacher($params); - if ($id > 0) { - $teacher = $this->staffservice->getTeacherById($id); - } - } - - if (isset($teacher)) { - return $res->withJson(array_merge($teacher->export(), [ - 'branch' => $teacher->branch->name, - ]))->withStatus(201); - } else { - return $res->withStatus(400); - } - } -} diff --git a/module/schools/src/Filter/Teacher.php b/module/schools/src/Filter/Teacher.php deleted file mode 100644 index 8542c4415c3667d2157d873445c0503f193df378..0000000000000000000000000000000000000000 --- a/module/schools/src/Filter/Teacher.php +++ /dev/null @@ -1,90 +0,0 @@ - 'Δεν ορίστηκε το σχολείο', - // 'branch_id' => 'Δεν ορίστηκε η ειδικότητα', - // 'name' => 'Δεν ορίστηκε το όνομα', - // 'surname' => 'Δεν ορίστηκε το επώνυμο', - // 'email'=> 'Δεν ορίστηκε το email', - // 'telephone' => 'Δεν ορίστηκε το τηλέφωνο', - // ]; - - private static $filter = [ - 'school_id' => [ - 'filter' => FILTER_VALIDATE_INT, - 'flags' => FILTER_REQUIRE_SCALAR, - ], - 'branch_id' => [ - 'filter' => FILTER_VALIDATE_INT, - 'flags' => FILTER_REQUIRE_SCALAR, - ], - 'name' => [ - 'filter' => FILTER_SANITIZE_STRING, - 'flags' => FILTER_REQUIRE_SCALAR, - ], - 'surname' => [ - 'filter' => FILTER_SANITIZE_STRING, - 'flags' => FILTER_REQUIRE_SCALAR, - ], - 'email' => FILTER_VALIDATE_EMAIL, - 'telephone' => FILTER_SANITIZE_NUMBER_INT, - 'is_principle' => [ - 'filter' => FILTER_VALIDATE_BOOLEAN, - ], - 'is_responsible' => [ - 'filter' => FILTER_VALIDATE_BOOLEAN, - ], - - ]; - - public function __invoke(array $data, $create = true) - { - - var_dump(filter_var_array($data, self::$filter, $create)); - die(); - - // $messages = []; - // $fields = array_merge(self::$required, self::$optional); - // $data = array_intersect_key($data, array_flip($fields)); - // $filtered = array_map('trim', $data); - - // foreach (self::$required as $required) { - // if (!isset($data[$required])|| empty($data[$required])) { - // $messages[$required][] = self::$messageTemplates[$required]; - // } - // } - - // if (filter_input_array(type)) - - // var_dump($messages); - // die(); - - } -} \ No newline at end of file diff --git a/module/schools/src/InputFilter/Teacher.php b/module/schools/src/InputFilter/Teacher.php new file mode 100644 index 0000000000000000000000000000000000000000..2e6fcad18e61117f44be7e41877ce61d4ddd06e7 --- /dev/null +++ b/module/schools/src/InputFilter/Teacher.php @@ -0,0 +1,99 @@ +setRequired(false) + ->setBreakOnFailure(true) + ->getValidatorChain() + ->attach(new Validator\Digits()); + + $name = new Input('name'); + $name->setRequired(true) + ->setBreakOnFailure(true) + ->getFilterChain() + ->attach(new Filter\StringTrim()); + $name->getValidatorChain() + ->attach(new Validator\NotEmpty()) + ->attach(new Validator\StringLength(['min' => 3])); + + $surname = new Input('surname'); + $surname->setRequired(true) + ->setBreakOnFailure(true) + ->getFilterChain() + ->attach(new Filter\StringTrim()); + $surname->getValidatorChain() + ->attach(new Validator\NotEmpty()) + ->attach(new Validator\StringLength(['min' => 3])); + + $email = new Input('email'); + $email->setRequired(true) + ->setBreakOnFailure(true) + ->getValidatorChain() + ->attach(new Validator\NotEmpty()) + ->attach(new Validator\EmailAddress()); + + $telephone = new Input('telephone'); + $telephone->setRequired(true) + ->setBreakOnFailure(true) + ->getValidatorChain() + ->attach(new Validator\NotEmpty()) + ->attach(new Validator\StringLength(['min' => 10])) + ->attach(new Validator\Digits()); + + $branch_id = new Input('branch_id'); + $branch_id->setRequired(true) + ->setBreakOnFailure(true) + ->getValidatorChain() + ->attach(new Validator\NotEmpty()) + ->attach(new Validator\Digits()); + + $is_principle = new Input('is_principle'); + $is_principle->setRequired(false); + + $is_responsible = new Input('is_responsible'); + $is_responsible->setRequired(false); + + + $this->inputFilter = new InputFilter(); + $this->inputFilter + ->add($id) + ->add($name) + ->add($surname) + ->add($email) + ->add($telephone) + ->add($branch_id) + ->add($is_principle) + ->add($is_responsible); + } + + public function __invoke(array $data) + { + $this->inputFilter->setData($data); + $isValid = $this->inputFilter->isValid(); + + return [ + 'is_valid' => $isValid, + 'values' => $isValid ? $this->inputFilter->getValues() : [], + 'messages' => $this->inputFilter->getMessages(), + ]; + } +} diff --git a/module/schools/src/Middleware/InputFilterTeacher.php b/module/schools/src/Middleware/InputFilterTeacher.php new file mode 100644 index 0000000000000000000000000000000000000000..9cd99b6ef9f79a495ad30d7c9b6bb368412dd330 --- /dev/null +++ b/module/schools/src/Middleware/InputFilterTeacher.php @@ -0,0 +1,41 @@ +inputFilter = $inputFilter; + } + + public function __invoke(Request $req, Response $res, callable $next) + { + $data = $req->getParams(); + $inputFilter = $this->inputFilter; + $result = $inputFilter($data); + + if (!$result['is_valid']) { + $res = $res->withStatus(422, 'validation error'); + $res->withJson($result['messages']); + + return $res; + } + + $req = $req->withParsedBody($result['values']); + + return $next($req, $res); + } +} diff --git a/module/schools/src/Service/StaffService.php b/module/schools/src/Service/StaffService.php index d35d4fbbe7fe3e3123c45d9fd38b8f687f0571a1..4ee7071b6e0d6e93199404c58654eb6629ca8491 100644 --- a/module/schools/src/Service/StaffService.php +++ b/module/schools/src/Service/StaffService.php @@ -13,48 +13,38 @@ use RedBeanPHP\R; class StaffService implements StaffServiceInterface { - private $filter; - - public function __construct(callable $filter) - { - $this->filter = $filter; - } - public function createTeacher(array $data) { - $data = call_user_func($this->filter, $data, true); - var_dump($data); - die(); unset($data['id']); - $teacher = R::dispense('teacher'); - $required = ['school_id', 'name','email', 'surname', 'telephone', - 'position', 'branch_id', ]; - - foreach ($required as $value) { - if (array_key_exists($value, $data)) { - $teacher[$value] = $data[$value]; - } else { - return -1; - } - } - $id = R::store($teacher); + $teacher = R::dispense('teacher'); + $this->persist($teacher, $data); - return $id; + return $this->export($teacher); } public function updateTeacher(array $data, $id) { - try { - $teacher = R::load('teacher', $id); - foreach ($data as $key => $value) { - $teacher[$key] = $value; - } - $id = R::store($teacher); + $teacher = R::load('teacher', $id); + if (!$teacher->id) { + throw new \InvalidArgumentException('No teacher found'); + } + $this->persist($teacher, $data); - return $id; - } catch (\Exception $e) { + return $this->export($teacher); + } - } + private function persist($teacher, array $data) + { + $teacher->school_id = $data['school_id']; + $teacher->name = $data['name']; + $teacher->surname = $data['surname']; + $teacher->telephone = $data['telephone']; + $teacher->email = $data['email']; + $teacher->branch_id = $data['branch_id']; + $teacher->is_principle = isset($data['is_principle']); + $teacher->is_responsible = isset($data['is_responsible']); + + R::store($teacher); } public function getTeacherById($id) @@ -78,6 +68,11 @@ class StaffService implements StaffServiceInterface }, R::findAll('branch', 'ORDER BY name ASC')); } + public function removeTeacher($id) + { + R::trash('teacher', $id); + } + private function export($teacherBean) { $position = []; @@ -87,8 +82,9 @@ class StaffService implements StaffServiceInterface if ($teacherBean->is_responsible) { $position[] = 'Υπεύθυνος εργαστηρίου'; } + return array_merge($teacherBean->export(), [ - 'branch' => $teacherBean->branch->name, + 'branch' => $teacherBean->branch->name, 'position' => implode(', ', $position), ]); } diff --git a/module/schools/src/Service/StaffServiceInterface.php b/module/schools/src/Service/StaffServiceInterface.php index 4f723120ab87d7edf5b6bde0e32860c374a8b047..5dcf46421dfb2e2a0c3f9db55ad2de65edbea6f7 100644 --- a/module/schools/src/Service/StaffServiceInterface.php +++ b/module/schools/src/Service/StaffServiceInterface.php @@ -16,4 +16,5 @@ interface StaffServiceInterface public function getTeachersBySchoolId($id); public function updateTeacher(array $data, $id); public function getBranches(); + public function removeTeacher($id); } diff --git a/module/schools/templates/schools/index.twig b/module/schools/templates/schools/index.twig index 3ae14588545f6dbeba12e263825ce41493329ff0..cc71e2fcdac2e0cbf27786319a2e3494e44c783b 100644 --- a/module/schools/templates/schools/index.twig +++ b/module/schools/templates/schools/index.twig @@ -18,12 +18,12 @@