schools module; assets manager

parent 89d81d23
......@@ -10,11 +10,13 @@
return [
'modules' => [
'module/assets_manager/bootstrap.php',
'module/authentication/bootstrap.php',
'module/authorization/bootstrap.php',
// 'module/sch_ldap/bootstrap.php',
'module/sch_sso/bootstrap.php',
// 'module/sch_auto_create/bootstrap.php',
'module/schools/bootstrap.php',
'module/application/bootstrap.php',
],
'cache_config' => 'data/cache/config/settings.php',
......
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
return [
'acl' => [
......@@ -14,11 +21,6 @@ return [
'callables' => [],
'routes' => [
['/', ['guest', 'user'], ['get']],
['/school', ['guest', 'user'], ['get']],
['/school/labs', ['guest', 'user'], ['get']],
['/school/staff', ['guest', 'user'], ['get']],
['/school/assets', ['guest', 'user'], ['get']],
],
],
],
......
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
return [
'assets' => [
'web_dir' => 'public',
'paths' => [
'module/schools/public',
],
],
];
......@@ -16,4 +16,4 @@ return [
],
],
],
];
\ No newline at end of file
];
<?php
/**
* gredu_labs
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
return [
'acl' => [
'guards' => [
'routes' => [
['/school', ['user'], ['get']],
['/school/labs', ['user'], ['get']],
['/school/staff', ['user'], ['get']],
['/school/assets', ['user'], ['get']],
],
],
],
];
......@@ -67,21 +67,7 @@ return function (Slim\App $app) {
return new GrEduLabs\Application\Action\Index($c['view']);
};
$container['GrEduLabs\\Application\\Action\\School\\Index'] = function ($c) {
return new GrEduLabs\Application\Action\School\Index($c->get('view'));
};
$container['GrEduLabs\\Application\\Action\\School\\Staff'] = function ($c) {
return new GrEduLabs\Application\Action\School\Staff($c->get('view'));
};
$container['GrEduLabs\\Application\\Action\\School\\Labs'] = function ($c) {
return new GrEduLabs\Application\Action\School\Labs($c->get('view'));
};
$container['GrEduLabs\\Application\\Action\\School\\Assets'] = function ($c) {
return new GrEduLabs\Application\Action\School\Assets($c->get('view'));
};
$events = $container['events'];
$events('on', 'bootstrap', function () use ($container) {
......@@ -110,10 +96,5 @@ return function (Slim\App $app) {
$app->get('/', 'GrEduLabs\\Application\\Action\\Index')->setName('index');
$app->group('/school', function () {
$this->get('', 'GrEduLabs\\Application\\Action\\School\\Index')->setName('school');
$this->get('/staff', 'GrEduLabs\\Application\\Action\\School\\Staff')->setName('school.staff');
$this->get('/labs', 'GrEduLabs\\Application\\Action\\School\\Labs')->setName('school.labs');
$this->get('/assets', 'GrEduLabs\\Application\\Action\\School\\Assets')->setName('school.assets');
});
};
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Http\Response;
return function (Slim\App $app) {
$mimeTypes = [
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',
// audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
// ms office
'doc' => 'application/msword',
'rtf' => 'application/rtf',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
];
$container = $app->getContainer();
$events = $container['events'];
$events('on', 'bootstrap', function () use ($app, $container, $mimeTypes) {
$app->add(function (
ServerRequestInterface $req,
ResponseInterface $res,
callable $next
) use ($mimeTypes, $container) {
$res = $next($req, $res);
if (404 === $res->getStatusCode()) {
$settings = $container['settings']['assets'];
$file = array_reduce($settings['paths'], function ($file, $path) use ($req) {
if (false !== $file) {
return $file;
}
$file = $path . $req->getUri()->getPath();
if (is_readable($file)) {
return $file;
}
return false;
}, false);
if (!$file) {
return $res;
}
$ext = strtolower(array_pop(explode('.', $file)));
$mime = array_key_exists($ext, $mimeTypes)
? $mimeTypes[$ext] : mime_content_type($file);
$contents = file_get_contents($file);
if (is_writable($settings['web_dir'])) {
$destFile = $settings['web_dir'] . $req->getUri()->getPath();
$destPath = dirname($destFile);
if (!is_dir($destPath)) {
mkdir($destPath);
}
file_put_contents($destFile, $contents);
}
$res = new Response(200);
$res->withHeader('Content-Type', $mime);
$res->getBody()->write($contents);
}
return $res;
});
}, -10000);
};
......@@ -38,7 +38,7 @@ class RouteGuard
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next)
{
if (!$request->getAttribute('route')) {
return $response->withStatus(500);
return $response->withStatus(404);
}
$isAllowed = false;
if ($this->acl->hasResource('route' . $request->getAttribute('route')->getPattern())) {
......
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
return function (Slim\App $app) {
$container = $app->getContainer();
$container['autoloader']->addPsr4('GrEduLabs\\Schools\\', __DIR__ . '/src/');
$container[GrEduLabs\Schools\Action\Index::class] = function ($c) {
return new GrEduLabs\Schools\Action\Index($c->get('view'));
};
$container[GrEduLabs\Schools\Action\Staff::class] = function ($c) {
return new GrEduLabs\Schools\Action\Staff($c->get('view'));
};
$container[GrEduLabs\Schools\Action\Labs::class] = function ($c) {
return new GrEduLabs\Schools\Action\Labs($c->get('view'));
};
$container[GrEduLabs\Schools\Action\Assets::class] = function ($c) {
return new GrEduLabs\Schools\Action\Assets($c->get('view'));
};
$events = $container['events'];
$events('on', 'bootstrap', function () use ($container) {
$container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates');
});
$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->get('/labs', GrEduLabs\Schools\Action\Labs::class)->setName('school.labs');
$this->get('/assets', GrEduLabs\Schools\Action\Assets::class)->setName('school.assets');
});
};
......@@ -8,7 +8,7 @@
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Application\Action\School;
namespace GrEduLabs\Schools\Action;
use Slim\Http\Request;
use Slim\Http\Response;
......@@ -25,7 +25,7 @@ class Assets
public function __invoke(Request $req, Response $res, array $args = [])
{
return $this->view->render($res, 'school/assets.twig', [
return $this->view->render($res, 'schools/assets.twig', [
'assets' => [
[
'id' => 1,
......
......@@ -8,7 +8,7 @@
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Application\Action\School;
namespace GrEduLabs\Schools\Action;
use Slim\Http\Request;
use Slim\Http\Response;
......@@ -25,6 +25,6 @@ class Index
public function __invoke(Request $req, Response $res, array $args = [])
{
return $this->view->render($res, 'school/index.twig');
return $this->view->render($res, 'schools/index.twig');
}
}
......@@ -8,7 +8,7 @@
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Application\Action\School;
namespace GrEduLabs\Schools\Action;
use Slim\Http\Request;
use Slim\Http\Response;
......@@ -25,7 +25,7 @@ class Labs
public function __invoke(Request $req, Response $res, array $args = [])
{
return $this->view->render($res, 'school/labs.twig', [
return $this->view->render($res, 'schools/labs.twig', [
'labs' => [
[
'id' => 1,
......
......@@ -8,7 +8,7 @@
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace GrEduLabs\Application\Action\School;
namespace GrEduLabs\Schools\Action;
use Slim\Http\Request;
use Slim\Http\Response;
......@@ -25,7 +25,7 @@ class Staff
public function __invoke(Request $req, Response $res, array $args = [])
{
return $this->view->render($res, 'school/staff.twig', [
return $this->view->render($res, 'schools/staff.twig', [
'staff' => array_fill(0, 1,
[
'id' => 150,
......
{% extends "school/index.twig" %}
{% extends "schools/index.twig" %}
{% import "school/index.twig" as macros %}
{% import "schools/index.twig" as macros %}
{% block schoolTitle %}
{{ parent() }} <small>Εξοπλισμός</small>
......@@ -85,5 +85,5 @@
{% block inlinejs %}
{{ parent() }}
<script src="{{ base_url }}/js/school/assets.js"></script>
<script src="{{ base_url }}/js/schools/assets.js"></script>
{% endblock %}
\ No newline at end of file
......@@ -150,5 +150,5 @@
{% block inlinejs %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script type="text/javascript" src="{{ base_url }}/js/school/index.js"></script>
<script type="text/javascript" src="{{ base_url }}/js/schools/index.js"></script>
{% endblock %}
\ No newline at end of file
{% extends "school/index.twig" %}
{% extends "schools/index.twig" %}
{% import "school/index.twig" as macros %}
{% import "schools/index.twig" as macros %}
{% block schoolTitle %}
{{ parent() }} <small>Χώροι</small>
......@@ -91,5 +91,5 @@
{% block inlinejs %}
{{ parent() }}
<script src="{{ base_url }}/js/school/labs.js"></script>
<script src="{{ base_url }}/js/schools/labs.js"></script>
{% endblock %}
\ No newline at end of file
{% extends "school/index.twig" %}
{% extends "schools/index.twig" %}
{% import "school/index.twig" as macros %}
{% import "schools/index.twig" as macros %}
{% block schoolTitle %}
{{ parent() }} <small>Εκπαιδευτικοί</small>
......@@ -100,5 +100,5 @@
{% block inlinejs %}
{{ parent() }}
<script src="{{ base_url }}/js/school/staff.js"></script>
<script src="{{ base_url }}/js/schools/staff.js"></script>
{% endblock %}
\ No newline at end of file
(function () {
'use strict';
var Asset,
Assets,
AssetView,
AssetsView,
AssetModalView,
assetTemplate;
Asset = Backbone.Model.extend({ idAttribute: 'id' });
Assets = Backbone.Collection.extend({
model: Asset,
comparator: 'name',
});
AssetView = Backbone.View.extend({
tagName: 'tr',
template: (function () {
if (typeof assetTemplate === 'undefined') {
assetTemplate = _.template($('#asset-row-template').html());
}
return assetTemplate;
}()),
initialize: function () {
this.model.on('change', this.render, this);
},
render: function () {
var html = this.template({ asset: this.model.attributes });
this.$el.attr('data-id', this.model.get('id'));
this.$el.html(html);
return this;
}
});
AssetsView = Backbone.View.extend({
el: '#school',
modal: null,
events: {
'click .btn-add-asset': 'addAsset',
'click tbody tr': 'editAsset'
},
initialize: function () {
var that = this;
this.modal = new AssetModalView();
_.each(this.$el.find('tbody tr[data-asset]'), function (tr) {
var data,
asset;
tr = $(tr);
data = tr.data('asset');
asset = new Asset(data);
that.model.add(asset);
new AssetView({ model: asset });
tr.attr('data-asset', null);
});
this.model.on('add', this.renderAsset, this);
},
renderAsset: function (asset) {
this.$el.find('tbody').append(new AssetView({
model: asset
}).render().el);
return this;
},
addAsset: function (evt) {
var that = this;
evt.preventDefault();
this.modal.render(function (data) {
that.model.add(data);
});
},
editAsset: function (evt) {
var asset = this.model.get($(evt.target).closest('tr').data('id'));
this.modal.render(function (data) {
asset.set(data);
}, asset.attributes);
}
});
AssetModalView = Backbone.View.extend({
el: '#asset-form-modal',
form: null,
events: {
'submit': 'submit',
},
initialize: function () {
this.form = this.$el.find('form');
},
show: function () {
this.$el.modal('show');
return this;
},
hide: function () {
this.$el.modal('hide');
return this;
},
render: function (done, asset) {
var template,
that = this;
asset = asset || {};
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');
if (typeof asset[name] !== undefined) {
element.val(asset[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);
}
this.form.data('done')(data);
this.form.data('done', undefined);
this.hide();
}
});
new AssetsView({ model: new Assets() });
}());
\ No newline at end of file
(function () {
'use strict';
$.each($('#school .nav-tabs li'), function (index, tab) {
tab = $(tab);
if (window.location.pathname === tab.find('a').attr('href')) {
tab.addClass('active');
} else {
tab.removeClass('active');
}
});
$('[required]').parents('.form-group').find('label').append('<span>*</span>');
}());
\ No newline at end of file
(function () {
'use strict';
var Lab,
Labs,
LabView,
LabsView,
LabModalView,
labTemplate,
utils = window.EDULABS.utils;
Lab = Backbone.Model.extend({ idAttribute: 'id' });
Labs = Backbone.Collection.extend({
model: Lab,
comparator: 'name'
});
LabView = Backbone.View.extend({
tagName: 'tr',
template: (function () {
if (typeof labTemplate === 'undefined') {
labTemplate = _.template($('#lab-row-template').html());
}
return labTemplate;
}()),
initialize: function () {
this.model.on('change', this.render, this);
},
render: function () {
var html = this.template({ lab: this.model.attributes });
this.$el.html(html);
this.$el.attr('data-id', this.model.get('id'));
return this;
}
});
LabsView = Backbone.View.extend({
el: '#school',
modal: 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);
that.model.add(lab);
new LabView({ model: lab });
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;
},
addLab: function (evt) {
var that = this;
evt.preventDefault();
this.modal.render(function (data) {
that.model.add(data);
});
},
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);
}
});
LabModalView = Backbone.View.extend({
el: '#lab-form-modal',
form: null,
events: {
'submit': 'submit',
},
initialize: function () {
this.form = this.$el.find('form');
},
show: function () {
this.$el.modal('show');
return this;
},
hide: function () {
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);
}
this.form.data('done')(data);