Broke all classes into separate files and activated class autoloading.
All free functions are now in functions.php
This commit is contained in:
parent
fe4e92b6e9
commit
692c2e0aeb
349
include/Ajax.php
Normal file
349
include/Ajax.php
Normal file
@ -0,0 +1,349 @@
|
||||
<?php
|
||||
class Ajax extends Responder {
|
||||
private $action = '';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['action'])) {
|
||||
$this->action = $_GET['action'];
|
||||
}
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$out = '';
|
||||
switch($this->action) {
|
||||
default:
|
||||
$out = new Success('ajax endpoint');
|
||||
break;
|
||||
case 'getfragment':
|
||||
$out = $this->get_fragment();
|
||||
break;
|
||||
case 'checkout':
|
||||
$out = $this->checkout_product();
|
||||
break;
|
||||
case 'return':
|
||||
$out = $this->return_product();
|
||||
break;
|
||||
case 'extend':
|
||||
$out = $this->extend_loan();
|
||||
break;
|
||||
case 'startinventory':
|
||||
$out = $this->start_inventory();
|
||||
break;
|
||||
case 'endinventory':
|
||||
$out = $this->end_inventory();
|
||||
break;
|
||||
case 'inventoryproduct':
|
||||
$out = $this->inventory_product();
|
||||
break;
|
||||
case 'updateproduct':
|
||||
$out = $this->update_product();
|
||||
break;
|
||||
case 'updateuser':
|
||||
$out = $this->update_user();
|
||||
break;
|
||||
case 'savetemplate':
|
||||
$out = $this->save_template();
|
||||
break;
|
||||
case 'deletetemplate':
|
||||
$out = $this->delete_template();
|
||||
break;
|
||||
case 'suggest':
|
||||
$out = $this->suggest();
|
||||
break;
|
||||
case 'discardproduct':
|
||||
$out = $this->discard_product();
|
||||
break;
|
||||
}
|
||||
print($out->toJson());
|
||||
}
|
||||
|
||||
private function get_fragment() {
|
||||
$fragment = $_POST['fragment'];
|
||||
if(isset($this->fragments[$fragment])) {
|
||||
return new Success($this->fragments[$fragment]);
|
||||
}
|
||||
return new Failure("Ogiltigt fragment '$fragment'");
|
||||
}
|
||||
|
||||
private function checkout_product() {
|
||||
$user = new User($_POST['user'], 'name');
|
||||
$product = null;
|
||||
try {
|
||||
$product = new Product($_POST['product'], 'serial');
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Ogiltigt serienummer.');
|
||||
}
|
||||
try {
|
||||
$user->create_loan($product, $_POST['end']);
|
||||
return new Success($product->get_name() . 'utlånad.');
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Artikeln är redan utlånad.');
|
||||
}
|
||||
}
|
||||
|
||||
private function return_product() {
|
||||
$product = null;
|
||||
try {
|
||||
$product = new Product($_POST['serial'], 'serial');
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Ogiltigt serienummer.');
|
||||
}
|
||||
$loan = $product->get_active_loan();
|
||||
if($loan) {
|
||||
$loan->end();
|
||||
$user = $loan->get_user();
|
||||
$userlink = replace(array('page' => 'users',
|
||||
'id' => $user->get_id(),
|
||||
'name' => $user->get_displayname()),
|
||||
$this->fragments['item_link']);
|
||||
$productlink = replace(array('page' => 'products',
|
||||
'id' => $product->get_id(),
|
||||
'name' => $product->get_name()),
|
||||
$this->fragments['item_link']);
|
||||
$user = $loan->get_user();
|
||||
return new Success($productlink . ' åter från ' . $userlink);
|
||||
}
|
||||
return new Failure('Artikeln är inte utlånad.');
|
||||
}
|
||||
|
||||
private function extend_loan() {
|
||||
$product = null;
|
||||
try {
|
||||
$product = new Product($_POST['product']);
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Ogiltigt ID.');
|
||||
}
|
||||
$loan = $product->get_active_loan();
|
||||
if($loan) {
|
||||
$loan->extend($_POST['end']);
|
||||
return new Success('Lånet förlängt');
|
||||
}
|
||||
return new Failure('Lån saknas.');
|
||||
}
|
||||
|
||||
private function start_inventory() {
|
||||
try {
|
||||
Inventory::begin();
|
||||
return new Success('Inventering startad.');
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Inventering redan igång.');
|
||||
}
|
||||
}
|
||||
|
||||
private function end_inventory() {
|
||||
$inventory = Inventory::get_active();
|
||||
if($inventory === null) {
|
||||
return new Failure('Ingen inventering pågår.');
|
||||
}
|
||||
$inventory->end();
|
||||
return new Success('Inventering avslutad.');
|
||||
}
|
||||
|
||||
private function inventory_product() {
|
||||
$inventory = Inventory::get_active();
|
||||
if($inventory === null) {
|
||||
return new Failure('Ingen inventering pågår.');
|
||||
}
|
||||
$product = null;
|
||||
try {
|
||||
$product = new Product($_POST['serial'], 'serial');
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Ogiltigt serienummer.');
|
||||
}
|
||||
$result = $inventory->add_product($product);
|
||||
if(!$result) {
|
||||
return new Failure('Artikeln är redan registrerad.');
|
||||
}
|
||||
return new Success('Artikeln registrerad.');
|
||||
}
|
||||
|
||||
private function update_product() {
|
||||
$info = $_POST;
|
||||
$id = $info['id'];
|
||||
$name = $info['name'];
|
||||
$serial = $info['serial'];
|
||||
$invoice = $info['invoice'];
|
||||
$tags = array();
|
||||
if(isset($info['tag'])) {
|
||||
$tags = $this->unescape_tags($info['tag']);
|
||||
}
|
||||
foreach(array('id', 'name', 'serial', 'invoice', 'tag') as $key) {
|
||||
unset($info[$key]);
|
||||
}
|
||||
if(!$name) {
|
||||
return new Failure('Artikeln måste ha ett namn.');
|
||||
}
|
||||
if(!$serial) {
|
||||
return new Failure('Artikeln måste ha ett serienummer.');
|
||||
}
|
||||
if(!$invoice) {
|
||||
return new Failure('Artikeln måste ha ett fakturanummer.');
|
||||
}
|
||||
$product = null;
|
||||
if(!$id) {
|
||||
try {
|
||||
$temp = new Product($serial, 'serial');
|
||||
return new Failure(
|
||||
'Det angivna serienumret finns redan på en annan artikel.');
|
||||
} catch(Exception $e) {}
|
||||
try {
|
||||
$product = Product::create_product($name,
|
||||
$invoice,
|
||||
$serial,
|
||||
$info,
|
||||
$tags);
|
||||
$prodlink = replace(array('page' => 'products',
|
||||
'id' => $product->get_id(),
|
||||
'name' => $product->get_name()),
|
||||
$this->fragments['item_link']);
|
||||
return new Success("Artikeln '$prodlink' sparad.");
|
||||
} catch(Exception $e) {
|
||||
return new Failure($e->getMessage());
|
||||
}
|
||||
}
|
||||
$product = new Product($id);
|
||||
if($product->get_discardtime()) {
|
||||
return new Failure('Skrotade artiklar får inte modifieras.');
|
||||
}
|
||||
if($name != $product->get_name()) {
|
||||
$product->set_name($name);
|
||||
}
|
||||
if($serial != $product->get_serial()) {
|
||||
try {
|
||||
$product->set_serial($serial);
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Det angivna serienumret finns redan på en annan artikel.');
|
||||
}
|
||||
}
|
||||
if($invoice != $product->get_invoice()) {
|
||||
$product->set_invoice($invoice);
|
||||
}
|
||||
foreach($product->get_info() as $key => $prodvalue) {
|
||||
if(!isset($info[$key]) || !$info[$key]) {
|
||||
$product->remove_info($key);
|
||||
continue;
|
||||
}
|
||||
if($prodvalue != $info[$key]) {
|
||||
$product->set_info($key, $info[$key]);
|
||||
}
|
||||
unset($info[$key]);
|
||||
}
|
||||
foreach($info as $key => $invalue) {
|
||||
if($invalue) {
|
||||
$product->set_info($key, $invalue);
|
||||
}
|
||||
}
|
||||
foreach($product->get_tags() as $tag) {
|
||||
if(!in_array($tag, $tags)) {
|
||||
$product->remove_tag($tag);
|
||||
continue;
|
||||
}
|
||||
unset($tags[array_search($tag, $tags)]);
|
||||
}
|
||||
foreach($tags as $tag) {
|
||||
$product->add_tag($tag);
|
||||
}
|
||||
return new Success('Ändringarna sparade.');
|
||||
}
|
||||
|
||||
private function update_user() {
|
||||
$id = $_POST['id'];
|
||||
$name = $_POST['name'];
|
||||
$notes = $_POST['notes'];
|
||||
if(!$name) {
|
||||
return new Failure('Användarnamnet får inte vara tomt.');
|
||||
}
|
||||
$user = new User($id);
|
||||
if($user->get_name() != $name) {
|
||||
$user->set_name($name);
|
||||
}
|
||||
if($user->get_notes() != $notes) {
|
||||
$user->set_notes($notes);
|
||||
}
|
||||
return new Success('Ändringarna sparade.');
|
||||
}
|
||||
|
||||
private function save_template() {
|
||||
$info = $_POST;
|
||||
$name = $info['template'];
|
||||
$tags = array();
|
||||
if(isset($info['tag'])) {
|
||||
$tags = $this->unescape_tags($info['tag']);
|
||||
}
|
||||
foreach(array('template',
|
||||
'id',
|
||||
'name',
|
||||
'serial',
|
||||
'invoice',
|
||||
'tags') as $key) {
|
||||
unset($info[$key]);
|
||||
}
|
||||
if(!$name) {
|
||||
return new Failure('Mallen måste ha ett namn.');
|
||||
}
|
||||
$template = null;
|
||||
try {
|
||||
$template = new Template($name, 'name');
|
||||
} catch(Exception $e) {
|
||||
$template = Template::create_template($name, $info, $tags);
|
||||
$name = $template->get_name();
|
||||
return new Success(
|
||||
"Aktuella fält och taggar har sparats till mallen '$name'.");
|
||||
}
|
||||
foreach($template->get_fields() as $field) {
|
||||
if(!isset($info[$field])) {
|
||||
$template->remove_field($field);
|
||||
}
|
||||
}
|
||||
$existingfields = $template->get_fields();
|
||||
foreach($info as $field) {
|
||||
if(!in_array($field, $existingfields)) {
|
||||
$template->add_field($field);
|
||||
}
|
||||
}
|
||||
foreach($template->get_tags() as $tag) {
|
||||
if(!in_array($tag, $tags)) {
|
||||
$template->remove_tag($tag);
|
||||
}
|
||||
}
|
||||
$existingtags = $template->get_tags();
|
||||
foreach($tags as $tag) {
|
||||
if(!in_array($tag, $existingtags)) {
|
||||
$template->add_tag($tag);
|
||||
}
|
||||
}
|
||||
$name = $template->get_name();
|
||||
return new Success("Mallen '$name' uppdaterad.");
|
||||
}
|
||||
|
||||
private function delete_template() {
|
||||
try {
|
||||
$template = $_POST['template'];
|
||||
Template::delete_template($template);
|
||||
$name = ucfirst(strtolower($template));
|
||||
return new Success("Mallen '$name' har raderats.");
|
||||
} catch(Exception $e) {
|
||||
return new Failure('Det finns ingen mall med det namnet.');
|
||||
}
|
||||
}
|
||||
|
||||
private function suggest() {
|
||||
return new Success(suggest($_POST['type']));
|
||||
}
|
||||
|
||||
private function discard_product() {
|
||||
$product = new Product($_POST['id']);
|
||||
if(!$product->get_discardtime()) {
|
||||
if($product->get_active_loan()) {
|
||||
return new Failure('Artikeln har ett aktivt lån.<br/>'
|
||||
.'Lånet måste avslutas innan artikeln skrotas.');
|
||||
}
|
||||
$product->discard();
|
||||
return new Success('Artikeln skrotad.');
|
||||
} else {
|
||||
return new Failure('Artikeln är redan skrotad.');
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
58
include/CheckoutPage.php
Normal file
58
include/CheckoutPage.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
class CheckoutPage extends Page {
|
||||
private $userstr = '';
|
||||
private $user = null;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['user'])) {
|
||||
$this->userstr = $_GET['user'];
|
||||
try {
|
||||
$this->user = new User($this->userstr, 'name');
|
||||
} catch(Exception $ue) {
|
||||
try {
|
||||
$ldap = new Ldap();
|
||||
$ldap->get_user($this->userstr);
|
||||
$this->user = User::create_user($this->userstr);
|
||||
} catch(Exception $le) {
|
||||
$this->error = "Användarnamnet '";
|
||||
$this->error .= $this->userstr;
|
||||
$this->error .= "' kunde inte hittas.";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
$username = '';
|
||||
$displayname = '';
|
||||
$notes = '';
|
||||
$loan_table = '';
|
||||
$subhead = '';
|
||||
$enddate = '';
|
||||
$disabled = 'disabled';
|
||||
if($this->user !== null) {
|
||||
$username = $this->user->get_name();
|
||||
$displayname = $this->user->get_displayname();
|
||||
$notes = $this->user->get_notes();
|
||||
$enddate = gmdate('Y-m-d', time() + 604800); # 1 week from now
|
||||
$disabled = '';
|
||||
$loans = $this->user->get_loans('active');
|
||||
$loan_table = 'Inga pågående lån.';
|
||||
if($loans) {
|
||||
$loan_table = $this->build_user_loan_table($loans, 'renew');
|
||||
}
|
||||
$subhead = replace(array('title' => 'Lånade artiklar'),
|
||||
$this->fragments['subtitle']);
|
||||
}
|
||||
print(replace(array('user' => $this->userstr,
|
||||
'displayname' => $displayname,
|
||||
'notes' => $notes,
|
||||
'end' => $enddate,
|
||||
'subtitle' => $subhead,
|
||||
'disabled' => $disabled,
|
||||
'loan_table' => $loan_table),
|
||||
$this->fragments['checkout_page']));
|
||||
}
|
||||
}
|
||||
?>
|
7
include/Failure.php
Normal file
7
include/Failure.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
class Failure extends Result {
|
||||
public function __construct($message) {
|
||||
parent::__construct('error', $message);
|
||||
}
|
||||
}
|
||||
?>
|
80
include/HistoryPage.php
Normal file
80
include/HistoryPage.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
class HistoryPage extends Page {
|
||||
private $action = 'list';
|
||||
private $inventory = null;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['action'])) {
|
||||
$this->action = $_GET['action'];
|
||||
}
|
||||
if(isset($_GET['id'])) {
|
||||
try {
|
||||
$this->inventory = new Inventory($_GET['id']);
|
||||
} catch(Exception $e) {
|
||||
$this->inventory = null;
|
||||
$this->action = 'list';
|
||||
$this->error = 'Det finns ingen inventering med det ID-numret.';
|
||||
}
|
||||
}
|
||||
switch($this->action) {
|
||||
case 'show':
|
||||
$this->subtitle = 'Inventeringsdetaljer';
|
||||
break;
|
||||
case 'list':
|
||||
$this->subtitle = 'Genomförda inventeringar';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
switch($this->action) {
|
||||
case 'list':
|
||||
print($this->build_inventory_table());
|
||||
print(replace(array('title' => 'Skrotade artiklar'),
|
||||
$this->fragments['title']));
|
||||
$discards = get_items('product_discarded');
|
||||
if($discards) {
|
||||
print($this->build_product_table($discards));
|
||||
} else {
|
||||
print('Inga artiklar skrotade.');
|
||||
}
|
||||
break;
|
||||
case 'show':
|
||||
if($this->inventory &&
|
||||
Inventory::get_active() !== $this->inventory) {
|
||||
print($this->build_inventory_details($this->inventory,
|
||||
false));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function build_inventory_table() {
|
||||
$items = get_items('inventory_old');
|
||||
if(!$items) {
|
||||
return 'Inga inventeringar gjorda.';
|
||||
}
|
||||
$rows = '';
|
||||
foreach($items as $inventory) {
|
||||
$id = $inventory->get_id();
|
||||
$inventory_link = replace(array('id' => $id,
|
||||
'name' => $id,
|
||||
'page' => 'history'),
|
||||
$this->fragments['item_link']);
|
||||
$duration = $inventory->get_duration();
|
||||
$num_seen = count($inventory->get_seen_products());
|
||||
$num_unseen = count($inventory->get_unseen_products());
|
||||
$rows .= replace(array('item_link' => $inventory_link,
|
||||
'start_date' => $duration['start'],
|
||||
'end_date' => $duration['end'],
|
||||
'num_seen' => $num_seen,
|
||||
'num_unseen' => $num_unseen),
|
||||
$this->fragments['inventory_row']);
|
||||
}
|
||||
return replace(array('item' => 'Tillfälle',
|
||||
'rows' => $rows),
|
||||
$this->fragments['inventory_table']);
|
||||
}
|
||||
}
|
||||
?>
|
141
include/Inventory.php
Normal file
141
include/Inventory.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
class Inventory {
|
||||
private $id = '';
|
||||
private $starttime = '';
|
||||
private $endtime = null;
|
||||
private $seen_products = array();
|
||||
|
||||
public static function begin() {
|
||||
if(Inventory::get_active() !== null) {
|
||||
throw new Exception('Inventory already in progress.');
|
||||
}
|
||||
$now = time();
|
||||
$start = prepare('insert into `inventory`(`starttime`) values (?)');
|
||||
bind($start, 'i', $now);
|
||||
execute($start);
|
||||
$invid = $start->insert_id;
|
||||
$prodid = '';
|
||||
$register = prepare('insert into
|
||||
`inventory_product`(`inventory`, `product`)
|
||||
values (?, ?)');
|
||||
foreach(get_items('loan_active') as $loan) {
|
||||
$prodid = $loan->get_product()->get_id();
|
||||
bind($register, 'ii', $invid, $prodid);
|
||||
execute($register);
|
||||
}
|
||||
return new Inventory($invid);
|
||||
}
|
||||
|
||||
public static function get_active() {
|
||||
$search = prepare('select * from `inventory` where `endtime` is null');
|
||||
execute($search);
|
||||
$result = result_single($search);
|
||||
if($result === null) {
|
||||
return null;
|
||||
}
|
||||
return new Inventory($result['id']);
|
||||
}
|
||||
|
||||
public function __construct($id) {
|
||||
$search = prepare('select `id` from `inventory` where `id`=?');
|
||||
bind($search, 'i', $id);
|
||||
execute($search);
|
||||
$result = result_single($search);
|
||||
if($result === null) {
|
||||
throw new Exception('Invalid id');
|
||||
}
|
||||
$this->id = $result['id'];
|
||||
$this->update_fields();
|
||||
}
|
||||
|
||||
private function update_fields() {
|
||||
$get = prepare('select * from `inventory` where `id`=?');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$result = result_single($get);
|
||||
$this->starttime = $result['starttime'];
|
||||
$this->endtime = $result['endtime'];
|
||||
$prodget = prepare('select * from `inventory_product`
|
||||
where `inventory`=?');
|
||||
bind($prodget, 'i', $this->id);
|
||||
execute($prodget);
|
||||
foreach(result_list($prodget) as $row) {
|
||||
$this->seen_products[] = $row['product'];
|
||||
}
|
||||
}
|
||||
|
||||
public function end() {
|
||||
$now = time();
|
||||
$update = prepare('update `inventory` set `endtime`=?
|
||||
where `id`=? and `endtime` is null');
|
||||
bind($update, 'ii', $now, $this->id);
|
||||
execute($update);
|
||||
$this->endtime = $now;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function add_product($product) {
|
||||
$add = prepare('insert into `inventory_product`(`inventory`, `product`)
|
||||
values (?, ?)');
|
||||
bind($add, 'ii', $this->id, $product->get_id());
|
||||
try {
|
||||
execute($add);
|
||||
} catch(Exception $e) {
|
||||
return false;
|
||||
}
|
||||
$this->products[] = $product->get_id();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_duration($format = true) {
|
||||
$style = function($time) {
|
||||
return $time;
|
||||
};
|
||||
if($format) {
|
||||
$style = function($time) {
|
||||
return gmdate('Y-m-d', $time);
|
||||
};
|
||||
}
|
||||
return array('start' => $style($this->starttime),
|
||||
'end' => $style($this->endtime));
|
||||
}
|
||||
|
||||
public function get_seen_products() {
|
||||
$out = array();
|
||||
foreach($this->seen_products as $prodid) {
|
||||
$out[] = new Product($prodid);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function get_unseen_products() {
|
||||
$all = get_items('product');
|
||||
$out = array();
|
||||
$include = function($product) {
|
||||
if(!in_array($product->get_id(), $this->seen_products)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if($this->endtime) {
|
||||
$include = function($product) {
|
||||
if($product->get_createtime() < $this->endtime
|
||||
&& !in_array($product->get_id(), $this->seen_products)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
foreach($all as $product) {
|
||||
if($include($product)) {
|
||||
$out[] = $product;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
?>
|
18
include/InventoryPage.php
Normal file
18
include/InventoryPage.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
class InventoryPage extends Page {
|
||||
private $inventory = null;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->inventory = Inventory::get_active();
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
if($this->inventory === null) {
|
||||
print($this->fragments['inventory_start']);
|
||||
return;
|
||||
}
|
||||
print($this->build_inventory_details($this->inventory));
|
||||
}
|
||||
}
|
||||
?>
|
56
include/Kvs.php
Normal file
56
include/Kvs.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
class Kvs {
|
||||
private $items = array();
|
||||
|
||||
public function __construct() {
|
||||
$get = prepare('select * from `kvs`');
|
||||
execute($get);
|
||||
foreach(result_list($get) as $row) {
|
||||
$key = $row['key'];
|
||||
$value = $row['value'];
|
||||
$this->items[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
public function get_keys() {
|
||||
return array_keys($this->items);
|
||||
}
|
||||
|
||||
public function get_value($key) {
|
||||
if(isset($this->items[$key])) {
|
||||
return $this->items[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function set_key($key, $value) {
|
||||
$find = prepare('select * from `kvs` where `key`=?');
|
||||
bind($find, 's', $key);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
$update = prepare('insert into `kvs`(`value`, `key`)
|
||||
values (?, ?)');
|
||||
} else {
|
||||
$update = prepare('update `kvs` set `value`=? where `key`=?');
|
||||
}
|
||||
bind($update, 'ss', $value, $key);
|
||||
execute($update);
|
||||
$this->items[$key] = $value;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function remove_key($key) {
|
||||
$find = prepare('select * from `kvs` where `key`=?');
|
||||
bind($find, 's', $key);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
return true;
|
||||
}
|
||||
$update = prepare('delete from `kvs` where `key`=?');
|
||||
bind($update, 's', $key);
|
||||
execute($update);
|
||||
unset($this->items[$key]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
class Ldap {
|
||||
private $conn;
|
||||
private $base_dn = "dc=su,dc=se";
|
||||
@ -42,6 +41,4 @@ class Ldap {
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
$ldap = new Ldap();
|
||||
?>
|
93
include/Loan.php
Normal file
93
include/Loan.php
Normal file
@ -0,0 +1,93 @@
|
||||
<?php
|
||||
class Loan {
|
||||
private $id = 0;
|
||||
private $user = 0;
|
||||
private $product = 0;
|
||||
private $starttime = 0;
|
||||
private $endtime = 0;
|
||||
private $returntime = null;
|
||||
|
||||
public function __construct($id) {
|
||||
$this->id = $id;
|
||||
$this->update_fields();
|
||||
}
|
||||
|
||||
private function update_fields() {
|
||||
$get = prepare('select * from `loan` where `id`=?');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$loan = result_single($get);
|
||||
$this->user = $loan['user'];
|
||||
$this->product = $loan['product'];
|
||||
$this->starttime = $loan['starttime'];
|
||||
$this->endtime = $loan['endtime'];
|
||||
$this->returntime = $loan['returntime'];
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_user() {
|
||||
return new User($this->user);
|
||||
}
|
||||
|
||||
public function get_product() {
|
||||
return new Product($this->product);
|
||||
}
|
||||
|
||||
public function get_duration($format = true) {
|
||||
$style = function($time) {
|
||||
return $time;
|
||||
};
|
||||
if($format) {
|
||||
$style = function($time) {
|
||||
if($time) {
|
||||
return gmdate('Y-m-d', $time);
|
||||
}
|
||||
return $time;
|
||||
};
|
||||
}
|
||||
return array('start' => $style($this->starttime),
|
||||
'end' => $style($this->endtime),
|
||||
'end_renew' => $style($this->endtime + 604800), # +1 week
|
||||
'return' => $style($this->returntime));
|
||||
}
|
||||
|
||||
public function is_active() {
|
||||
if($this->returntime === null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function extend($time) {
|
||||
$ts = strtotime($time . ' 13:00');
|
||||
$query = prepare('update `loan` set `endtime`=? where `id`=?');
|
||||
bind($query, 'ii', $ts, $this->id);
|
||||
execute($query);
|
||||
$this->endtime = $ts;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function end() {
|
||||
$now = time();
|
||||
$query = prepare('update `loan` set `returntime`=? where `id`=?');
|
||||
bind($query, 'ii', $now, $this->id);
|
||||
execute($query);
|
||||
$this->returntime = $now;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function is_overdue() {
|
||||
if($this->returntime !== null) {
|
||||
return false;
|
||||
}
|
||||
$now = time();
|
||||
if($now > $this->endtime) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
?>
|
306
include/Page.php
Normal file
306
include/Page.php
Normal file
@ -0,0 +1,306 @@
|
||||
<?php
|
||||
abstract class Page extends Responder {
|
||||
protected abstract function render_body();
|
||||
|
||||
protected $page = 'checkout';
|
||||
protected $title = "DSV Utlåning";
|
||||
protected $subtitle = '';
|
||||
protected $error = null;
|
||||
protected $menuitems = array('checkout' => 'Låna',
|
||||
'return' => 'Lämna',
|
||||
'products' => 'Artiklar',
|
||||
'users' => 'Låntagare',
|
||||
'inventory' => 'Inventera',
|
||||
'history' => 'Historik',
|
||||
'search' => 'Sök');
|
||||
private $template_parts = array();
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->template_parts = get_fragments('./html/base.html');
|
||||
|
||||
if(isset($_GET['page'])) {
|
||||
$this->page = $_GET['page'];
|
||||
}
|
||||
if(isset($this->menuitems[$this->page])) {
|
||||
$this->subtitle = $this->menuitems[$this->page];
|
||||
}
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->render_head();
|
||||
$this->render_body();
|
||||
if($this->error) {
|
||||
$this->render_error();
|
||||
}
|
||||
$this->render_foot();
|
||||
}
|
||||
|
||||
final private function render_head() {
|
||||
$headtitle = $this->title;
|
||||
$pagetitle = $this->title;
|
||||
if($this->subtitle) {
|
||||
$headtitle .= ' - '. $this->subtitle;
|
||||
$pagetitle = $this->subtitle;
|
||||
}
|
||||
$query = '';
|
||||
if(isset($_GET['q'])) {
|
||||
$query = $_GET['q'];
|
||||
}
|
||||
print(replace(
|
||||
array('title' => $headtitle,
|
||||
'menu' => $this->build_menu(),
|
||||
'query'=> $query),
|
||||
$this->template_parts['head']
|
||||
));
|
||||
print(replace(array('title' => $pagetitle),
|
||||
$this->fragments['title']));
|
||||
}
|
||||
|
||||
private function build_menu() {
|
||||
$menu = '';
|
||||
foreach($this->menuitems as $page => $title) {
|
||||
$align = 'left';
|
||||
$active = '';
|
||||
if($this->page == $page) {
|
||||
$active = 'active';
|
||||
}
|
||||
if($page == 'search') {
|
||||
$align = 'right';
|
||||
}
|
||||
$menu .= replace(array('title' => $title,
|
||||
'page' => $page,
|
||||
'align' => $align,
|
||||
'active' => $active),
|
||||
$this->template_parts['menuitem']);
|
||||
}
|
||||
return $menu;
|
||||
}
|
||||
|
||||
final private function render_error() {
|
||||
print(replace(array('type' => 'error',
|
||||
'message' => $this->error),
|
||||
$this->fragments['message']));
|
||||
}
|
||||
|
||||
final private function render_foot() {
|
||||
print($this->template_parts['foot']);
|
||||
}
|
||||
|
||||
final protected function build_user_table($users) {
|
||||
$rows = '';
|
||||
foreach($users as $user) {
|
||||
$replacements = array('name' => '',
|
||||
'loan' => '',
|
||||
'has_notes' => '',
|
||||
'notes' => '',
|
||||
'item_link' => '');
|
||||
$replacements['name'] = $user->get_name();
|
||||
$notes = $user->get_notes();
|
||||
if($notes) {
|
||||
$replacements['notes'] = $notes;
|
||||
$replacements['has_notes'] = '*';
|
||||
}
|
||||
$userlink = replace(array('id' => $user->get_id(),
|
||||
'name' => $user->get_displayname(),
|
||||
'page' => 'users'),
|
||||
$this->fragments['item_link']);
|
||||
$replacements['item_link'] = $userlink;
|
||||
$loans = $user->get_loans('active');
|
||||
$loan_str = '';
|
||||
$count = count($loans);
|
||||
switch($count) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
$product = $loans[0]->get_product();
|
||||
$loan_str = $product->get_name();
|
||||
break;
|
||||
default:
|
||||
$loan_str = $count .' artiklar';
|
||||
break;
|
||||
}
|
||||
$replacements['loan'] = $loan_str;
|
||||
$rows .= replace($replacements, $this->fragments['user_row']);
|
||||
}
|
||||
return replace(array('rows' => $rows),
|
||||
$this->fragments['user_table']);
|
||||
}
|
||||
|
||||
final protected function build_product_table($products) {
|
||||
$rows = '';
|
||||
foreach($products as $product) {
|
||||
$prodlink = replace(array('id' => $product->get_id(),
|
||||
'name' => $product->get_name(),
|
||||
'page' => 'products'),
|
||||
$this->fragments['item_link']);
|
||||
$available = 'Tillgänglig';
|
||||
$status = 'available';
|
||||
$discarded = $product->get_discardtime();
|
||||
if($discarded) {
|
||||
$available = 'Skrotad '.$discarded;
|
||||
$status = 'discarded';
|
||||
} else {
|
||||
$loan = $product->get_active_loan();
|
||||
if($loan) {
|
||||
$user = $loan->get_user();
|
||||
$userlink = replace(array('name' => $user->get_displayname(),
|
||||
'id' => $user->get_id(),
|
||||
'page' => 'users'),
|
||||
$this->fragments['item_link']);
|
||||
$available = 'Utlånad till '.$userlink;
|
||||
if($loan->is_overdue()) {
|
||||
$status = 'overdue';
|
||||
$available .= ', försenad';
|
||||
} else {
|
||||
$status = 'on_loan';
|
||||
$available .= ', åter '.$loan->get_duration()['end'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$rows .= replace(array('available' => $available,
|
||||
'status' => $status,
|
||||
'item_link' => $prodlink),
|
||||
$this->fragments['product_row']);
|
||||
}
|
||||
return replace(array('rows' => $rows),
|
||||
$this->fragments['product_table']);
|
||||
}
|
||||
|
||||
final protected function build_user_loan_table($loans, $show = 'none') {
|
||||
$vis_return = 'hidden';
|
||||
$vis_renew = 'hidden';
|
||||
switch($show) {
|
||||
case 'return':
|
||||
$vis_return = '';
|
||||
break;
|
||||
case 'renew':
|
||||
$vis_renew = '';
|
||||
break;
|
||||
case 'both':
|
||||
$vis_return = '';
|
||||
$vis_renew = '';
|
||||
break;
|
||||
case 'none':
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid argument.');
|
||||
}
|
||||
$rows = '';
|
||||
foreach($loans as $loan) {
|
||||
$product = $loan->get_product();
|
||||
$prodlink = replace(array('id' => $product->get_id(),
|
||||
'name' => $product->get_name(),
|
||||
'page' => 'products'),
|
||||
$this->fragments['item_link']);
|
||||
$available = '';
|
||||
$duration = $loan->get_duration();
|
||||
$status = 'on_loan';
|
||||
if($loan->is_overdue()) {
|
||||
$status = 'overdue';
|
||||
}
|
||||
$returndate = '';
|
||||
if($duration['return'] !== null) {
|
||||
$returndate = $duration['return'];
|
||||
}
|
||||
$rows .= replace(array('id' => $product->get_id(),
|
||||
'item_link' => $prodlink,
|
||||
'start_date' => $duration['start'],
|
||||
'end_date' => $duration['end'],
|
||||
'return_date' => $returndate,
|
||||
'status' => $status,
|
||||
'vis_renew' => $vis_renew,
|
||||
'vis_return' => $vis_return,
|
||||
'end_new' => $duration['end_renew']),
|
||||
$this->fragments['loan_row']);
|
||||
}
|
||||
return replace(array('rows' => $rows,
|
||||
'vis_renew' => $vis_renew,
|
||||
'vis_return' => $vis_return,
|
||||
'item' => 'Artikel'),
|
||||
$this->fragments['loan_table']);
|
||||
}
|
||||
|
||||
final protected function build_product_loan_table($loans) {
|
||||
$rows = '';
|
||||
$renew_column_visible = 'hidden';
|
||||
foreach($loans as $loan) {
|
||||
$user = $loan->get_user();
|
||||
$product = $loan->get_product();
|
||||
$userlink = replace(array('id' => $user->get_id(),
|
||||
'name' => $user->get_name(),
|
||||
'page' => 'users'),
|
||||
$this->fragments['item_link']);
|
||||
$available = '';
|
||||
$duration = $loan->get_duration();
|
||||
$status = 'on_loan';
|
||||
if($loan->is_overdue()) {
|
||||
$status = 'overdue';
|
||||
}
|
||||
$returndate = '';
|
||||
$renew_visible = '';
|
||||
if($duration['return']) {
|
||||
$returndate = $duration['return'];
|
||||
$renew_visible = 'hidden';
|
||||
} else {
|
||||
$renew_column_visible = '';
|
||||
}
|
||||
$rows .= replace(array('item_link' => $userlink,
|
||||
'start_date' => $duration['start'],
|
||||
'end_date' => $duration['end'],
|
||||
'return_date' => $returndate,
|
||||
'status' => $status,
|
||||
'vis_renew' => $renew_column_visible,
|
||||
'vis_renew_button' => $renew_visible,
|
||||
'vis_return' => '',
|
||||
'id' => $product->get_id(),
|
||||
'end_new' => $duration['end_renew']),
|
||||
$this->fragments['loan_row']);
|
||||
}
|
||||
return replace(array('rows' => $rows,
|
||||
'vis_renew' => $renew_column_visible,
|
||||
'vis_return' => '',
|
||||
'item' => 'Låntagare'),
|
||||
$this->fragments['loan_table']);
|
||||
}
|
||||
|
||||
final protected function build_inventory_details($inventory,
|
||||
$interactive = true) {
|
||||
$duration = $inventory->get_duration();
|
||||
$all_products = get_items('product');
|
||||
$seen = $inventory->get_seen_products();
|
||||
$unseen = array();
|
||||
foreach($all_products as $product) {
|
||||
if(!in_array($product, $seen)) {
|
||||
$unseen[] = $product;
|
||||
}
|
||||
}
|
||||
$missing = 'Saknade artiklar';
|
||||
$hidden = 'hidden';
|
||||
if($interactive) {
|
||||
$missing = 'Kvarvarande artiklar';
|
||||
$hidden = '';
|
||||
}
|
||||
$out = replace(array('start_date' => $duration['start'],
|
||||
'total_count' => count($all_products),
|
||||
'seen_count' => count($seen),
|
||||
'hide' => $hidden),
|
||||
$this->fragments['inventory_do']);
|
||||
$out .= replace(array('title' => $missing),
|
||||
$this->fragments['subtitle']);
|
||||
if($unseen) {
|
||||
$out .= $this->build_product_table($unseen);
|
||||
} else {
|
||||
$out .= 'Inga artiklar saknas.';
|
||||
}
|
||||
$out .= replace(array('title' => 'Inventerade artiklar'),
|
||||
$this->fragments['subtitle']);
|
||||
if($seen) {
|
||||
$out .= $this->build_product_table($seen);
|
||||
} else {
|
||||
$out .= 'Inga artiklar inventerade.';
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
?>
|
18
include/Printer.php
Normal file
18
include/Printer.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
class Printer extends QR {
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$label = replace(array('id' => $this->product->get_id(),
|
||||
'name' => $this->product->get_name(),
|
||||
'serial' => $this->product->get_serial()),
|
||||
$this->fragments['product_label']);
|
||||
$title = 'Etikett för artikel '.$this->product->get_serial();
|
||||
print(replace(array('title' => $title,
|
||||
'label' => $label),
|
||||
$this->fragments['label_page']));
|
||||
}
|
||||
}
|
||||
?>
|
318
include/Product.php
Normal file
318
include/Product.php
Normal file
@ -0,0 +1,318 @@
|
||||
<?php
|
||||
class Product {
|
||||
private $id = 0;
|
||||
private $name = '';
|
||||
private $invoice = '';
|
||||
private $serial = '';
|
||||
private $createtime = null;
|
||||
private $discardtime = null;
|
||||
private $info = array();
|
||||
private $tags = array();
|
||||
|
||||
public static function create_product(
|
||||
$name = '',
|
||||
$invoice = '',
|
||||
$serial = '',
|
||||
$info = array(),
|
||||
$tags = array()
|
||||
) {
|
||||
$now = time();
|
||||
begin_trans();
|
||||
try {
|
||||
$stmt = 'insert into
|
||||
`product`(`name`, `invoice`, `serial`, `createtime`)
|
||||
values (?, ?, ?, ?)';
|
||||
$ins_prod = prepare($stmt);
|
||||
bind($ins_prod, 'sssi', $name, $invoice, $serial, $now);
|
||||
execute($ins_prod);
|
||||
$product = new Product($serial, 'serial');
|
||||
foreach($info as $field => $value) {
|
||||
$product->set_info($field, $value);
|
||||
}
|
||||
foreach($tags as $tag) {
|
||||
$product->add_tag($tag);
|
||||
}
|
||||
commit_trans();
|
||||
return $product;
|
||||
} catch(Exception $e) {
|
||||
revert_trans();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function __construct($clue, $type = 'id') {
|
||||
$search = null;
|
||||
switch($type) {
|
||||
case 'id':
|
||||
$search = prepare('select `id` from `product`
|
||||
where `id`=?');
|
||||
bind($search, 'i', $clue);
|
||||
break;
|
||||
case 'serial':
|
||||
$search = prepare('select `id` from `product`
|
||||
where `serial`=?');
|
||||
bind($search, 's', $clue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid type.');
|
||||
}
|
||||
execute($search);
|
||||
$result = result_single($search);
|
||||
if($result === null) {
|
||||
throw new Exception('Product does not exist..');
|
||||
}
|
||||
$this->id = $result['id'];
|
||||
$this->update_fields();
|
||||
$this->update_info();
|
||||
$this->update_tags();
|
||||
}
|
||||
|
||||
private function update_fields() {
|
||||
$get = prepare('select * from `product` where `id`=?');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$product = result_single($get);
|
||||
$this->name = $product['name'];
|
||||
$this->invoice = $product['invoice'];
|
||||
$this->serial = $product['serial'];
|
||||
$this->createtime = $product['createtime'];
|
||||
$this->discardtime = $product['discardtime'];
|
||||
return true;
|
||||
}
|
||||
|
||||
private function update_info() {
|
||||
$get = prepare('select * from `product_info`
|
||||
where `product`=? order by `field`');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
foreach(result_list($get) as $row) {
|
||||
$field = $row['field'];
|
||||
$data = $row['data'];
|
||||
$this->info[$field] = $data;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function update_tags() {
|
||||
$get = prepare('select * from `product_tag`
|
||||
where `product`=? order by `tag`');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$newtags = array();
|
||||
foreach(result_list($get) as $row) {
|
||||
$newtags[] = $row['tag'];
|
||||
}
|
||||
$this->tags = $newtags;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matches($terms) {
|
||||
foreach($terms as $field => $values) {
|
||||
$matchvalues = array();
|
||||
if(property_exists($this, $field)) {
|
||||
$matchvalues[] = $this->$field;
|
||||
} else if(array_key_exists($field, $this->get_info())) {
|
||||
$matchvalues[] = $this->get_info()[$field];
|
||||
} else {
|
||||
switch($field) {
|
||||
case 'tag':
|
||||
$matchvalues = $this->get_tags();
|
||||
case 'status':
|
||||
$matchvalues[] = $this->get_loan_status();
|
||||
case 'fritext':
|
||||
$matchvalues[] = $this->name;
|
||||
$matchvalues[] = $this->serial;
|
||||
$matchvalues[] = $this->invoice;
|
||||
$matchvalues = array_merge($matchvalues,
|
||||
$this->get_tags(),
|
||||
array_values(
|
||||
$this->get_info()));
|
||||
}
|
||||
}
|
||||
if(!match($values, $matchvalues)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_createtime() {
|
||||
return $this->createtime;
|
||||
}
|
||||
|
||||
public function get_discardtime($format = true) {
|
||||
if($this->discardtime && $format) {
|
||||
return gmdate('Y-m-d', $this->discardtime);
|
||||
}
|
||||
return $this->discardtime;
|
||||
}
|
||||
|
||||
public function discard() {
|
||||
$now = time();
|
||||
$update = prepare('update `product` set `discardtime`=? where `id`=?');
|
||||
bind($update, 'ii', $now, $this->id);
|
||||
execute($update);
|
||||
$this->discardtime = $now;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function set_name($newname) {
|
||||
$update = prepare('update `product` set `name`=? where `id`=?');
|
||||
bind($update, 'si', $newname, $this->id);
|
||||
execute($update);
|
||||
$this->name = $newname;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_invoice() {
|
||||
return $this->invoice;
|
||||
}
|
||||
|
||||
public function set_invoice($newinvoice) {
|
||||
$update = prepare('update `product` set `invoice`=? where `id`=?');
|
||||
bind($update, 'si', $newinvoice, $this->id);
|
||||
execute($update);
|
||||
$this->invoice = $newinvoice;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_serial() {
|
||||
return $this->serial;
|
||||
}
|
||||
|
||||
public function set_serial($newserial) {
|
||||
$update = prepare('update `product` set `serial`=? where `id`=?');
|
||||
bind($update, 'si', $newserial, $this->id);
|
||||
execute($update);
|
||||
$this->serial = $newserial;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_info() {
|
||||
return $this->info;
|
||||
}
|
||||
|
||||
public function set_info($field, $value) {
|
||||
if(!$value) {
|
||||
return true;
|
||||
}
|
||||
$find = prepare('select * from `product_info`
|
||||
where `product`=? and `field`=?');
|
||||
bind($find, 'is', $this->id, $field);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
$update = prepare('insert into
|
||||
`product_info`(`data`, `product`, `field`)
|
||||
values (?, ?, ?)');
|
||||
} else {
|
||||
$update = prepare('update `product_info` set `data`=?
|
||||
where `product`=? and `field`=?');
|
||||
}
|
||||
bind($update, 'sis', $value, $this->id, $field);
|
||||
execute($update);
|
||||
$this->update_info();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function remove_info($field) {
|
||||
$find = prepare('select * from `product_info`
|
||||
where `product`=? and `field`=?');
|
||||
bind($find, 'is', $this->id, $field);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
return true;
|
||||
}
|
||||
$update = prepare('delete from `product_info`
|
||||
where `field`=? and `product`=?');
|
||||
bind($update, 'si', $field, $this->id);
|
||||
execute($update);
|
||||
$this->update_info();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_tags() {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
public function add_tag($tag) {
|
||||
if(!$tag) {
|
||||
return true;
|
||||
}
|
||||
$find = prepare('select * from `product_tag`
|
||||
where `product`=? and `tag`=?');
|
||||
bind($find, 'is', $this->id, $tag);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
$update = prepare('insert into `product_tag`(`tag`, `product`)
|
||||
values (?, ?)');
|
||||
bind($update, 'si', $tag, $this->id);
|
||||
execute($update);
|
||||
$this->update_tags();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function remove_tag($tag) {
|
||||
$find = prepare('select * from `product_tag`
|
||||
where `product`=? and `tag`=?');
|
||||
bind($find, 'is', $this->id, $tag);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
return true;
|
||||
}
|
||||
$update = prepare('delete from `product_tag`
|
||||
where `tag`=? and `product`=?');
|
||||
bind($update, 'si', $tag, $this->id);
|
||||
execute($update);
|
||||
$this->update_tags();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_loan_status() {
|
||||
if($this->get_discardtime(false)) {
|
||||
return 'discarded';
|
||||
}
|
||||
$loan = $this->get_active_loan();
|
||||
if(!$loan) {
|
||||
return 'no_loan';
|
||||
}
|
||||
if($loan->is_overdue()) {
|
||||
return 'overdue';
|
||||
}
|
||||
return 'on_loan';
|
||||
}
|
||||
|
||||
public function get_active_loan() {
|
||||
$find = prepare('select `id` from `loan`
|
||||
where `returntime` is null and product=?');
|
||||
bind($find, 'i', $this->id);
|
||||
execute($find);
|
||||
$result = result_single($find);
|
||||
if($result === null) {
|
||||
return null;
|
||||
}
|
||||
return new Loan($result['id']);
|
||||
}
|
||||
|
||||
public function get_loan_history() {
|
||||
$find = prepare('select `id` from `loan`
|
||||
where product=? order by `starttime` desc');
|
||||
bind($find, 'i', $this->id);
|
||||
execute($find);
|
||||
$loans = result_list($find);
|
||||
$out = array();
|
||||
foreach($loans as $loan) {
|
||||
$out[] = new Loan($loan['id']);
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
?>
|
133
include/ProductPage.php
Normal file
133
include/ProductPage.php
Normal file
@ -0,0 +1,133 @@
|
||||
<?php
|
||||
class ProductPage extends Page {
|
||||
private $action = 'list';
|
||||
private $template = null;
|
||||
private $product = null;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['action'])) {
|
||||
$this->action = $_GET['action'];
|
||||
}
|
||||
if(isset($_GET['template'])) {
|
||||
$template = $_GET['template'];
|
||||
if($template) {
|
||||
try {
|
||||
$this->template = new Template($template, 'name');
|
||||
} catch(Exception $e) {
|
||||
$this->template = null;
|
||||
$this->error = 'Det finns ingen mall med det namnet.';
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($_GET['id'])) {
|
||||
$id = $_GET['id'];
|
||||
if($id) {
|
||||
try {
|
||||
$this->product = new Product($id);
|
||||
} catch(Exception $e) {
|
||||
$this->action = 'list';
|
||||
$this->product = null;
|
||||
$this->error = 'Det finns ingen artikel med det ID-numret.';
|
||||
}
|
||||
}
|
||||
}
|
||||
switch($this->action) {
|
||||
case 'show':
|
||||
$this->subtitle = 'Artikeldetaljer';
|
||||
break;
|
||||
case 'new':
|
||||
$this->subtitle = 'Ny artikel';
|
||||
break;
|
||||
case 'list':
|
||||
$this->subtitle = 'Artikellista';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
switch($this->action) {
|
||||
case 'list':
|
||||
print($this->fragments['create_product']);
|
||||
print($this->build_product_table(get_items('product')));
|
||||
break;
|
||||
case 'show':
|
||||
print($this->build_product_details());
|
||||
break;
|
||||
case 'new':
|
||||
print($this->build_new_page());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function build_product_details() {
|
||||
$info = '';
|
||||
foreach($this->product->get_info() as $key => $value) {
|
||||
$info .= replace(array('name' => ucfirst($key),
|
||||
'key' => $key,
|
||||
'value' => $value),
|
||||
$this->fragments['info_item']);
|
||||
}
|
||||
$tags = '';
|
||||
foreach($this->escape_tags($this->product->get_tags()) as $tag) {
|
||||
$tags .= replace(array('tag' => ucfirst($tag)),
|
||||
$this->fragments['tag']);
|
||||
}
|
||||
$fields = array('id' => $this->product->get_id(),
|
||||
'name' => $this->product->get_name(),
|
||||
'serial' => $this->product->get_serial(),
|
||||
'invoice' => $this->product->get_invoice(),
|
||||
'tags' => $tags,
|
||||
'info' => $info);
|
||||
$label = '';
|
||||
if(class_exists('QRcode', false)) {
|
||||
$label = replace($fields, $this->fragments['product_label']);
|
||||
}
|
||||
$fields['label'] = $label;
|
||||
$out = replace($fields, $this->fragments['product_details']);
|
||||
if(!$this->product->get_discardtime()) {
|
||||
$out .= replace(array('id' => $this->product->get_id()),
|
||||
$this->fragments['discard_button']);
|
||||
}
|
||||
$out .= replace(array('title' => 'Lånehistorik'),
|
||||
$this->fragments['subtitle']);
|
||||
$loan_table = 'Inga lån att visa.';
|
||||
$history = $this->product->get_loan_history();
|
||||
if($history) {
|
||||
$loan_table = $this->build_product_loan_table($history);
|
||||
}
|
||||
$out .= $loan_table;
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function build_new_page() {
|
||||
$template = '';
|
||||
$fields = '';
|
||||
$tags = '';
|
||||
if($this->template) {
|
||||
$template = $this->template->get_name();
|
||||
foreach($this->template->get_fields() as $field) {
|
||||
$fields .= replace(array('name' => ucfirst($field),
|
||||
'key' => $field,
|
||||
'value' => ''),
|
||||
$this->fragments['info_item']);
|
||||
}
|
||||
foreach($this->template->get_tags() as $tag) {
|
||||
$tags .= replace(array('tag' => ucfirst($tag)),
|
||||
$this->fragments['tag']);
|
||||
}
|
||||
}
|
||||
$out = replace(array('template' => $template),
|
||||
$this->fragments['template_management']);
|
||||
$out .= replace(array('id' => '',
|
||||
'name' => '',
|
||||
'serial' => '',
|
||||
'invoice' => '',
|
||||
'tags' => $tags,
|
||||
'info' => $fields,
|
||||
'label' => ''),
|
||||
$this->fragments['product_details']);
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
?>
|
18
include/QR.php
Normal file
18
include/QR.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
class QR extends Responder {
|
||||
protected $product = '';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['id'])) {
|
||||
$this->product = new Product($_GET['id']);
|
||||
}
|
||||
}
|
||||
|
||||
public function render() {
|
||||
if(class_exists('QRcode', false)) {
|
||||
QRcode::svg((string)$this->product->get_serial());
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
31
include/Responder.php
Normal file
31
include/Responder.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
abstract class Responder {
|
||||
protected $fragments = array();
|
||||
|
||||
public function __construct() {
|
||||
$this->fragments = get_fragments('./html/fragments.html');
|
||||
}
|
||||
|
||||
final protected function escape_tags($tags) {
|
||||
foreach($tags as $key => $tag) {
|
||||
$tags[$key] = str_replace(array("'",
|
||||
'"'),
|
||||
array(''',
|
||||
'"'),
|
||||
strtolower($tag));
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
|
||||
final protected function unescape_tags($tags) {
|
||||
foreach($tags as $key => $tag) {
|
||||
$tags[$key] = str_replace(array(''',
|
||||
'"'),
|
||||
array("'",
|
||||
'"'),
|
||||
strtolower($tag));
|
||||
}
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
?>
|
18
include/Result.php
Normal file
18
include/Result.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
class Result {
|
||||
private $type = '';
|
||||
private $message = '';
|
||||
|
||||
public function __construct($type, $message) {
|
||||
$this->type = $type;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function toJson() {
|
||||
return json_encode(array(
|
||||
'type' => $this->type,
|
||||
'message' => $this->message
|
||||
));
|
||||
}
|
||||
}
|
||||
?>
|
7
include/ReturnPage.php
Normal file
7
include/ReturnPage.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
class ReturnPage extends Page {
|
||||
protected function render_body() {
|
||||
print($this->fragments['return_page']);
|
||||
}
|
||||
}
|
||||
?>
|
156
include/SearchPage.php
Normal file
156
include/SearchPage.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
class SearchPage extends Page {
|
||||
private $terms = array();
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
unset($_GET['page']);
|
||||
if(isset($_GET['q']) && !$_GET['q']) {
|
||||
unset($_GET['q']);
|
||||
}
|
||||
$this->terms = $this->translate_keys($_GET);
|
||||
}
|
||||
|
||||
private function do_search() {
|
||||
$out = array();
|
||||
if(!$this->terms) {
|
||||
return $out;
|
||||
}
|
||||
foreach(array('user', 'product') as $type) {
|
||||
$result = $this->search($type, $this->terms);
|
||||
if($result) {
|
||||
$out[$type] = $result;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function translate_keys($terms) {
|
||||
$translated = array();
|
||||
foreach($terms as $key => $value) {
|
||||
$newkey = $key;
|
||||
switch($key) {
|
||||
case 'q':
|
||||
$newkey = 'fritext';
|
||||
break;
|
||||
case 'namn':
|
||||
$newkey = 'name';
|
||||
break;
|
||||
case 'faktura':
|
||||
case 'fakturanummer':
|
||||
$newkey = 'invoice';
|
||||
break;
|
||||
case 'serienummer':
|
||||
$newkey = 'serial';
|
||||
break;
|
||||
case 'tagg':
|
||||
$newkey = 'tag';
|
||||
break;
|
||||
case 'status':
|
||||
$value = $this->translate_values($value);
|
||||
break;
|
||||
}
|
||||
if(!array_key_exists($newkey, $translated)) {
|
||||
$translated[$newkey] = $value;
|
||||
} else {
|
||||
$temp = $translated[$newkey];
|
||||
$translated[$newkey] = array_merge((array)$temp, (array)$value);
|
||||
}
|
||||
}
|
||||
return $translated;
|
||||
}
|
||||
|
||||
private function translate_values($value) {
|
||||
if(!is_array($value)) {
|
||||
$value = array($value);
|
||||
}
|
||||
$translated = array();
|
||||
foreach($value as $item) {
|
||||
$newitem = $item;
|
||||
switch($item) {
|
||||
case 'ute':
|
||||
case 'utlånad':
|
||||
case 'utlånat':
|
||||
case 'lånad':
|
||||
case 'lånat':
|
||||
$newitem = 'on_loan';
|
||||
break;
|
||||
case 'inne':
|
||||
case 'ledig':
|
||||
case 'ledigt':
|
||||
case 'tillgänglig':
|
||||
case 'tillgängligt':
|
||||
$newitem = 'no_loan';
|
||||
break;
|
||||
case 'sen':
|
||||
case 'sent':
|
||||
case 'försenad':
|
||||
case 'försenat':
|
||||
case 'överdraget':
|
||||
$newitem = 'overdue';
|
||||
break;
|
||||
case 'skrotad':
|
||||
case 'skrotat':
|
||||
case 'slängd':
|
||||
case 'slängt':
|
||||
$newitem = 'discarded';
|
||||
break;
|
||||
}
|
||||
$translated[] = $newitem;
|
||||
}
|
||||
return $translated;
|
||||
}
|
||||
|
||||
private function search($type, $terms) {
|
||||
$items = get_items($type);
|
||||
$out = array();
|
||||
foreach($items as $item) {
|
||||
if($item->matches($terms)) {
|
||||
$out[] = $item;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
$terms = '';
|
||||
foreach($this->terms as $key => $value) {
|
||||
if(!is_array($value)) {
|
||||
$terms .= replace(array('term' => ucfirst($key).": $value",
|
||||
'key' => $key,
|
||||
'value' => $value),
|
||||
$this->fragments['search_term']);
|
||||
} else {
|
||||
foreach($value as $item) {
|
||||
$terms .= replace(array('term' => ucfirst($key).": $item",
|
||||
'key' => $key,
|
||||
'value' => $item),
|
||||
$this->fragments['search_term']);
|
||||
}
|
||||
}
|
||||
}
|
||||
print(replace(array('terms' => $terms),
|
||||
$this->fragments['search_form']));
|
||||
if($this->terms) {
|
||||
$hits = $this->do_search();
|
||||
print(replace(array('title' => 'Sökresultat'),
|
||||
$this->fragments['title']));
|
||||
$result = '';
|
||||
if(isset($hits['user'])) {
|
||||
$result = replace(array('title' => 'Låntagare'),
|
||||
$this->fragments['subtitle']);
|
||||
$result .= $this->build_user_table($hits['user']);
|
||||
}
|
||||
if(isset($hits['product'])) {
|
||||
$result .= replace(array('title' => 'Artiklar'),
|
||||
$this->fragments['subtitle']);
|
||||
$result .= $this->build_product_table($hits['product']);
|
||||
}
|
||||
if(!$result) {
|
||||
$result = 'Inga träffar.';
|
||||
}
|
||||
print($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
7
include/Success.php
Normal file
7
include/Success.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
class Success extends Result {
|
||||
public function __construct($message) {
|
||||
parent::__construct('success', $message);
|
||||
}
|
||||
}
|
||||
?>
|
196
include/Template.php
Normal file
196
include/Template.php
Normal file
@ -0,0 +1,196 @@
|
||||
<?php
|
||||
class Template {
|
||||
private $id = 0;
|
||||
private $name = '';
|
||||
private $fields = array();
|
||||
private $tags = array();
|
||||
|
||||
public static function create_template(
|
||||
$name = '',
|
||||
$fields = array(),
|
||||
$tags = array()
|
||||
) {
|
||||
begin_trans();
|
||||
try {
|
||||
$stmt = 'insert into `template`(`name`) values (?)';
|
||||
$ins_prod = prepare($stmt);
|
||||
bind($ins_prod, 's', strtolower($name));
|
||||
execute($ins_prod);
|
||||
$template = new Template($name, 'name');
|
||||
foreach(array_keys($fields) as $field) {
|
||||
$template->add_field($field);
|
||||
}
|
||||
foreach($tags as $tag) {
|
||||
$template->add_tag($tag);
|
||||
}
|
||||
commit_trans();
|
||||
return $template;
|
||||
} catch(Exception $e) {
|
||||
revert_trans();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function delete_template($name) {
|
||||
$template = new Template($name, 'name');
|
||||
foreach($template->get_fields() as $field) {
|
||||
$template->remove_field($field);
|
||||
}
|
||||
foreach($template->get_tags() as $tag) {
|
||||
$template->remove_tag($tag);
|
||||
}
|
||||
$delete = prepare('delete from `template` where `id`=?');
|
||||
bind($delete, 'i', $template->get_id());
|
||||
execute($delete);
|
||||
return true;
|
||||
}
|
||||
|
||||
public function __construct($clue, $type = 'id') {
|
||||
switch($type) {
|
||||
case 'id':
|
||||
$this->id = $clue;
|
||||
$search = prepare('select `name` from `template`
|
||||
where `id`=?');
|
||||
bind($search, 'i', $this->id);
|
||||
execute($search);
|
||||
$result = result_single($search);
|
||||
if($result === null) {
|
||||
throw new Exception('Invalid id');
|
||||
}
|
||||
$this->name = $result['name'];
|
||||
break;
|
||||
case 'name':
|
||||
$this->name = strtolower($clue);
|
||||
$search = prepare('select `id` from `template`
|
||||
where `name`=?');
|
||||
bind($search, 's', $this->name);
|
||||
execute($search);
|
||||
$result = result_single($search);
|
||||
if($result === null) {
|
||||
throw new Exception('Invalid name.');
|
||||
}
|
||||
$this->id = $result['id'];
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid type.');
|
||||
}
|
||||
$this->update_fields();
|
||||
$this->update_tags();
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return ucfirst($this->name);
|
||||
}
|
||||
|
||||
public function set_name($name) {
|
||||
$update = prepare('update `template` set `name`=? where `id`=?');
|
||||
bind($update, 'si', $name, $this->id);
|
||||
execute($update);
|
||||
$this->name = $name;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function update_fields() {
|
||||
$get = prepare('select `field` from `template_info`
|
||||
where `template`=? order by `field`');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$fields = array();
|
||||
foreach(result_list($get) as $row) {
|
||||
$fields[] = $row['field'];
|
||||
}
|
||||
$this->fields = $fields;
|
||||
return true;
|
||||
}
|
||||
|
||||
private function update_tags() {
|
||||
$get = prepare('select * from `template_tag`
|
||||
where `template`=? order by `tag`');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$newtags = array();
|
||||
foreach(result_list($get) as $row) {
|
||||
$newtags[] = $row['tag'];
|
||||
}
|
||||
$this->tags = $newtags;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_fields() {
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
public function add_field($field) {
|
||||
$find = prepare('select * from `template_info`
|
||||
where `template`=? and `field`=?');
|
||||
bind($find, 'is', $this->id, $field);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
$update = prepare('insert into `template_info`(`template`, `field`)
|
||||
values (?, ?)');
|
||||
bind($update, 'is', $this->id, $field);
|
||||
execute($update);
|
||||
$this->update_fields();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function remove_field($field) {
|
||||
$find = prepare('select * from `template_info`
|
||||
where `template`=? and `field`=?');
|
||||
bind($find, 'is', $this->id, $field);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
return true;
|
||||
}
|
||||
$update = prepare('delete from `template_info`
|
||||
where `field`=? and `template`=?');
|
||||
bind($update, 'si', $field, $this->id);
|
||||
execute($update);
|
||||
$this->update_fields();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_tags() {
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
public function add_tag($tag) {
|
||||
if(!$tag) {
|
||||
return true;
|
||||
}
|
||||
$find = prepare('select * from `template_tag`
|
||||
where `template`=? and `tag`=?');
|
||||
bind($find, 'is', $this->id, $tag);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
$update = prepare('insert into `template_tag`(`tag`, `template`)
|
||||
values (?, ?)');
|
||||
bind($update, 'si', $tag, $this->id);
|
||||
execute($update);
|
||||
$this->update_tags();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function remove_tag($tag) {
|
||||
$find = prepare('select * from `template_tag`
|
||||
where `template`=? and `tag`=?');
|
||||
bind($find, 'is', $this->id, $tag);
|
||||
execute($find);
|
||||
if(result_single($find) === null) {
|
||||
return true;
|
||||
}
|
||||
$update = prepare('delete from `template_tag`
|
||||
where `tag`=? and `template`=?');
|
||||
bind($update, 'si', $tag, $this->id);
|
||||
execute($update);
|
||||
$this->update_tags();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
176
include/User.php
Normal file
176
include/User.php
Normal file
@ -0,0 +1,176 @@
|
||||
<?php
|
||||
class User {
|
||||
private $id = 0;
|
||||
private $name = '';
|
||||
private $notes = '';
|
||||
private $ldap = null;
|
||||
|
||||
public static function create_user($name) {
|
||||
$ins_user = prepare('insert into `user`(`name`) values (?)');
|
||||
bind($ins_user, 's', $name);
|
||||
execute($ins_user);
|
||||
return new User($ins_user->insert_id);
|
||||
}
|
||||
|
||||
public function __construct($clue, $type = 'id') {
|
||||
$find = null;
|
||||
switch($type) {
|
||||
case 'id':
|
||||
$find = prepare('select `id` from `user` where `id`=?');
|
||||
bind($find, 'i', $clue);
|
||||
break;
|
||||
case 'name':
|
||||
$find = prepare('select `id` from `user` where `name`=?');
|
||||
bind($find, 's', $clue);
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid type');
|
||||
}
|
||||
execute($find);
|
||||
$id = result_single($find)['id'];
|
||||
if($id === null) {
|
||||
throw new Exception("Invalid username '$clue'");
|
||||
}
|
||||
$this->id = $id;
|
||||
$this->update_fields();
|
||||
$this->ldap = new Ldap();
|
||||
}
|
||||
|
||||
private function update_fields() {
|
||||
$get = prepare('select * from `user` where `id`=?');
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$user = result_single($get);
|
||||
$this->name = $user['name'];
|
||||
$this->notes = $user['notes'];
|
||||
return true;
|
||||
}
|
||||
|
||||
public function matches($terms) {
|
||||
foreach($terms as $field => $values) {
|
||||
$matchvalues = array();
|
||||
if($field == 'name') {
|
||||
$matchvalues[] = $this->name;
|
||||
$matchvalues[] = $this->get_displayname();
|
||||
} else if(property_exists($this, $field)) {
|
||||
$matchvalues[] = $this->$field;
|
||||
} else if($field == 'fritext') {
|
||||
$matchvalues[] = $this->name;
|
||||
$matchvalues[] = $this->get_displayname();
|
||||
$matchvalues[] = $this->notes;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
if(!match($values, $matchvalues)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_displayname() {
|
||||
try {
|
||||
return $this->ldap->get_user($this->name);
|
||||
} catch(Exception $e) {
|
||||
return 'Ej i SUKAT';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_email() {
|
||||
try {
|
||||
return $this->ldap->get_user_email($this->name);
|
||||
} catch(Exception $e) {
|
||||
return 'Mailadress saknas';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function get_name() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function set_name($newname) {
|
||||
$update = prepare('update `user` set `name`=? where `id`=?');
|
||||
bind($update, 'si', $newname, $this->id);
|
||||
execute($update);
|
||||
$this->name = $newname;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_notes() {
|
||||
return $this->notes;
|
||||
}
|
||||
|
||||
public function set_notes($newnotes) {
|
||||
$update = prepare('update `user` set `notes`=? where `id`=?');
|
||||
bind($update, 'si', $newnotes, $this->id);
|
||||
execute($update);
|
||||
$this->notes = $newnotes;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function get_loans($type = 'both') {
|
||||
$statement = 'select `id` from `loan` where `user`=?';
|
||||
switch($type) {
|
||||
case 'active':
|
||||
$statement .= ' and `returntime` is null';
|
||||
break;
|
||||
case 'inactive':
|
||||
$statement .= ' and `returntime` is not null';
|
||||
break;
|
||||
case 'both':
|
||||
break;
|
||||
default:
|
||||
$err = "$type is not a valid argument. Valid arguments are active, inactive, both.";
|
||||
throw new Exception($err);
|
||||
break;
|
||||
}
|
||||
$statement .= ' order by `starttime` desc';
|
||||
$get = prepare($statement);
|
||||
bind($get, 'i', $this->id);
|
||||
execute($get);
|
||||
$loans = array();
|
||||
foreach(result_list($get) as $row) {
|
||||
$loans[] = new Loan($row['id']);
|
||||
}
|
||||
return $loans;
|
||||
}
|
||||
|
||||
public function get_overdue_loans() {
|
||||
$overdue = array();
|
||||
foreach($this->get_loans('active') as $loan) {
|
||||
if($loan->is_overdue()) {
|
||||
$overdue[] = $loan;
|
||||
}
|
||||
}
|
||||
return $overdue;
|
||||
}
|
||||
|
||||
public function create_loan($product, $endtime) {
|
||||
$find = prepare('select * from `loan`
|
||||
where `product`=? and `returntime` is null');
|
||||
$prod_id = $product->get_id();
|
||||
bind($find, 'i', $prod_id);
|
||||
execute($find);
|
||||
$loan = result_single($find);
|
||||
if($loan !== null) {
|
||||
$loan_id = $loan['id'];
|
||||
throw new Exception(
|
||||
"Product $prod_id has an active loan (id $loan_id) already.");
|
||||
}
|
||||
$now = time();
|
||||
$insert = prepare('insert into
|
||||
`loan`(`user`, `product`, `starttime`, `endtime`)
|
||||
values (?, ?, ?, ?)');
|
||||
bind($insert, 'iiii',
|
||||
$this->id, $prod_id,
|
||||
$now, strtotime($endtime . ' 13:00'));
|
||||
execute($insert);
|
||||
$loan_id = $insert->insert_id;
|
||||
return new Loan($loan_id);
|
||||
}
|
||||
}
|
||||
?>
|
65
include/UserPage.php
Normal file
65
include/UserPage.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
class UserPage extends Page {
|
||||
private $action = 'list';
|
||||
private $user = null;
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
if(isset($_GET['action'])) {
|
||||
$this->action = $_GET['action'];
|
||||
}
|
||||
if(isset($_GET['id'])) {
|
||||
$id = $_GET['id'];
|
||||
if($id) {
|
||||
try {
|
||||
$this->user = new User($_GET['id']);
|
||||
} catch(Exception $e) {
|
||||
$this->user = null;
|
||||
$this->action = 'list';
|
||||
$this->error = 'Det finns ingen användare med det ID-numret.';
|
||||
}
|
||||
}
|
||||
}
|
||||
switch($this->action) {
|
||||
case 'show':
|
||||
$this->subtitle = 'Låntagardetaljer';
|
||||
break;
|
||||
case 'list':
|
||||
$this->subtitle = 'Låntagarlista';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected function render_body() {
|
||||
switch($this->action) {
|
||||
case 'list':
|
||||
print($this->build_user_table(get_items('user')));
|
||||
break;
|
||||
case 'show':
|
||||
print($this->build_user_details());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function build_user_details() {
|
||||
$active_loans = $this->user->get_loans('active');
|
||||
$table_active = 'Inga aktuella lån.';
|
||||
if($active_loans) {
|
||||
$table_active = $this->build_user_loan_table($active_loans, 'renew');
|
||||
}
|
||||
$inactive_loans = $this->user->get_loans('inactive');
|
||||
$table_inactive = 'Inga gamla lån.';
|
||||
if($inactive_loans) {
|
||||
$table_inactive = $this->build_user_loan_table($inactive_loans,
|
||||
'return');
|
||||
}
|
||||
return replace(array('active_loans' => $table_active,
|
||||
'inactive_loans' => $table_inactive,
|
||||
'id' => $this->user->get_id(),
|
||||
'name' => $this->user->get_name(),
|
||||
'displayname' => $this->user->get_displayname(),
|
||||
'notes' => $this->user->get_notes()),
|
||||
$this->fragments['user_details']);
|
||||
}
|
||||
}
|
||||
?>
|
1111
include/db.php
1111
include/db.php
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once("./config.php");
|
||||
|
||||
/*
|
||||
Takes an html file containing named fragments.
|
||||
Returns an associative array on the format array[name]=>fragment.
|
||||
@ -76,4 +74,237 @@ function replace($assoc_arr, $subject) {
|
||||
return str_replace($keys, $values, $subject);
|
||||
}
|
||||
|
||||
function make_page($page) {
|
||||
switch($page) {
|
||||
default:
|
||||
case 'checkout':
|
||||
return new CheckoutPage();
|
||||
case 'return':
|
||||
return new ReturnPage();
|
||||
case 'search':
|
||||
return new SearchPage();
|
||||
case 'products':
|
||||
return new ProductPage();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
function get_ids($type) {
|
||||
$append = '';
|
||||
switch($type) {
|
||||
case 'user':
|
||||
break;
|
||||
case 'product':
|
||||
$append = 'where `discardtime` is null';
|
||||
break;
|
||||
case 'loan':
|
||||
break;
|
||||
case 'inventory':
|
||||
break;
|
||||
case 'product_discarded':
|
||||
$append = 'where `discardtime` is not null';
|
||||
$type = 'product';
|
||||
break;
|
||||
case 'loan_active':
|
||||
$append = 'where `returntime` is null';
|
||||
$type = 'loan';
|
||||
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 'loan':
|
||||
case 'loan_active':
|
||||
$construct = function($id) {
|
||||
return new Loan($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 match($testvalues, $matchvalues) {
|
||||
if(!is_array($testvalues)) {
|
||||
$testvalues = array($testvalues);
|
||||
}
|
||||
foreach($testvalues as $value) {
|
||||
foreach($matchvalues as $candidate) {
|
||||
if(fnmatch($value, $candidate, FNM_CASEFOLD)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
### 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;
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
require_once("./config.php");
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
?>
|
1289
include/view.php
1289
include/view.php
File diff suppressed because it is too large
Load Diff
10
index.php
10
index.php
@ -1,5 +1,13 @@
|
||||
<?php
|
||||
require_once('./include/view.php');
|
||||
|
||||
set_include_path(get_include_path().PATH_SEPARATOR.'include/');
|
||||
spl_autoload_register(function ($class) {
|
||||
if($class == 'qrcode') {
|
||||
include('./phpqrcode/qrlib.php');
|
||||
}
|
||||
});
|
||||
require('./config.php');
|
||||
require('functions.php');
|
||||
|
||||
header('Content-Type: text/html; charset=UTF-8');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user