$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') { parent::__construct(); $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->brand = $product['brand']; $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, $matchAll=false) { print('DEBUG $terms in matches: '); var_dump($terms); print('

'); $terms = $this->specify_search($terms, array('brand', 'name', 'serial', 'invoice', 'status', 'tag')); print('DEBUG $terms POST TRANSLATION: '); var_dump($terms); print('

'); $matches = array(); foreach($terms as $field => $values) { if(property_exists($this, $field)) { if(match($values, $this->$field)) { $matches[$field] = $this->$field; } else { if($matchAll) { return array(); } } } else if(array_key_exists($field, $this->get_info())) { if(match($values, $this->get_info()[$field])) { $matches[$field] = $this->get_info()[$field]; } else { if($matchAll) { return array(); } } } else if($field == 'tag') { foreach($this->get_tags() as $tag) { if(match($values, $tag)) { if(!array_key_exists('tags', $matches)) { $matches['tags'] = array(); } $matches['tags'][] = $tag; } else { if($matchAll) { return array(); } } } } else if($field == 'status') { if(match($values, $this->get_status())) { $matches['status'] = $this->get_status(); } else { if($matchAll) { return array(); } } } } return $matches; } public function get_id() { return $this->id; } public function get_createtime() { return $this->createtime; } public function get_discardtime() { return $this->discardtime; } public function discard() { if($this->get_status() != 'available') { return false; } $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 toggle_service() { $status = $this->get_status(); $now = time(); $update = ''; if($status == 'service') { return $this->get_active_service()->end(); } else if($status == 'available') { Service::create_service($this); return true; } $id = $this->get_id(); throw new Exception("The state ($status) of this product (id $id) " ."does not allow servicing."); } public function get_active_service() { $find = prepare("select `id` from `event` where `type`='service' and `returntime` is null and product=?"); bind($find, 'i', $this->id); execute($find); $result = result_single($find); if($result === null) { return null; } return new Service($result['id']); } public function get_brand() { return $this->brand; } public function set_brand($newbrand) { $update = prepare('update `product` set `brand`=? where `id`=?'); bind($update, 'si', $newbrand, $this->id); execute($update); $this->brand = $newbrand; 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_status() { if($this->get_discardtime()) { return 'discarded'; } if($this->get_active_service()) { return 'service'; } $loan = $this->get_active_loan(); if(!$loan) { return 'available'; } if($loan->is_overdue()) { return 'overdue'; } return 'on_loan'; } public function get_historic_event($time) { $search = prepare("select `id`,`type` from `event` where `product` = ? and `starttime` < ? and ( `returntime` > ? or `returntime` is null )"); bind($search, 'iii', $this->id, $time, $time); execute($search); $result = result_single($search); if(!$result) { return null; } $id = $result['id']; $type = $result['type']; switch($type) { case 'service': return new Service($id); break; case 'loan': return new Loan($id); break; default: throw new Exception("Invalid type '$type'"); } } public function get_active_loan() { $find = prepare("select `id` from `event` where `type`='loan' and `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_history() { $out = array(); $find = prepare('select `id`,`type` from `event` ' .'where `product`=? order by `starttime` desc'); bind($find, 'i', $this->id); execute($find); $items = result_list($find); foreach($items as $item) { $id = $item['id']; switch($item['type']) { case 'service': $out[] = new Service($id); break; case 'loan': $out[] = new Loan($id); break; default: $type = $item['type']; throw new Exception("Invalid type '$type'"); } } return $out; } public function get_attachments() { $out = array(); $find = prepare('select `id` from `attachment` where `product`=? and `deletetime` is NULL order by `uploadtime` asc'); bind($find, 'i', $this->id); execute($find); $items = result_list($find); foreach($items as $item) { $out[] = new Attachment($item['id']); } return $out; } } ?>