labs; need to fix ajax file upload

parent 0e973a68
......@@ -18,4 +18,9 @@ return [
],
],
],
'schools' => [
'file_upload' => [
'target_path' => 'data/uploads',
],
],
];
......@@ -28,7 +28,8 @@ return function (Slim\App $app) {
$container['settings']['db']['user'],
$container['settings']['db']['pass']
);
RedBeanPHP\R::freeze();
// RedBeanPHP\R::freeze();
// RedBeanPHP\R::debug( true );
$container['view'] = function ($c) {
$settings = $c['settings'];
......
......@@ -20,6 +20,7 @@
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
{% block htmlHead %}{% endblock %}
</head>
<body class="{% block bodyClass %}{% endblock %}">
{% include 'navigation/main.twig' %}
......
......@@ -110,10 +110,7 @@ return function (Slim\App $app) {
};
$container[Service\LabServiceInterface::class] = function ($c) {
return new Service\LabService(
$c->get(Service\SchoolServiceInterface::class),
$c->get(Service\StaffServiceInterface::class)
);
return new Service\LabService();
};
$container[Service\AssetServiceInterface::class] = function ($c) {
......@@ -168,7 +165,12 @@ return function (Slim\App $app) {
};
$container[InputFilter\Lab::class] = function ($c) {
return new InputFilter\Lab();
$settings = $c->get('settings');
$fileUploadSettings = $settings['schools']['file_upload'];
return new InputFilter\Lab(
$fileUploadSettings,
$c->get(Service\LabServiceInterface::class)
);
};
});
......
......@@ -270,7 +270,7 @@ CREATE TABLE `lab` (
`use_in_program` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`attachment` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`has_network` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`has_server` tinyint(1) unsigned DEFAULT NULL,
`has_server` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`school_id` int(11) unsigned DEFAULT NULL,
`teacher_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
......
(function () {
(function (utils) {
'use strict';
var Lab,
Labs,
LabView,
LabRow,
LabsView,
LabModalView,
labTemplate,
utils = window.EDULABS.utils;
LabView,
labTemplate;
Lab = Backbone.Model.extend({ idAttribute: 'id' });
......@@ -16,7 +15,7 @@
comparator: 'name'
});
LabView = Backbone.View.extend({
LabRow = Backbone.View.extend({
tagName: 'tr',
template: (function () {
if (typeof labTemplate === 'undefined') {
......@@ -26,67 +25,134 @@
}()),
initialize: function () {
this.model.on('change', this.render, this);
this.model.on('remove', this.remove, this);
},
render: function () {
var html = this.template({ lab: this.model.attributes });
this.$el.html(html);
this.$el.html(this.template({ lab: this.model.attributes }));
this.$el.attr('data-id', this.model.get('id'));
return this;
},
remove: function () {
this.$el.remove();
}
});
LabsView = Backbone.View.extend({
el: '#school',
modal: null,
labView: null,
events: {
'click .btn-add-lab': 'addLab',
'click tbody tr': 'editLab'
},
initialize: function () {
var that = this;
this.modal = new LabModalView();
_.each(this.$el.find('tbody tr[data-lab]'), function (tr) {
var data,
lab;
tr = $(tr);
data = tr.data('lab');
lab = new Lab(data);
this.labView = new LabView({model: this.model});
_.each(this.$el.find('tbody tr'), function (tr) {
var data = $(tr).data('lab'),
lab = new Lab(data);
that.model.add(lab);
new LabView({ model: lab });
tr.attr('data-lab', null);
new LabRow({ model: lab, el: tr });
$(tr).attr('data-lab', null);
});
this.model.on('add', this.renderLab, this);
},
renderLab: function (lab) {
this.$el.find('tbody').append(new LabView({
model: lab
}).render().el);
return this;
this.model.on('remove', function () {
if (this.model.length === 0) {
this.$el.find('tbody tr.no-records').show();
}
}, this);
},
addLab: function (evt) {
var that = this;
evt.preventDefault();
this.modal.render(function (data) {
that.model.add(data);
});
this.labView.render();
return this;
},
editLab: function (evt) {
var lab = this.model.get(utils.parseInt($(evt.target).closest('tr').data('id')));
if (!lab) return;
this.modal.render(function (data) {
lab.set(data);
}, lab.attributes);
var labId;
labId = $(evt.target).closest('tr').data('id');
this.labView.render(labId);
return this;
},
renderLab: function (lab) {
this.$el.find('tbody tr.no-records').hide();
this.$el.find('tbody').append(new LabRow({
model: lab
}).render().el);
return this;
}
});
LabModalView = Backbone.View.extend({
LabView = Backbone.View.extend({
el: '#lab-form-modal',
form: null,
lab: null,
url: null,
events: {
'submit': 'submit',
// 'submit': 'persistLab',
'click button.remove': 'removeLab'
},
initialize: function () {
var that = this;
this.form = this.$el.find('form');
this.url = this.form.data('url');
this.$el.on('hide.bs.modal', function () {
utils.formMessages.clear(that.form);
that.form[0].reset();
that.form.find('input[type="hidden"]').val('');
});
this.form.find('input[type="file"]').fileupload({
url: that.form.data('url'),
multipart: true,
submit: function (e, data) {
data.formData = utils.serializeObject(that.form);
data.jqXHR = $(this).fileupload('send', data);
return false;
},
done: function (response) {
if (that.lab) {
that.lab.set(response);
} else {
that.model.add(response);
}
that.hide();
},
fail: function (xhr, err) {
var messages;
if (422 === xhr.status) {
messages = JSON.parse(xhr.responseText).messages || {};
utils.formMessages.render(that.form, messages);
} else {
alert('Προέκυψε κάποιο σφάλμα');
}
}
});
},
render: function (labId) {
var labAttributes;
if (!labId) {
this.$el.find('.modal-footer button.remove')
.prop('disabled', true)
.hide();
} else {
this.$el.find('.modal-fotter button.remove')
.prop('disabled', false)
.show();
}
this.lab = labId && this.model.get(labId) || null;
labAttributes = this.lab && this.lab.attributes || {};
_.each(this.form[0].elements, function (element) {
var name;
element = $(element);
name = element.attr('name');
if ('checkbox' === element.attr('type')) {
element.prop('checked', utils.parseInt(labAttributes[name]));
} else {
element.val(labAttributes[name] || '');
}
});
this.show();
return this;
},
show: function () {
this.$el.modal('show');
......@@ -96,40 +162,73 @@
this.$el.modal('hide');
return this;
},
render: function (done, lab) {
var template,
that = this;
lab = lab || {};
this.form[0].reset();
this.form.find('input[type="hidden"]').val('');
this.form.data('done', done);
_.each(this.form[0].elements, function (element) {
var element = $(element),
name = element.attr('name');
element.val(lab[name] || '');
});
this.show();
return this;
},
submit: function (evt) {
var data;
evt.preventDefault();
data = _.reduce(this.form.serializeArray(), function (hash, pair) {
hash[pair.name] = pair.value;
return hash;
}, {});
evt.preventDefault();
if (!data.id) {
data.id = (100 * Math.random()).toFixed(0);
// persistLab: function (evt) {
// var formData = utils.serializeObject(this.form),
// that = this,
// upload = this.form.find('input[type="file"]');
// evt.preventDefault();
// upload
// $('#fileupload').fileupload('send', {
// files: upload[0].files
// });
////
//// ({
//// url: that.url,
//// submit: function (e, data) {
//// var $this = $(this);
//// data.formData = formData;
//// data.jqXHR = $this.fileupload('send', data);
//// return false;
//// },
//// done: function (response) {
//// if (that.lab) {
//// that.lab.set(response);
//// } else {
//// that.model.add(response);
//// }
//// that.hide();
//// },
//// error: function (xhr, err) {
//// var messages;
//// if (422 === xhr.status) {
//// messages = JSON.parse(xhr.responseText).messages || {};
//// utils.formMessages.render(that.form, messages);
//// } else {
//// alert('Προέκυψε κάποιο σφάλμα');
//// }
//// }
//// });
//// upload.fileupload('send');
// upload.fileupload('destroy');
////
//// $.ajax({
//// url: that.url,
//// type: 'post',
//// contentType: 'multipart/form-data',
//// data: data,
//// }).).fail(function );
// },
removeLab: function(evt) {
var that = this;
if (!confirm('Να διαγραφεί ο χώρος;')) {
return;
}
$.ajax({
url: that.url,
type: 'delete',
dataType: 'json',
data: {
id: that.lab.get('id')
}
this.form.data('done')(data);
this.form.data('done', undefined);
this.hide();
}
}).done(function () {
that.model.remove(that.asset.get('id'));
that.hide();
}).fail(function (xhr, err){
alert('Δεν ήταν δυνατή η διαγραφή του χώρου');
});
}
});
new LabsView({ model: new Labs() });
}());
\ No newline at end of file
}(window.EDULABS.utils));
\ No newline at end of file
......@@ -12,23 +12,38 @@ namespace GrEduLabs\Schools\Action\Lab;
use GrEduLabs\Schools\Service\LabServiceInterface;
use GrEduLabs\Schools\Service\StaffServiceInterface;
use RedBeanPHP\R;
use Slim\Http\Request;
use Slim\Http\Response;
use Slim\Views\Twig;
class ListAll
{
/**
*
* @var Twig
*/
protected $view;
/**
*
* @var LabServiceInterface
*/
protected $labService;
/**
*
* @var StaffServiceInterface
*/
protected $staffService;
public function __construct(
Twig $view,
LabServiceInterface $labservice,
StaffServiceInterface $staffservice
) {
$this->view = $view;
$this->labservice = $labservice;
$this->staffservice = $staffservice;
$this->labService = $labservice;
$this->staffService = $staffservice;
}
public function __invoke(Request $req, Response $res, array $args = [])
......@@ -38,44 +53,25 @@ class ListAll
return $res->withStatus(403, 'No school');
}
$labs = $this->labservice->getLabsBySchoolId($school->id);
$staff = $this->staffservice->getTeachersBySchoolId($school->id);
$clean_staff = [];
foreach ($staff as $obj) {
$clean_staff[] = [
'value' => $obj['id'],
'label' => $obj['name'] . " " . $obj['surname'],
];
}
$lessons = $this->labservice->getLessons();
$lessons_formatted = [];
foreach ($lessons as $lesson) {
$lessons_formatted[] = ['value' => $lesson->id, 'label' => $lesson->name];
}
$labs_formatted = [];
foreach($labs as $lab) {
$lab['responsible'] = $lab['teacher_id'];
$labs_formatted[] = $lab;
}
$labs = $this->labService->getLabsBySchoolId($school->id);
return $this->view->render($res, 'schools/labs.twig', [
'labs' => $labs_formatted,
'staff' => $clean_staff,
'lab_types' => [
[
'value' => 1,
'label' => 'ΕΡΓΑΣΤΗΡΙΟ',
],
[
'value' => 2,
'label' => 'ΑΙΘΟΥΣΑ',
],
[
'value' => 3,
'label' => 'ΓΡΑΦΕΙΟ',
],
],
'lessons' => $lessons_formatted,
'labs' => $labs,
'staff' => array_map(function ($teacher) {
return ['value' => $teacher['id'], 'label' => $teacher['fullname']];
}, $this->staffService->getTeachersBySchoolId($school->id)),
'network_options' => array_map(function ($option) {
return ['value' => $option, 'label' => $option];
}, $this->labService->getHasNetworkValues()),
'server_options' => array_map(function ($option) {
return ['value' => $option, 'label' => $option];
}, $this->labService->getHasServerValues()),
'lab_types' => array_map(function ($type) {
return ['value' => $type['id'], 'label' => $type['name']];
}, $this->labService->getLabTypes()),
'lessons_options' => array_map(function ($lesson) {
return ['value' => $lesson['id'], 'label' => $lesson['name']];
}, $this->labService->getLessons()),
]);
}
}
......@@ -33,26 +33,21 @@ class PersistLab
$params = $req->getParams();
$id = $params['id'];
$params['school_id'] = $school->id;
$params['lessons'] = [1,2];
unset($params['id']);
try {
if ($id > 0) {
$id = $this->labservice->updateLab($params, $id);
$lab = $this->labservice->getLabById($id);
if ($id) {
$lab = $this->labservice->updateLab($params, $id);
$res = $res->withStatus(200);
} else {
$id = $this->labservice->createLab($params);
if ($id > 0) {
$lab = $this->labservice->getLabById($id);
}
}
if (isset($lab)) {
return $res->withJson($lab->export())->withStatus(201);
$lab = $this->labservice->createLab($params);
$res = $res->withStatus(201);
}
$res = $res->withJson($lab);
} catch (Exception $ex) {
$res = $res->withStatus(500, $ex->getMessage());
}
return $res->withStatus(400);
return $res;
}
}
......@@ -17,7 +17,7 @@ trait InputFilterTrait
{
$this->inputFilter->setData($data);
$isValid = $this->inputFilter->isValid();
return [
'is_valid' => $isValid,
'values' => $isValid ? $this->inputFilter->getValues() : [],
......
......@@ -9,7 +9,9 @@
namespace GrEduLabs\Schools\InputFilter;
use GrEduLabs\Schools\Service\LabServiceInterface;
use Zend\Filter;
use Zend\InputFilter\FileInput;
use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter;
use Zend\Validator;
......@@ -17,9 +19,11 @@ use Zend\Validator;
class Lab
{
use InputFilterTrait;
public function __construct()
{
public function __construct(
array $fileUploadSettings,
LabServiceInterface $labService
) {
$id = new Input('id');
$id->setRequired(false)
->getValidatorChain()
......@@ -33,13 +37,13 @@ class Lab
->attach(new Validator\NotEmpty())
->attach(new Validator\StringLength(['min' => 3]));
$type = new Input('type');
$type->setRequired(true);
$type->getValidatorChain()
$labTypeId = new Input('labtype_id');
$labTypeId->setRequired(true);
$labTypeId->getValidatorChain()
->attach(new Validator\NotEmpty());
$responsible = new Input('responsible');
$responsible->setRequired(false)
$responsibleId = new Input('responsible_id');
$responsibleId->setRequired(false)
->getValidatorChain()
->attach(new Validator\Digits());
......@@ -50,32 +54,48 @@ class Lab
->attach(new Validator\Digits());
$lessons = new Input('lessons');
$lessons->setRequired(true)
->getValidatorChain()
$lessons->setRequired(false);
$lessons->getValidatorChain()
->attach(new Validator\NotEmpty());
$attachment = new Input('attachment');
$attachment->setRequired(false);
$attachment = new FileInput('attachment');
$attachment->setRequired(false)
->getFilterChain()
->attach(new Filter\File\RenameUpload([
'target' => $fileUploadSettings['target_path'],
'randomize' => true,
]));
$attachment->getValidatorChain()
->attach(new Validator\File\UploadFile());
$use_ext_program= new Input('use_ext_program');
$use_ext_program->setRequired(false);
$use_in_program = new Input('use_in_program');
$use_in_program->setRequired(false);
$has_server = new Input('has_server');
$has_server->setRequired(false);
$has_network = new Input('has_network');
$has_network->setRequired(false);
$has_network->getValidatorChain()
->attach(new Validator\NotEmpty())->attach(new Validator\InArray([
'haystack' => $labService->getHasNetworkValues(),
]));
$has_server = new Input('has_server');
$has_server->setRequired(false);
$has_server->getValidatorChain()
->attach(new Validator\NotEmpty())
->attach(new Validator\InArray([
'haystack' => $labService->getHasServerValues(),
]));
$this->inputFilter = new InputFilter();
$this->inputFilter
->add($id)
->add($name)
->add($type)
->add($responsible)
->add($labTypeId)
->add($responsibleId)
->add($area)
->add($lessons)
->add($attachment)
......