\n"; echo ''; echo '
';
    switch ($e->getCode()) {
        case 2002:
            echo "Unable to connect to database, perhaps host info is wrong.\n";
            break;
        case 1044:
        case 1045:
            // access denied to db or generic access denied
            echo "Unable to connect to database, perhaps username or password is wrong.\n";
            break;
        case 1049:
            echo "Unable to connect to database, perhaps database name is wrong.\n";
            break;
        default:
            print_r($e);
    }
    echo '
'; echo ''; exit(1); } $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); # $pdo->query("SET lc_time_names='de_DE'"); try { $sth = $pdo->query("SELECT valint FROM settings WHERE userid=0 AND sno=0"); } catch (PDOException $e) { if ($e->getCode() == 1146) { echo '
';
        echo 'Settings table not found! Perhaps database is not initialized';
        echo '
'; exit(1); } } $g_db_scheme_version = $sth->fetchColumn(); // TODO Check version $user = User::GetInstance(); // There can be only one if ($g_scriptname != 'login.php') { $user->init_from_session(); $user->load_vessel(); $user->load_settings(); } $action = NULL; $valid = FALSE; // document storage $g_doc_mimetypes = ['image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf']; // form option lists $g_opt_all = array(-2 => _('― all ―')); $g_opt_none = array(-1 => _('― none ―')); $g_opt_empty = array('' => _('― none ―')); $g_opt_unknown = array(-1 => _('― unknown ―')); // Initialize message system $g_message = new Message; $g_success = new MessageSuccess; $g_warning = new MessageWarning; $g_error = new MessageError; // ========== MESSAGE FUNCTIONS =============================================== class Message { var $count = 0; var $text = array(); var $caption; var $alertclass; function __construct() { $this->caption = _('Information'); $this->alertclass = 'alert-info'; if (isset($_SESSION['message']['info'])) { $this->Add($_SESSION['message']['info']); unset($_SESSION['message']['info']); } } function SetCaption($str) { $this->caption = $str; } function Add($msg) { $this->count++; $this->text[$this->count] = $msg; } function GetCount() { return $this->count; } function PrintOut() { if ($this->count > 0) { echo '\n"; } } } class MessageSuccess extends Message { function __construct() { $this->caption = _('Success'); $this->alertclass = 'alert-success'; if (isset($_SESSION['message']['succ'])) { $this->Add($_SESSION['message']['succ']); unset($_SESSION['message']['succ']); } } } class MessageWarning extends Message { function __construct() { $this->caption = _('Warning'); $this->alertclass = 'alert-warning'; if (isset($_SESSION['message']['warn'])) { $this->Add($_SESSION['message']['warn']); unset($_SESSION['message']['warn']); } } } class MessageError extends Message { function __construct() { $this->caption = _('Error'); $this->alertclass = 'alert-danger'; if (isset($_SESSION['message']['err'])) { $this->Add($_SESSION['message']['err']); unset($_SESSION['message']['err']); } } } // ========== USER FUNCTIONS ================================================== class User { private static $instance = NULL; private $loggedin; private $errormessage; public $id; public $login; public $displayname; public $role; public $flags; public $vid; // current selected vessel public $vessel; // name of current vessel public $datefmt; public $rows_pp; public $menu; private function __construct() { global $g_rows_pp; $this->loggedin = FALSE; $this->errormessage = NULL; $this->flags = []; $this->vid = 1; $this->vessel = 'Yacht'; $this->datefmt = 'Y-m-d'; $this->rows_pp = $g_rows_pp; $this->menu = [1, 2, 3, 4, 5, 6]; } public static function getInstance() { if (self::$instance == NULL) { self::$instance = new User(); } return self::$instance; } function login($user_name, $user_pass) { global $pdo; if ($user_name == '' or $user_pass == '') { $this->loggedin = FALSE; $this->errormessage = _('Username or password was empty'); return FALSE; } $sql = "SELECT userid, pass, displayname, role, flags FROM user WHERE login=?"; $sth = $pdo->prepare($sql); $sth->execute([$user_name]); $row = $sth->fetch(PDO::FETCH_OBJ); $this->role = $row->role; $this->flags = array_filter(explode(',', $row->flags)); if ($row->flags != 0 ) { // deleted or locked, intentionally not return detailed reason $this->errormessage = _('User account does not exist'); } elseif (password_verify($user_pass, $row->pass)) { // password check successful $_SESSION['userid'] = $row->userid; $this->loggedin = TRUE; $target = $_SESSION['prelogin'] ?? 'index.php'; unset($_SESSION['prelogin']); header_location($target); } else { $this->errormessage = _('Username or password invalid'); } return FALSE; } function logout() { global $pdo; // remove session completely $_SESSION = array(); if (ini_get("session.use_cookies")) { $params = session_get_cookie_params(); setcookie(session_name(), '', time() - 42000, $params["path"], $params["domain"], $params["secure"], $params["httponly"] ); } session_destroy(); } function init_from_session() { global $pdo; if (!isset($_SESSION['userid'])) { $this->loggedin = FALSE; $this->errormessage = _('User not logged in'); $this->id = NULL; return; } $this->id = $_SESSION['userid']; $sql = "SELECT displayname, role FROM user WHERE userid=?"; $sth = $pdo->prepare($sql); $sth->execute([$this->id]); $row = $sth->fetch(); if ($row) { $this->displayname = $row['displayname']; $this->role = $row['role']; } } function load_vessel() { global $pdo; $sql = "SELECT v.vid, v.vesselname " . "FROM settings AS s INNER JOIN vessel AS v ON s.valint=v.vid " . "WHERE s.userid=? and s.sno=1"; $sth = $pdo->prepare($sql); $sth->execute([$this->id]); $row = $sth->fetch(); if ($row) { $this->vid = $row['vid']; $this->vessel = $row['vesselname']; } } function load_settings() { global $pdo; // additional user settings // date format from user settings $sql = "SELECT valstr FROM settings WHERE userid=? AND sno=2"; $sth = $pdo->prepare($sql); $sth->execute([$this->id]); $user_datefmt = $sth->fetchColumn(); if ($user_datefmt) { $this->datefmt = $user_datefmt; } // pagination rows from user settings $sql = "SELECT valint FROM settings WHERE userid=? AND sno=10"; $sth = $pdo->prepare($sql); $sth->execute([$this->id]); $user_rows_pp = $sth->fetchColumn(); if ($user_rows_pp) { $this->rows_pp = $user_rows_pp; } // user defined menu $sql = "SELECT valstr FROM settings WHERE userid=? AND sno=3"; $sth = $pdo->prepare($sql); $sth->execute([$this->id]); $res = $sth->fetchColumn(); if ($res === false) { $sql = "INSERT INTO settings (userid, sno, valstr) VALUES (?, 3, ?)"; $sth = $pdo->prepare($sql); $sth->execute([$this->id, implode(',', $this->menu)]); } else { $this->menu = array_map('intval', explode(',', $res)); } } function get_last_error() { return $this->errormessage; } } function get_userlist() { // Get list of all users for fast name lookup global $pdo; $ulist = array(-1 => ['-', 0]); // unknown $sql = "SELECT userid, displayname, role, flags FROM user ORDER BY displayname"; $sth = $pdo->query($sql); $res = $sth->fetchAll(); foreach ($res as $row) { $flags = array_filter(explode(',', $row['flags'])); $deleted = in_array('deleted', $flags); $locked = in_array('locked', $flags); $ulist[$row['userid']] = [$row['displayname'], $deleted, $locked]; } return $ulist; } // ========== DATABASE FUNCTIONS ============================================== function db_exec_insert($table, $params) { // $params must have keys corresponding to table fields prefixed with ':' // e.g. $param[':field'] global $pdo; global $g_error; $keys = array_keys($params); $fields = join(',', array_map(function($s) { return ltrim($s, ':'); }, $keys)); $pnames = join(',', $keys); $sql = "INSERT INTO $table ($fields) VALUES ($pnames)"; // $sth = $pdo->prepare("INSERT INTO $table ($fields) VALUES ($pnames)"); $sth = $pdo->prepare($sql); try { $sth->execute($params); } catch (PDOexception $e) { $g_error->Add('SQL-Error: '. $e->getMessage()); $g_error->Add($sql); $g_error->Add(print_r($params, true)); return false; } return $pdo->LastInsertId(); } function db_exec_update($table, $params, $pk) { // primary key can be a single field name or multiple fields: $pk is an array global $pdo; global $g_error; // remove primary key fields from list of fields to update if (is_array($pk)) { if (count($pk) == 1) { $pk = $pk[0]; $fields = $params; unset($fields[':'.$pk]); $where = "$pk=:$pk"; } else { $pkparams = array_map(fn($value) => ':' . $value, $pk); $fields = array_diff_key($params, array_flip($pkparams)); $where = join(' AND ', array_map(fn($s) => "$s=:$s", $pk)); } } else { $fields = $params; unset($fields[':'.$pk]); $where = "$pk=:$pk"; } $fieldlist = join(',', array_map(fn($s) => ltrim($s, ':') . '=' . $s, array_keys($fields))); $sql = "UPDATE $table SET $fieldlist WHERE $where"; $sth = $pdo->prepare($sql); try { $sth->execute($params); } catch (PDOexception $e) { $g_error->Add('SQL-Error: '. $e->getMessage()); $g_error->Add($sql); $g_error->Add(print_r($params, true)); return false; } return true; } function db_exec_delete($table, $condition, $params) { // WIP untested! // condition contains the where part of the sql statement // params are values for placeholders in condition // returns the number of deleted records global $pdo; global $g_error; // convert params to array if single value is given if (!is_array($params)) { $params = [$params]; } $sql = "DELETE FROM $table"; if (!empty($condition)) { $sql .= ' WHERE ' . $condition; } $sth = $pdo->prepare($sql); try { $sth->execute($params); } catch (PDOexception $e) { $g_error->Add('SQL-Error: '. $e->getMessage()); $g_error->Add($sql); $g_error->Add(print_r($params, true)); return -1; } return $sth->rowCount(); } function db_clear_filter($sno) { global $user; global $pdo; $sql = "DELETE FROM settings WHERE userid=? AND sno=?"; $sth = $pdo->prepare($sql); try { $sth->execute([$user->id, $sno]); } catch (PDOexception $e) { $g_warning->Add('SQL-Error: '. $e->getMessage()); $g_warning->Add($sql); $g_warning->Add('Setting: ', $sno); return false; } return true; } function db_save_filter($flt, $sno) { global $user; global $pdo; global $g_warning; $sql = "UPDATE settings SET valstr=? WHERE userid=? AND sno=?"; $sth = $pdo->prepare($sql); try { $sth->execute([json_encode($flt), $user->id, $sno]); } catch (PDOexception $e) { $g_warning->Add('SQL-Error: '. $e->getMessage()); $g_warning->Add($sql); $g_warning->Add(print_r($flt, true)); $g_warning->Add('Setting: ', $sno); return false; } return true; } function get_enum($enum) { // translate and beautify enums $lookup = array( 'NULL' => _('n/a'), 'active' => _('Active'), 'bad' => _('Bad'), 'box' => _('Box'), 'cable' => _('Cable'), 'cat' => _('Catamaran'), 'completed' => _('Completed'), 'closed' => _('Closed'), 'company' => _('Company'), 'defect' => _('Defect'), 'deleted' => _('Deleted'), 'done' => _('Done'), 'drawing' => _('Drawing'), 'equipment' => _('Equipment'), 'estimated' => _('Estimated'), 'finished' => _('Finished'), 'fixed' => _('Fixed'), 'fuse' => _('Fuse'), 'generic' => _('Generic'), 'good' => _('Good'), 'high' => _('High'), 'invoice' => _('Invoice'), 'locked' => _('Locked'), 'low' => _('Low'), 'manual' => _('Manual'), 'medium' => _('Medium'), 'mono' => _('Monohull'), 'new' => _('New'), 'none' => _('None'), 'normal' => _('Normal'), 'ongoing' => _('Ongoing'), 'open' => _('Open'), 'ordered' => _('Ordered'), 'paused' => _('Paused'), 'pending' => _('Pending'), 'picture' => _('Picture'), 'planned' => _('Planned'), 'precise' => _('Precise'), 'project' => _('Project'), 'removed' => _('Removed'), 'repairable' => _('Repairable'), 'rough' => _('Rough'), 'storage' => _('Storage'), 'task' => _('Task'), 'tri' => _('Trimaran'), 'unknown' => _('Unknown'), 'user' => _('User'), 'vessel' => _('Vessel'), 'waiting' => _('waiting') ); return $lookup[$enum] ?? $enum; } function db_load_enum($table, $column, $lookup=false, $as_dict=false, $check_null=false) { // returns array of enum-values as defined in database // if lookup is true the name lookup and translaton is applied // if as_dict is true the enum value is returned as the array key // if check_null is true the nullable-check is applied and returned // works also for set datatype global $pdo; $sql = "SELECT TRIM(TRAILING ')' FROM SUBSTRING(column_type,6)), is_nullable " . "FROM information_schema.columns " . "WHERE table_schema=DATABASE() AND table_name=? AND column_name=?"; $sth = $pdo->prepare($sql); $sth->execute([$table, $column]); $row = $sth->fetch(PDO::FETCH_NUM); // for PHP < 7.4 // return array_map(function($x) { return trim($x, "'"); }, explode(',', $row[0])); // for PHP => 7.4 $arr = array_map(fn($x) => trim($x, "'"), explode(',', $row[0])); // prepend special value NULL if column is nullable if ($check_null and $row[1] == 'YES') { array_unshift($arr, 'NULL'); } if ($lookup) { if ($as_dict) { $dict = array(); foreach ($arr as $x) { $dict[$x] = get_enum($x); } return $dict; } else { return array_map(fn($x) => get_enum($x), $arr); } } else { return $arr; } } function db_load_taglist($objtype, $objid) { // returns comma separated list for object global $pdo; global $g_error; $taglist = ''; $sql = "SELECT GROUP_CONCAT(tagname) " . "FROM tagref JOIN tag USING (tagid) " . "WHERE objtype=? AND objid=?"; $sth = $pdo->prepare($sql); try { $sth->execute([$objtype, $objid]); $taglist = $sth->fetchColumn(); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } return $taglist; } function db_save_taglist($objtype, $objid, $taglist) { global $pdo; global $g_error; // WIP // - taglist is comma separated string // - create not existing tags // - update tagref: create new, remove unused $tags = array_filter(explode(',', preg_replace('/\s+/u', '', $taglist))); if (empty($tags)) { // remove all from tagref $sth = $pdo->prepare("DELETE FROM tagref WHERE objtype=? AND objid=?"); try { $sth->execute([$objtype, $objid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } } else { // get list of non existing tags $in = str_repeat('?,', count($tags) - 1) . '?'; $sql = "SELECT tagid, tagname FROM tag WHERE tagname IN ($in)"; $sth = $pdo->prepare($sql); try { $sth->execute(array_values($tags)); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } $tagids = array(); $existing = array(); foreach ($sth->fetchAll() as $row) { $existing[] = $row['tagname']; $tagids[] = $row['tagid']; } $newtags = array_diff($tags, $existing); $sth = $pdo->prepare("INSERT INTO tag (tagname) VALUES (?)"); foreach ($newtags as $t) { // maxlength 20 for each tag! $sth->execute([substr($t, 0, 20)]); $tagids[] = $pdo->LastInsertId(); } // update references $sql = "SELECT tagid FROM tagref WHERE objtype=? AND objid=?"; $sth = $pdo->prepare($sql); $sth->execute([$objtype, $objid]); $refids = array(); $obsolete = array(); foreach ($sth->fetchAll() as $row) { if (in_array($row['tagid'], $tagids)) { // mark existing used references $refids[] = $row['tagid']; } else { // obsolete reference $obsolete[] = $row['tagid']; } } // create missing references $missing = array_diff($tagids, $refids); if (! empty($missing)) { $sql = "INSERT INTO tagref (tagid, objid, objtype) VALUES (?, ?, ?)"; $sth = $pdo->prepare($sql); foreach ($missing as $m) { $sth->execute([$m, $objid, $objtype]); } } // remove obsolete references if (! empty($obsolete)) { $sql = "DELETE FROM tagref WHERE tagid=? AND objid=? and objtype=?"; $sth = $pdo->prepare($sql); foreach ($obsolete as $o) { $sth->execute([$o, $objid, $objtype]); } } } } function db_get_tag_target($objtype, $objid) { // get page name and desctiption e.g. for link creation global $pdo; global $g_error; switch ($objtype) { case 'equip': $sql = "SELECT ename FROM equipment WHERE eid=?"; $target = "equipment.php"; break; case 'inv': $sql = "SELECT invname FROM inventory WHERE invid=?"; $target = "inventory.php"; break; case 'prov': $sql = "SELECT provname FROM provisions WHERE provvid=?"; $target = "provisions.php"; break; case 'doc': $sql = "SELECT title FROM document WHERE docid=?"; $target = "documents.php"; break; case 'proj': $sql = "SELECT projname FROM project WHERE projid=?"; $target = "projects.php"; break; case 'task': $sql = "SELECT taskname FROM task WHERE taskid=?"; $target = "task.php"; break; case 'maint': $sql = "SELECT activities FROM maintenance WHERE maintid=?"; $target = 'maintenance.php'; break; } $sth = $pdo->prepare($sql); $sth->execute([$objid]); $desc = $sth->fetchColumn(); return [$target, $desc]; } function db_get_ddtext($ddid, $ddval) { // returns single value for dropdown global $pdo; global $g_error; $sql = "SELECT ddtext FROM dropdown WHERE ddid=? AND ddval=?"; $sth = $pdo->prepare($sql); try { $sth->execute([$ddid, $ddval]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); return '#err'; } return $sth->fetchColumn(); } // Functions to get option lists (key/value) function db_get_options($ddid, $orderby = '', $short = False, $default = NULL) { // returns list for dropdown // if short is set the short value will be returned global $pdo; $list = array(); if ($default != NULL) { $list[0] = $default; } if ($short) { $sql = "SELECT ddval, ddshort"; } else { $sql = "SELECT ddval, ddtext"; } $sql .= " FROM dropdown WHERE ddid=?"; if ($orderby == 'ddtext') { $sql .= ' ORDER BY ddtext'; } elseif ($orderby == 'sort') { $sql .= ' ORDER BY sort'; } else { $sql .= ' ORDER BY ddval'; } $sth = $pdo->prepare($sql); $sth->execute([$ddid]); foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) { $list[$rec[0]] = $rec[1]; } return $list; } function db_get_opt_vessel() { global $pdo; $list = array(); $sth = $pdo->query("SELECT vid, vesselname, model FROM vessel ORDER BY vid"); foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) { $list[$rec[0]] = $rec[1]; } return $list; } function db_get_opt_storage($vid) { global $pdo; global $g_error; $list = array(); // exclude storage type "tank" from list $sql = "SELECT sid, sname FROM storage WHERE vid=? AND stype<>1 ORDER BY sname"; $sth = $pdo->prepare($sql); try { $sth->execute([$vid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) { $list[$rec[0]] = $rec[1]; } return $list; } function db_get_opt_box($vid) { global $pdo; global $g_error; $list = array(); $sql = "SELECT boxid, label, content " . "FROM box INNER JOIN storage USING (sid) " . "WHERE vid=? " . "ORDER BY label"; $sth = $pdo->prepare($sql); try { $sth->execute([$vid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) { $list[$rec[0]] = $rec[1] . ' - '. $rec[2]; } return $list; } function db_get_opt_equip($vid, $default=NULL) { global $pdo; global $g_error; if (isset($default)) { $list = $default; } else { $list = array(); } $sql = "SELECT eid, ename FROM equipment WHERE vid=? ORDER BY ename"; $sth = $pdo->prepare($sql); try { $sth->execute([$vid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) { $list[$rec[0]] = $rec[1]; } return $list; } function db_get_opt_manuf($default=NULL) { global $pdo; if (isset($default)) { $list = $default; } else { $list = array(); } $sql = "SELECT compid, compname FROM company WHERE comptype=2 ORDER BY compname"; $sth = $pdo->query($sql); foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) { $list[$row[0]] = $row[1]; } return $list; } function db_get_opt_supp($default=NULL) { global $pdo; if (isset($default)) { $list = $default; } else { $list = array(); } $sql = "SELECT compid, compname FROM company WHERE comptype=1 ORDER BY compname"; $sth = $pdo->query($sql); foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) { $list[$row[0]] = $row[1]; } return $list; } function db_get_opt_user($userid, $default=NULL) { global $pdo; if (isset($default)) { $list = $default; } else { $list = array(); } $sql = "SELECT userid, displayname FROM user WHERE userid>0 ORDER BY displayname"; $sth = $pdo->query($sql); foreach ($sth->fetchAll(PDO::FETCH_NUM) as $row) { $list[$row[0]] = $row[1]; } return $list; } function db_get_opt_proj($vid, $default=NULL) { global $pdo; global $g_error; if (isset($default)) { $list = $default; } else { $list = array(); } $sql = "SELECT projid, projname FROM project WHERE vid=? ORDER BY projname"; $sth = $pdo->prepare($sql); try { $sth->execute([$vid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); } foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) { $list[$rec[0]] = $rec[1]; } return $list; } function db_get_filter($user, $sno, $fields = []) { // if fields supplied empting missing field are created global $pdo; global $g_warning; $flt = new stdClass(); $sth = $pdo->prepare("SELECT valstr FROM settings WHERE userid=? AND sno=?"); try { $sth->execute([$user, $sno]); $json = $sth->fetchColumn(); if ($json === false) { // no settings record. create empty one for later updates $sth = $pdo->prepare("INSERT INTO settings (userid, sno, valstr) VALUES (?, ?, '{}')"); $sth->execute([$user, $sno]); } else { $flt = json_decode($json); } // create missing fields foreach ($fields as $f) { if (!property_exists($flt, $f)) { $flt->$f = null; } } } catch (PDOexception $e) { $g_warning->Add('SQL-Error: '. $e->getMessage()); $g_warning->PrintOut(); } return $flt; } function db_get_default_storage($vesselid, $fallback=true) { global $pdo; global $g_error, $g_warning; $sql = "SELECT sid_default FROM vessel WHERE vid=?"; $sth = $pdo->prepare($sql); try { $sth->execute([$vesselid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); return false; } $sid = $sth->fetchColumn(); if ($sid == NULL && $fallback) { // try to get another storage as last fallback $g_warning->Add(_('No default storage defined for current vessel')); $sql = "SELECT MIN(sid), sname FROM storage WHERE vid=?"; $sth = $pdo->prepare($sql); try { $sth->execute([$vesselid]); } catch(PDOException $e) { $g_error->Add($e->getMessage()); return false; } $row = $sth->fetch(PDO::FETCH_NUM); if ($row[0] == NULL) { $g_error->Add('Error: No storage defined for current vessel'); return false; } $sid = $row[0]; $g_warning->Add(sprintf(_("Selected fallback storage '%s'"), $row[1])); } return $sid; } function date_to_sql($var) { if (!isset($var) || $var == '') { return NULL; } else { list($d, $m, $y) = explode('.', $var); return sprintf("%04d-%02d-%02d", $y, $m, $d); } } function float_to_sql($var) { global $g_lconv; if (!isset($var) || $var == '') { return NULL; } else { // remove thousands separator $var = str_replace($g_lconv['thousands_sep'], '', $var); // force decimal point if ($g_lconv['decimal_point'] != '.') { $var = str_replace($g_lconv['decimal_point'], '.', $var); } return $var; } } // ========== FORM FUNCTIONS ================================================== function form_get_action() { if (!isset($_POST['submit'])) { if (isset($_GET['f'])) { $submit = $_GET['f']; // strip parameters /* $pos = strpos($submit, '?'); if ($pos > 2) { $submit = substr($submit, 0, $pos); } */ } else { $submit = NULL; } } else { $submit = $_POST['submit']; } if (is_array($submit)) { $submit = key($submit); } return strtolower($submit); } function form_create_input($fieldname, $label, $value) { // TODO WIP echo '
', "\n"; echo "
\n"; } function form_create_text($fieldname, $label, $value) { // TODO WIP echo '
', "\n"; echo "
\n"; } function form_create_select($fieldname, $label, $optlist, $selval=NULL, $multiple=FALSE) { echo '
', "\n"; echo '\n"; echo '\n"; echo "
\n"; } function form_create_checks($fieldname, $label, $optlist, $selected) { echo '
', "\n"; echo '\n"; print_r($optlist); echo "
\n"; } // TODO DEPRECATED for touch multiple adjacent buttuns are not well suited. function form_action_buttons($script, $id) { echo ""; echo '', "\n"; echo '', "\n"; echo "\n"; } function form_add_button($script, $id=NULL, $idname='id') { echo '
', "\n"; echo '', _('Add'), "\n"; echo "
\n"; } function form_view_buttons($script, $id, $backlink=NULL) { echo '
', "\n"; echo '', _('Edit'), "\n"; echo ' '; echo '', _('Delete'), "\n"; echo ' '; echo '', _('Back'), "\n"; echo "
\n"; } function form_new_buttons($script) { echo '
', "\n"; echo '\n"; echo '', _('Back'), "\n"; echo "
\n"; } function form_edit_buttons($script, $id) { echo '
', "\n"; echo '\n"; echo '', _('Back'), "\n"; echo "
\n"; } function form_delete_buttons($script, $id, $token) { echo '
', "\n"; echo '
', "\n"; echo '', "\n"; echo '', "\n"; echo '\n"; echo '', _('Back'), "\n"; echo "
\n"; echo "
\n"; } function form_tag_assignment($script, $id, $tags) { echo ''; echo '', _('Tags'), "\n"; echo '', $tags, ''; echo "\n"; echo '', _('Tag assignment'), "\n"; echo '
', "\n"; echo '
'; echo '', "\n"; echo '', "\n"; echo '', "\n"; echo '', "\n"; echo "
\n"; echo ""; } function filter_create_select($fieldname, $label, $optlist, $selval=NULL, $multiple=FALSE) { // - Wenn multiple gesetzt ist, muß selval ein array sein // ansonsten ein einfacher String /* if ($multiple) { if (!is_array($selval)) { } } */ echo '
', "\n"; echo '', "\n"; echo '\n"; echo "
"; } function filter_create_checks($fieldname, $label, $optlist, $selected = []) { // TODO WIP echo '
'; echo '', $label, "\n"; echo '
'; foreach ($optlist as $k => $v) { echo '
'; $checked = in_array($k, $selected, true) ? ' checked' : ''; echo ''; echo '
'; } echo '
'; echo '
'; } // ========== FORMAT FUNCTIONS ================================================ function format_float($val, $decimals = 2, $suffix = '') { global $g_lconv; if (!isset($val) || $val == '') { return ''; } return number_format($val, $decimals, $g_lconv['decimal_point'], $g_lconv['thousands_sep']) . ($suffix ? " $suffix" : ''); } function format_currency($val) { global $g_lconv; if (!isset($val) || $val == '') { return ''; } if ($g_lconv['currency_symbol'] == '$') { return '$'.number_format($val, 2, $g_lconv['decimal_point'], $g_lconv['thousands_sep']); } else { return number_format($val, 2, $g_lconv['decimal_point'], $g_lconv['thousands_sep']) . ' ' . $g_lconv['currency_symbol']; } } function format_color($color) { $colstr = '#' . $color . '' ; return $colstr; } function format_filesize($size, $format=2) { switch ($format) { case 1: // short if ($size < 1024) { $size_string = sprintf(_('%d B'), $size); } elseif ($size < 1048576) { $size_string = sprintf(_('%.1f kB'), $size/1024); } else { $size_string = sprintf(_('%.1f MB'), $size/1048576); } break; case 2: // medium if ($size < 1024) { $size_string = sprintf(_('%d Byte'), $size); } elseif ($size < 1048576) { $size_string = sprintf(_('%.1f kByte'), $size/1024); } else { $size_string = sprintf(_('%.1f MByte'), $size/1048576); } break; case 3: // long if ($size < 1024) { $size_string = sprintf(_('%d Byte'), $size); } elseif ($size < 1048576) { $size_string = sprintf(_('approx. %.1f kByte'), $size/1024); } else { $size_string = sprintf(_('approx. %.1f MByte'), $size/1048576); } break; default: $size_string = trim($size); } return $size_string; } function format_measurement($n, $unit, $v1, $v2, $v3) { $m = ''; switch ($n) { case 1: $m = "$v1 $unit"; break; case 2: $m = "$v1×$v2 $unit"; break; case 3: $m = "$v1×$v2×$v3 $unit"; break; } return $m; } // ========== COMMON FUNCTIONS ================================================ function header_location($location, $message=NULL) { if (is_array($message)) { $valid_keys = array('succ', 'info', 'warn', 'err'); foreach ($message as $k => $v) { if (in_array($k, $valid_keys)) { $_SESSION['message'][$k] = $v; } } } header("Location: $location"); exit; } function pgettext($context, $msgid) { // implement missing function global $g_textdomain; $ctxstr = "{$context}\004{$msgid}"; $translation = dcgettext($g_textdomain, $ctxstr, LC_MESSAGES); if ($translation == $ctxstr) { return $msgid; } else { return $translation; } } function get_color_brightness($color, $default=0.5) { // returns a value between 0 and 1 // color is a 6 char hex string if (strlen($color) != 6) { return $default; } list($red, $green, $blue) = array_map('hexdec', str_split($color, 2)); $red = $red / 255 * 0.2126; $green = $green / 255 * 0.7152; $blue = $blue / 255 * 0.0722; return $red + $green + $blue; } function page_caption_search($caption) { // print page caption with searchbox ?>

' . "\n"; $out .= '\n\n"; return $out; } function table_rec_summary($start, $end, $total, $cols) { // common summary table footer for data tables echo "\n"; echo ' '; if ($total > 0) { echo sprintf(_('Records %d to %d of %d'), $start, $end, $total); } else { echo _('No records found'); } echo "\n"; echo "\n"; } function pdf_get_pagecount($filename) { $pages = exec("/usr/bin/mutool show $filename Root/Pages/Count", $output, $retval); // TODO error checking return $pages; } function pdf_get_preview($docid) { global $g_doc_basepath; // create file in thumbs if needed $thumbfile = $g_doc_basepath . '/thumbs/doc-' . $docid . '.jpg'; if (file_exists($thumbfile)) { //return "'; } function make_maillink($dest) { $dest = trim($dest); if ($dest === '') { return ''; } $scheme = strtolower((string) parse_url($dest, PHP_URL_SCHEME)); if ($scheme === '') { $dest = 'mailto:' . $dest; } elseif ($scheme !== 'mailto') { return ''; } return ''; } function make_phonelink($dest) { $dest = normalize_phone_e164($dest); if ($dest === '') { return ''; } $scheme = strtolower((string) parse_url($dest, PHP_URL_SCHEME)); if ($scheme === '') { $dest = 'tel:' . $dest; } elseif ($scheme !== 'tel') { return ''; } return ''; } function normalize_phone_e164($phone) { $phone = trim($phone); if ($phone === '') { return ''; } $phone = preg_replace('/[^\d+]/', '', $phone); if (str_starts_with($phone, '+')) { return $phone; } if (str_starts_with($phone, '00')) { return '+' . substr($phone, 2); } if (str_starts_with($phone, '0')) { $phone = substr($phone, 1); } return '+49' . $phone; } // ========== MENU FUNCTIONS ================================================== $g_modules = Array( 1 => ['file' => 'equipment.php', 'title' => _('Equipment'), 'type' => 'primary', 'group' => 'main'], 2 => ['file' => 'inventory.php', 'title' => _('Inventory'), 'type' => 'primary', 'group' => 'main'], 3 => ['file' => 'provisions.php', 'title' => _('Provisions'), 'type' => 'primary', 'group' => 'main'], 4 => ['file' => 'maintenance.php', 'title' => _('Maintenance'), 'type' => 'primary', 'group' => 'main'], 5 => ['file' => 'projects.php', 'title' => _('Projects'), 'type' => 'primary', 'group' => 'main'], 6 => ['file' => 'documents.php', 'title' => _('Documents'), 'type' => 'primary', 'group' => 'main'], 7 => ['file' => 'company.php', 'title' => _('Companies'), 'type' => 'primary', 'group' => 'base'], 8 => ['file' => 'task.php', 'title' => _('Task'), 'type' => 'primary', 'group' => 'extra'], 9 => ['file' => 'measurement.php', 'title' => _('Measurement'), 'type' => 'primary', 'group' => 'extra'], 10 => ['file' => 'storage.php', 'title' => _('Storage'), 'type' => 'primary', 'group' => 'base'], 11 => ['file' => 'box.php', 'title' => _('Boxes'), 'type' => 'primary', 'group' => 'extra'], 12 => ['file' => 'cable.php', 'title' => _('Cables'), 'type' => 'primary', 'group' => 'extra'], 13 => ['file' => 'fuse.php', 'title' => _('Fuses'), 'type' => 'primary', 'group' => 'extra'], 14 => ['file' => 'checklist.php', 'title' => _('Checklists'), 'type' => 'primary', 'group' => 'extra'], 15 => ['file' => 'tag.php', 'title' => _('Tags'), 'type' => 'secondary', 'group' => 'base'], 16 => ['file' => 'settings.php', 'title' => _('Settings'), 'type' => 'secondary', 'group' => 'extra'], 17 => ['file' => 'dropdown.php', 'title' => _('Selection lists'), 'type' => 'secondary', 'group' => 'base']);