45f80a0855
Any user who can log in via SSO but doesn't have one of the required entitlements will only ever see a listing of their own loans.
371 lines
9.1 KiB
PHP
371 lines
9.1 KiB
PHP
<?php
|
|
|
|
require_once('./include/translations.php');
|
|
|
|
/*
|
|
Takes an html file containing named fragments.
|
|
Returns an associative array on the format array[name]=>fragment.
|
|
|
|
Fragments are delimited like this:
|
|
|
|
¤¤ name 1 ¤¤
|
|
fragment 1
|
|
¤¤ name 2 ¤¤
|
|
fragment 2
|
|
¤¤ name 3 ¤¤
|
|
fragment 3
|
|
|
|
The first delimiter and name ('¤¤ name 1 ¤¤' in the above example) can
|
|
be omitted, in which case the first fragment will be assigned the
|
|
name 'base'. All other fragments must be named.
|
|
|
|
Throws an exception if:
|
|
- any fragment except the first is missing a name
|
|
- two (or more) fragments share a name
|
|
*/
|
|
function get_fragments($infile) {
|
|
$out = array();
|
|
$name = '';
|
|
$current_fragment = '';
|
|
|
|
$filecontents = file($infile);
|
|
$iter = 0;
|
|
foreach($filecontents as $line) {
|
|
if(strpos(trim($line), '¤¤') === 0) {
|
|
if($iter != 0) {
|
|
$out = try_adding($name, $current_fragment, $out, $infile);
|
|
}
|
|
$name = trim($line, "\t\n\r ¤");
|
|
$current_fragment = '';
|
|
} else {
|
|
$current_fragment .= $line;
|
|
}
|
|
$iter++;
|
|
}
|
|
return try_adding($name, $current_fragment, $out, $infile);
|
|
}
|
|
|
|
function i18n($string, ...$args) {
|
|
global $language, $i18n;
|
|
return $i18n[$string][$language](...$args);
|
|
}
|
|
|
|
function try_adding($key, $value, $array, $filename) {
|
|
if(array_key_exists($key, $array)) {
|
|
throw new Exception('There is already a fragment with that name in '.$filename);
|
|
} else if($key === '') {
|
|
throw new Exception('There is an unnamed fragment in '.$filename);
|
|
}
|
|
|
|
$array[$key] = trim($value);
|
|
|
|
return $array;
|
|
}
|
|
|
|
/*
|
|
Takes an associative array and a string.
|
|
Returns a string.
|
|
|
|
Replaces each occurrence of each array key in the input string
|
|
with the associated array value, and returns the result.
|
|
*/
|
|
function replace($assoc_arr, $subject) {
|
|
$keys = array();
|
|
$values = array();
|
|
|
|
foreach($assoc_arr as $key => $value) {
|
|
$keys[] = '¤'.$key.'¤';
|
|
$values[] = $value;
|
|
}
|
|
|
|
return str_replace($keys, $values, $subject);
|
|
}
|
|
|
|
function make_page($page) {
|
|
switch($page) {
|
|
default:
|
|
die("Invalid page.");
|
|
case 'checkout':
|
|
return new CheckoutPage();
|
|
case 'return':
|
|
return new ReturnPage();
|
|
case 'search':
|
|
return new SearchPage();
|
|
case 'products':
|
|
return new ProductPage();
|
|
case 'new':
|
|
return new NewPage();
|
|
case 'users':
|
|
return new UserPage();
|
|
case 'inventory':
|
|
return new InventoryPage();
|
|
case 'history':
|
|
return new HistoryPage();
|
|
case 'ajax':
|
|
return new Ajax();
|
|
case 'qr':
|
|
return new QR();
|
|
case 'print':
|
|
return new Printer();
|
|
case 'dl':
|
|
return new Download();
|
|
case 'public':
|
|
return new PublicPage();
|
|
}
|
|
}
|
|
|
|
function get_ids($type) {
|
|
$append = '';
|
|
switch($type) {
|
|
case 'user':
|
|
break;
|
|
case 'product':
|
|
$append = 'where `discardtime` is null';
|
|
break;
|
|
case 'product_discarded':
|
|
$type = 'product';
|
|
$append = 'where `discardtime` is not null';
|
|
break;
|
|
case 'event':
|
|
break;
|
|
case 'event_active':
|
|
$type = 'event';
|
|
$append = 'where `returntime` is null';
|
|
break;
|
|
case 'inventory':
|
|
break;
|
|
case 'inventory_old':
|
|
$append = 'where `endtime` is not null order by `id` desc';
|
|
$type = 'inventory';
|
|
break;
|
|
default:
|
|
$err = "$type is not a valid argument.";
|
|
throw new Exception($err);
|
|
break;
|
|
}
|
|
$query = "select `id` from `$type`";
|
|
if($append) {
|
|
$query .= " $append";
|
|
}
|
|
$get = prepare($query);
|
|
execute($get);
|
|
$ids = array();
|
|
foreach(result_list($get) as $row) {
|
|
$ids[] = $row['id'];
|
|
}
|
|
return $ids;
|
|
}
|
|
|
|
function get_items($type) {
|
|
$construct = null;
|
|
switch($type) {
|
|
case 'user':
|
|
$construct = function($id) {
|
|
return new User($id);
|
|
};
|
|
break;
|
|
case 'product':
|
|
case 'product_discarded':
|
|
$construct = function($id) {
|
|
return new Product($id);
|
|
};
|
|
break;
|
|
case 'event':
|
|
case 'event_active':
|
|
$construct = function($id) {
|
|
return new Event($id);
|
|
};
|
|
break;
|
|
case 'inventory':
|
|
case 'inventory_old':
|
|
$construct = function($id) {
|
|
return new Inventory($id);
|
|
};
|
|
break;
|
|
default:
|
|
$err = "$type is not a valid argument.";
|
|
throw new Exception($err);
|
|
break;
|
|
}
|
|
$ids = get_ids($type);
|
|
$list = array();
|
|
foreach($ids as $id) {
|
|
$list[] = $construct($id);
|
|
}
|
|
return $list;
|
|
}
|
|
|
|
function suggest($type) {
|
|
$search = '';
|
|
$typename = 'name';
|
|
switch($type) {
|
|
case 'user':
|
|
$search = prepare('select `name` from `user` order by `name`');
|
|
break;
|
|
case 'template':
|
|
$search = prepare('select `name` from `template` order by `name`');
|
|
break;
|
|
case 'tag':
|
|
$search = prepare(
|
|
'(select `tag` from `product_tag`)
|
|
union
|
|
(select `tag` from `template_tag`)
|
|
order by `tag`');
|
|
$typename = 'tag';
|
|
break;
|
|
case 'field':
|
|
$search = prepare(
|
|
'(select `field` from `product_info`)
|
|
union
|
|
(select `field` from `template_info`)
|
|
order by `field`');
|
|
$typename = 'field';
|
|
break;
|
|
default:
|
|
return array();
|
|
}
|
|
execute($search);
|
|
$out = array();
|
|
foreach(result_list($search) as $row) {
|
|
$out[] = $row[$typename];
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
function suggest_content($fieldname) {
|
|
$search = '';
|
|
$resultfield = $fieldname;
|
|
switch($fieldname) {
|
|
case 'name':
|
|
$search = prepare('select distinct `name`
|
|
from `product` order by `name`');
|
|
break;
|
|
case 'brand':
|
|
$search = prepare('select distinct `brand`
|
|
from `product` order by `brand`');
|
|
break;
|
|
default:
|
|
$search = prepare("select distinct `data` from `product_info`
|
|
where `field` = ? order by `data`");
|
|
bind($search, 's', $fieldname);
|
|
$resultfield = 'data';
|
|
}
|
|
$out = array();
|
|
execute($search);
|
|
try {
|
|
$results = result_list($search);
|
|
} catch(Exception $e) {
|
|
return array();
|
|
}
|
|
foreach($results as $row) {
|
|
$out[] = $row[$resultfield];
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
function match_term($term, $subject) {
|
|
if(fnmatch('*'.$term->get_query().'*', $subject, FNM_CASEFOLD)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function match_tags($searchterm, $tags) {
|
|
$found = array();
|
|
foreach($tags as $tag) {
|
|
if(fnmatch('*'.$tag.'*', $searchterm, FNM_CASEFOLD)) {
|
|
$found[] = $tag;
|
|
}
|
|
}
|
|
return $found;
|
|
}
|
|
|
|
function format_date($date) {
|
|
if($date) {
|
|
return gmdate('Y-m-d', $date);
|
|
}
|
|
return $date;
|
|
}
|
|
|
|
function default_loan_end($start) {
|
|
return $start + 604800; # 1 week later
|
|
}
|
|
|
|
|
|
### Database interaction functions ###
|
|
|
|
$db = new mysqli($db_host, $db_user, $db_pass, $db_name);
|
|
if($db->connect_errno) {
|
|
$error = 'Failed to connect to db. The error was: '.$db->connect_error;
|
|
throw new Exception($error);
|
|
}
|
|
|
|
function prepare($statement) {
|
|
global $db;
|
|
|
|
if(!($s = $db->prepare($statement))) {
|
|
$error = 'Failed to prepare the following statement: '.$statement;
|
|
$error .= '\n';
|
|
$error .= $db->error.' ('.$db->errno.')';
|
|
throw new Exception($error);
|
|
}
|
|
|
|
return $s;
|
|
}
|
|
|
|
function bind($statement, $types, ...$values) {
|
|
global $db;
|
|
|
|
return $statement->bind_param($types, ...$values);
|
|
}
|
|
|
|
function execute($statement) {
|
|
if(!$statement->execute()) {
|
|
$error = 'Failed to execute statement.';
|
|
$error .= '\n';
|
|
$error .= $statement->error.' ('.$statement->errno.')';
|
|
throw new Exception($error);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function result_list($statement) {
|
|
return $statement->get_result()->fetch_all(MYSQLI_ASSOC);
|
|
}
|
|
|
|
function result_single($statement) {
|
|
$out = result_list($statement);
|
|
switch(count($out)) {
|
|
case 0:
|
|
return null;
|
|
case 1:
|
|
foreach($out as $value) {
|
|
return $value;
|
|
}
|
|
default:
|
|
throw new Exception('More than one result available.');
|
|
}
|
|
}
|
|
|
|
function begin_trans() {
|
|
global $db;
|
|
|
|
$db->begin_transaction(MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT);
|
|
}
|
|
|
|
function commit_trans() {
|
|
global $db;
|
|
|
|
$db->commit();
|
|
return true;
|
|
}
|
|
|
|
function revert_trans() {
|
|
global $db;
|
|
|
|
$db->rollback();
|
|
return false;
|
|
}
|
|
|
|
?>
|