summaryrefslogtreecommitdiff
path: root/public/includes
diff options
context:
space:
mode:
Diffstat (limited to 'public/includes')
-rw-r--r--public/includes/functions.php135
-rw-r--r--public/includes/menu-contents.php50
-rw-r--r--public/includes/menu.php16
-rw-r--r--public/includes/sessions.php143
-rw-r--r--public/includes/ui-login.php98
-rw-r--r--public/includes/ui-message.php47
-rw-r--r--public/includes/ui-panel.php141
7 files changed, 630 insertions, 0 deletions
diff --git a/public/includes/functions.php b/public/includes/functions.php
new file mode 100644
index 0000000..5e83994
--- /dev/null
+++ b/public/includes/functions.php
@@ -0,0 +1,135 @@
+<?php
+
+## Help Constants and Functions ------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+
+ // Cache fields options (json format) ////////////////////////////////////////
+ // ---------------------------------------------------------------------------
+ $formJSON = file_get_contents('config/kallassa.json');
+ define("FORMJSON", $formJSON);
+
+ // Cache CCODE attributes (json format) //////////////////////////////////////
+ // ---------------------------------------------------------------------------
+ $codeJSON = file_get_contents('config/ccode.json');
+ define("CODEJSON", $codeJSON);
+
+ // Parse anythig from a field ////////////////////////////////////////////////
+ // ARGS:
+ // $fkey = keyname (as in json fields oprions)
+ // $inp = input value (string)
+ // RETURN: array(
+ // 'label' = field label,
+ // 'multi' = (true|false) is multiple choice (select|radio|check) or not,
+ // 'value' = human readable value (or array of values if multi)
+ // ) -------------------------------------------------------------------------
+ function parse_any($fkey, $inp ="") {
+ $formARRAY = json_decode(FORMJSON);
+
+ foreach ($formARRAY as $key => $section) {
+ foreach ($section->childs as $kk => $field) {
+
+ // find the field
+ if ($field->nam == $fkey) {
+
+ $values = array(); // human readble values if select (comma separated)
+
+ if ($field->typ == 'select') {
+ $multi = true;
+
+ if ($inp !='') {
+ $codes = explode(",", $inp); // split coded values
+ foreach ($field->opt as $kkk => $v) {
+ if (in_array($v->id, $codes)) { // check if option is in array
+ $values[] = ($field->nam == 'ccode') ? ($v->id.": ".$v->tag) : $v->tag;
+ }
+ }
+ }
+
+ }
+ else $multi = false;
+
+ // return everything in an array
+ return array(
+ 'label' => $field->lab,
+ 'multi' => $multi,
+ 'value' => ($multi ? $values : $inp)
+ );
+ }
+ }
+ }
+
+ // if not escaped already, then name return same
+ return array('label' => $fkey, 'multi' => false, 'value' => $inp );
+ }
+
+ // Parse anythig from ccode
+ function parse_ccode($ckey) {
+ $ccARRAY = json_decode(CODEJSON);
+
+ foreach ($ccARRAY as $key => $val) {
+ // find the field
+ if ($val->id == $ckey) {
+ // return everything in an array
+ return $val;
+ }
+ }
+ }
+
+
+ // Get totals of alla categories /////////////////////////////////////////////
+ // RETURN array of items (value) per category (array key)
+ // ---------------------------------------------------------------------------
+ function get_totals() {
+ $result = array();
+ $sum = 0;
+
+ $dbc = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DBMS);
+ if ($dbc->connect_errno) {
+ echo "Database connection failed; Please try in a few minutes. ";
+ if (TESTING) echo $dbc->connect_error;
+ $dbc->close(); die();
+ }
+ $dbc->set_charset("utf8");
+
+ // prepare statemet
+ $stm = $dbc->prepare("SELECT ccode, count(id) total FROM `items` GROUP BY ccode");
+ $stm->execute(); // execute query
+ $stm->store_result(); // store result
+ $stm->bind_result($c, $tot);
+ while ($stm->fetch()) {
+ // using md5() you can have any unicode string as key ;)
+ // credit: https://stackoverflow.com/questions/10696067/characters-allowed-in-php-array-keys -> Rob's answer
+ // but newer versions of php (v7+) seem to handle unicide keys nicely
+ $result[$c] = $tot;
+ $sum += $tot;
+ }
+
+ $result['all'] = $sum;
+
+ return $result;
+ }
+
+
+ // Preview Local Datetime ////////////////////////////////////////////////////
+ // (in Greek format and names )
+ // ---------------------------------------------------------------------------
+ function local_dt($t) {
+ $day = array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
+ $dayL = array("Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ");
+ $mon = array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
+ $monL = array("Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαϊ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ");
+ $tm = array("am", "pm");
+ $tmL = array("πμ", "μμ");
+ $r = date("D. j M. Y, h:i:sa", $t);
+ $r = str_replace($day, $dayL, $r);
+ $r = str_replace($mon, $monL, $r);
+ $r = str_replace($tm, $tmL, $r);
+ return $r;
+ }
+
+
+ // Part of string
+ // UTF-8 SAFE
+ function str_part($str, $len) {
+ return (mb_strlen($str) > $len) ? mb_substr($str, 0, $len-1) ."…" : $str;
+ }
diff --git a/public/includes/menu-contents.php b/public/includes/menu-contents.php
new file mode 100644
index 0000000..7cdee94
--- /dev/null
+++ b/public/includes/menu-contents.php
@@ -0,0 +1,50 @@
+<?php
+ // dropdown-item(s)
+ // -------------------------------------------------------------------------
+ // * are hosting the main menu options
+ // * are called via javascript (one script for all)
+ // * behaviour options are passed through data-* attributes
+ // --- -- -- - - -
+ // Format of data-goto attribute : {method} , {location-url}
+ // * method : url (goto url asap) | ajax (goto url after ajax request succeded)
+ // * location-url : the url to call
+?>
+<a class="dropdown-item disabled" href="#"></a>
+
+<?php if ((ROLE) && (ROLE != ADMIN)) : ?>
+ <a class="dropdown-item" data-goto="url,/" href="#">Πίνακας Ελέγχου</a>
+ <a class="dropdown-item" data-goto="url,ui-new-item.php" href="#">Εισαγωγή Αντικειμένου</a>
+ <a class="dropdown-item" data-goto="url,ui-search.php" href="#">Αναζήτηση</a>
+<?php endif; ?>
+
+
+<div class="dropdown-divider"></div>
+
+
+<!-- Catalog Management -->
+<?php if (ROLE >= ADMIN) : ?>
+
+ <a class="dropdown-item disabled" href="#">Αρχειοθέτηση</a>
+ <a class="dropdown-item" data-goto="url,ui-catalogs.php" href="#">Κατάλογοι Αντικειμένων</a>
+ <a class="dropdown-item" data-goto="url,ui-backup.php" href="#">Τοπικό Backup</a>
+
+<?php endif; ?>
+
+
+<div class="dropdown-divider"></div>
+
+
+
+<a class="dropdown-item disabled" href="#">Χρήστες</a>
+
+<a class="dropdown-item" data-goto="url,ui-profile.php" href="#">Προφίλ Χρήστη</a>
+
+<?php if (ROLE >= ADMIN) : ?>
+ <a class="dropdown-item" data-goto="url,ui-user-management.php" href="#">Διαχείριση Χρηστών</a>
+<?php endif; ?>
+
+
+<div class="dropdown-divider"></div>
+
+
+<a class="dropdown-item" data-goto="ajax,ajax.php?do=logout" href="#">Αποσύνδεση</a>
diff --git a/public/includes/menu.php b/public/includes/menu.php
new file mode 100644
index 0000000..754a805
--- /dev/null
+++ b/public/includes/menu.php
@@ -0,0 +1,16 @@
+
+<!-- menu -->
+<div id="pi-menu">
+ <div class="dropdown">
+ <a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdown-Menu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+ Μενού Εργασιών
+ </a>
+
+ <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
+ <?php
+ include("includes/menu-contents.php")
+ ?>
+ </div>
+ </div>
+</div>
+<!-- / menu -->
diff --git a/public/includes/sessions.php b/public/includes/sessions.php
new file mode 100644
index 0000000..d33aa30
--- /dev/null
+++ b/public/includes/sessions.php
@@ -0,0 +1,143 @@
+<?php
+// reset admin if needed
+/* ---
+ $user = "admin@kallassa.dev";
+ $pass = "1234!@!@";
+ $time = time();
+ $role = 5;
+ $salt = md5(rand(0,9999) .$time. rand(0,9999));
+ $pass = md5($user.$salt.$pass);
+ $name = "Θάλεια Μελίσσα";
+ $acid = 0;
+
+ // init database connection
+ $_dbc = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_DBMS);
+ if ($_dbc->connect_errno) {
+ $_cError = "Database connection failed; Please try in a few minutes. ";
+ if (TESTING) echo $_dbc->connect_error;
+ $_dbc->close(); die();
+ }
+ $_dbc->set_charset("utf8");
+
+ $_hack = $_dbc->prepare("INSERT INTO users (user, salt, pass, acid, role, birthstamp, realname) VALUES (?, ?, ?, ?, ?, ?, ?)");
+ $_hack->bind_param( "sssiids", $user, $salt, $pass, $acid, $role, $time, $name );
+ $_chk = $_hack->execute();
+ if ((TESTING) && (!$_chk)) echo "Database workaround failed; ". $_hack->error;
+ else echo "Workaround succeded!";
+ $_hack->close();
+ die();
+--- */
+
+
+
+// -- 00. INITIALIZATION ///////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+session_name(MAIN_COOKIE); // set a custom session name
+session_start();
+
+
+if ( (isset($_SESSION['user_status'])) && ($_SESSION['user_status'] == 1) ) {
+ define("ROLE", $_SESSION['role']);
+}
+else
+ define("ROLE", 0);
+
+// -- 01. Session Functions needed /////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// check session existance -----------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+ function check_session_existance__() {
+ // session should exist from the first time of code
+ // what really matters is if has certain keys
+ if (!isset($_SESSION['user_status'])) {
+ $_SESSION['user_status'] = 0;
+ }
+ }
+
+// check and update SESSION ID -------------------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+ function check_update_session__() {
+ if (!isset($_SESSION['sess_update'])) {
+ $_SESSION['sess_update'] = time() + SESSION_UPD; // set sess_uddate limt if not exist
+ }
+ else if ($_SESSION['sess_update'] < time()) { // session needs to update id to mitigate session fixation
+ session_regenerate_id(); // change session ID (invalidate old session ID)
+ $_SESSION['sess_update'] = time() + SESSION_UPD; // shall re-update after SESS_UPD seconds
+ }
+ }
+
+// check and remove SESSION if expired -----------------------------------------
+////////////////////////////////////////////////////////////////////////////////
+ function check_kill_session__() {
+
+ if (isset($_SESSION['sess_expire']) && ($_SESSION['sess_expire'] < time())) {
+ session_unset(); // unset $_SESSION variable for the run-time
+ session_destroy(); // destroy session data in storage before continue
+ session_start();
+ session_regenerate_id();
+
+ // TODO:
+ // should you save any data|indo before destroy?
+ }
+ $_SESSION['sess_expire'] = time() + SESSION_TTL; // set new expire limit;
+ }
+
+// common session data ---------------------------------------------------------
+// format: json | string | array | or other format of data
+// (includes data for user's browser via cookie)
+////////////////////////////////////////////////////////////////////////////////
+ function common_session_data__($format = 'json') {
+
+ if ((isset($_SESSION['uid'])) && (isset($_SESSION['role']))) {
+ $arr = array(
+ "uid" => $_SESSION['uid'],
+ "name" => $_SESSION['realname'],
+ "role" => $_SESSION['role']
+ );
+ }
+ else $arr = array(
+ "uid" => '', "name" => '', "role" => ''
+ );
+
+ switch ($format) {
+ case 'array':
+ return $arr;
+ break;
+
+ case ('semicolon'):
+ case (';'):
+ return implode(";", $arr);
+ break;
+
+ default:
+ return json_encode($arr);
+ break;
+ }
+ }
+
+
+
+
+
+// -- 02. Handle Security Issues ///////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// do it every time nomater what
+
+check_session_existance__();
+
+check_kill_session__();
+
+check_update_session__();
+
+
+// check_login_attempts__()
+// check_inquire_attempts__()
+ // TODO
+ // all these should become a single function
+ // this function shall validate all session's keys
+ // print_r($_SESSION); die();
diff --git a/public/includes/ui-login.php b/public/includes/ui-login.php
new file mode 100644
index 0000000..8ab4d9b
--- /dev/null
+++ b/public/includes/ui-login.php
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB" dir="ltr">
+ <head>
+ <!-- Metas + Title -->
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+
+ <title><?=PROJECT?> : Είσοδος</title>
+
+ <!-- CSS needed -->
+ <link rel="stylesheet" href="/css/bootstrap.min.css" /><!-- v4.4.1 -->
+ <link rel="stylesheet" href="/css/select2.min.css" /><!-- v4.0.10 -->
+ <link rel="stylesheet" href="/css/pi.css" />
+ </head>
+ <body>
+
+ <div class="login-container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2><?=PROJECT?></h2>
+ <h4>Είσοδος στη βάση δεδομένων</h4>
+ <hr />
+
+ <form id="kallassa-login" method="post">
+
+ <div class="form-group">
+ <label for="user">Email χρήστη</label>
+ <input class="form-control" type="email" name="email" required>
+ </div>
+ <div class="form-group">
+ <label for="pass">Κωδικός πρόσβασης</label>
+ <input class="form-control" type="password" name="pass" required>
+ </div>
+ <br />
+
+ <input class="btn btn-primary" type="submit" value="Πιστοποίηση Χρήστη">
+
+ </form>
+
+ </div>
+ </div>
+ </div>
+
+ <!-- scripts and libraries
+ load and register one by one, so you don't need to worry about if they are ready -->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.4.1/jquery-migrate.min.js"></script>
+ <script src="/js/bootstrap.min.js"></script>
+ <script>
+ // LOGIN
+ // -------------------------------------------------------------------------
+ $('#kallassa-login').on('submit', function (e) {
+ if (e.isDefaultPrevented()) { // handle the invalid form...
+ alert('WTF validation error');
+ }
+ else { // everything looks good!
+
+ var postUrl = "/ajax.php?do=login";
+ var data2send = {
+ user : $('#kallassa-login input[name=email]').val(),
+ pass : $('#kallassa-login input[name=pass]').val()
+ };
+
+ $.ajax({
+ type: "POST",
+ url: postUrl,
+ data: data2send,
+ success: function(data) {
+ var json = $.parseJSON(data);
+ // ** Workaround
+ // ** for server may handle respond as json ready
+ // ** var json = data
+
+ if (json.success) { // good! user is ok
+
+ // reset form
+ $('#kallassa-login').trigger("reset");
+
+ // and goto root (will load control panel)
+ window.location.href = '/';
+
+ }
+ else { // nope!
+ alert("Login Failed; try again.");
+ }
+
+ },
+ error: function() { alert('WTF ajax error'); }
+ });
+ return false;
+ }
+ });
+
+ </script>
+
+ </body>
+</html>
diff --git a/public/includes/ui-message.php b/public/includes/ui-message.php
new file mode 100644
index 0000000..55ff531
--- /dev/null
+++ b/public/includes/ui-message.php
@@ -0,0 +1,47 @@
+<?php
+if (!defined("PROJECT")) {
+ define("PROJECT", "Application Error");
+}
+if (!isset($deny)) {
+ $deny = array(
+ 'head' => 'Application Error!',
+ 'message' => "<p>Παρακαλώ ενημερώστε τον διαχειριστή του συστήματος. Στη σχετική ενημέρωση επισυνάψτε τα παρακάτω στοιχεία:</p>
+ <pre style='font: 11px 700 \"Ununt Mono\", Consolas, Monaco, Courier, monospace; white-space: pre-wrap; color:#b32;'>".
+ "\n". ((isset($_SERVER['REQUEST_URI'])) ? "URI: ".$_SERVER['REQUEST_URI'] : "") .
+ "\n". ((isset($_SERVER['REQUEST_METHOD'])) ? "Method: ".$_SERVER['REQUEST_METHOD'] : "") .
+ "\n". ((isset($_SERVER['HTTP_USER_AGENT'])) ? "Agent: ".$_SERVER['HTTP_USER_AGENT'] : "") .
+ "\nTimestamp: ". time() . ((isset($_SERVER['HTTP_REFERER'])) ? "\nRef: ".$_SERVER['HTTP_REFERER'] : "") ."</pre>"
+ );
+}
+?><!DOCTYPE html>
+<html prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB" dir="ltr">
+ <head>
+ <!-- Metas + Title -->
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+
+ <title><?=PROJECT?> : Message</title>
+
+ <!-- CSS needed -->
+ <link rel="stylesheet" href="/css/bootstrap.min.css" /><!-- v4.4.1 -->
+ <link rel="stylesheet" href="/css/pi.css" />
+ </head>
+ <body>
+
+ <div class="login-container">
+ <div class="row">
+ <div class="col-md-12">
+ <h2><?=PROJECT?></h2>
+ <h4><?=$deny['head']?></h4>
+ <hr />
+ <div><?=$deny['message']?></div>
+ <br />
+ <hr />
+
+ </div>
+ </div>
+ </div>
+
+ </body>
+</html>
diff --git a/public/includes/ui-panel.php b/public/includes/ui-panel.php
new file mode 100644
index 0000000..1f40803
--- /dev/null
+++ b/public/includes/ui-panel.php
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html prefix="og: http://ogp.me/ns#" xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-GB" lang="en-GB" dir="ltr">
+ <head>
+ <!-- Metas + Title -->
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+
+ <title><?=PROJECT?> : Πίνακας Ελέγχου</title>
+
+ <!-- CSS needed -->
+ <link href="https://fonts.googleapis.com/css?family=Ubuntu:400,700&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="/css/bootstrap.min.css" /><!-- v4.4.1 -->
+ <link rel="stylesheet" href="/css/select2.min.css" /><!-- v4.0.10 -->
+ <link rel="stylesheet" href="/css/pi.css" />
+ </head>
+ <body>
+
+ <div class="pi-container">
+ <div class="row">
+
+ <div class="col-md-12">
+ <h2><?=PROJECT?></h2>
+ </div>
+
+ <!-- menu section -->
+ <div class="col-md-4 col-lg-3">
+ <h4>Πίνακας Ελέγχου</h4>
+ <hr />
+ <?php
+ include("includes/menu-contents.php")
+ ?>
+ </div>
+ <!-- / menu section -->
+
+ <div class="col-md-8 col-lg-9 panel-sections">
+
+ <!-- statistics section -->
+ <?php if (ROLE > EDITOR) : ?>
+ <p>
+ <a class="btn btn-warning" data-toggle="collapse" href="#collapse-stats" role="button">Στατιστικά</a>
+ </p>
+ <div class="collapse show stats" id="collapse-stats">
+ <div class="card card-body">
+ <table>
+ <?php
+ $stats = get_totals();
+ $ccAr = json_decode(CODEJSON);
+ foreach ($ccAr as $key => $val) {
+ if (isset($stats[$val->id])) {
+ echo "<tr>
+ <td><span>". $val->id ."</span> ". $val->tag . "<a class='btn btn-pi-light' href='/ui-search.php?id=". $val->id ."'>Αναζήτηση</a></td>
+ <td style='width:45px; text-align:right;'>". $stats[$val->id] ."</td>
+ </tr>
+ ";
+ }
+ }
+ ?>
+ <tr class="summary"><td>Σύνολο</td><td style='width:45px; text-align:right;'><?=$stats['all']?></td></tr>
+ </table>
+ </div>
+ </div>
+ <?php endif; ?>
+ <!-- / statistics section -->
+
+ <!-- last items section -->
+
+ <!-- / last items section -->
+
+ <!-- edits history -->
+ <!-- / edits history -->
+
+ </div>
+
+ </div>
+ </div>
+
+
+
+
+
+ <!-- scripts and libraries
+ load and register one by one, so you don't need to worry about if they are ready -->
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-migrate/1.4.1/jquery-migrate.min.js"></script>
+ <script src="/js/bootstrap.min.js"></script>
+ <script>
+
+ // functions needed
+ // ---------------------------------------------------------------------------
+
+ // pure JS ajax GET request
+ // return data as JSON
+ // no fancy things like UTF8; if needed use base64 ---------------------------
+ function ajax_get(url, callback) {
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+
+ try {
+ var data = JSON.parse(xmlhttp.responseText);
+ } catch(err) {
+ console.log(err.message + " in " + xmlhttp.responseText);
+ return;
+ }
+ callback(data);
+ }
+ };
+
+ xmlhttp.open("GET", url, true);
+ xmlhttp.send();
+ }
+
+ // menu management
+ // ---------------------------------------------------------------------------
+ $('.dropdown-item').on('click', function(e){
+ e.preventDefault();
+
+ // all data-goto have the format: 'method,uri_address'
+ // uri_address is the url to call
+ // method options:
+ // * url : means goto url (redirect)
+ // * ajax : means call url via ajax; if 'success = true' then goto '/' after that
+ // -------------------------------------------------------------------------
+ var opt = $(this).data('goto').split(','); // split data-goto
+
+ if (opt[0] == 'url') { // if method = url
+ window.location.href = opt[1];
+ }
+ else { // else, method = ajax
+ ajax_get(opt[1], function(response) {
+ if (response.success) {
+ window.location.href = '/';
+ }
+ });
+ }
+ });
+ </script>
+
+ </body>
+</html>