summaryrefslogtreecommitdiff
path: root/public/app
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-05-04 03:02:01 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2023-05-04 03:02:01 +0300
commit63f714d5a78b765c117ebf6bbdfdbd748dd45644 (patch)
tree87a4db40e1ff699222ccfdf699a3904d1c665bfc /public/app
parent931a93cd7bae092e2752064568cebe407d2bf46e (diff)
downloadgyraf1gov-63f714d5a78b765c117ebf6bbdfdbd748dd45644.tar.gz
gyraf1gov-63f714d5a78b765c117ebf6bbdfdbd748dd45644.tar.bz2
gyraf1gov-63f714d5a78b765c117ebf6bbdfdbd748dd45644.zip
authentication; invitation; activation; base form setup
Diffstat (limited to 'public/app')
-rw-r--r--public/app/config/app_constants.php124
-rw-r--r--public/app/controllers/Auth.php280
-rw-r--r--public/app/controllers/Cms.php259
-rw-r--r--public/app/controllers/JsonToForm.php89
-rw-r--r--public/app/controllers/Office.php424
-rw-r--r--public/app/extends/App_manager.php4
-rw-r--r--public/app/extends/App_user.php63
-rw-r--r--public/app/extends/Cache_service.php19
-rw-r--r--public/app/models/Access_model.php57
-rw-r--r--public/app/models/Office_model.php (renamed from public/app/models/Cms_model.php)0
-rw-r--r--public/app/models/_info.md21
-rw-r--r--public/app/routes/backend.php11
-rw-r--r--public/app/routes/frontend.php15
-rw-r--r--public/app/routes/user.php13
-rw-r--r--public/app/views/error/404.php12
-rw-r--r--public/app/views/templates/penalty.php12
-rw-r--r--public/app/views/user/invitation.php (renamed from public/app/views/user/registration.php)96
-rw-r--r--public/app/views/welcome.php15
18 files changed, 858 insertions, 656 deletions
diff --git a/public/app/config/app_constants.php b/public/app/config/app_constants.php
index 9dff566..262a727 100644
--- a/public/app/config/app_constants.php
+++ b/public/app/config/app_constants.php
@@ -25,6 +25,12 @@ if (file_exists("../core/auth/.env")) {
define('SITE_TITLE', 'Classroom');
define('SITE_URL', 'http://localhost');
+// Session and cookie names
+// --- -- -- - - -
+define('SESSION_NAME', 'offticket'); // cookie for session (office ticket)
+define('CONNECTION_COOKIE', 'con'); // cookie for connection
+define('MAX_SESSION_LIFE', 2*60*60); // maximum session lifetime (2 hours)
+
// email setup
// --- -- -- - - -
// SMTP
@@ -144,82 +150,110 @@ define('ACCOUNT_ACTIVATED_TITLE', 'Ο λογαριασμός σας έχει ε
define('ACCOUNT_ACTIVATED_MESSAGE', 'Τώρα μπορείτε να
<a href="/login">συνδεθείτε στο σύστημα</a>.');
define('NOT_VALID_ACTIVATION_TITLE', 'Σφάλμα!');
+define('NOT_VALID_ACTIVATION_MESSAGE', 'Ο λογαριασμός δεν έχει ενεργοποιηθεί.
+ Ξαναδοκιμάστε αργότερα κι αν το σφάλμα επιμείνει, επικοινωνήστε με την υπεύθυνη του προγράμμαρος.');
+// forms
+// --- -- -- - - -
-
+// registration/activation form (from invitation)
+// ---
define('REGISTRATION_FORM', [
'defaults' => [
'outer_class' => 'col-12',
'inner_class' => 'form-control',
- 'type' => 'text'
+ 'type' => 'text',
+ 'source' => '\app\controllers\User::current'
],
'form' => [
[
'name' => 'first_name',
'label' => 'Όνομα',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
'name' => 'last_name',
'label' => 'Επίθετο',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
'name' => 'email',
'label' => 'e-mail',
'type' => 'email',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
'name' => 'father_name',
'label' => 'Πατρώνυμο',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
'name' => 'registration_number',
'label' => 'Αριθμός μητρώου',
'class' => 'col-8',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
'name' => 'sector',
'label' => 'Κλάδος / Ειδικότητα',
+ 'value' => 'auto',
'type' => 'select',
- // 'source' => 'sectors',
'attributes' => ['required'],
'options' => [
- 'Π01.00 Θεολόγοι',
- 'Π02.00 Φιλόλογοι',
- 'Π04.01 Φυσικοί',
- 'Π04.02 Χημικοί'
+ 'ΠΕ01 ΘΕΟΛΟΓΟΙ',
+ 'ΠΕ02 ΦΙΛΟΛΟΓΟΙ',
+ 'ΠΕ02.50 ΦΙΛΟΛΟΓΟΙ ΕΙΔΙΚΗΣ ΑΓΩΓΗΣ',
+ 'ΠΕ03 ΜΑΘΗΜΑΤΙΚΟΙ',
+ 'ΠΕ03.50 ΜΑΘΗΜΑΤΙΚΟΙ ΕΙΔΙΚΗΣ ΑΓΩΓΗΣ',
+ 'ΠΕ04.01 ΦΥΣΙΚΟΙ',
+ 'ΠΕ04.01.50 ΦΥΣΙΚΟΙ ΕΙΔΙΚΗΣ ΑΓΩΓΗΣ',
+ 'ΠΕ04.02 ΧΗΜΙΚΟΙ',
+ 'ΠΕ04.04 ΒΙΟΛΟΓΟΙ',
+ 'ΠΕ05 ΓΑΛΛΙΚΗΣ ΦΙΛΟΛΟΓΙΑΣ',
+ 'ΠΕ06 ΑΓΓΛΙΚΗΣ ΦΙΛΟΛΟΓΙΑΣ',
+ 'ΠΕ07 ΓΕΡΜΑΝΙΚΗΣ ΦΙΛΟΛΟΓΙΑΣ',
+ 'ΠΕ08 ΚΑΛΛΙΤΕΧΝΙΚΩΝ',
+ 'ΠΕ11 ΦΥΣΙΚΗΣ ΑΓΩΓΗΣ',
+ 'ΠΕ23-ΣΔΕΥ ΨΥΧΟΛΟΓΟΙ',
+ 'ΠΕ30-ΣΔΕΥ ΚΟΙΝΩΝΙΚΟΙ ΛΕΙΤΟΥΡΓΟΙ',
+ 'ΠΕ78 ΚΟΙΝΩΝΙΚΩΝ ΕΠΙΣΤΗΜΩΝ',
+ 'ΠΕ79.01 ΜΟΥΣΙΚΗΣ ΕΠΙΣΤΗΜΗΣ',
+ 'ΠΕ80 ΟΙΚΟΝΟΜΙΑΣ',
+ 'ΠΕ81 ΠΟΛ.ΜΗΧΑΝΙΚΩΝ-ΑΡΧΙΤΕΚΤΟΝΩΝ',
+ 'ΠΕ82 ΜΗΧΑΝΟΛΟΓΩΝ',
+ 'ΠΕ86 ΠΛΗΡΟΦΟΡΙΚΗΣ',
+ 'ΠΕ88.01 ΓΕΩΠΟΝΟΙ'
]
],
[
'name' => 'belonging_school',
'label' => 'Σχολείο τοποθέτησης',
+ 'value' => 'auto',
'attributes' => ['required']
],
- [
- 'name' => 'working_school',
- 'label' => 'Σχολείο εργασίας',
- 'attributes' => ['required']
- ],
+ // [ // working school = (obviously) is the current school
+ // 'name' => 'working_school',
+ // 'label' => 'Σχολείο εργασίας',
+ // 'attributes' => ['required']
+ // ],
[
'name' => 'position',
'label' => 'Θέση',
'type' => 'select',
+ 'value' => 'auto',
'attributes' => ['required'],
- 'options' => [
- 'Διευθυν-τής/τρια',
- 'Υποδιευθυν-τής/τρια',
- 'Μόνιμ-ος/η Καθηγη-τής/τρια',
- 'Αναπληρω-τής/τρια',
- ]
+ 'options' => []
],
[
'name' => 'phone',
'label' => 'Τηλέφωνο',
'class' => 'col-8',
+ 'value' => 'auto',
'attributes' => ['required']
],
[
@@ -239,7 +273,8 @@ define('REGISTRATION_FORM', [
]
]);
-
+// common requesy form (for any application)
+// ---
define('COMMON_REQUEST_FORM', [
'defaults' => [
'outer_class' => 'col-12',
@@ -317,6 +352,8 @@ define('COMMON_REQUEST_FORM', [
]
]);
+// penalty form
+// ---
define('PENALTY_FORM', [
'defaults' => [
@@ -382,6 +419,7 @@ define('PENALTY_FORM', [
[
'name' => 'rapporteur',
'label' => 'εισηγητής',
+ 'type' => 'select',
'source' => '\app\extends\Cache_service::all_users',
'attributes' => ['required']
],
@@ -426,7 +464,7 @@ define('PENALTY_FORM', [
[
'name' => 'president',
'label' => 'Πρόεδρος συνεδρίασης',
- 'type' => 'text',
+ 'type' => 'select',
'source' => '\app\extends\Cache_service::all_users',
'attributes' => ['required']
],
@@ -435,51 +473,7 @@ define('PENALTY_FORM', [
'label' => 'Μέλη',
'type' => 'select',
'attributes' => ['required', 'multiple'],
- 'source' => '\app\extends\Cache_service::all_users',
- 'options' => [
- 'Μαρία Χαλκιαδάκη',
- 'Σπαγκοβαγγελοδημήτρης Νικόλαος',
- 'Χατζηχριστοδούλου Παναγιώτης',
- 'Μαρία Χαλκιά',
- 'Σπανοβαγγελοδημήτρης Νικόλαος',
- 'Χριστοδούλου Παναγιώτης',
- 'Μαρίκα Χαλκιαδάκη',
- 'Σπανακοβαγγελοδημήτρης Νικόλαος',
- 'Χατζηχριστοδούλου Χριστόδουλος',
- 'Αννέτα Καββαδία',
- 'Γιώργος Καΐσας',
- 'Διονύσης - Χαράλαμπος Καλαματιανός',
- 'Ηλίας Καματερός',
- 'Μαρία Κανελλοπούλου',
- 'Ιωάννης Καραγιάννης',
- 'Χρήστος Καραγιαννίδης',
- 'Ευαγγελία Καρακώστα',
- 'Απόστολος Καραναστάσης',
- 'Ευφροσύνη Καρασαρλίδου',
- 'Νίνα Κασιμάτη',
- 'Αστέριος Καστόρης',
- 'Βασιλική Κατριβάνου',
- 'Γιώργος Κατρούγκαλος',
- 'Χρυσούλα Κατσαβριά-Σιωροπούλου',
- 'Μάριος Κάτσης',
- 'Χαρά Καφαντάρη',
- 'Σίμος Α. Κεδίκογλου',
- 'Παναγιώτα Κοζομπόλη-Αμανατίδη',
- 'Βασίλης Κόκκαλης',
- 'Σταύρος Κοντονής',
- 'Περικλής Κοροβέσης',
- 'Νίκος Κοτζιάς',
- 'Φώτης Κουβέλης',
- 'Τάσος Κουράκης',
- 'Παναγιώτης Κουρουμπλής',
- 'Μιχαήλ Κριτσωτάκης',
- 'Βασίλης Κυριακάκης',
- 'Αγλαΐα Κυρίτση',
- 'Γιώργος Κυρίτσης',
- 'Πέτρος Κωνσταντινέας',
- 'Ζωή Κωνσταντοπούλου',
- 'Ηλίας Κωστοπαναγιώτου'
- ]
+ 'source' => '\app\extends\Cache_service::all_users'
]
]
]);
diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php
index 4b3dcfb..118b4d0 100644
--- a/public/app/controllers/Auth.php
+++ b/public/app/controllers/Auth.php
@@ -5,8 +5,9 @@ use Registry;
use Render;
// user classes and models
-use app\extends\Classroom_user;
-use app\extends\Classroom_manager;
+use app\controllers\JsonToForm;
+use app\extends\App_user;
+use app\extends\App_manager;
use app\models\Access_model;
use app\extends\SendMail_service;
@@ -37,50 +38,40 @@ class Auth {
// user is valid; check user password
// create a user object
- $user = (new Classroom_user())
+ $user = (new App_user())
->setID($record['id'])
+ ->setSex( ($record['prefix'] == 'η') ? 2 : 1 )
->setUserName($record['email'])
->setName($record['first_name'] .' '. $record['last_name'])
->setPassword($record['password'])
+ ->setRoles([ $record['role_id'] ]) // roles is an array
->setEnabled($record['active']);
+
// let user manager to validate user credentials
- $userManager = new Classroom_manager();
+ $userManager = new App_manager();
if ($userManager->isPasswordValid($user, $req->POST['password'])) {
- // get user's security attributes
- $attributes = Access_model::getUser($record['id']);
- $roles = json_decode($attributes['Roles_json']);
- $user
- ->setRoles($roles)
- ->setPrivileges(
- array_merge(
- json_decode($attributes['RootPrivileges_json']),
- self::merge_lists_array(
- json_decode($attributes['SubPrivileges_json'])
- )
- )
- );
-
// regeneration session ID (prevent session fixation)
+ session_unset(); // unset $_SESSION variable for the run-time
+ session_destroy(); // destroy session data in storage before continue
+ session_start();
session_regenerate_id();
+
// set cookie for connected user
setcookie(
- 'cluser',
+ CONNECTION_COOKIE,
'connected;'. $user->getName(),
- time()+60*60*8, // 8 hours
+ time()+60*60*10, // 10 hours
'/'
);
-
- // check if admin (and redirect differently)
- $is_admin = (!empty(array_intersect([1,2,3], $roles)));
-
+
// login OK, set Token in session
$userManager->createUserToken($user);
return [
'success' => true,
- 'goto' => $is_admin ? '/admin/lessons' : '/user/profile',
+ 'goto' => '/admin/panel'
];
} else {
@@ -89,33 +80,27 @@ class Auth {
}
- /**
- * merges an array of lists to one list
- */
- private static function merge_lists_array( $list )
- {
- $current = [];
- foreach($list as $sublist) {
- $current = array_merge($current, $sublist);
- }
- return $current;
- }
-
-
/** activate
- * resolves a call like: /account/activate?ticket=ca42d68cfba5fbbafeacc010b8e3a551
+ * resolves call POST:/account/activate
+ *
+ * @param void : all parametres passed via request->POST
*/
public static function activate()
{
$req = Registry::get('REQUEST');
+ // print_r($req->POST); die();
- // get the record of the target user
- $check = Access_model::activate($req->GET['ticket']);
+ // create a salted password hash
+ $userManager = new App_manager();
+ $password = $userManager->cryptPassword($req->POST['password']);
- if ($check == true) {
+ // acivate target user and set password
+ $check = Access_model::activate_set_password($req->POST, $password);
+
+ if ($check != 0) {
Render::view('/error/general', [
'title' => ACCOUNT_ACTIVATED_TITLE,
- 'message' => ACCOUNT_ACTIVATED_MESSAGE
+ 'message' => ACCOUNT_ACTIVATED_MESSAGE . '<br>(msg code: '. $check .')'
]);
} else {
@@ -127,64 +112,72 @@ class Auth {
}
- /** register
+
+ /** invitation
+ *
+ * setups and renders the form for a certain invitation
+ *
+ * NOTE:
+ * after form is submited, client calls Auth::activate()
*
- * Method for new user registration
+ * @param $id (string|MD5) : invitation code
*
*/
- public static function register()
+ public static function invitation($id)
{
- $userManager = new Classroom_manager();
- $req = Registry::get('REQUEST');
+ // get user from invitation number
+ $user_array = Registry::use('database')->query(
+ "SELECT * FROM user WHERE invitation = :id",
+ ['id' => $id]
+ )->getFirst();
+ if ($user_array == false) {
+ Render::view('error/404', ['moto' => 'Δεν βρέθηκε η πρόσκληση']);
+ die();
+ }
+ $user = json_decode( json_encode($user_array, JSON_UNESCAPED_UNICODE)); // user in json format
- // create a salted password hash
- $password = $userManager->cryptPassword($req->POST['password']);
+ // format form_setup to a json array
+ $form_setup = json_decode(json_encode(REGISTRATION_FORM, JSON_UNESCAPED_UNICODE));
- // echo $password; print_r($req->POST); die(); // OK!
-
- $user = (new Classroom_user())
- ->setUserName($req->POST['email'])
- ->setName($req->POST['name'] .' '. $req->POST['surname'])
- ->setPassword($password)
- ->setRoles([ READER ]) // Role: authorized reader
- ->setPrivileges([]); // none privilege until acount confirmation
-
- // create user record
- $activation_code = Access_model::registerUser($req->POST, $password);
-
- // TODO:
- // handle error on user registration
- // ...
- //
- // if ($activatopn_code[] == -1) {
- // return [
- // 'success' => false,
- // 'message' => REGISTRATION_USER_EXISTS
- // ];
- // }
-
- $send_mail = SendMail_service::send_activation_code([
- 'email' => $req->POST['email'],
- 'name' => $req->POST['name'] .' '. $req->POST['surname'],
- 'code' => $activation_code['activation']
- ]);
+ // get $key of position item inside the form_setup->form array
+ for($i=0; $i < sizeof($form_setup->form) ; $i++) {
+ if ($form_setup->form[$i]->name == 'position') { $key = $i; }
+ }
- // Send replies
- if ($send_mail) {
- return [
- 'success' => true,
- 'message' => REGISTRATION_SUCCESS
+ // prepare gendered options to position field
+ $positions = ($user->prefix != 'η')
+ ? [
+ 'Διευθυντής',
+ 'Υποδιευθυντής',
+ 'Μόνιμος Καθηγητής',
+ 'Αναπληρωτής Καθηγητής'
+ ]
+ : [
+ 'Διευθύντρια',
+ 'Υποδιευθύντρια',
+ 'Μόνιμη Καθηγήτρια',
+ 'Αναπληρώτρια Καθηγήτρια'
];
+ $gendered_position = json_decode( json_encode( $positions, JSON_UNESCAPED_UNICODE ));
- } else {
- return [
- 'success' => false,
- 'message' => 'error on sending email'
- ];
- }
+ // attach gendered options
+ $form_setup->form[$key]->options = $gendered_position;
+
+ // attach default values
+ $form_setup->defaults->values = $user;
+
+ // get Form's HTML and Jsvascript
+ $form = JsonToForm::json_form($form_setup, [
+ // pass invitation identity for security
+ ['name' => 'id', 'value' => $user->id],
+ ['name' => 'invitation', 'value' => $user->invitation]
+
+ ]);
+ Render::view('user/invitation', ['form' => $form]);
}
+
/** is_connected
* checks if the user is connected
*
@@ -192,7 +185,7 @@ class Auth {
*/
public static function is_connected()
{
- $manager = new Classroom_manager();
+ $manager = new App_manager();
if ($manager->hasUserToken()) {
// user is connected;
@@ -215,16 +208,19 @@ class Auth {
*/
public static function logout()
{
- $userManager = new Classroom_manager();
+ $userManager = new App_manager();
$userManager->logout();
// regeneration session ID (prevent session fixation)
+ session_unset(); // unset $_SESSION variable for the run-time
+ session_destroy(); // destroy session data in storage before continue
+ session_start();
session_regenerate_id();
// remove user-conected cookie
- if (isset($_COOKIE['cluser'])) {
- unset($_COOKIE['cluser']);
- setcookie('cluser', '', -1, '/');
+ if (isset($_COOKIE[CONNECTION_COOKIE])) {
+ unset($_COOKIE[CONNECTION_COOKIE]);
+ setcookie(CONNECTION_COOKIE, '', -1, '/');
return true;
} else {
@@ -233,97 +229,27 @@ class Auth {
}
-
- /** hasPermition( PERMIT )
- *
- * checks if the user owns the specified permition
- * to access the source
+ /** TODO:
*
*/
- public static function hasPermition($permit = [0])
+ public static function forgot_password()
{
- if (in_array(0, $permit)) { // permision 0 means public
- return true; // permision 0 is always granted
- }
-
- if ($user = self::is_connected() === false) { // if not connected
- return false; // then no other permition is granted
- }
-
- if ($user instanceof UserInterface) {
- return ( !empty( array_intersect($permit, $user->getPrivileges()) ) );
- }
}
- /** isAuthenticated()
- *
- * chechs if the user's roles and permitions
- * satisfy the specified requirements
- * to access the source
- *
- * @param $requirements (array of rules-array)
- *
- * example:
- * [
- * [
- * role => [2, 3]
- * permition => ['10', '12', '18']
- * ],
- * [
- * role => [1 , 4]
- * ],
- * [
- * permition => [ 3 ]
- * ]
- * ]
- *
- * defines (and parses to) a requirements rule of:
- * [
- * user should be creator or editor
- * _AND_ have permition 10 or 12 or 18
- * ]
- * OR
- * [
- * user should be an administrator or developer
- * ]
- * OR
- * [
- * user should have permition #3
- * ]
- *
+ /** TODO:
*
*/
- public static function isAuthorized($requirements)
- {
- $authorized = false;
- foreach($requirements as $required) {
-
- if (isset($required['role'])) { // if a role is required
- if ( (self::isGranted($required['role'])) // authorize both role
- && (self::hasPermition($required['permition'] ?? [ 0 ])) ) { // and permition
- // $authorized = true;
- return true;
- }
-
- } else { // else, if not is not required
- if (self::hasPermition($required['permition'] ?? [ 0 ])) { // authorize permition
- // $authorized = true;
- return true;
- }
- }
- }
- return $authorized;
- }
-
-
- public static function forgot_pass()
+ public static function validate_otp()
{
}
- public static function validate_otp()
+ /** TODO:
+ *
+ */
+ public static function reset_password()
{
}
@@ -339,7 +265,7 @@ class Auth {
*/
public static function allowRoles($allowed)
{
- $manager = new Classroom_manager();
+ $manager = new App_manager();
if ($manager->isGranted($allowed)) { // if valid, return true (continue)
return true;
@@ -361,21 +287,17 @@ class Auth {
*/
public static function hasValidRole($allowed)
{
- $manager = new Classroom_manager();
+ $manager = new App_manager();
return ($manager->isGranted($allowed));
}
public static function in_admin_group()
{
- $manager = new Classroom_manager();
+ $manager = new App_manager();
return ($manager->isGranted([1, 2, 3]));
}
}
-
-
-// NOTE:
-// check: https://netcorecloud.com/tutorials/send-an-email-via-gmail-smtp-server-using-php/ \ No newline at end of file
diff --git a/public/app/controllers/Cms.php b/public/app/controllers/Cms.php
deleted file mode 100644
index 306bc88..0000000
--- a/public/app/controllers/Cms.php
+++ /dev/null
@@ -1,259 +0,0 @@
-<?php
-
-namespace app\controllers;
-
-use Registry;
-use Render;
-use app\controllers\Auth;
-use app\models\Cms_model;
-use app\extends\Cache_service;
-
-/** CMS class
- * (Content Management System)
- *
- * Serves the content;
- * Reponds to all front-end front-office requests
- *
- */
-class Cms {
-
-
- ## PERMITION
- ## -------------------------------------------------------------------------
-
-
- /** is admin or permited
- *
- * shortcut method for checking access authorization
- *
- * returns true if user belogns to the admin group
- * OR has the specified permition/privilege
- *
- * @param $privilege_id (int)
- *
- * NOTE:
- * unlike the other authorization methods ...
- * $privilege_id is NOT an array but a single privilege id
- *
- * @return true|false
- */
- private static function is_admin_or_permited( $privilege_id )
- {
- return (
- Auth::in_admin_group()
- || Auth::hasPermition([ $privilege_id ])
- );
- }
-
-
-
- ## FILES
- ## -------------------------------------------------------------------------
-
-
- /** serve file by file_path
- * (request is valid only for admin users)
- *
- * @param $file_path (string): relative file path
- * GET @param type (string) : media-type of file
- */
- public static function serve_file($file_path)
- {
- $file = self::get_file_attributes($file_path);
-
- // if user is authorized
- if (self::is_admin_or_permited($file['privilege_id'])) {
-
- $media_type = Registry::get('REQUEST')->GET['type']; // get media-type
- $real_path = MEDIA_STORAGE_ROOT . $file_path; // construct real path
-
- if (!file_exists($real_path)) {
- Render::view('error/404');
-
- } else {
- Render::file($real_path, $media_type);
- }
-
- } else {
- Render::view('error/404', [
- 'error_code' => 403,
- 'moto' => 'Forbidden',
- 'message' => ''
- ]);
- }
- }
-
-
- /** get_file_attributes
- *
- * returns attributes of a file
- * (medias are proxied for speed optimization)
- *
- * @param $path (string) : file path
- * @return $file attributes --or-- false
- */
- private static function get_file_attributes($path)
- {
- $medias = Cache_service::files_attributes();
-
- foreach($medias as $key => $medi) {
-
- if ($medi['path'] == $path) {
-
- return $medi;
- }
- }
-
- return false;
- }
-
-
-
- ## COURSES
- ## -------------------------------------------------------------------------
-
-
- /** course
- * prepare and render the course view
- *
- * @param $id : course id
- */
- public static function course($id)
- {
- $id = intval($id); // course id
-
- // collect all data needed for course view
- // --- -- -- - - -
- $cache = Cache_service::courses_struct();
- $tree = $cache['tree'];
- $breadcrumbs = $cache['breadcrumbs'];
- $lessons = Cms_model::lessons_of_course(intval($id));
-
- // find parent_ids of current category (to open the menu tree)
- // ---
- $course_path = [];
- foreach($breadcrumbs[$id]['parents'] as $key => $parent) {
- $course_path[] = intval($parent['id']);
- }
- $course_path[] = $id;
-
- // then Render
- // --- -- -- - - -
- Render::view('templates/course', [
- 'id' => $id,
- 'title' => $breadcrumbs[ $id ]['rec']['label'],
- 'categories' => $tree,
- 'breadcrumbs' => $breadcrumbs,
- 'lessons' => $lessons,
- 'course_path' => $course_path,
- // needed by footer
- 'entity' => Cache_service::pages_list()
- ]);
- }
-
-
-
- ## LESSONS
- ## -------------------------------------------------------------------------
-
-
-
- /** lesson
- *
- * check if user is authorized to view the content;
- * if so, prepare and render the lesson view
- *
- * @param $id : lesson id
- */
- public static function lesson($id)
- {
- $id = intval($id); // lesson id
-
- $lesson = Cms_model::lesson($id); // get lesson
- $course_id = $lesson['course_id']; // get course id
- $pri_id = $lesson['privilege_id']; // privilege needed
-
-
- if (self::is_admin_or_permited($pri_id)) {
-
- // collect all data needed for course view
- // --- -- -- - - -
- $cache = Cache_service::courses_struct();
- $tree = $cache['tree'];
- $breadcrumbs = $cache['breadcrumbs'];
-
- // find parent_ids of current category (to open the menu tree)
- // ---
- $course_path = [];
- foreach($breadcrumbs[$course_id]['parents'] as $key => $parent) {
- $course_path[] = intval($parent['id']);
- }
- $course_path[] = intval($course_id);
-
- // NOTE: CRITICAL:
- // do not pass Class::method directly to the eported variables
- // $entity = Cache_service::pages_list();
-
- // var_dump($entity); die();
-
- // then Render
- // --- -- -- - - -
- Render::view('templates/lesson', [
- // main content
- 'id' => $id,
- 'course_id' => $course_id,
- 'title' => $lesson['title'],
- 'lesson' => $lesson,
- // needed for side panel and breadcrunbs
- 'categories' => $tree,
- 'breadcrumbs' => $breadcrumbs,
- 'course_path' => $course_path,
- // needed by footer
- 'entity' => Cache_service::pages_list()
- ]);
-
- } else { // user is not authorized
- Render::view('error/general', [
- 'title' => 'Δεν έχετε πρόσβαση',
- 'message' => 'Θα πρέπει να αγοράσετε το πακέτο πρόσβασης '
- . $pri_id
- .' για να δείτε το περιεχόμενο!
- <br><br>
- Αγόρασε τώρα το <button class="btn">πακέτο πρόσβασης '. $pri_id .'</button>'
- ]);
- }
-
- }
-
-
- ## PAGES
- ## -------------------------------------------------------------------------
-
-
- /** lesson
- *
- * check if user is authorized to view the content;
- * if so, prepare and render the lesson view
- *
- * @param $id : lesson id
- */
- public static function page($id)
- {
- $id = intval($id); // lesson id
-
- $pages = Cache_service::pages_list();
- $page = $pages[$id];
-
- // then Render
- // --- -- -- - - -
- Render::view('templates/page', [
- // main content
- 'id' => $id,
- 'page' => $page,
- // needed by footer
- 'entity' => $pages
- ]);
-
- }
-
-}
diff --git a/public/app/controllers/JsonToForm.php b/public/app/controllers/JsonToForm.php
index 1b05af7..5df650d 100644
--- a/public/app/controllers/JsonToForm.php
+++ b/public/app/controllers/JsonToForm.php
@@ -1,4 +1,5 @@
<?php
+namespace app\controllers;
class JsonToForm
{
@@ -141,14 +142,20 @@ class JsonToForm
return (mb_strlen($str) > $len) ? mb_substr($str, 0, $len-1) ."…" : $str;
}
-
- public static function make_a_form($form)
+ /** json_form
+ *
+ * construct a form (html, javasctipt)
+ * from a json designer
+ *
+ */
+ public static function json_form($formJson, $require_identity = [])
{
- $formJson = json_decode(json_encode($form));
+ // $formJson = json_decode(json_encode($form));
- $default_outer = $form->defaults->outer_class ?? '';
- $default_inner = $form->defaults->inner_class ?? '';
- $default_type = $form->defaults->type ?? 'text';
+ $default_outer = $formJson->defaults->outer_class ?? '';
+ $default_inner = $formJson->defaults->inner_class ?? '';
+ $default_type = $formJson->defaults->type ?? 'text';
+ $default_values = $formJson->defaults->values ?? ((object) ['nothing' => true]);
// TODO handle $form->defaults->source;
@@ -180,8 +187,15 @@ class JsonToForm
$initSelectsJS = ""; // js to initialize select fields (single or multiple)
+ $identity = ""; // construct required identity hidden fields
+ foreach ($require_identity as $group) {
+ $identity .= "
+ <input type='hidden' name='". $group['name']
+ ."' value='". $group['value'] ."'>";
+ }
- $html = "
+ // now constuct the form body
+ $html = "{$identity}
<div class='row'>
";
@@ -191,15 +205,22 @@ class JsonToForm
$type = $field->type ?? $default_type;
$class = $field->class ?? "";
$label = $field->label;
- $name = $field->name ?? "$field->label";
-
- // TODO: auto value
-
+ $name = $field->name ?? $field->label;
+
+ // handle value assignment
+ if (isset($field->value)) { // if value property is set
+ $set_value = true; // (flag: value seted)
+ $value = (($field->value == 'auto') && isset($default_values->$name))
+ ? $default_values->$name // set auto value
+ : $field->value; // or other set-value
+ } else {
+ $set_value = false;
+ }
+ // print_r([ $set_value, $name, ($default_values->$name ?? 'none') ]);
+
$appendKey = in_array('append-key', $attributes) ? true : false; // append key (for selects)
- $required = in_array('required', $attributes) ? 'required' : ''; // required
+ $required = in_array('required', $attributes) ? '' : ''; // required
$asterisk = in_array('required', $attributes) ? '*' : ''; // asterisk in label if required
-
-
$html .= "
<div class='form-group {$class}'>
@@ -220,6 +241,15 @@ class JsonToForm
var {$name} = $('#{$name}');
{$name}.select2({ width: '100%', placeholde: '{$label}' });";
+ if ($set_value) { // if default value is set
+ $initSelectsJS .= "
+ select2_set_multi_text( {$name} , {$value} );";
+
+ } else {
+ $initSelectsJS .= "
+ {$name}.val(null).trigger('change');";
+ }
+
// prepare check if empty field
$checkFilledJS .= "
if (getValues({$name}) =='') { empty += '{$label} {$asterisk}<br />'; }
@@ -234,8 +264,16 @@ class JsonToForm
// prepare initialization of select2 (single)
$initSelectsJS .= "
var {$name} = $('#{$name}');
- {$name}.select2({ });
- {$name}.val(null).trigger('change')";
+ {$name}.select2();";
+
+ if ($set_value) { // if default value is set
+ $initSelectsJS .= "
+ select2_set_text( {$name} , '{$value}' );";
+
+ } else {
+ $initSelectsJS .= "
+ {$name}.val(null).trigger('change');";
+ }
// prepare check if empty field
$checkFilledJS .= "
@@ -259,8 +297,10 @@ class JsonToForm
case 'text':
+ $def_value = ($set_value) ? "value='{$value}'" : "value=''";
+
$html .= "
- <input type='text' class='form-control form-control-sm' name='{$name}' {$required}>";
+ <input type='text' class='form-control form-control-sm' name='{$name}' $def_value {$required}>";
$checkFilledJS = "
if ($('input[name={$name}]').val() =='') { empty += '{$label} {$asterisk}<br />'; }
@@ -271,6 +311,8 @@ class JsonToForm
case 'password':
+ $def_value = ($set_value) ? "value='{$value}'" : "value=''";
+
$html .= "
<input type='password' class='form-control form-control-sm' name='{$name}' {$required}>";
@@ -283,8 +325,10 @@ class JsonToForm
case 'integer':
+ $def_value = ($set_value) ? "value='{$value}'" : "value=''";
+
$html .= "
- <input type='number' class='form-control form-control-sm' name='{$name}' min='0' step='1' {$required}>";
+ <input type='number' class='form-control form-control-sm' name='{$name}' min='0' step='1' $def_value {$required}>";
$checkFilledJS .= "
if ($('input[name={$name}]').val() =='') { empty += '{$label} {$asterisk}<br />'; }
@@ -295,8 +339,10 @@ class JsonToForm
case 'textarea':
+ $def_value = ($set_value) ? "{$value}" : "";
+
$html .= "
- <textarea class='form-control form-control-sm' name='{$name}' {$required}></textarea>";
+ <textarea class='form-control form-control-sm' name='{$name}' {$required}>{$def_value}</textarea>";
$checkFilledJS .= "
if ($('textarea[name={$name}]').val() =='') { empty += '{$label} {$asterisk}<br />'; }
@@ -319,8 +365,10 @@ class JsonToForm
case 'email':
+ $def_value = ($set_value) ? "value='{$value}'" : "value=''";
+
$html .= "
- <input type='email' class='form-control form-control-sm' name='{$name}' {$required}>";
+ <input type='email' class='form-control form-control-sm' name='{$name}' {$def_value} {$required}>";
$checkFilledJS .= "
if ($('input[name={$name}]').val() =='') { empty += '{$label} {$asterisk}<br />'; }
@@ -332,7 +380,6 @@ class JsonToForm
default: // label, acts as common text
//$html .= "<label>{$label}</label";
-
}
diff --git a/public/app/controllers/Office.php b/public/app/controllers/Office.php
new file mode 100644
index 0000000..cfadde3
--- /dev/null
+++ b/public/app/controllers/Office.php
@@ -0,0 +1,424 @@
+<?php
+
+namespace app\controllers;
+
+use Registry;
+use Render;
+use app\controllers\Auth;
+use app\extends\App_manager;
+use app\models\Cms_model;
+use app\extends\Cache_service;
+
+/** Office class
+ *
+ * Manages all requests (front/back-office)
+ */
+class Office {
+
+ ## -------------------------------------------------------------------------
+ ##
+ ## SERVE METHODS (selects)
+ ##
+ ## -------------------------------------------------------------------------
+
+ ## PERMITION
+ ## -------------------------------------------------------------------------
+
+
+ /** is admin or permited
+ *
+ * shortcut method for checking access authorization
+ *
+ * returns true if user belogns to the admin group
+ * OR has the specified permition/privilege
+ *
+ * @param $privilege_id (int)
+ *
+ * NOTE:
+ * unlike the other authorization methods ...
+ * $privilege_id is NOT an array but a single privilege id
+ *
+ * @return true|false
+ */
+ private static function is_admin_or_permited( $privilege_id )
+ {
+ return (
+ Auth::in_admin_group()
+ || Auth::hasPermition([ $privilege_id ])
+ );
+ }
+
+
+
+ ## SERVE FILE
+ ## -------------------------------------------------------------------------
+
+
+ /** serve file by file_path
+ * (request is valid only for admin users)
+ *
+ * @param $file_path (string): relative file path
+ * GET @param type (string) : media-type of file
+ */
+ public static function serve_file($file_path)
+ {
+ $file = self::get_file_attributes($file_path);
+
+ // if user is authorized
+ if (self::is_admin_or_permited($file['privilege_id'])) {
+
+ $media_type = Registry::get('REQUEST')->GET['type']; // get media-type
+ $real_path = MEDIA_STORAGE_ROOT . $file_path; // construct real path
+
+ if (!file_exists($real_path)) {
+ Render::view('error/404');
+
+ } else {
+ Render::file($real_path, $media_type);
+ }
+
+ } else {
+ Render::view('error/404', [
+ 'error_code' => 403,
+ 'moto' => 'Forbidden',
+ 'message' => ''
+ ]);
+ }
+ }
+
+
+ /** get_file_attributes
+ *
+ * returns attributes of a file
+ * (medias are proxied for speed optimization)
+ *
+ * @param $path (string) : file path
+ * @return $file attributes --or-- false
+ */
+ private static function get_file_attributes($path)
+ {
+ $medias = Cache_service::files_attributes();
+
+ foreach($medias as $key => $medi) {
+
+ if ($medi['path'] == $path) {
+
+ return $medi;
+ }
+ }
+
+ return false;
+ }
+
+
+
+ ## PETITIONS
+ ## -------------------------------------------------------------------------
+ ## secretarial support / teachers' requests and applications
+
+
+
+ /** (any) petition
+ *
+ * check if user is authorized to view the content;
+ * if so, prepare and render the petition view
+ *
+ * @param $petition_type (string): [common|penalty]
+ */
+ public static function request_petition($petition_tag)
+ {
+ // get current user
+ $manager = new App_manager();
+ if (!$manager->hasUserToken()) { // if user is not connected
+ Render::view('error/404', [
+ 'error_code' => 403, // serve forbidden
+ 'moto' => 'Forbidden',
+ 'message' => 'Για να έχετε πρόσβαση, θα πρέπει πρώτα να συνδεθείτε'
+ ]);
+ die(); // then end;
+ }
+
+ $token = $manager->getUserToken(); // from token
+ $user = $token->getUser(); // create user
+ $id = $user->getID(); // keep id user
+
+ switch ($petition_tag) { // route to specific type of petition
+
+ case 'common':
+ self::render_common_petition(['user' => $user]);
+ break;
+
+ case 'penalty':
+ self::render_penalty_form(['user' => $user]);
+ break;
+
+ default: // if not a known petition type
+ Render::view('error/404', [ // then serve not-found
+ 'message' => 'Δεν βρέθηκε το είδος της αίτησης ή του εγγράφου που ζητήσατε.'
+ ]);
+ }
+ }
+
+
+ private static function render_penalty_form($opts)
+ {
+ $user_id = $opts['user']->getID();
+
+ $form_setup = json_decode(json_encode(PENALTY_FORM, JSON_UNESCAPED_UNICODE));
+
+ // get all teachers
+ $teachers_array = Registry::use('database')->runQuery(
+ "SELECT concat(last_name, ' ', first_name) as TeacherName
+ FROM user ORDER BY TeacherName", []
+ );
+ $teachers = []; // constuct teacher names as a simple array
+ foreach($teachers_array as $key => $person) {
+ $teachers[] = $person['TeacherName'];
+ }
+ // print_r( $teachers); die();
+
+ // get $key of rapporteur, president and members inside the form_setup->form array
+ for($i=0; $i < sizeof($form_setup->form) ; $i++) {
+ if (isset($form_setup->form[$i]->name)) {
+ if ($form_setup->form[$i]->name == 'rapporteur') { $keyRapporteur = $i; }
+ if ($form_setup->form[$i]->name == 'president') { $keyPresident = $i; }
+ if ($form_setup->form[$i]->name == 'members') { $keyMembers = $i; }
+ }
+ }
+
+ // set option sources for rapporteur, president and members
+ $form_setup->form[$keyRapporteur]->options = $teachers;
+ $form_setup->form[$keyPresident]->options = $teachers;
+ $form_setup->form[$keyMembers]->options = $teachers;
+
+ // get Form's HTML and Jsvascript
+ $form = JsonToForm::json_form($form_setup, [
+ ['name' => 'id', 'value' => $user_id] // pass user identity
+ ]);
+
+ Render::view('templates/penalty', ['form' => $form]);
+
+ }
+
+
+
+ ## -------------------------------------------------------------------------
+ ##
+ ## ADMIN METHODS (insert, updated etc.)
+ ##
+ ## -------------------------------------------------------------------------
+
+
+ /** files
+ * echo all files
+ *
+ * @return (array)
+ */
+ public static function files()
+ {
+ return Cache_service::files_attributes();
+ }
+
+
+ /** upload_file
+ * upload the file to the file system
+ *
+ * the method reads the POST and FILES array
+ * to retrieve all needed parametres
+ *
+ * FILES @param file
+ * POST @param folder : petition's ID or somthing random
+ * SESSION @param user_id
+ */
+ public static function upload_file()
+ {
+ $request = Registry::get('REQUEST');
+
+ $uploaded = self::upload_to_fs(); // upload file to file-system
+
+ if ($uploaded['success']) {
+
+ $media_id = self::define_media([ // define media in database; get id
+ 'title' => $request->POST['title'],
+ 'type' => $uploaded['type'],
+ 'path' => $uploaded['path']
+ ]);
+
+ Render::json([ // render results as json
+ 'success' => true,
+ 'id' => $media_id,
+ 'title' => $request->POST['title'],
+ 'path' => $uploaded['path'],
+ 'type' => $uploaded['type']
+ ]);
+
+ } else {
+ Render::json(['success' => false ]);
+ }
+ }
+
+
+ /** upload to fs
+ * upload file to File-System
+ *
+ * POST @param folder
+ * FILES @param file
+ */
+ private static function upload_to_fs()
+ {
+ $post = Registry::get('REQUEST')->POST;
+ $files = Registry::get('REQUEST')->FILES;
+
+
+ // Checks before uploading the file
+ ////////////////////////////////////////////////////////////////////////
+
+ // ** 1: file is upladed to temporary folder ---------------------------
+ if (! is_uploaded_file($files['file']['tmp_name'])) {
+ return ['success' => false]; // bye!
+ }
+
+ // ** 2: File belongs to the allowed MIME types ------------------------
+ $allowed_file_types = [
+ // pdf
+ 'application/pdf',
+ // images
+ 'image/png', 'image/jpeg',
+ // word
+ 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ // excel
+ 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ // rar
+ 'application/vnd.rar', 'application/x-rar-compressed', 'application/octet-stream',
+ // zip
+ 'application/zip', 'application/x-zip-compressed', 'multipart/x-zip'
+ // 'application/octet-stream' refers to zip; also to rar (no-need to re-include)
+ ];
+ // Recomended MIME type checking via mime_content_type():
+ $mime_type = mime_content_type($files['file']['tmp_name']);
+ if (! in_array($mime_type, $allowed_file_types)) { // File type NOT allowed ...
+ return ['success' => false]; // bye!
+ }
+
+ $file_name = $files['file']['name'];
+ $file_type = $files['file']['type']; // do not take it for granted
+ $file_size = $files['file']['size'];
+ $file_tmp = $files['file']['tmp_name'];
+
+ $bare_name = pathinfo($file_name, PATHINFO_FILENAME);
+ $file_ext = pathinfo($file_name, PATHINFO_EXTENSION);
+
+
+ // ** 3: filename or size checks may be added --------------------------
+ if ($file_name == "") {
+ return ['success' => false]; // bye!
+ }
+
+
+ // READY to finaly save/upload the file to CDN /////////////////////////
+
+ $folder = MEDIA_STORAGE_ROOT . $post['folder'];
+ if (!file_exists($folder)) { // create folder if not exists
+ mkdir($folder, 0757, true);
+ }
+
+ // print_r([
+ // 'dir' => $folder,
+ // 'file' => $bare_name,
+ // 'ext' => $file_ext,
+ // 'type' => $file_type
+ // ]); die();
+
+ $relative_filename = $post['folder']
+ .'/'
+ . strtolower(self::clear_file_name($bare_name) .'.'. $file_ext);
+ $store_filename = MEDIA_STORAGE_ROOT . $relative_filename;
+
+ if (move_uploaded_file($files["file"]["tmp_name"], $store_filename)) {
+ return [
+ 'success' => true,
+ 'path' => $relative_filename,
+ 'type' => $mime_type
+ ];
+
+ } else { return ['success' => false]; }
+
+ }
+
+
+ /** clear_file_name
+ * replace greek characters and strip symbols
+ */
+ private static function clear_file_name($str)
+ {
+ $el = mb_split( "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωάέήίόύώϊϋς ", "");
+ $en = str_split("ABGDEZHUIKLMNJOPRSTYFXCVabgdezhuiklmnjoprstyfxcvaehioyviys-");
+ $strip = str_split("!@#$%^&*()+~`[]{};'/<>?=\"");
+
+ return str_replace($strip, '', str_replace($el, $en, $str));
+ }
+
+
+ /** define_media
+ *
+ * create a record in media table
+ *
+ * @param $data (array): [title => , path => , type => mime-type]
+ * @return id (int): id of created media record
+ */
+ private static function define_media($data)
+ {
+ $request = Registry::get('REQUEST');
+
+ $media_id = Registry::use('database')->query(
+ "INSERT INTO media (label, `type`, `path`)
+ VALUES (:label, :mimetype, :filepath)",
+ [
+ 'label' => $data['title'],
+ 'mimetype' => $data['type'],
+ 'filepath' => $data['path']
+ ]
+ )->lastInsertID();
+ return $media_id;
+ }
+
+
+ /** create media for petition
+ *
+ * links petition to each media-file of the media `id`s array
+ *
+ * @param $media (array): a list of media-file `id`s
+ * @param $petition_id (int)
+ */
+ private static function create_medias_for_petition($medias, $petition_id)
+ {
+ foreach($medias as $key => $medi) {
+ self::link_media_to_petition($medi, $petition_id); // link to petition
+ }
+ return true;
+ }
+
+ /** link one media-file to a specific post
+ *
+ * NOTE:
+ * the method does not check if media is linked already
+ * so be sure that the pair of (media_id,post_id) not exist
+ *
+ * @param $media_id (int)
+ * @param $petition_id (int)
+ */
+ private static function link_media_to_petition( $media_id, $petition_id )
+ {
+ Registry::use('database')->runQuery(
+ "INSERT INTO petition_media (petition_id, media_id)
+ VALUES (:petition, :media)",
+ [
+ 'petition' => $petition_id,
+ 'media' => $media_id,
+ ]
+ );
+ return true;
+ }
+
+
+}
diff --git a/public/app/extends/App_manager.php b/public/app/extends/App_manager.php
index 8e6ce95..b003015 100644
--- a/public/app/extends/App_manager.php
+++ b/public/app/extends/App_manager.php
@@ -53,7 +53,9 @@ class App_manager extends UserManager
}
-
+ /** ??
+ *
+ */
public function login_user()
{
diff --git a/public/app/extends/App_user.php b/public/app/extends/App_user.php
index 9aed489..6e93969 100644
--- a/public/app/extends/App_user.php
+++ b/public/app/extends/App_user.php
@@ -12,14 +12,6 @@ use Registry;
* this way it specializes the UserManagement
* according to this app's special rules
*
- * Add privileges concept
- * ---
- * A Class_user has privileges (which are deferent than Roles)
- * In fact, privileges extend the authorization requirements for users
- *
- * Authorized content is marked with some 'minimum Privilege'
- * So the content is available to the READER(s) that have certain Privileges
- *
*/
class App_user extends User
{
@@ -29,18 +21,20 @@ class App_user extends User
*/
private $id;
- /** user privileges
- * @var array
+ /** sex (gender)
+ * @var int (1 = male, 2 = female )
*/
- private $privileges = [];
+ private $sex;
/** user name
- * @var string
+ * @var string : first_name +' '+ last_name
*/
private $name;
+
+
/** SETTERS AND GETTERS
- * for id, name, privileges attributes
+ * for id, name, attributes
* -------------------------------------------------------------------------
*/
@@ -68,54 +62,55 @@ class App_user extends User
}
- // name
+ // sex
// --- -- -- - - -
- /** getName
+ /** getSex()
* @return int
*/
- public function getName(): string
+ public function getSex(): int
{
- return $this->name;
+ return $this->sex;
}
- /** setName()
+
+ /** setSex()
*
- * @param string : user's full name
+ * @param int : sex (id)
*
* @return User
*/
- public function setName(string $name): self
+ public function setSex(int $sex): self
{
- $this->name = $name;
+ $this->sex = $sex;
return $this;
}
-
- // privileges
+
+
+ // name
// --- -- -- - - -
- /** getPrivileges
- *
- * @return privileges (array)
+ /** getName
+ * @return string
*/
- public function getPrivileges(): array
+ public function getName(): string
{
- return $this->privileges;
+ return $this->name;
}
-
- /** setPrivileges()
+ /** setFirstName()
*
- * @param array $privileges
+ * @param string : user's full name
*
* @return User
*/
- public function setPrivileges(array $privileges): self
+ public function setName(string $name): self
{
- $this->privileges = $privileges;
+ $this->name = $name;
return $this;
}
-
+
+
} \ No newline at end of file
diff --git a/public/app/extends/Cache_service.php b/public/app/extends/Cache_service.php
index c435b75..05fd39e 100644
--- a/public/app/extends/Cache_service.php
+++ b/public/app/extends/Cache_service.php
@@ -36,25 +36,6 @@ class Cache_service
}
- public static function privileges_hierarchy( $options = 0 )
- {
- return proxy(
- [\app\models\Access_model::class, 'privileges'],
- [], CACHE_ROOT_TTL,
- $options
- );
- }
-
- public static function pages_list( $options = 0 )
- {
- return proxy(
- [\app\models\Cms_model::class, 'pages'],
- [], CACHE_ROOT_TTL,
- $options
- );
- }
-
-
/** entity
*
* create and retrieve a cached array of some entity
diff --git a/public/app/models/Access_model.php b/public/app/models/Access_model.php
index 8d446dc..8a2e5ce 100644
--- a/public/app/models/Access_model.php
+++ b/public/app/models/Access_model.php
@@ -3,6 +3,7 @@
namespace app\models;
use \Registry;
+use app\extends\App_manager;
use app\models\History_model;
class Access_model
@@ -148,36 +149,52 @@ class Access_model
}
- /** activate
+ /** activate_set_password
*
- * check if activation code is valid;
- * if valid, set account active;
+ * activate user and set password
*
* @param $ticket (hex/MD5): activation code;
*
*/
- public static function activate($ticket)
+ public static function activate_set_password($post, $password)
{
- $user = Registry::use('database')->query(
- "SELECT * FROM user WHERE activation = :ticket",
- [ 'ticket' => $ticket ]
- )->getFirst();
-
- // if no user with this activation code, return false
- if ($user === false) return false;
-
- // remove activation code from user record
- Registry::use('database')->runQuery(
+ // Update and set activate = true
+ $rowCount = Registry::use('database')->query(
"UPDATE user
- SET active = 1, `activation` = NULL
- WHERE activation = :ticket",
- [ 'ticket' => $ticket ]
- );
+ SET first_name = :first_name,
+ last_name = :last_name,
+ email = :email,
+ father_name = :father_name,
+ registration_number = :registration_number,
+ sector = :sector,
+ belonging_school = :belonging_school,
+ position = :position,
+ phone = :phone,
+ `password` = :password,
+ invitation = NULL,
+ active = :active
+ WHERE id = :id AND invitation = :invitation",
+ [
+ ':first_name' => $post['first_name'],
+ ':last_name' => $post['last_name'],
+ ':email' => $post['email'],
+ ':father_name' => $post['father_name'],
+ ':registration_number' => $post['registration_number'],
+ ':sector' => $post['sector'],
+ ':belonging_school' => $post['belonging_school'],
+ ':position' => $post['position'],
+ ':phone' => $post['phone'],
+ ':password' => $password,
+ ':active' => 1,
+ ':id' => $post['id'],
+ ':invitation' => $post['invitation']
+ ]
+ )->rowCount();
// update history
- History_model::trackUserAccess($user['id'], TRACK_ACCOUNT, 'User Account Activated');
+ History_model::trackUserAccess($post['id'], TRACK_ACCOUNT, 'User Account Activated');
- return true;
+ return $rowCount;
}
diff --git a/public/app/models/Cms_model.php b/public/app/models/Office_model.php
index fad11b8..fad11b8 100644
--- a/public/app/models/Cms_model.php
+++ b/public/app/models/Office_model.php
diff --git a/public/app/models/_info.md b/public/app/models/_info.md
index 82143bf..ac6d334 100644
--- a/public/app/models/_info.md
+++ b/public/app/models/_info.md
@@ -150,3 +150,24 @@ $myobject = new myclass();
call_user_func(array($myobject, 'say_hello'));
?>
+
+
+
+
+# APPlication
+
+\ controllers
+ [ ] App
+ [ ] Auth
+
+\ extends
+ [ ] Cache_service
+ [*] App_manager
+ [*] App_user
+ [ ] SendMail_service
+ [ ] Form_builder
+
+
+\ models
+ [ ] Access_model
+ [ ] History_model \ No newline at end of file
diff --git a/public/app/routes/backend.php b/public/app/routes/backend.php
index 1290f8a..6fbc157 100644
--- a/public/app/routes/backend.php
+++ b/public/app/routes/backend.php
@@ -1,9 +1,9 @@
<?php
-use app\controllers\Auth;
-use app\controllers\CmsAdmin;
-use app\models\admin\Privilege_model;
-use app\extends\Cache_service;
+//// use app\controllers\Auth;
+//// use app\controllers\CmsAdmin;
+//// use app\models\admin\Privilege_model;
+//// use app\extends\Cache_service;
/** admin pages
@@ -11,7 +11,7 @@ use app\extends\Cache_service;
* NOTE:
* All adminitration routes MUST INCLUDE an Auth::allowRoles() check
*/
-
+/*
// admin panel
////////////////////////////////////////////////////////////////////////////////
@@ -167,3 +167,4 @@ Route::add('/admin/api/pages', function () { // ajax: get all pages
CmsAdmin::all_pages();
});
+*/ \ No newline at end of file
diff --git a/public/app/routes/frontend.php b/public/app/routes/frontend.php
index 2defce5..b0e064b 100644
--- a/public/app/routes/frontend.php
+++ b/public/app/routes/frontend.php
@@ -1,8 +1,8 @@
<?php
use app\controllers\Auth;
-use app\controllers\Classroom_user;
-use app\controllers\Cms;
+use app\controllers\App_user;
+use app\controllers\Office;
use app\extends\Cache_service;
@@ -10,9 +10,16 @@ use app\extends\Cache_service;
////////////////////////////////////////////////////////////////////////////////
// Route::add('/', function() { Render::view('welcome'); });
-Route::add('/', function() { Render::view('user/registration'); });
+Route::add('/', function() { Render::view('user/login'); });
-Route::add('/penalty', function() { Render::view('templates/penalty'); });
+
+Route::add('/invitation/([0-9]*)', function($id) {
+ Auth::invitation($id);
+});
+
+Route::add('/petition/([0-9a-z\-_]*)', function($tag) {
+ Office::request_petition($tag);
+});
// Error pages
////////////////////////////////////////////////////////////////////////////////
diff --git a/public/app/routes/user.php b/public/app/routes/user.php
index 146b212..a2d48d6 100644
--- a/public/app/routes/user.php
+++ b/public/app/routes/user.php
@@ -13,29 +13,28 @@ use app\controllers\Classroom_user;
// request login ... -> then sends to POST:/account/check-login
Route::add('/login', function() { Render::view('user/login'); });
-// request registration ... -> then sends to POST:/account/register
-Route::add('/registration', function() { Render::view('user/registration'); });
-
// request logout
Route::add('/logout', function() {
Auth::logout();
header('Location: /'); die();
});
-// request activation
-Route::add('/account/activate', function() { Auth::activate(); } );
+// request activation (from invitation page; POST:form is sent)
+Route::add('/account/activate', function() { Auth::activate(); }, 'post');
// request password reset
Route::add('/account/reset_password', function() { Auth::reset_password(); } );
-// invite
+// invite some users
Route::add('/invite', function() {
Auth::allowRoles([1, 2, 3]);
Render::view('admin/invite');
});
-
+Route::add('/panel', function() {
+ Render::json(['connected' => Auth::is_connected()]);
+});
// Replies to common requests (POST method)
// --- -- -- - - -
diff --git a/public/app/views/error/404.php b/public/app/views/error/404.php
index a085830..41f17da 100644
--- a/public/app/views/error/404.php
+++ b/public/app/views/error/404.php
@@ -7,7 +7,6 @@
*
* optional @var $error_code (int) : error code
* optional @var $moto (string) : super-mini description text
- * optional @var $message (string)
*
*/
@@ -15,14 +14,14 @@
$error_code = 404; // set default (404)
}
- http_response_code(403);
+ http_response_code($error_code);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
- <title>404: Not Found</title>
+ <title><?=$error_code?> : <?= $moto ?? 'Not found' ?></title>
<style>
html,body{
@@ -52,13 +51,10 @@
<body>
<div class='container'>
<div class='content'>
+
<h3><?=$error_code?></h3>
<?= $moto ?? 'Not found' ?><br />
- <!--
- —
- <br />
- <span><?= $message ?? "and I still haven't found what I'm looking for." ?></span>
- -->
+
</div>
</div>
</body>
diff --git a/public/app/views/templates/penalty.php b/public/app/views/templates/penalty.php
index 6a8f563..bbd7b4a 100644
--- a/public/app/views/templates/penalty.php
+++ b/public/app/views/templates/penalty.php
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
- <title><?=SITE_TITLE?> - Εγγραφή</title>
+ <title><?=SITE_TITLE?> - Πρακτικό Πειθαρχικής Υπόθεσης</title>
<?php // header includes
////////////////////////////////////////////////////////////////////////
@@ -56,14 +56,8 @@
<div class='content-form'>
<form method="post">
<div>
- <p>1o Γυμνάσιο Ραφήνας /<br />
- Πλατφόρμα ηλεκτρονικών αιτήσεων και δημιουργίας διαδικαστικών εγγράφων</p>
- <h2>Πρόσκληση #</h2>
-
- <?php
- $form = JsonToForm::make_a_form(PENALTY_FORM);
- ?>
+ <h2>Πρακτικό Πειθαρχικής Υπόθεσης</h2>
<?=$form['html']?>
@@ -122,6 +116,8 @@
<?=$form['init_js']?>
+
+ <?=$form['values_js']?>
</script>
</html>
diff --git a/public/app/views/user/registration.php b/public/app/views/user/invitation.php
index 9eb0ea3..eb34bc4 100644
--- a/public/app/views/user/registration.php
+++ b/public/app/views/user/invitation.php
@@ -43,7 +43,7 @@
label { font-size: 14px; }
</style>
</head>
-<body class="classroom">
+<body class="office">
<div class='container'>
<div class="content">
<div class="info">
@@ -58,10 +58,6 @@
<h2>Πρόσκληση #</h2>
- <?php
- $form = JsonToForm::make_a_form(REGISTRATION_FORM);
- ?>
-
<?=$form['html']?>
<br />
@@ -80,42 +76,104 @@
</body>
<script>
+var values = {};
+var empty = '';
+
+$(document).ready(function() {
+
+ /** select2_set_text
+ * select an (select2-)option by text
+ *
+ * @param control = jquery selector,
+ * @param t (string) = text of option
+ */
+ function select2_set_text(control, t) { /* define function */
+ opts = control.select2()[0].options;
+ var id;
+ for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
+ control.val(id).trigger('change');
+ }
+
+ /** get_id_of_text
+ * get id (=value) of an option with `t` text
+ *
+ * @param control = jquery selector,
+ * @param t (string) = text of option
+ */
+ function get_id_of_text( control , t) { /* define id from text */
+ opts = control.select2()[0].options;
+ var id = false;
+ for(i=0; i<opts.length; i++) { if (opts[i].text == t) id = i; }
+ return id;
+ }
+
+ /** select2_set_multi_text
+ * select several (select2-)options by text
+ *
+ * @param control = jquery selector,
+ * #param t_list (string) = list of selected texts
+ */
+ function select2_set_multi_text(control, t_list) { /* define function */
+ var ids = [];
+ t_list.forEach (t => { let id = get_id_of_text(control, t);
+ if (id !== false) ids.push(id);
+ })
+ control.val(ids).change();
+ }
+
+
+ <?=$form['init_js']?>
+
+ <?=$form['values_js']?>
+
// When form is submited
// -------------------------------------------------------------------------
- $('.content-form form').submit( event => {
+ $('form').submit( event => {
event.preventDefault();
- if ($('input[name=password]').val() != $('input[name=password2]').val()) {
- alert('Τα δυο passrods δεν ταιριάζουν!');
+ if ($('input[name=password]').val() != $('input[name=confirm_password]').val()) {
+ alert('Τα δυο κωδικοί πρόσβασης δεν ταιριάζουν!');
+
+ } else if ($('input[name=password]').val() == "") {
+ alert('Ο κωδικός πρόσβασης δεν μπορεί να είναι κενός')
- } else {
+ } else if ( ($('input[name=password]').val() == '0')
+ || ($('input[name=password]').val() =='') ) {
+ alert('Παρκαλώ συμπληρώστε ένα τηλέφωνο επικοινωνίας')
+ } else {
// prepare data to POST
var data = {
+ // identification fields
+ id: $('input[name=id]').val(),
+ invitation: $('input[name=invitation]').val(),
+ // data fields
first_name: $('input[name=first_name]').val(),
last_name: $('input[name=last_name]').val(),
+ father_name: $('input[name=father_name]').val(),
email: $('input[name=email]').val(),
registration_number: $('input[name=registration_number]').val(),
- sector: $('input[name=sector]').val(),
+ sector: $('select[name=sector]').select2('data')[0].text,
belonging_school: $('input[name=belonging_school]').val(),
- working_shcool: $('input[name=working_shcool]').val(),
- position_type_id: $('input[name=position_type_id]').val(),
+ position: $('select[name=position]').select2('data')[0].text,
phone: $('input[name=phone]').val(),
+ // access verification
password: $('input[name=password]').val()
};
-
- // select action url (add or update)
- var request = '/account/register';
+ // console.log('post:', data);
+
+ var request = '/account/activate'; // set action url
// send POST request
$.post(request, data)
.done(function( data ) {
- $('.classroom .content-form').html(data.message)
+ $('.office .content-form').html(data.message)
});
- }
-
+ }
});
-</script>
+
+});
+</script>
</html>
diff --git a/public/app/views/welcome.php b/public/app/views/welcome.php
index e97f748..fd3f703 100644
--- a/public/app/views/welcome.php
+++ b/public/app/views/welcome.php
@@ -26,15 +26,14 @@ select option { font-size: .87rem; }
</head>
<body class='classroom'>
<div class="container" style="max-width: 640px;">
- <div class="row">
+ <div class="row">
- <?php
- $form = JsonToForm::make_a_form(REGISTRATION_FORM);
- ?>
+<?php
+ $form = JsonToForm::make_a_form(REGISTRATION_FORM);
+?>
+<?=$form['html']?>
- <?=$form['html']?>
-
- </div>
+ </div>
</div>
@@ -196,6 +195,8 @@ $('.select-field').select2({ width: '100%' });
// ---------------------------------------------------------------------------
<?=$form['init_js']?>
+<?=$form['values_js']?>
+
// 04. FORM-LOGIC
// ---------------------------------------------------------------------------