From daa21ea7c7b22aff32cca8c00488c80c2ce05bb0 Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 03:24:19 +0700 Subject: [PATCH 01/73] Fix: unsaved data member Because member_id is not only number --- admin/modules/membership/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/admin/modules/membership/index.php b/admin/modules/membership/index.php index 3b18f52f..993e13ec 100755 --- a/admin/modules/membership/index.php +++ b/admin/modules/membership/index.php @@ -76,7 +76,7 @@ function getimagesizefromstring($string_data) $query_image = $dbs->query("SELECT member_id FROM member WHERE member_id='{$member_id}' AND member_image='{$image_name}'"); if (!empty($query_image->num_rows)) { - $_delete = $dbs->query(sprintf('UPDATE member SET member_image=NULL WHERE member_id=%d', $member_id)); + $_delete = $dbs->query(sprintf("UPDATE member SET member_image=NULL WHERE member_id='%s", $member_id)); if ($_delete) { $postImage = stripslashes($_POST['img']); $postImage = str_replace('/', '', $postImage); @@ -232,7 +232,7 @@ function getimagesizefromstring($string_data) // update custom data if (isset($custom_data)) { // check if custom data for this record exists - $_sql_check_custom_q = sprintf('SELECT member_id FROM member_custom WHERE member_id=%d', $updateRecordID); + $_sql_check_custom_q = sprintf("SELECT member_id FROM member_custom WHERE member_id='%s'", $updateRecordID); $check_custom_q = $dbs->query($_sql_check_custom_q); if ($check_custom_q->num_rows) { @$sql_op->update('member_custom', $custom_data, 'member_id=\''.$updateRecordID.'\''); @@ -431,7 +431,7 @@ function getimagesizefromstring($string_data) $form->submit_button_attr = 'name="saveData" value="'.__('Update').'" class="s-btn btn btn-primary"'; // custom field data query - $_sql_rec_cust_q = sprintf('SELECT * FROM member_custom WHERE member_id=%d', $itemID); + $_sql_rec_cust_q = sprintf("SELECT * FROM member_custom WHERE member_id='%s'", $itemID); $rec_cust_q = $dbs->query($_sql_rec_cust_q); $rec_cust_d = $rec_cust_q->fetch_assoc(); From 99f4e70220b89dd5ee85a01d124c107eef62b7ff Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 12:40:24 +0700 Subject: [PATCH 02/73] Fix: blank screen after login failed --- lib/contents/login.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/contents/login.inc.php b/lib/contents/login.inc.php index 6dfd6b90..572b8c81 100755 --- a/lib/contents/login.inc.php +++ b/lib/contents/login.inc.php @@ -140,7 +140,7 @@ // message $msg = ''; simbio_security::destroySessionCookie($msg, COOKIES_NAME, SWB.'admin', false); } From 3ceacb241aeaba0a3ac201a7122fdb1e71aad663 Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 12:44:00 +0700 Subject: [PATCH 03/73] Change return type in doc --- simbio2/simbio_UTILS/simbio_tokenizecql.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simbio2/simbio_UTILS/simbio_tokenizecql.inc.php b/simbio2/simbio_UTILS/simbio_tokenizecql.inc.php index c5a0e56f..474c2194 100755 --- a/simbio2/simbio_UTILS/simbio_tokenizecql.inc.php +++ b/simbio2/simbio_UTILS/simbio_tokenizecql.inc.php @@ -34,7 +34,7 @@ * * @param string $str_query * @param array $arr_stop_words - * @return string + * @return array **/ function simbio_tokenizeCQL($str_query, $arr_searcheable_fields, $arr_stop_words = array(), $int_max_words = 20) { From 3e456ab7314e1ad679ee750ab4425e0d866e4de0 Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 13:01:16 +0700 Subject: [PATCH 04/73] Validate url next destination --- lib/contents/member.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/contents/member.inc.php b/lib/contents/member.inc.php index ae381a27..9ef7d1d7 100644 --- a/lib/contents/member.inc.php +++ b/lib/contents/member.inc.php @@ -119,7 +119,7 @@ if ($logon->valid($dbs)) { // write log utility::writeLogs($dbs, 'member', $username, 'Login', sprintf(__('Login success for member %s from address %s'),$username,$_SERVER['REMOTE_ADDR'])); - if (isset($_GET['destination'])) { + if (isset($_GET['destination']) && filter_var($_GET['destination'], FILTER_VALIDATE_URL)) { header("location:" . $_GET['destination']); } else { header('Location: index.php?p=member'); From 77daff860e2b0edaaeca63dc1b145a188af9382d Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 13:30:54 +0700 Subject: [PATCH 05/73] Change path check order Plugin first then content so plugin can overwrite default SLiMS contents --- index.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.php b/index.php index 7efeb467..4eb99bd4 100755 --- a/index.php +++ b/index.php @@ -64,15 +64,8 @@ // some extra checking $path = preg_replace('@^(http|https|ftp|sftp|file|smb):@i', '', $path); $path = preg_replace('@\/@i','',$path); - // check if the file exists - if (file_exists(LIB.'contents/'.$path.'.inc.php')) { - if ($path != 'show_detail') { - $metadata = ''; - } - include LIB.'contents/'.$path.'.inc.php'; - } // check path from plugins - elseif (isset(($menu = \SLiMS\Plugins::getInstance()->getMenus('opac'))[$path])) { + if (isset(($menu = \SLiMS\Plugins::getInstance()->getMenus('opac'))[$path])) { if (file_exists($menu[$path][3])) { $page_title = $menu[$path][0]; include $menu[$path][3]; @@ -80,6 +73,13 @@ // not found http_response_code(404); } + } + // check if the file exists + elseif (file_exists(LIB.'contents/'.$path.'.inc.php')) { + if ($path != 'show_detail') { + $metadata = ''; + } + include LIB.'contents/'.$path.'.inc.php'; } else { // get content data from database $metadata = ''; From d29ade13ade96387d1225d219944d9a291ec46e3 Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 19:42:23 +0700 Subject: [PATCH 06/73] Add: file password field Express access in SLiMS but need password on other reader. --- admin/modules/bibliography/pop_attach.php | 11 ++++++++++- install/Upgrade.inc.php | 19 ++++++++++++++++++- js/pdfjs/mobile/index.php | 1 + js/pdfjs/mobile/js/viewer.js | 2 ++ js/pdfjs/web/viewer.js | 1 + js/pdfjs/web/viewer.php | 4 ++-- lib/contents/fstream.inc.php | 1 + 7 files changed, 35 insertions(+), 4 deletions(-) diff --git a/admin/modules/bibliography/pop_attach.php b/admin/modules/bibliography/pop_attach.php index 8cb9a2fb..d9641d63 100755 --- a/admin/modules/bibliography/pop_attach.php +++ b/admin/modules/bibliography/pop_attach.php @@ -88,6 +88,8 @@ $fdata['file_url'] = $dbs->escape_string($url); $fdata['file_dir'] = $dbs->escape_string($file_dir); $fdata['file_desc'] = $dbs->escape_string(trim(strip_tags($_POST['fileDesc']))); + if(isset($_POST['fileKey']) && trim($_POST['fileKey']) !== '') + $fdata['file_key'] = $dbs->escape_string(trim(strip_tags($_POST['fileKey']))); $fdata['mime_type'] = $sysconf['mimetype'][$file_ext]; $fdata['input_date'] = date('Y-m-d H:i:s'); $fdata['last_update'] = $fdata['input_date']; @@ -110,6 +112,8 @@ $fdata['file_url'] = $dbs->escape_string($fdata['file_name']); $fdata['file_dir'] = 'literal{NULL}'; $fdata['file_desc'] = $dbs->escape_string(trim(strip_tags($_POST['fileDesc']))); + if(isset($_POST['fileKey']) && trim($_POST['fileKey']) !== '') + $fdata['file_key'] = $dbs->escape_string(trim(strip_tags($_POST['fileKey']))); $fdata['mime_type'] = 'text/uri-list'; $fdata['input_date'] = date('Y-m-d H:i:s'); $fdata['last_update'] = $fdata['input_date']; @@ -144,7 +148,10 @@ // file biblio access update $update1 = $sql_op->update('biblio_attachment', array('access_type' => $data['access_type'], 'access_limit' => $data['access_limit'], 'placement' => $data['placement']), 'biblio_id='.$updateBiblioID.' AND file_id='.$fileID); // file description update - $update2 = $sql_op->update('files', array('file_title' => $title, 'file_url' => $url, 'file_desc' => $dbs->escape_string(trim($_POST['fileDesc']))), 'file_id='.$fileID); + $file_desc_update = array('file_title' => $title, 'file_url' => $url, 'file_desc' => $dbs->escape_string(trim($_POST['fileDesc']))); + if(isset($_POST['fileKey']) && trim($_POST['fileKey']) !== '') + $file_desc_update['file_key'] = $dbs->escape_string(trim(strip_tags($_POST['fileKey']))); + $update2 = $sql_op->update('files', $file_desc_update, 'file_id='.$fileID); if ($update1) { utility::jsToastr('File Attachment', __('File Attachment data updated!'), 'success'); echo ' diff --git a/js/pdfjs/mobile/js/viewer.js b/js/pdfjs/mobile/js/viewer.js index 66de5559..98add622 100644 --- a/js/pdfjs/mobile/js/viewer.js +++ b/js/pdfjs/mobile/js/viewer.js @@ -68,6 +68,7 @@ var PDFViewerApplication = { maxImageSize: MAX_IMAGE_SIZE, cMapUrl: CMAP_URL, cMapPacked: CMAP_PACKED, + password: params.loaderInit }); this.pdfLoadingTask = loadingTask; @@ -446,6 +447,7 @@ document.addEventListener( PDFViewerApplication.animationStartedPromise.then(function () { PDFViewerApplication.open({ url: DEFAULT_URL, + loaderInit: LOADER_INIT }); }); diff --git a/js/pdfjs/web/viewer.js b/js/pdfjs/web/viewer.js index 71f92e7b..8b445df1 100755 --- a/js/pdfjs/web/viewer.js +++ b/js/pdfjs/web/viewer.js @@ -1050,6 +1050,7 @@ _pdfjsLib.GlobalWorkerOptions[key] = workerParameters[key]; } parameters = Object.create(null); + parameters.password = loaderInit; if (typeof file === 'string') { this.setTitleUsingUrl(file); diff --git a/js/pdfjs/web/viewer.php b/js/pdfjs/web/viewer.php index 2b190ad7..06a3d41c 100755 --- a/js/pdfjs/web/viewer.php +++ b/js/pdfjs/web/viewer.php @@ -38,8 +38,8 @@ diff --git a/lib/contents/fstream.inc.php b/lib/contents/fstream.inc.php index b2046f3e..cba22bf8 100755 --- a/lib/contents/fstream.inc.php +++ b/lib/contents/fstream.inc.php @@ -66,6 +66,7 @@ if ($file_d['mime_type'] == 'application/pdf') { if ($sysconf['pdf']['viewer'] == 'pdfjs') { $file_loc_url = SWB . 'index.php?p=fstream-pdf&fid=' . $fileID . '&bid=' . $biblioID; + $loader_init = $file_d['file_key']; \SLiMS\Plugins::getInstance()->execute('fstream_pdf_before_download', ['data' => array('fileID' => $fileID, 'memberID' => $memberID, 'userID' => $userID, 'biblioID' => $biblioID, 'file_d' => $file_d)]); if (utility::isMobileBrowser()) { From f36838e135125f9e811876d7593afb130eab8980 Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 24 Jun 2021 19:49:30 +0700 Subject: [PATCH 07/73] Update installer --- install/install.sql.php | 1 + install/sections/SelectVersion.js | 2 ++ install/senayan.sql | 1 + install/tables.php | 6 ++++++ 4 files changed, 10 insertions(+) diff --git a/install/install.sql.php b/install/install.sql.php index d0cb8923..67ae4632 100644 --- a/install/install.sql.php +++ b/install/install.sql.php @@ -124,6 +124,7 @@ `file_dir` text collate utf8_unicode_ci, `mime_type` varchar(100) collate utf8_unicode_ci default NULL, `file_desc` text collate utf8_unicode_ci, + `file_key` text collate utf8_unicode_ci, `uploader_id` int(11) NOT NULL, `input_date` datetime NOT NULL, `last_update` datetime NOT NULL, diff --git a/install/sections/SelectVersion.js b/install/sections/SelectVersion.js index e5bd02a3..47af6d3c 100644 --- a/install/sections/SelectVersion.js +++ b/install/sections/SelectVersion.js @@ -50,6 +50,8 @@ export default { {value: 26, text: 'SLiMS 9.3.0 | Bulian'}, {value: 27, text: 'SLiMS 9.3.1 | Bulian'}, {value: 28, text: 'SLiMS 9.4.0 | Bulian'}, + {value: 29, text: 'SLiMS 9.4.1 | Bulian'}, + {value: 30, text: 'SLiMS 9.4.2 | Bulian'}, ] } }, diff --git a/install/senayan.sql b/install/senayan.sql index 8725d7c9..81de393e 100755 --- a/install/senayan.sql +++ b/install/senayan.sql @@ -185,6 +185,7 @@ CREATE TABLE IF NOT EXISTS `files` ( `file_dir` text collate utf8_unicode_ci, `mime_type` varchar(100) collate utf8_unicode_ci default NULL, `file_desc` text collate utf8_unicode_ci, + `file_key` text collate utf8_unicode_ci, `uploader_id` int(11) NOT NULL, `input_date` datetime NOT NULL, `last_update` datetime NOT NULL, diff --git a/install/tables.php b/install/tables.php index c789df20..d3c71181 100644 --- a/install/tables.php +++ b/install/tables.php @@ -533,6 +533,12 @@ 'null' => true, 'default' => null ], + [ + 'field' => 'file_key', + 'type' => 'text', + 'null' => true, + 'default' => null + ], [ 'field' => 'uploader_id', 'type' => 'int(11)', From 7a961819af57ccfb34d8fde4d9acb87d4c3cd2e4 Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 25 Jun 2021 16:25:50 +0700 Subject: [PATCH 08/73] Change quotes server --- template/default/visitor_template.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/template/default/visitor_template.php b/template/default/visitor_template.php index 1f57dd1f..392c742f 100644 --- a/template/default/visitor_template.php +++ b/template/default/visitor_template.php @@ -98,7 +98,8 @@ this.image = './images/persons/photo.png' }, getQuotes: function() { - axios.get('https://api.quotable.io/random') + // Alternative Free Quotes API: https://api.quotable.io/random + axios.get('https://kutipan.herokuapp.com/') .then(res => { this.quotes = res.data }) From 5708db4ee430e44690a44f06d54d0feb94740df2 Mon Sep 17 00:00:00 2001 From: idoalit Date: Wed, 30 Jun 2021 16:01:05 +0700 Subject: [PATCH 09/73] Fix: ignore holiday fines --- .../circulation/circulation_base_lib.inc.php | 977 +++++++++--------- 1 file changed, 489 insertions(+), 488 deletions(-) diff --git a/admin/modules/circulation/circulation_base_lib.inc.php b/admin/modules/circulation/circulation_base_lib.inc.php index 458449f2..4470f35c 100755 --- a/admin/modules/circulation/circulation_base_lib.inc.php +++ b/admin/modules/circulation/circulation_base_lib.inc.php @@ -1,488 +1,489 @@ -loan_limit = intval($this->member_type_prop['loan_limit']); - $this->loan_periode = intval($this->member_type_prop['loan_periode']); - $this->reborrow_limit = intval($this->member_type_prop['reborrow_limit']); - $this->fine_each_day = intval($this->member_type_prop['fine_each_day']); - $this->grace_periode = intval($this->member_type_prop['grace_periode']); - } - - - /* - * Set complex loan rules - * @return void - **/ - public function setLoanRules($int_coll_type = 0, $int_gmd_id = 0) - { - // if the collection type and gmd is not specified - // get from the membership type directly - if (!$int_coll_type AND !$int_gmd_id) { - return; - } - - $ctype_string = ''; - if ($int_coll_type) { - $ctype_string .= ' AND coll_type_id='.intval($int_coll_type).' '; - } - $gmd_string = ''; - if ($int_gmd_id) { - $gmd_string .= ' AND gmd_id='.intval($int_gmd_id).' '; - } - - // get the data from the loan rules table - $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules - WHERE member_type_id=".intval($this->member_type_id)." $ctype_string $gmd_string"); - // check if the loan rules exists - if ($_loan_rules_q->num_rows > 0) { - $_loan_rules_d = $_loan_rules_q->fetch_assoc(); - $this->loan_limit = $_loan_rules_d['loan_limit']; - $this->loan_periode = $_loan_rules_d['loan_periode']; - $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; - $this->fine_each_day = $_loan_rules_d['fine_each_day']; - $this->grace_periode = $_loan_rules_d['grace_periode']; - $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; - } else { - // get data from the loan rules table with collection type specified but GMD not specified - $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules - WHERE member_type_id=".intval($this->member_type_id)." $ctype_string"); - // check if the loan rules exists - if ($_loan_rules_q->num_rows > 0) { - $_loan_rules_d = $_loan_rules_q->fetch_assoc(); - $this->loan_limit = $_loan_rules_d['loan_limit']; - $this->loan_periode = $_loan_rules_d['loan_periode']; - $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; - $this->fine_each_day = $_loan_rules_d['fine_each_day']; - $this->grace_periode = $_loan_rules_d['grace_periode']; - $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; - } else { - // get data from the loan rules table with GMD specified but collection type not specified - $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules - WHERE member_type_id=".intval($this->member_type_id)." $gmd_string"); - // check if the loan rules exists - if ($_loan_rules_q->num_rows > 0) { - $_loan_rules_d = $_loan_rules_q->fetch_assoc(); - $this->loan_limit = $_loan_rules_d['loan_limit']; - $this->loan_periode = $_loan_rules_d['loan_periode']; - $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; - $this->fine_each_day = $_loan_rules_d['fine_each_day']; - $this->grace_periode = $_loan_rules_d['grace_periode']; - $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; - } - } - } - // destroy query object - unset($_loan_rules_q); - } - - - /** - * Add item to loan session - * @param string $str_item_code - * @param boolean $bool_ignore_rules - * @return void - **/ - public function addLoanSession($str_item_code, $bool_ignore_rules = false) - { - // you cant borrow any collection if your membership is expired or in pending state - if ($this->is_expire) { - return LOAN_NOT_PERMITTED; - } - if ($this->is_pending) { - return LOAN_NOT_PERMITTED_PENDING; - } - $_q = $this->obj_db->query("SELECT b.title, i.coll_type_id, - b.gmd_id, ist.no_loan FROM biblio AS b - LEFT JOIN item AS i ON b.biblio_id=i.biblio_id - LEFT JOIN mst_item_status AS ist ON i.item_status_id=ist.item_status_id - WHERE i.item_code='$str_item_code'"); - $_d = $_q->fetch_row(); - if ($_q->num_rows > 0) { - // first, check for availability for this item - $_avail_q = $this->obj_db->query("SELECT item_code FROM loan AS L - WHERE L.item_code='$str_item_code' AND L.is_lent=1 AND L.is_return=0"); - // if we find any record then it means the item is unavailable - if ($_avail_q->num_rows > 0) { - return ITEM_UNAVAILABLE; - } - // check loan status for item - if ((integer)$_d[3] > 0) { - return ITEM_LOAN_FORBID; - } - // check if loan rules are ignored - if (!defined('IGNORE_LOAN_RULES')) { - // check if this item is being reserved by other member - $_resv_q = $this->obj_db->query("SELECT * FROM reserve AS rs - WHERE rs.item_code='$str_item_code' AND rs.member_id<>'".$_SESSION['memberID']."'"); - if ($_resv_q->num_rows > 0) { - $_resv2_q = $this->obj_db->query("SELECT * FROM reserve AS rs - WHERE rs.item_code='$str_item_code' ORDER BY reserve_date ASC LIMIT 1"); - $_resv2_d = $_resv2_q->fetch_assoc(); - if ($_resv2_d['member_id'] != $_SESSION['memberID']) { - return ITEM_RESERVED; - } - } - } - // loan date - $_loan_date = date('Y-m-d'); - // set loan rules - self::setLoanRules($_d[1], $_d[2]); - // calculate due date - $_due_date = simbio_date::getNextDate($this->loan_periode, $_loan_date); - $_due_date = simbio_date::getNextDateNotHoliday($_due_date, $this->holiday_dayname, $this->holiday_date); - // check if due date is not more than member expiry date - $_expiry_date_compare = simbio_date::compareDates($_due_date, $this->expire_date); - if ($_expiry_date_compare != $this->expire_date) { - $_due_date = $this->expire_date; - } - $_curr_loan_num = count(parent::getItemLoan($this->item_loan_rules)); - $_curr_session_loan_num = count($_SESSION['temp_loan']); - // get number of temporay loan session for specific loan rules - if ($this->item_loan_rules) { - $_curr_session_loan_num = 0; - foreach ($_SESSION['temp_loan'] as $loan_session_item) { - if ($loan_session_item['loan_rules_id'] == $this->item_loan_rules) { - $_curr_session_loan_num++; - } - } - } - - // check if we ignoring loan rules - if (defined('IGNORE_LOAN_RULES')) { - $_SESSION['temp_loan'][$str_item_code] = array( - 'item_code' => $str_item_code, - 'loan_rules_id' => $this->item_loan_rules, - 'title' => $_d[0], - 'loan_date' => $_loan_date, - 'due_date' => $_due_date - ); - return ITEM_SESSION_ADDED; - } else if ($this->loan_limit > ($_curr_loan_num + $_curr_session_loan_num)) { - // are the loan limit reached? - $_SESSION['temp_loan'][$str_item_code] = array( - 'item_code' => $str_item_code, - 'loan_rules_id' => $this->item_loan_rules, - 'title' => $_d[0], - 'loan_date' => $_loan_date, - 'due_date' => $_due_date - ); - return ITEM_SESSION_ADDED; - } else { - return LOAN_LIMIT_REACHED; - } - } else { - return ITEM_NOT_FOUND; - } - } - - - /** - * Remove item from loan session - * @param string $str_item_code - * @return void - **/ - public function removeLoanSession($str_item_code) - { - unset($_SESSION['temp_loan'][$str_item_code]); - } - - - /** - * Return an item from loan session - * @param integer $int_loan_id - * @return integer/boolean - **/ - public function returnItem($int_loan_id) - { - $_return_date = date('Y-m-d'); - // check for overdue - $_fines = self::countOverdueValue($int_loan_id, $_return_date); - // put data to fines table - if ($_fines) { - // set overdue flags - $this->loan_have_overdue = true; - $this->overdue_days = $_fines['days']; - $overdue_description = str_replace("{item_code}", $_fines['item'], __("Overdue fines for item {item_code}")); - if (is_numeric($this->overdue_days) AND $this->overdue_days > 0) { - $this->obj_db->query("INSERT INTO fines VALUES(NULL, '$_return_date', '".$this->member_id ."', ".$_fines['value'].", 0, '". $this->obj_db->escape_string($overdue_description) ."')"); - } - // add to receipt - if (isset($_SESSION['receipt_record'])) { - $_SESSION['receipt_record']['fines'][] = array('days' => $_fines['days'], 'value' => $_fines['value']); - } - } - // update the loan data - #$this->obj_db->query("UPDATE loan SET is_return=1, return_date='$_return_date' WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."' AND is_lent=1 AND is_return=0"); - $this->obj_db->query("UPDATE loan SET is_return=1, return_date='$_return_date', last_update='".date("Y-m-d H:i:s")."' WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."' AND is_lent=1 AND is_return=0"); - // add to receipt - if (isset($_SESSION['receipt_record'])) { - // get item data - $_title_q = $this->obj_db->query('SELECT b.title, l.item_code FROM loan AS l - LEFT JOIN item AS i ON l.item_code=i.item_code - INNER JOIN biblio AS b ON i.biblio_id=b.biblio_id WHERE l.loan_id='.$int_loan_id); - $_title_d = $_title_q->fetch_assoc(); - $_SESSION['receipt_record']['return'][] = array('itemCode' => $_title_d['item_code'], 'title' => $_title_d['title'], 'returnDate' => $_return_date, 'overdues' => $_fines); - } - // check if this item is being reserved by other member - $_resv_q = $this->obj_db->query("SELECT l.item_code FROM reserve AS rs - INNER JOIN loan AS l ON rs.item_code=l.item_code - WHERE l.loan_id=$int_loan_id AND rs.member_id!='".$this->member_id."'"); - if ($_resv_q->num_rows > 0) { - return ITEM_RESERVED; - } - return true; - } - - - - /** - * extend item loan - * @param integer $int_loan_id - * @return integer/boolean - **/ - public function extendItemLoan($int_loan_id) - { - // check if this item is being reserved by other member - $_resv_q = $this->obj_db->query("SELECT l.item_code FROM reserve AS rs - INNER JOIN loan AS l ON rs.item_code=l.item_code - WHERE l.loan_id=$int_loan_id AND rs.member_id!='".$_SESSION['memberID']."'"); - if ($_resv_q->num_rows > 0) { - return ITEM_RESERVED; - } - // return this item first - self::returnItem($int_loan_id); - // get loan rules for this loan - $_loan_rules_q = $this->obj_db->query("SELECT loan_periode FROM mst_loan_rules AS lr LEFT JOIN - loan AS l ON lr.loan_rules_id=l.loan_rules_id WHERE loan_id=$int_loan_id"); - if ($_loan_rules_q->num_rows > 0) { - $_loan_rules_d = $_loan_rules_q->fetch_row(); - $this->loan_periode = $_loan_rules_d[0]; - } - // due date - $_loan_date = date('Y-m-d'); - // calculate due date - $_due_date = simbio_date::getNextDate($this->loan_periode, $_loan_date); - $_due_date = simbio_date::getNextDateNotHoliday($_due_date, $this->holiday_dayname, $this->holiday_date); - // check if due date is not more than member expiry date - $_expiry_date_compare = simbio_date::compareDates($_due_date, $this->expire_date); - if ($_expiry_date_compare != $this->expire_date) { - $_due_date = $this->expire_date; - } - $query = $this->obj_db->query("UPDATE loan SET renewed=renewed+1, due_date='$_due_date', is_return=0 - WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."'"); - $_SESSION['reborrowed'][] = $int_loan_id; - // add to receipt - if (isset($_SESSION['receipt_record'])) { - // get item data - $_title_q = $this->obj_db->query('SELECT b.title, l.item_code FROM loan AS l - LEFT JOIN item AS i ON l.item_code=i.item_code - INNER JOIN biblio AS b ON i.biblio_id=b.biblio_id WHERE l.loan_id='.$int_loan_id); - $_title_d = $_title_q->fetch_assoc(); - $_SESSION['receipt_record']['extend'][] = array('itemCode' => $_title_d['item_code'], 'title' => $_title_d['title'], 'loanDate' => $_loan_date, 'dueDate' => $_due_date); - } - return true; - } - - - /** - * count overdue value - * @param integer $int_loan_id - * @param string $str_return_date - * @return boolean - **/ - public function countOverdueValue($int_loan_id, $str_return_date) - { - $_on_grace_periode = false; - // get due date for this loan - $_loan_q = $this->obj_db->query("SELECT l.due_date, l.loan_rules_id, l.item_code FROM loan AS l WHERE loan_id=$int_loan_id"); - $_loan_d = $_loan_q->fetch_row(); - // compare dates - $_date = simbio_date::compareDates($str_return_date, $_loan_d[0]); - if ($_date == $str_return_date) { - // how many days the overdue - $_overdue_days = simbio_date::calcDay($str_return_date, $_loan_d[0]); - - /* modified by Indra Sutriadi */ - if ($this->ignore_holidays_fine_calc === true) { - // count holiday and subtract it from overdue days - $_holiday_count = simbio_date::countHolidayBetween($_loan_d[0], $str_return_date, $this->holiday_dayname, $this->holiday_date); - $_overdue_days = $_overdue_days-$_holiday_count; - } - /* end of modification */ - - if ($_overdue_days < 1) { - return false; - } - // check for grace periode - if (!empty($this->grace_periode)) { - $_due_plus_grace_date = simbio_date::getNextDate($this->grace_periode, $_loan_d[0]); - $_latest_date = simbio_date::compareDates($str_return_date, $_due_plus_grace_date); - if ($_latest_date == $_due_plus_grace_date) { - $_on_grace_periode = true; - } - } - // check for loan rules if any - if (!empty($_loan_d[1])) { - $_loan_rules_q = $this->obj_db->query('SELECT fine_each_day, grace_periode FROM mst_loan_rules WHERE loan_rules_id='.$_loan_d[1]); - $_loan_rules_d = $_loan_rules_q->fetch_row(); - $this->fine_each_day = $_loan_rules_d[0]; - // check for grace periode - if (!empty($_loan_rules_d[1])) { - $_due_plus_grace_date = simbio_date::getNextDate($_loan_rules_d[1], $_loan_d[0]); - $_latest_date = simbio_date::compareDates($str_return_date, $_due_plus_grace_date); - if ($_latest_date == $_due_plus_grace_date) { - $_on_grace_periode = true; - } - } - } - // calculate fines value - if ($_on_grace_periode) { - return array('days' => 'On Grace Periode', 'value' => 0, 'item' => $_loan_d[2]); - } else { - $_fines_value = $this->fine_each_day*$_overdue_days; - return array('days' => $_overdue_days, 'value' => $_fines_value, 'item' => $_loan_d[2]); - } - } - return false; - } - - - /** - * Get overdue days - * @return integer - **/ - public function getOverdueDays() - { - return $this->overdue_days; - } - - - /** - * Finish loan transaction session - * @return void - **/ - public function finishLoanSession() - { - // receipt - if (isset($_SESSION['receipt_record'])) { - if (isset($_SESSION['receipt_record']['return']) || isset($_SESSION['receipt_record']['extend']) || isset($_SESSION['temp_loan'])) { - $_SESSION['receipt_record']['memberID'] = $this->member_id; - $_SESSION['receipt_record']['memberName'] = $this->member_name; - $_SESSION['receipt_record']['memberType'] = $this->member_type_name; - $_SESSION['receipt_record']['date'] = date('Y-m-d H:i:s'); - } else { - unset($_SESSION['receipt_record']); - } - } - // count number of loans - if (count($_SESSION['temp_loan']) > 0) { - $error_num = 0; - foreach ($_SESSION['temp_loan'] as $loan_item) { - // insert loan data to database - if ($loan_item['loan_rules_id']) { - $data['loan_rules_id'] = $loan_item['loan_rules_id']; - } else { - $data['loan_rules_id'] = 'literal{0}'; - } - $data['item_code'] = $loan_item['item_code']; - $data['member_id'] = $this->member_id; - $data['loan_date'] = $loan_item['loan_date']; - $data['due_date'] = $loan_item['due_date']; - $data['renewed'] = 'literal{0}'; - $data['is_lent'] = 1; - $data['is_return'] = 'literal{0}'; - $data['input_date'] = date("Y-m-d H:i:s"); - $data['last_update'] = date("Y-m-d H:i:s"); - $data['uid'] = $_SESSION['uid']; - $sql_op = new simbio_dbop($this->obj_db); - if (!$sql_op->insert('loan', $data)) { - $error_num++; - } else { - if (isset($_SESSION['receipt_record'])) { - // get title - $_title_q = $this->obj_db->query('SELECT title FROM biblio AS b INNER JOIN item AS i ON b.biblio_id=i.biblio_id WHERE i.item_code=\''.$data['item_code'].'\''); - $_title_d = $_title_q->fetch_row(); - $_title = $_title_d[0]; - // add to receipt - $_SESSION['receipt_record']['loan'][] = array('itemCode' => $data['item_code'], 'title' => $_title, 'loanDate' => $data['loan_date'], 'dueDate' => $data['due_date']); - } - // remove any reservation related to this items - @$this->obj_db->query('DELETE FROM reserve WHERE member_id=\''.$this->member_id.'\' AND item_code=\''.$data['item_code'].'\''); - } - } - // clean all circulation sessions - $_SESSION['temp_loan'] = array(); - $_SESSION['reborrowed'] = array(); - unset($_SESSION['memberID']); - // return the status - if ($error_num) { - return TRANS_FLUSH_ERROR; - } else { - return TRANS_FLUSH_SUCCESS; - } - } else { - // clean all circulation sessions - $_SESSION['temp_loan'] = array(); - $_SESSION['reborrowed'] = array(); - unset($_SESSION['memberID']); - } - } -} +loan_limit = intval($this->member_type_prop['loan_limit']); + $this->loan_periode = intval($this->member_type_prop['loan_periode']); + $this->reborrow_limit = intval($this->member_type_prop['reborrow_limit']); + $this->fine_each_day = intval($this->member_type_prop['fine_each_day']); + $this->grace_periode = intval($this->member_type_prop['grace_periode']); + } + + + /* + * Set complex loan rules + * @return void + **/ + public function setLoanRules($int_coll_type = 0, $int_gmd_id = 0) + { + // if the collection type and gmd is not specified + // get from the membership type directly + if (!$int_coll_type AND !$int_gmd_id) { + return; + } + + $ctype_string = ''; + if ($int_coll_type) { + $ctype_string .= ' AND coll_type_id='.intval($int_coll_type).' '; + } + $gmd_string = ''; + if ($int_gmd_id) { + $gmd_string .= ' AND gmd_id='.intval($int_gmd_id).' '; + } + + // get the data from the loan rules table + $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules + WHERE member_type_id=".intval($this->member_type_id)." $ctype_string $gmd_string"); + // check if the loan rules exists + if ($_loan_rules_q->num_rows > 0) { + $_loan_rules_d = $_loan_rules_q->fetch_assoc(); + $this->loan_limit = $_loan_rules_d['loan_limit']; + $this->loan_periode = $_loan_rules_d['loan_periode']; + $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; + $this->fine_each_day = $_loan_rules_d['fine_each_day']; + $this->grace_periode = $_loan_rules_d['grace_periode']; + $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; + } else { + // get data from the loan rules table with collection type specified but GMD not specified + $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules + WHERE member_type_id=".intval($this->member_type_id)." $ctype_string"); + // check if the loan rules exists + if ($_loan_rules_q->num_rows > 0) { + $_loan_rules_d = $_loan_rules_q->fetch_assoc(); + $this->loan_limit = $_loan_rules_d['loan_limit']; + $this->loan_periode = $_loan_rules_d['loan_periode']; + $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; + $this->fine_each_day = $_loan_rules_d['fine_each_day']; + $this->grace_periode = $_loan_rules_d['grace_periode']; + $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; + } else { + // get data from the loan rules table with GMD specified but collection type not specified + $_loan_rules_q = $this->obj_db->query("SELECT * FROM mst_loan_rules + WHERE member_type_id=".intval($this->member_type_id)." $gmd_string"); + // check if the loan rules exists + if ($_loan_rules_q->num_rows > 0) { + $_loan_rules_d = $_loan_rules_q->fetch_assoc(); + $this->loan_limit = $_loan_rules_d['loan_limit']; + $this->loan_periode = $_loan_rules_d['loan_periode']; + $this->reborrow_limit = $_loan_rules_d['reborrow_limit']; + $this->fine_each_day = $_loan_rules_d['fine_each_day']; + $this->grace_periode = $_loan_rules_d['grace_periode']; + $this->item_loan_rules = $_loan_rules_d['loan_rules_id']; + } + } + } + // destroy query object + unset($_loan_rules_q); + } + + + /** + * Add item to loan session + * @param string $str_item_code + * @param boolean $bool_ignore_rules + * @return void + **/ + public function addLoanSession($str_item_code, $bool_ignore_rules = false) + { + // you cant borrow any collection if your membership is expired or in pending state + if ($this->is_expire) { + return LOAN_NOT_PERMITTED; + } + if ($this->is_pending) { + return LOAN_NOT_PERMITTED_PENDING; + } + $_q = $this->obj_db->query("SELECT b.title, i.coll_type_id, + b.gmd_id, ist.no_loan FROM biblio AS b + LEFT JOIN item AS i ON b.biblio_id=i.biblio_id + LEFT JOIN mst_item_status AS ist ON i.item_status_id=ist.item_status_id + WHERE i.item_code='$str_item_code'"); + $_d = $_q->fetch_row(); + if ($_q->num_rows > 0) { + // first, check for availability for this item + $_avail_q = $this->obj_db->query("SELECT item_code FROM loan AS L + WHERE L.item_code='$str_item_code' AND L.is_lent=1 AND L.is_return=0"); + // if we find any record then it means the item is unavailable + if ($_avail_q->num_rows > 0) { + return ITEM_UNAVAILABLE; + } + // check loan status for item + if ((integer)$_d[3] > 0) { + return ITEM_LOAN_FORBID; + } + // check if loan rules are ignored + if (!defined('IGNORE_LOAN_RULES')) { + // check if this item is being reserved by other member + $_resv_q = $this->obj_db->query("SELECT * FROM reserve AS rs + WHERE rs.item_code='$str_item_code' AND rs.member_id<>'".$_SESSION['memberID']."'"); + if ($_resv_q->num_rows > 0) { + $_resv2_q = $this->obj_db->query("SELECT * FROM reserve AS rs + WHERE rs.item_code='$str_item_code' ORDER BY reserve_date ASC LIMIT 1"); + $_resv2_d = $_resv2_q->fetch_assoc(); + if ($_resv2_d['member_id'] != $_SESSION['memberID']) { + return ITEM_RESERVED; + } + } + } + // loan date + $_loan_date = date('Y-m-d'); + // set loan rules + self::setLoanRules($_d[1], $_d[2]); + // calculate due date + $_due_date = simbio_date::getNextDate($this->loan_periode, $_loan_date); + $_due_date = simbio_date::getNextDateNotHoliday($_due_date, $this->holiday_dayname, $this->holiday_date); + // check if due date is not more than member expiry date + $_expiry_date_compare = simbio_date::compareDates($_due_date, $this->expire_date); + if ($_expiry_date_compare != $this->expire_date) { + $_due_date = $this->expire_date; + } + $_curr_loan_num = count(parent::getItemLoan($this->item_loan_rules)); + $_curr_session_loan_num = count($_SESSION['temp_loan']); + // get number of temporay loan session for specific loan rules + if ($this->item_loan_rules) { + $_curr_session_loan_num = 0; + foreach ($_SESSION['temp_loan'] as $loan_session_item) { + if ($loan_session_item['loan_rules_id'] == $this->item_loan_rules) { + $_curr_session_loan_num++; + } + } + } + + // check if we ignoring loan rules + if (defined('IGNORE_LOAN_RULES')) { + $_SESSION['temp_loan'][$str_item_code] = array( + 'item_code' => $str_item_code, + 'loan_rules_id' => $this->item_loan_rules, + 'title' => $_d[0], + 'loan_date' => $_loan_date, + 'due_date' => $_due_date + ); + return ITEM_SESSION_ADDED; + } else if ($this->loan_limit > ($_curr_loan_num + $_curr_session_loan_num)) { + // are the loan limit reached? + $_SESSION['temp_loan'][$str_item_code] = array( + 'item_code' => $str_item_code, + 'loan_rules_id' => $this->item_loan_rules, + 'title' => $_d[0], + 'loan_date' => $_loan_date, + 'due_date' => $_due_date + ); + return ITEM_SESSION_ADDED; + } else { + return LOAN_LIMIT_REACHED; + } + } else { + return ITEM_NOT_FOUND; + } + } + + + /** + * Remove item from loan session + * @param string $str_item_code + * @return void + **/ + public function removeLoanSession($str_item_code) + { + unset($_SESSION['temp_loan'][$str_item_code]); + } + + + /** + * Return an item from loan session + * @param integer $int_loan_id + * @return integer/boolean + **/ + public function returnItem($int_loan_id) + { + $_return_date = date('Y-m-d'); + // check for overdue + $_fines = self::countOverdueValue($int_loan_id, $_return_date); + // put data to fines table + if ($_fines) { + // set overdue flags + $this->loan_have_overdue = true; + $this->overdue_days = $_fines['days']; + $overdue_description = str_replace("{item_code}", $_fines['item'], __("Overdue fines for item {item_code}")); + if (is_numeric($this->overdue_days) AND $this->overdue_days > 0) { + $this->obj_db->query("INSERT INTO fines VALUES(NULL, '$_return_date', '".$this->member_id ."', ".$_fines['value'].", 0, '". $this->obj_db->escape_string($overdue_description) ."')"); + } + // add to receipt + if (isset($_SESSION['receipt_record'])) { + $_SESSION['receipt_record']['fines'][] = array('days' => $_fines['days'], 'value' => $_fines['value']); + } + } + // update the loan data + #$this->obj_db->query("UPDATE loan SET is_return=1, return_date='$_return_date' WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."' AND is_lent=1 AND is_return=0"); + $this->obj_db->query("UPDATE loan SET is_return=1, return_date='$_return_date', last_update='".date("Y-m-d H:i:s")."' WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."' AND is_lent=1 AND is_return=0"); + // add to receipt + if (isset($_SESSION['receipt_record'])) { + // get item data + $_title_q = $this->obj_db->query('SELECT b.title, l.item_code FROM loan AS l + LEFT JOIN item AS i ON l.item_code=i.item_code + INNER JOIN biblio AS b ON i.biblio_id=b.biblio_id WHERE l.loan_id='.$int_loan_id); + $_title_d = $_title_q->fetch_assoc(); + $_SESSION['receipt_record']['return'][] = array('itemCode' => $_title_d['item_code'], 'title' => $_title_d['title'], 'returnDate' => $_return_date, 'overdues' => $_fines); + } + // check if this item is being reserved by other member + $_resv_q = $this->obj_db->query("SELECT l.item_code FROM reserve AS rs + INNER JOIN loan AS l ON rs.item_code=l.item_code + WHERE l.loan_id=$int_loan_id AND rs.member_id!='".$this->member_id."'"); + if ($_resv_q->num_rows > 0) { + return ITEM_RESERVED; + } + return true; + } + + + + /** + * extend item loan + * @param integer $int_loan_id + * @return integer/boolean + **/ + public function extendItemLoan($int_loan_id) + { + // check if this item is being reserved by other member + $_resv_q = $this->obj_db->query("SELECT l.item_code FROM reserve AS rs + INNER JOIN loan AS l ON rs.item_code=l.item_code + WHERE l.loan_id=$int_loan_id AND rs.member_id!='".$_SESSION['memberID']."'"); + if ($_resv_q->num_rows > 0) { + return ITEM_RESERVED; + } + // return this item first + self::returnItem($int_loan_id); + // get loan rules for this loan + $_loan_rules_q = $this->obj_db->query("SELECT loan_periode FROM mst_loan_rules AS lr LEFT JOIN + loan AS l ON lr.loan_rules_id=l.loan_rules_id WHERE loan_id=$int_loan_id"); + if ($_loan_rules_q->num_rows > 0) { + $_loan_rules_d = $_loan_rules_q->fetch_row(); + $this->loan_periode = $_loan_rules_d[0]; + } + // due date + $_loan_date = date('Y-m-d'); + // calculate due date + $_due_date = simbio_date::getNextDate($this->loan_periode, $_loan_date); + $_due_date = simbio_date::getNextDateNotHoliday($_due_date, $this->holiday_dayname, $this->holiday_date); + // check if due date is not more than member expiry date + $_expiry_date_compare = simbio_date::compareDates($_due_date, $this->expire_date); + if ($_expiry_date_compare != $this->expire_date) { + $_due_date = $this->expire_date; + } + $query = $this->obj_db->query("UPDATE loan SET renewed=renewed+1, due_date='$_due_date', is_return=0 + WHERE loan_id=$int_loan_id AND member_id='".$this->member_id."'"); + $_SESSION['reborrowed'][] = $int_loan_id; + // add to receipt + if (isset($_SESSION['receipt_record'])) { + // get item data + $_title_q = $this->obj_db->query('SELECT b.title, l.item_code FROM loan AS l + LEFT JOIN item AS i ON l.item_code=i.item_code + INNER JOIN biblio AS b ON i.biblio_id=b.biblio_id WHERE l.loan_id='.$int_loan_id); + $_title_d = $_title_q->fetch_assoc(); + $_SESSION['receipt_record']['extend'][] = array('itemCode' => $_title_d['item_code'], 'title' => $_title_d['title'], 'loanDate' => $_loan_date, 'dueDate' => $_due_date); + } + return true; + } + + + /** + * count overdue value + * @param integer $int_loan_id + * @param string $str_return_date + * @return boolean + **/ + public function countOverdueValue($int_loan_id, $str_return_date) + { + $_on_grace_periode = false; + // get due date for this loan + $_loan_q = $this->obj_db->query("SELECT l.due_date, l.loan_rules_id, l.item_code FROM loan AS l WHERE loan_id=$int_loan_id"); + $_loan_d = $_loan_q->fetch_row(); + // compare dates + $_date = simbio_date::compareDates($str_return_date, $_loan_d[0]); + if ($_date == $str_return_date) { + // how many days the overdue + $_overdue_days = simbio_date::calcDay($str_return_date, $_loan_d[0]); + + /* modified by Indra Sutriadi */ + if ($this->ignore_holidays_fine_calc === true || $this->ignore_holidays_fine_calc > 0) { + // count holiday and subtract it from overdue days + $_holiday_count = simbio_date::countHolidayBetween($_loan_d[0], $str_return_date, $this->holiday_dayname, $this->holiday_date); + $_overdue_days_ignore_holiday = $_overdue_days-$_holiday_count; + } + /* end of modification */ + + if ($_overdue_days < 1) { + return false; + } + // check for grace periode + if (!empty($this->grace_periode)) { + $_due_plus_grace_date = simbio_date::getNextDate($this->grace_periode, $_loan_d[0]); + $_latest_date = simbio_date::compareDates($str_return_date, $_due_plus_grace_date); + if ($_latest_date == $_due_plus_grace_date) { + $_on_grace_periode = true; + } + } + // check for loan rules if any + if (!empty($_loan_d[1])) { + $_loan_rules_q = $this->obj_db->query('SELECT fine_each_day, grace_periode FROM mst_loan_rules WHERE loan_rules_id='.$_loan_d[1]); + $_loan_rules_d = $_loan_rules_q->fetch_row(); + $this->fine_each_day = $_loan_rules_d[0]; + // check for grace periode + if (!empty($_loan_rules_d[1])) { + $_due_plus_grace_date = simbio_date::getNextDate($_loan_rules_d[1], $_loan_d[0]); + $_latest_date = simbio_date::compareDates($str_return_date, $_due_plus_grace_date); + if ($_latest_date == $_due_plus_grace_date) { + $_on_grace_periode = true; + } + } + } + // calculate fines value + if ($_on_grace_periode) { + return array('days' => 'On Grace Periode', 'value' => 0, 'item' => $_loan_d[2]); + } else { + $_fines_value = $this->fine_each_day*$_overdue_days; + if (isset($_overdue_days_ignore_holiday)) $_fines_value = $this->fine_each_day*$_overdue_days_ignore_holiday; + return array('days' => $_overdue_days, 'value' => $_fines_value, 'item' => $_loan_d[2]); + } + } + return false; + } + + + /** + * Get overdue days + * @return integer + **/ + public function getOverdueDays() + { + return $this->overdue_days; + } + + + /** + * Finish loan transaction session + * @return void + **/ + public function finishLoanSession() + { + // receipt + if (isset($_SESSION['receipt_record'])) { + if (isset($_SESSION['receipt_record']['return']) || isset($_SESSION['receipt_record']['extend']) || isset($_SESSION['temp_loan'])) { + $_SESSION['receipt_record']['memberID'] = $this->member_id; + $_SESSION['receipt_record']['memberName'] = $this->member_name; + $_SESSION['receipt_record']['memberType'] = $this->member_type_name; + $_SESSION['receipt_record']['date'] = date('Y-m-d H:i:s'); + } else { + unset($_SESSION['receipt_record']); + } + } + // count number of loans + if (count($_SESSION['temp_loan']) > 0) { + $error_num = 0; + foreach ($_SESSION['temp_loan'] as $loan_item) { + // insert loan data to database + if ($loan_item['loan_rules_id']) { + $data['loan_rules_id'] = $loan_item['loan_rules_id']; + } else { + $data['loan_rules_id'] = 'literal{0}'; + } + $data['item_code'] = $loan_item['item_code']; + $data['member_id'] = $this->member_id; + $data['loan_date'] = $loan_item['loan_date']; + $data['due_date'] = $loan_item['due_date']; + $data['renewed'] = 'literal{0}'; + $data['is_lent'] = 1; + $data['is_return'] = 'literal{0}'; + $data['input_date'] = date("Y-m-d H:i:s"); + $data['last_update'] = date("Y-m-d H:i:s"); + $data['uid'] = $_SESSION['uid']; + $sql_op = new simbio_dbop($this->obj_db); + if (!$sql_op->insert('loan', $data)) { + $error_num++; + } else { + if (isset($_SESSION['receipt_record'])) { + // get title + $_title_q = $this->obj_db->query('SELECT title FROM biblio AS b INNER JOIN item AS i ON b.biblio_id=i.biblio_id WHERE i.item_code=\''.$data['item_code'].'\''); + $_title_d = $_title_q->fetch_row(); + $_title = $_title_d[0]; + // add to receipt + $_SESSION['receipt_record']['loan'][] = array('itemCode' => $data['item_code'], 'title' => $_title, 'loanDate' => $data['loan_date'], 'dueDate' => $data['due_date']); + } + // remove any reservation related to this items + @$this->obj_db->query('DELETE FROM reserve WHERE member_id=\''.$this->member_id.'\' AND item_code=\''.$data['item_code'].'\''); + } + } + // clean all circulation sessions + $_SESSION['temp_loan'] = array(); + $_SESSION['reborrowed'] = array(); + unset($_SESSION['memberID']); + // return the status + if ($error_num) { + return TRANS_FLUSH_ERROR; + } else { + return TRANS_FLUSH_SUCCESS; + } + } else { + // clean all circulation sessions + $_SESSION['temp_loan'] = array(); + $_SESSION['reborrowed'] = array(); + unset($_SESSION['memberID']); + } + } +} From 619fac824aff388a6515c4a8b88f9ab4773dd7e8 Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Wed, 30 Jun 2021 16:47:53 +0700 Subject: [PATCH 10/73] Update senayan.sql Update line for installation in mysql command. --- install/senayan.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/senayan.sql b/install/senayan.sql index 81de393e..9ef05af2 100755 --- a/install/senayan.sql +++ b/install/senayan.sql @@ -1453,7 +1453,7 @@ DROP TABLE IF EXISTS `files_read`; CREATE TABLE `files_read` ( `filelog_id` int(11) NOT NULL AUTO_INCREMENT, `file_id` int(11) NOT NULL, - `date_read` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP, + `date_read` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT NOW(), `member_id` varchar(20) NULL, `user_id` int(11) DEFAULT NULL, `client_ip` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, From c0cab74aac6f203972227254ac945e6b7f29ca5f Mon Sep 17 00:00:00 2001 From: idoalit Date: Thu, 1 Jul 2021 07:47:24 +0700 Subject: [PATCH 11/73] Fix: unable download backup file from user not admin --- admin/modules/system/backup.php | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/admin/modules/system/backup.php b/admin/modules/system/backup.php index c7e6fc09..0741622e 100755 --- a/admin/modules/system/backup.php +++ b/admin/modules/system/backup.php @@ -143,23 +143,15 @@ $table_spec = 'backup_log AS bl LEFT JOIN user AS u ON bl.user_id=u.user_id'; // create datagrid $datagrid = new simbio_datagrid(); -if ($can_read AND $can_write) { - $datagrid->setSQLColumn('bl.backup_log_id', - 'u.realname AS \''.__('Backup Executor').'\'', - 'bl.backup_time AS \''.__('Backup Time').'\'', - 'bl.backup_file AS \''.__('Backup File Location').'\'', - 'bl.backup_file AS \''.__('File Size').'\''); - $datagrid->setSQLorder('backup_time DESC'); - $datagrid->modifyColumnContent(4, 'callback{showFileSize}'); -}else{ - $datagrid->setSQLColumn( - 'u.realname AS \''.__('Backup Executor').'\'', +$datagrid->setSQLColumn('bl.backup_log_id', + 'u.realname AS \''.__('Backup Executor').'\'', 'bl.backup_time AS \''.__('Backup Time').'\'', 'bl.backup_file AS \''.__('Backup File Location').'\'', - 'bl.backup_file AS \''.__('File Size').'\''); - $datagrid->setSQLorder('backup_time DESC'); - $datagrid->modifyColumnContent(3, 'callback{showFileSize}'); -} + 'bl.backup_file AS \''.__('File Size').'\''); +$datagrid->setSQLorder('backup_time DESC'); +$datagrid->modifyColumnContent(4, 'callback{showFileSize}'); +if (!$can_write) $datagrid->invisible_fields = [0]; + // is there any search if (isset($_GET['keywords']) AND $_GET['keywords']) { $keywords = $dbs->escape_string($_GET['keywords']); From c7329a502102a0bf759f3605d3270c6cd1e1d5c6 Mon Sep 17 00:00:00 2001 From: Heru Subekti Date: Fri, 16 Jul 2021 10:30:38 +0700 Subject: [PATCH 12/73] fix holiday settings --- admin/modules/system/holiday.php | 61 ++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/admin/modules/system/holiday.php b/admin/modules/system/holiday.php index 80873180..c79aba73 100755 --- a/admin/modules/system/holiday.php +++ b/admin/modules/system/holiday.php @@ -55,12 +55,12 @@ // check form validity $holDesc = trim($dbs->escape_string(strip_tags($_POST['holDesc']))); if (empty($holDesc)) { - utility::jsAlert(__('Holiday description can\'t be empty!')); + utility::jsToastr(__('Holiday Settings'),__('Holiday description can\'t be empty!'),'warning'); exit(); } else { $data['holiday_date'] = trim($_POST['holDate']); // remove extra whitespace if(!preg_match('@^[0-9]{4}-[0-9]{2}-[0-9]{2}$@', $data['holiday_date'])) { - utility::jsAlert(__('Holiday Date Start must have the format YYYY-MM-DD!')); + utility::jsToastr(__('Holiday Settings'),__('Holiday Date Start must have the format YYYY-MM-DD!'),'warning'); exit(); } $holiday_start_date = $data['holiday_date']; @@ -75,28 +75,28 @@ $updateRecordID = (integer)$_POST['updateRecordID']; if ($sql_op->update('holiday', $data, 'holiday_id='.$updateRecordID)) { utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' update holiday date for '.$data['description'], 'Holiday', 'Update'); - utility::jsAlert(__('Holiday Data Successfully updated')); + utility::jsToastr(__('Holiday Settings'),__('Holiday Data Successfully updated'),'success'); // update holiday_dayname session $_SESSION['holiday_date'][$data['holiday_date']] = $data['holiday_date']; echo ''; exit(); } else { utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' failed update holiday data for '.$data['description'], 'Holiday', 'Fail'); - utility::jsAlert(__('Holiday FAILED to update. Please Contact System Administrator')."\n".$sql_op->error); + utility::jsToastr(__('Holiday Settings'),__('Holiday FAILED to update. Please Contact System Administrator')."\n".$sql_op->error,'error'); } } else { /* INSERT RECORD MODE */ // insert the data if ($sql_op->insert('holiday', $data)) { utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' add holiday date for '.$data['description'], 'Holiday', 'Add'); - utility::jsAlert(__('New Holiday Successfully Saved')); + utility::jsToastr(__('Holiday Settings'),__('New Holiday Successfully Saved'),'success'); // update holiday_dayname session $_SESSION['holiday_date'][$data['holiday_date']] = $data['holiday_date']; // date range insert if (!empty($_POST['holDateEnd'])) { $holiday_end_date = trim($_POST['holDateEnd']); // remove extra whitespace if(!preg_match('@^[0-9]{4}-[0-9]{2}-[0-9]{2}$@', $holiday_end_date)) { - utility::jsAlert(__('Holiday Date End must have the format YYYY-MM-DD if it is not empty!')); + utility::jsToastr(__('Holiday Settings'),__('Holiday Date End must have the format YYYY-MM-DD if it is not empty!'),'warning'); exit(); } // check if holiday end date is more than holiday start date @@ -121,7 +121,7 @@ exit(); } else { utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' failed to add holiday data for '.$data['description'], 'Holiday', 'Fail'); - utility::jsAlert(__('Holiday FAILED to Save. Please Contact System Administrator')."\n".$sql_op->error); + utility::jsToastr(__('Holiday Settings'),__('Holiday FAILED to Save. Please Contact System Administrator')."\n".$sql_op->error,'error'); } } } @@ -157,10 +157,10 @@ // error alerting if ($error_num == 0) { utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' remove holiday date with id '.$_log, 'Holiday', 'Delete'); - utility::jsAlert(__('All Data Successfully Deleted')); + utility::jsToastr(__('Holiday Settings'),__('All Data Successfully Deleted'),'success'); echo ''; } else { - utility::jsAlert(__('Some or All Data NOT deleted successfully!\nPlease contact system administrator')); + utility::jsToastr(__('Holiday Settings'),__('Some or All Data NOT deleted successfully!\nPlease contact system administrator'),'warning'); echo ''; } exit(); @@ -272,26 +272,34 @@ } } else { // holiday setting saving proccess - if (isset($_POST['dayname'])) { - // make sure that not all day selected - if (count($_POST['dayname']) > 6) { - echo '
'.__('Maximum 6 day can be set as holiday!').'
'; - } else { - // delete previous holiday dayname settings - $dbs->query('DELETE FROM holiday WHERE holiday_date IS NULL'); - if ($_POST['dayname']) { - // emptying holiday dayname session first - $_SESSION['holiday_dayname'] = array(); - foreach ($_POST['dayname'] as $dayname) { - $dbs->query("INSERT INTO holiday VALUES(NULL, '" . $dbs->escape_string($dayname) . "', NULL, NULL)"); - // update holiday_dayname session - $_SESSION['holiday_dayname'][] = $dayname; + if(isset($_POST['holiday_update'])){ + if (isset($_POST['dayname'])) { + // make sure that not all day selected + if (count($_POST['dayname']) > 6) { + echo '
'.__('Maximum 6 day can be set as holiday!').'
'; + } else { + // delete previous holiday dayname settings + $dbs->query('DELETE FROM holiday WHERE holiday_date IS NULL'); + if ($_POST['dayname']) { + // emptying holiday dayname session first + $_SESSION['holiday_dayname'] = array(); + foreach ($_POST['dayname'] as $dayname) { + $dbs->query("INSERT INTO holiday VALUES(NULL, '" . $dbs->escape_string($dayname) . "', NULL, NULL)"); + // update holiday_dayname session + $_SESSION['holiday_dayname'][] = $dayname; + } + // information box + utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' update holiday settings for '.implode(', ', $_SESSION['holiday_dayname']), 'Holiday', 'Set'); + utility::jsToastr(__('Holiday Settings'),__('Holiday settings saved'),'success'); } - // information box - utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' update holiday settings for '.implode(', ', $_SESSION['holiday_dayname']), 'Holiday', 'Set'); - echo '
'.__('Holiday settings saved').'
'; } } + else{ + $dbs->query('DELETE FROM holiday WHERE holiday_date IS NULL'); + $_SESSION['holiday_dayname'] = []; + utility::writeLogs($dbs, 'staff', $_SESSION['uid'], 'System', $_SESSION['realname'].' update holiday settings for empty Holidays', 'Set'); + utility::jsToastr(__('Holiday Settings'),__('Holiday settings saved'),'success'); + } } // get holiday data from database @@ -336,6 +344,7 @@ function isChecked($str_data) $table->setCellAttr(4, 0, 'colspan="3" class="alterCell"'); echo '
'; + echo ''; echo $table->printTable(); echo '
'; } From 5e85c89062d415f800d6fcc54784e9562218ca36 Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Wed, 21 Jul 2021 16:31:21 +0700 Subject: [PATCH 13/73] Update translation Update translation for Bahasa Indonesia. --- lib/lang/locale/id_ID/LC_MESSAGES/messages.mo | Bin 136317 -> 136365 bytes lib/lang/locale/id_ID/LC_MESSAGES/messages.po | 121 ++++++++++-------- 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo b/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo index 39f5d6bf71dd3dd7cb0b8490c5fe2d3d97430ec1..bb23403c777b13b2995410db34a570cf6879adec 100644 GIT binary patch delta 37092 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 delta 37043 zcmZAA1$Y%#pswMG5L|->Nw5GxLvVL@x8UyXFt`LKNO7k?i@RHq;>F#e#og_G|6Yr8 zxM!Yc`Y!jGy^}(_dS$e4E26nK6ZlSdxX$=FP70ix$8l0dC)`P?jx%|R^Qkegx8yFdm!ZdTfjdBORwH z_Q0fg9+TlS48W+<948Rdpz=%Dctg~{24D~lvFVFY1KE#p@Hl3mf9EOz&B&W|h>x)` z76xKm%z{a<5XQq=s2R7y5bTWVaF%sGYC=n}03Jma)$y5O22j9S3S-m1Q-wfcY-H_$ z8fgS-OQzZQdh1T>A?s=D73)3gGxYazoDaB;c4GeKIOT8`mcl5rSpO~rDiCOiJFpc7 z&UT#EI1=yUQ(TJw%yFFE*n6(yjKy5@9Onq`L2cQn`Hu4^KEUEQbpf-+^Qe`)jGEYg zHvW16>mQQ@?}cVb2jw*L$p=%m=MnY5)-lH1)j;a`S5eEztV?xZ2Itx`$Gir@$u(x#tYQR%b6I*K2 z*P%MxW8-I0?ca87!VA>l`i7ceoW*8FA*l4is0vk34TYly(9Jp&HION&0W3h3UvKmG zp(bz!)!qZtA$Q-~fX@=sVLVhuTGR}3pgJsM zAF8W2R48|{*1=IYlSC8XV#q`(*l|Rq=7v>=T#F}D-<76aW88xupsHGZ> z0XS;~$5@-Ri3E-8C~CxS&<{VLDtyPH7;mLk-f^m75JqBt+=SZn=hn|wzg1>M6QDW_ zLalv4)M>5g+CUqOPQq|oV1jiXRwR8jY7;+URE+kAX*eE6Bc2Mi6&b7rP+L$L)ougS z09vB9*hL){cLD*;aH&n$V&f-KBfW)c=mlyCzoJGS`%jaf3AG~mQ7btRbxbE?3|xj; zaUI6Qo2UsqM%r_o*90^GpVelDiBKa7l--VjR@Z;PpL4VJ@`sD=}-F)NYE z8j4!EQZ`=G+8SffztfL^W;z1Z;WX5Y7NM5tKI*i8!E~5#tua5wCf*n|^NyGnhhPvc zMQzC;)ET*qYCpj`^C}F)()91-C7>A$LY?Nrs6+S+wS=#%U#(Hsn>|f{TIv+2jzZBF zOQGtQM=g0}tc~?i?X5)(d$sMA7DmIw!u6FB`}D1c~p9POn{N7C0~wl zaSf`yJ*b(Uw(;wjfcP`agw94&K4c^7uNP1O5;UTEs2R0JE%^Xc{xs_b)LA%#n(0%F zhOf{cKVy81v&pPb5Gp?eHS;ixgGEsNRo=w<>p5>of>xlpEzsG<2Vo-8$D%r1fO?#k z+V~n&y^W}b_o4=J3bg`vQ3HB`I!j)g&5JE5YJ&M(0(vP|w|1}@BT+M-kJ)h-=D?>I z1ygP@14@e;P)2J`Oh~*CYNe{9z6y0hZBc~HpN-lIcP#;(+AFA;e8Wl@eXDsR*1=rF zhoY8pi*+w%C4LmOwC_;^_S$CJ3q(z*hFNYuCt1O4$WTFVLF2)@v@Dl z*lw0I9coGQq4ut{jn_oYuqo<&FbH+n=Au?&Eox$ap|<)A>M_2A{(Anu5>UtSc9;T5 zQA-twY9Kp?VJR$!eX%0$M=fFOon}UPQRQo*2HMufd!Ys#fjSGnVF0eeczXU15zvS) zVlsS$D(JJzEPWyjAzlH~U@t6=zhO?iidw52E6(;bAGP=3@F)I^=3Ca4u| zyO;IXW7U@gEzuzBIMf?#7OKKL)Tv)?)Bi+m**Z*w+idGF`Eie*tNPzBXMGiw*rKn9^Y9)*fe#Edu-Q{X<-O58xzPqyE*p8>TJ z`B3fGKnM_}idcj;pt;_>Vi9b*craWR+AiXsk zDm^dez@n&?>xx>*A*eGk1@q9qvz$PB5^kUd;B(Y$NdnX!1z~y2f|^lpR09(*2`2EXOT9}=9XN-#TQT;4OKl*nz6VUUx3)SHn%z)Q17=4eKH(O>@eg)Kk z>tG-b#27dimH)eSBdY#h)R}pRsnO@SDW4u)Jw7=Is6ZL?!xpH=r9EoN2U=%fG~(+} zGue*CaX(f^pA+UiQXADybJUq=hw7&@=E4!E72JM;^^ZZ|6bU|f1y%6|hTwe+!nh~R z3gtkRFNNCEs;INj1XXX4O&@{jh)=^{+>R=D8?|!ZQD-6DDb_zaf!wFeo)ooK!EB_5 z+xU1?$8&7@a?}7WU~GJVoMz_@7Qs)bmC1M7Y*Bwy{n@BPxeVjrMb~CLKrP8jjD=Co zn8TI;wKbVgFOD*(J+F^xuperx=Gy!fWA-!v zRWS|bz>KJw)Wrp`MK;a1EBmSC|&_p7RXEbs7@T zW7HfIV1FB*VB^a$9_iaqXXJ0x%uk{Y<4X*}PpAO~oHswJ)kW?3OjNne);*{dJ%UB` z{NE=KpM-Q5Ohz8m3e-d`Wqs6=wZxd%0d@NOpbnXfTB)U&8!uoO#=L0GLQ&KT4n}R= zK2*E6CH*^32{jP1FF}qgJX5 zY9$AtCN>l^Vgzb{8?Uhbs<4j)9iBs|3a7CiUceyCcGWak6_wu*)nPMCgncnNPDFLE z3N?UpsI9n#q3D0jtUzhh7PPs>`m11f62^G3N4Sr8)EnlI9mVv-pI`-yf75i_2-QFj zRQ(zjC!#=K%JSlsHOgjTH)w-%oh1$YT|BE0?7#!Ks^?9P#yO`os9@o#nadv zuV8j8bk}_TcSJ4i8Prqcea{@`gs8KU4GUut>p;{%cOZw*b*>OdLc(Lzh`sNd!xaP7 zadOlvHa%*lVK%=gmLgsa%i?s@i{}RFbo)Lq^%9{5kQP&8GpvZiF`1tK(*$yn@CXZF zs)uGT>!X%#FluGSVH8|}>R=6OrS_uAT|^(ehdS;5q9*Xtrhm46N3DSOzr6D4-$|_i z=0P=F5u;)w^uv~@4mzOrwl8WRqcIImz#_N~i{lFn#L)lDmQ+Wbu@=_Os4eV=ZZLtB z1d`zy>tod3`93l;Nr>8ll&B6eqn5rCY5*Io7f|IsqE^iBvFSK1Mkk&PwT1am6DswX z^;e)e33}l)#*)|_wIW;47muSFID>jRuA&C`2DJq~PfU6Ms+};@N|r^nQxDZoCu@Jy zKu14e{S}x_f+{RQHM|Mc@L#9_T*Hib8#7__r)Gv>r~y?&J=g6}Pt$1B8+8fBz%3XP z_oLc7iF#Vjx&$<{`>4HrjvBx>)Bs{XGXqSA>L4e^!fL1&N;s;69;lfQwobJ!$Lyr< zz%YD_8c3?=rhPYrfGQS8WzUc57fY(p$^wKRQZ%IOgs|?5igHAob6GM zbytjrV=ygF!PvMNY1efQ63}6a^3oip3aEmePz9%07oZ-m)u;~EV+d|VZOL7XgRx$j zPsQY@{IaMe?~a;SA5{Cp&`;0*asp~#wJmT7HM6_c=NOOpXKT#YW=1Jcr$0Ta;c}?0 ztclv9a2$#4u_?Yp4ZQjrGoZSdk^Y@V1cGoR`r~rcq1u6(@i~l(moO^+Ytvt#2KvVO z12vGCZ%w(xn2vZV)MH)})n0p4xz6b71=Ej!8XAHLaXiMyMVJ6LVi`PaN{p`;wrMPeU#Bax8&cPy_jdYPj@A zV`WTCyf&uCj#w0@qUxQ+AWZbhtY9A0%*$JAqYhy+mw*}`iCV%5SPo~Sw&ot{&^$&p z@DjDOUr{si`)mdr-aa&(YIHXd@F#E)wbzfW-%yWDye}p{ z5$f<{LY?}osI97odhGh4_IM0t#?7c1-a)NUl&@x`Gov~#i=?|wI|AC%Nj76G>f`Yr z48oU~0pou&BhQaofflHSI-ySaBpcsk;}=l_{bEh^-NcKdR=Opo*7M(ufJPW;3v5S? z{5ooe&JWW;CJZ841(RVH)C!HYPDF3wk*F=5fg0$1)R|g=iEtZg#ZM{UC2*I34&PJM zo_$A+(BJX$qz9o^ASbGU1{i={F%ZY02J#1LE7qZ2SbI?eIb-9OQRNNb~&r$D%?-&hZd3$*#lnC<>PlGzV^}W4Z z&!K8bf|jbSE!Z8^p^Iv0G-^wxqgG-&YKC`EigpKe7MqnmiGk{H~0qjDR{|EEozos1@joy>SGp{uk7W#EPx*E{_}m&mqB-WaLJzL`~Ed)JHYc z+}as+7W$)}mZ7Ky*Q3gBN7X-I(~qJa%QL8zzGd^DVodsXUK0qy@2I^CjAIT{PSo>V z7PYi(Q29eqdp-?ys#jqu+=H6=4NQkGP=_*MT$7#&HPC{ntt*MHW>$rO8f<`CqOO=6 zhoU;1hkD_xL(T9ws-g3k6tCO(JJf)_p*oHq&#Y81>aoj;T7kl-Gg2WQ&wmL5wMfvR zn2B1doz`QhExCdk*auWY(c+tilA_}2QIA<}48nS-PrZJqnNCJ^JO_2^SD*&IFFwz| z-e^}yPzN`yFHi$<5}1l{QSlV04m0B_EQqTA5Y@pG)XY9wz4>EAsuv4&W|E^;FpW*m z?Aky9)FCX78c1DhTbtewwH2dLOFY}U2G#KaRKurHTY4GQ;eDI`1Xced>TJYJX!>z; z5YUW@qbgKK4Wu4wCarCLSIkCy2&#j%sKd4s)8k3h(!N0rFlHiiMgmds45)z?MAa*Y z49ImF5KxDmPCVgLkXy21nN}(hAOxaHR3-}9dAbsXfLYVX;j0PPWLB zOk&zgjEbkl06qWN2&h7N)M2WDnqghkbKefNGQ%+iEaK-GJK8t_Zh1iqo# zjh@s@AOWi5q^K26i>?y#6VOabp=MGMHGl@Fjyj?m?2jrp3RQ1{&HoLxGRrX-w_r8A zfqJa7B{S{RK)uqNq8`6t$$0+tqM1X2_GByi;8DzpCr};#Kn*NrfSF-{H3Mouxv(e} zM7>W2U=Z#>9pYQ4b{<*Zq23o>$$9=Y@^r~ffn2DLilLUSDr%|fpWkXCAXK@+HXiO0(CO}PGp3_fWHV|2|DZa!YU7VkEA<-H zkxxo9utcackOhM<6xB`*RQsJ#OFq`-FGig$_aFhy!VI*Thz=V zPS8V(-YN@}XI!c&+Y z!94#Od0CrL6?JIppc-g`+RG7G3J;?iikZQ@P_kJIq0UML)E2ZseF5o=8rX1Dhci$w zq(!Jhc_@Qx0>?@4JZ`AR=qh?%95((4wa3pQlgWHX z%#W(y4mHq`s6)NjB~XmOZq&Eg?^qb~gqRiRiHnKPvhhNh&G-Lis4W?bg>VMu!gHvO zqGd5>C>?5IB~TNqh^ki&wdHO&0nM}{YH50-W;7dBa3N~xR-+E(HY|e|QD-G(R#Pt* zD!(48d~ej!55?^`&8An$X6n^P`f;7E1T>P~s3jR`U5MJtou~mFKrQi6)C{kq_V^>} z>4}})#M7gmngXc9TM0FgMyLUIL2cnEPn_p(nJusjHS*J_nOsG^GC!g^h@ZpD3BpXM zjw_%VY=SD+8?|DSP!pMps<#zY?lh|2L)5407sd7bM-MeCkP6jMR@9553~DBgPy_0W zYG6F-O|}R%;IpU|x`A4md#I=C2Wn-b<}~rds8@6<)L95YSBEY;fehFN^WY>@$A?iB zE~6g5`>0Q~Oku{Xs18C=9Tr2CFNa$CTB!D0qE==uYD-tz__{Ej|9m9uCP5Y7TfK9c zm576yVFoOSIk6LV#=>|VHIsnc=1mxgN-v7Va1eTaGD5X;19jN{v%b#F^PirCueLy% zJf=Wa)MJwub7C=@-UHR)AkAcB3B5rb+8?M_uzy}NvE0@wE&YNyirBMUwh-zmHX2C6}diPK(@CCIse)&y5 zZejvjvJ9wT!k9pc}(HOmq%1bUkjT7c@;6IKM|_qWT;afj5iYf%uI@-wx}Zp z;b_zVR-oEBf~x=6=Eo^+;@QzvgEa{RVK3AOXQ0w|q8hki)14Atp5N`J$GW6f$K1Hm zdJFZKCMs!usa4%N5;c+SsI9(ZeN&R>UmZm$Wxl^>KrMY6)N|e)b!cv5HGG3Q-K9#K zz3z^B^9@Fwi4mxoPDH(sHlWVL4%Cb1FlsALqTaM;OS@(dpOBymAF&=fWy~wLKI%Qt z$Hs@C7xDS1EnA41z&_O1>AR>`^jFl=5x=Z?LuNp|S@WO<&$w1T|PDGvh zm8i#NxAi1?6Te}-jj@T}L%lCvp-#1TIrGBGibaSwMGa&DYGpTLDcpyeh#RH6S>mXe zi-Z8wQdLEr<~o=e2Vy9$z|xH5Dyn=?CG!HRjT+EERQ(9l(=i40_{~R6a0`avKgfVw zCrV{gAs%W5Nl-H?fjWFOu@&~lrg$BjW8o@hr52*LU=ynRMbu&YgqlF=s^+mSi(2|_ z7=*nsP|yEN0@{nMs86%~s8f9gH3PqDW`+DwGYq!zT&U-}ENaUdqs~fq)JhFNb-3EP z0d;t{q9*zPJ%9c`UUjnqb*$m2j$5J{?uJ^zkv4xG>TE2v@lDp9)&thRt!J#4tT!=$ z&3}NdzMDBU&5vL^up-eIwY;2xSO>e~IqZsMYMZ6sikFB7)bVmA<7+&E!|QtSFC+Mp zSkKfQNU0PH;3u>v0pjM(1YR2_Z72BcS z3tdo;+c4D9&P1K^L#VAdgQ|B0b*3Jn4(Df^?$wCrUm5Wmna3mzs=<7y7e{4lebhi& zp&qC1s6#gfwKc0yTXn#C5!LQvRJ|{#0Y?ir151wTC!I?`pY!=q4c9@fKu7Cf)Jjao zAe@hSbL~ZSco}tQpW5^Y9K*V zvs9s|kruF4M(tr!)J)o-Iv#*}9LJ){FSKs7`G-;8kj|sd$V-f?=l=@h(u;JQ?+LtV3 zG5w`!W1s&lB&c8!tc=xBd%M6E+=!mTh}x=?sKa#?^`Y|GrpIn;&P)IXlb#l}6%|lh zRtGiEo;DuQ)-?$$NYE+YgBr*=Tks)j=3i|*bvyHh%!@j-!%>HBA*$Y1)CwI#ofY5q z=CCG4#Z#hIEW5RcOF%QKj5@^)P>1smZ*-qqdFLA(`TY) zx(qe3ov4n_*!)|le%)sTwAY_eU!C%IG)o(f+RI+3!!jMUl-p1p{)PH@y@XoYZ#F%7 zCoj*RfXs#}KLWKvld&-Vj>Yi-vPG_wp|g3XS3#{nE!6Yb95upDsD}EZ8X9GthkD0v zLVe8cMjheu#qB&eq(4Jy9?>djf!#;c&`_x}wEXz5y`2GSK( zaFk7-fLh|2s2R>hE#Yb#-;NsCG1L~_L=Eg6>gh??!@RKaqaMq)7=)90@cgU7Iuf+x zM^KN?3u~sHW=1Vg189euNoUlG3_xwcIMm9`L%nFWqRO2^4eT~*E8n6Hb#O29b-zq6 zo`1cQtB{}pOu-zu9d)=KqgLh(YDvFYqxCjh z-iKP@i!On@1a8=bM14$!6sXgh6*ZHBr~#Ej&9FM^vFl_Vhnm?+)YklsI?NYP?~QAy zL;DTYPJ+H>0B&*udNHIyEmbILsY+u}?1OqzY&3AB=kTn-6qu1?n5o%P1Ii9$DH^C!!Xq#Q@#f3 zv^Pd|GzfJDW}sGfIqGa|Mjhf4sIB-1J%9i2q0RV!I&5E29s3P7UnpXsD#k-qOoTd& zA*gb>Q5_XTEo}wViZn*G*A+Fe{-|=1s0l4b&)@%DNkA2L*a9a|hvXV+sqWkOYt$L| zg8EEI&C{c^Q3}=YC{#PsQK$TO)Y;gLI>e`J{x#IVpSe8$Iy7%cknx6?Ly{HMaWT{( zs)CwHTh!8aM=j|vR710@3ot72WmpSWqXz0d)cg)9JvJoX4?E$7p>*7ZK*?d|V|63e zB%WZnm*+q1(HiyHa2(s9-v}?yf8e7ts-p|2rM+Q&k6MAaBhA24qqZu8jpsxyeLmF6 z6m0R zf@@G`#l1#A4ZT1$`~&rv#Tjk(umWmeO;JnU5A|40MtyI%Y)vx847d&|y)UZ0t*8MU zMtwWJiF#4pHTkaNJ=Pqm_!vw^Ueum7MvZVNhTwG6itIxT_%3P*U!zvgC&HAAhna{M zM7^3@p~^>~CNdlKMQ0;={{H_Z0-D)f)T{Lqs)0n~%-$8XRzR&xZLEeBT<6BUB zdJuIO&!RrOE~8c^-Xt$42rHpF>V#Qv0IIze*3GCF*?~zs|0;Ni1kK=q&4@DDoZ5$8tTLAC2A|u zPB#N_a}dz!t%zEQ8mKL4WNnWcX z?S91|j4{(QK-bAkK!+|D>Ul4X+MD{;W~dcuhuLue>go6cwFUc8^-iK@dI#0vd(;5@ zelz(YSe|$h)P%-hK7IbrA)p4&qh|CNb(+)6G6fr3yP-a$MxdVWMW})9Mh)Z;dS20} z0bD|r|JUaG&bA-psFhA6>7V~u=7o5xUe}IIe^Gv~U^Nnk;5$XS+-i+B6m@O)e z8hIVm0GeV+?1ws3yHTh6nDqf_1)POug;Sy?6lN{Hkmp~gwkip#*cmI}Sk&Wo-WK#* zWd2=FLev0URK2mN8LdDa;%%sz?nQNU3RV6(2H`{0fTAuoTbORKYi3xCgr;QFMK!Pu zyWZE37!W`d!p6|IC?u@)`? zRqTp-3L>m?tbd{o=Wf)VoXVD zL_i-Jek;s~vZ7wO1yD;@12y7CsHN+HTA|74g9}hgy#)0%thedgt-DcMwI9{aZR-c* z(7H~XmFBdkM(tr1)JlY*PIW2NV^tTkVmRi+ahM19U=Y4TorT1!%tV4wPf-|V!6K-E zbU=O9M4;!-|EwaQ4)>x4a0c}}UqZdh?_nWK@rU^WQXexAAAp{jqh3(!QCn~j)$t|N z1n!~+_Ri)<`O}n7h6VNfXC|P6ZBQNeM>Q}Cwd7M!16+eTD|=B-%N10|Z&4lltv2Za zsPx>ZcFUsj8`$*DsQN?DRbUPQEy)(t9$rK(^-T=HSZmDlp4VCp^#*K*TGElIfh|Ry z>OH8597nC_CDg0=ChF|Gv2pLUJpVeqN!FUB&5AmFRZ(xQHmDgySm&XZavkagv=39` z71RK}U=B>Q&OEkdQ1wTmR`NGYkDG1!wRJrITB_$H=s9=Ro6q;6s1Amq_IeJg+(8V( z3#daCeS_JmJg5N|N6ok;hGGZQO3Xu@rIo0&bQd-7KzF0*pg8IxFJ$->0(PxwS(8_}PZrB#pPAAmN`=JIl166+>YUSMv1a!EbpqBP4YOi8# zHZx9*$`3=Gg;J=7yP&>c3_$Jq2po=6uoEWQVkR^k^&Xjm*>MhP=Esq<;5yF;=n#EH zjXe2Qb4Y?v9b`wnX!4=9pb%<6RZs(Nf-2VqwN-sFEiOdW`wR6n9Yw9cIn;o!Vp4tn z|4TrJ#Mx$+)E`R`&45bph(YMu_(IfHZA7iqepCk+QA>RXwb$QKr#(_tA@y_%>A zG{gLQ{<{;XihrW^^s6lpZ-<#lY78d5H0rVIh&t_KP-kQ@YA;uz=NA{KExL&s&|{k) zb*ITsiCVdW==u4-B7t%wG{Q=_40Y&Uqn7L=YG6N5r`&&+IYfCdKk?3}EnIwi`o(wwPg|L`96T!nguq03+hnrN1csJs6+W4wFTaPdHQu7e*&r)idy<|m<^kv zPWdG3O4Q06M4g3~sF{664KT(b({M2AvCWHmIx1Lepxy@!Fc&uV$nzIz6ON+3P<%sG z%yrnDi9)E3ilb&)9W{Was6*Nwb@=+)^a#`pr(q~Av+0*m1Gs}~{{edb`ybB;sDqEF z$1K_rb81tdwxj~8;~uDr!%*cSP#w=l4P+haY1o4rz&X^)+(+%bbJTpyr$rsYlIZI6 zHzuHl`kEUKfq*cX>#7fkuL>1YCKtL9iYVhQ5MQHM6pG4mCz0BS&;PCU>JpcOGJxqcQRg~lA+i5&(O1uVUz>TP_xrQ2Wf)l2}%&39qMV+DYsFi4nTG7s^ zb_ZiL9BcEZq8|5!CtUNVS(lNZ)BP0l;TtT8Sx%bAs4J@Bsi>u0h&t8lQ5~E?&FmT$ z!|12X_k;?l$89i{!X>yF|3hubeD}1MGl{@{)K{?TXUsR4Zm6YOj5btV%1 zW45XYYNpju18jz4unTHMKB6WT_pB+G7`0--m=@i91XQ3AYR_AsmZ}4);hr{q1Zp7T zQ8V6S{TuZjIB&g*s(0JwzqILJPy_TjXWlPykwfe{IZVJQWi#rbUL5^UBb{XP7oldf z8MX8$Z2A)nCjP_b2cI{GvoLBRwNbC^#?}rtzc0qq=l^5^YH$&%!+og7<1DIyXQ&l= zZ}Y#QRv_*LGtdCk8#D*1Tou&gS{v1IOH@1EumJW)E&XPUtIz){1hh1dFbF@`c+!ie zfnd~%NYu(~vK~i0#&=N@d58LpiFe7I`kbhV=0(q+|1VEK9n?Xc z?$*{msDfi~2hK)4HnlICS91eYeoxf%Jj%u=TNk5NViRgW2W|W!s=o)9dHyx>cO>Yv z$GTz)rbfN{bD?HX1@*>jhpIRTb?7Fbwj$ET=cATtqFzW5s2OcQt-vAF3S6@3cWnAwRL6eTOveGJ70!;C zu$W6g4Yju!gHVTQBI=d-C#vIZs6%uLHSa6=$JFycG3x?6&FWQ8T-R`r7?37RJ038>*8sM8wtuIV^A<|3XGRk00fEBd2mHXe02 zH=r6kiYj*z)y^Z-1ismL!h5EEMpSx%dp!TDP@Mz~pe1Ss9Z{#f52~Rd)@i7vTw(JM zpq}sJm>pkWZVbF{-gvb!n0Ox>pO5NzA8Ly)-FMAWy&yq*{T+*-?*sD~mPD;kGt?RA ziW=ZR8y}5Yfk>Oa64lNo)Y9*;9zi|#=dmTu>kJ%&|Lfp$7O6wK88&6NvN7e1*$`8dxRNKzm>m?2mdu4YBDF z=&R>{3V~cW12y8~SOC4Bn+6M`Mjno8pdD%kJy0D?MlJD7>q^uf??k;(kD=^ z>J8}gg6Cg>XarOsHtLm`1cNXG24XpDTU7ZmsB#l(+bj>QkCr(x)8^Mk}v)FHiuweT*M$GmUMVH%1$yt7a< z+-Tj7TA975t^LP(6E)x``hy3mkl?M^)1;_^SuqF;U{P#{I`wlf6K+DiaBiXo7U!LL z?2_S5;vuMxAEFNLM^r!l?@d3+P)|WNmw=Y045~m&YkO3OT~W{JSkwxw#vnX_s`m_4 zF6IaGxTZs`L_rL~+L#`DquQB^`VP4d^`3CA+XBx}4f=mHBMwC!o=P^}3xkMHMvZ(u zYKDKK>Rm%^*(cNhQhYLpG!JTpYN8&)#;CK?5qZD3&OicMqDa&WWDV+c|Ap${4rakO zsD^?*n^T_|RWGNFS4MSE3$=yKQBO@5)XEOP95@s;u??6--~X=>(Bl&Ai!ljm&x6qi zTU*s1}KguVx}~QSGKi4YZl0f2RupoyI|^hL>V~ z+=Tt{ITpiq-^`3wp~`PTHFyK{qDuMQ>~SO1$_+uaHx6(I%Ai-U2o5)(pwU=L_t2@o}d4-p&Dp|TEc$lc??kvtVVqXe851AdcHs)nDuqC`@20YKHHy8ODy{ZB8%hl{*0aa0qHfqfs5rN3Fnm zY=k#49TxO6<(pz2;%!jv%*Qgg1aqSMn1D`c%BbGXSImgo^YqcYJ&#dl^d_DUwL%3^ z4VFi($Pm;(mZE0174^b7X?=rwFC>d@wzv@L?6g5v&UGdd2qIw(YUHO;hv+S;1OFH% zo)^_{9n_K!w9ZAHkzF=^6@!R>MjgK7F-^QQ>JYZJ@iCZ2&;LrBal(_pd*zo_4fQc5Q=)d2BO|%OHo_14pnXo2H{cEA$w%gU!(TgH=Z#%>h#A!ZB+); zx9tMxh7%}3Kpibab#xSU>d&JW-bXF{L)6~Iif>jZ3^k(~Hr@qe5ub>9(ab>&_&Dl} z{ewCS*HJ6-BR~GpB zfI96JP!pMgI;4?U0$2L;{A+|yNzkEsjiHzzp?MFKLRH+SLiQTZ$og>i<-=hlX@~K+ zA79rfSP6A4B&|N-=%nckoW_E*!S@!=m5u$$P8)OE+6u#|P=JL0dkrLi0eQM+Qc0`x z^9rTGBjoqO9X9a`P9Q#;j#g5BDsA!&-dPj*s#9_|CMjCSP*Ou}tE?C<=9^#C{sp#aClz72)=TQ_=Vw%9OW_dkXN6?zB;k zG95^d71^wde`MD#zHSmy*HR;lmUX41r7^Z9U+DkmI!{^-;zcR9kko?QXKnA-NE<{u zYseqYy^DAW;=1&zc}m?zwtc15Cp^^Db)DyQevQZl3U$QYzZ9%OBg05LOxj>OsJUu^ ztAZ_;k@~v&*m(S3>Nh7`n*sf>Wv-Y`J>?gZ{=z3SpUO16o{s({^Nc5puZx726P{(` zf6`Fn$a!6pyZ(gwkUM}T-x6L23S1>KEAn!O`=({{1h&vAPVSZt}$7!q)_X!g6(ZC_XwQWbm z83ey0@LU(k+r}NjGwknfv&}Ul@2L&z(_oRU*^O346Fy?|{vhl_ZCzPynP-@Qw14P< zPdjHOdE2<_bGNl+uaXzXhDmn%nYw&na{WtW2bsg^Oc!4qJ^%f5g%6Q;8Mos)(#KM6 z7v&C^2Aub-*KYFba!)0%9%cBgh4VXQ2G|boQg(=4V~RQajPDG<#hxFSmBRIgLbs?; zgv@YmKPrs0vmS#ph#w+d*DcBxvxA*v%P4&ucL&OJA^!qK<$g|^Er?I0e0k!-Y3Cc| zYH`=(1H)-gfr~^=6V}y?LN!d#No&*U(@7O+r>SP z_yO(`)CnQJpYl;`+3B?Dt{@=}8SfaxX2S8vyiWWKcUR(*sJw~18r-^8($IJ;OuPvV z6rs!|;)$p?p0rN3ah28e2kl%XUEdIfQvMz`=I%~CuJ%rR3Opp@N5#lrDkmnlzwJ~% zV(MyZDmf9@+a!6uODTAix-YD%V|q^{p6 z6_XPBmgTv~8$`L9q$lRyN4bNf-Llz3ssD`lI_`bc%RxLk>+B29_iV4xex`HfrGcY{-f_#47AZC9O$A7&`cNn4Ehs5gRePx5Qi7QgcNpQ|rr z+mkktl#Z0UY^U(nO0s!j+@bPwZhnY&YLPjRa1gf_4d^;S+DsZsN%#n5cH%|b$ZW#7 zD4UxO9P$E5&t?aanQ%hx1!U<8piEKXV=1p|u^;_UvXSL<@H^qwWPGq4Kc?`{%Zo;@ z(?D9vWm9KdsqrIq9%FCPbsZsIhj>EU#!Bj)CeCl4|G(>~@-_dI1UA~N!dS>wOh6@F z+o{;v4pQ++*d6BX$DR+nTf(&E|<-<@vM(R4jy@Rw;c8~)p?@N8RolWqR zvi}(Jvoo7_mkus#^i()0x%S%5`xCBCV;yb!2FjMF-dOHn(&Lie&r^fn2HAEGQKpEg z?>fOm#!z@Xg>@CfjohtF)M-xx$Ee6x2~V8Ul;)SJBQ+`9T> za_UT{{n;8k#;^k|O?MSaEaw2=k)D@fXLhjvE$il5F z7B=9{Pnk@V-#}V9?!ttZkUo&|`k6;p>Bz$Ulen|Uc}eNt@DtA9-b{ELr9&9PW@_ka zhn-2!PWrFc1JW{cAExY1?&D-;A)b^w9&HW6|F9qRuaO^@DfS?(8EH{{oyc?jz(cQB(W$i0TN zwhW{P>BD~(#)9POx<~u}*>*;HMKyDEAB7R({IYAiV?iI}uLD{g}M#lu1uG(w57rzrJ75M$||V{ez2NX?m`ybb5?? z6Xmv1F*>)d0@Qho`?+&b_7eH&Z5`!LAwIwkI65Y^eI#Q*`W3=-?uwLgPw|ggBsQi% zNg5bOJcRhq>ka9P#ivk+xHjr>l?crz!1J;=V!pas75+7=e8x%%_1wgo_c@b<+-eG4gM2oWF1uKBM6S zG**;&a_Y?HzC)elq$T8zVe4%pJdgCo{2ZawA{0hlwOygI$ zb&VozF5#uz4{e1+c!a#|n3eoruRmz4Fm22ueF7OL38((G0O6#x^^Ww04B`s+cJ3OH z)rTanP?^wcT9`=gBubsNHM5fT^QvP<@q{veQRa8@G7{D`k-Rd5e?*DgG9;whFyS;5SJ!M-^?>EYoB>y()e-hV~;+M%NzMeL8Eh9gU?Zc0@dYQ26RI-g; zQAHbWL1tnqX2x$64n=>m&k;^TnI_!3XprAodagp0T}wPSZM3v$$|!CJRUe-b??--B z>_++6wAIyzgVCADU?M@>%L)I7+teWUZ7QU|zT5{jK&}#mKU3!CHI%`pZyD3nV>`f1lTI*vvYQRoKuDbo7?(!oFqmf`;O>SObtP&OKM zGthWA;TeSIk=GNyQRfBfT0uBJ;cZyjw$%+|H?*VbNTG6(g@-3`^Du<5w#Xi=OtW2W zscwXI1rYB{IFhn?2>(mkBkn?WSVM3Q`D1MPCX`t~TNNm?iEtNNt}a8WLmRphnzR^> z7X|ZD$c?y2qMy#j{JUUupZ&4q|K!8LGn*af76>Z*X!b2$gCnc&z(bLLRjf4*-= zKlXeZOGoL7kwZr%aa&X7JhASm>lh`xZ7Iczb2p@2U8Qi@FJn2w7;93mlgV~2Q|}e= zNbUucOF;f3oW{My*7G562I*HR`;QNwj4_BbC-D}O_=FpXrzEoyab1_GxY|}OOS+F8 zOiIe>T3}T;1NDzkc0J`9aJS{&Lir}PeweKrLb=?YdXY0m$8pP%9fj^-jp3{%k3mDnDlj|RiNoA#52;sdg8l@AEjJs!ujbc8R2*2Ehl|6P9uJky#4wg zb$ut2jLN=bo*;2Gjeep~JJJTLG4eOkNM7=f6AvJ7jvde+l+iVUGP;@&-(`Z%Ae>FT zQKS{4uCD2Lp1Nmje3NFB$49^H=hMI$K=G0|oYbro`^vq9qUT6^jeCigBAgjlQ&yM1 z?Yb)YI|xr9EwOF>H#@vA(#p`Lk1czR`u8Z)nKteaK2Ewjh=kh|>`uaY3eUBTkmQ`9 zp^c>Lnu#@tmnOd-4J5S#sYWBKNLxj`Df#ON=cOH8*|`&WLcCij*M{_7L23XuTSIdG;os05(?<5Z5w}RqW|;HW2E1vOcR@ufN*L$()Cp7G~R}R zrs9svt!n~l>1n^AZF_)CuSYx+;U_Kyylo?U>`bCzbyMGYO~E+B=knzriNjJD!IqI5YaN-j`_)DFa#1|2-NB-aXEkYeC zEwGhTrvsT2X?Q7}wdJlw{$0}3GN4hmp?RbiuXP<1<#JJXBkgUcp03H%S&5g( z*8%dfZOo?}!)GnwD4Ff3@Q4CSDNv8QyYjix+J?d-i%;+m?@7t?wu$?{4ErWEbJ~)L zDYKdII?CCUuxj(lCA)G1GXC(5nn{u;S{g1=jm&~n>SI!fw0XgSgz#dCvII;xXTcp%UzZhr%?VB^)A}cwV~%2q%|fULHb(Tc3#T=;c0>2Ws!cFjpz*QLlpbQ@VAYPra&w*cG!Y5>>zGiJuUMOAM)4GU{pFuL0-9^<;fdKxE1$n z!nq?;Px3F_nijYG(!xt}6A`aK3(K%EcYo3r64w>M-GKOC!~^LeC(elMHz}}P31a)n z(N&hzH5xayd*T^9M07G`eo*E$@g>A_Q0_jruCnAMW;7#kuu1a#pCSLCYyfpKQmzPX zHH`F{?C(CH)O=fN3#rAqPmxxKlD%mqiEXt!wMS7dElweAAmI_@uOhyiczf>Vg!@x> zA#J3$^)^v19^oIP>#AvRGEn!4zHP@QBOjgBA)_i4f4wS`_s%vnfeNp~-css@+?-*_A%16Bnggs7#Z@-r=*KrVHNVOYwRFYZg=>&EF*HW%7h@6^)) sG4f>185$HCS|Bv{)+!aec9h&2FwrYtX0M(z7cKWnxV6o8uQCn)AA5%fc>n+a diff --git a/lib/lang/locale/id_ID/LC_MESSAGES/messages.po b/lib/lang/locale/id_ID/LC_MESSAGES/messages.po index 06484e3c..09b5c109 100755 --- a/lib/lang/locale/id_ID/LC_MESSAGES/messages.po +++ b/lib/lang/locale/id_ID/LC_MESSAGES/messages.po @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: Senayan3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-21 11:10+0700\n" -"PO-Revision-Date: 2021-06-21 11:15+0700\n" +"POT-Creation-Date: 2021-07-21 16:29+0700\n" +"PO-Revision-Date: 2021-07-21 16:30+0700\n" "Last-Translator: Arif Syamsudin Budi W. \n" "Language-Team: Arie Nugraha; Hendro Wicaksono; Wardiyono \n" @@ -333,7 +333,7 @@ msgstr "Perpanjang" #: admin/default/home.php:240 admin/default/home.php:303 #: admin/modules/membership/member_base_lib.inc.php:208 -#: admin/modules/reporting/customs/overdued_list.php:196 +#: admin/modules/reporting/customs/overdued_list.php:209 msgid "Overdue" msgstr "Keterlambatan" @@ -622,7 +622,7 @@ msgstr "ID Anggota" #: admin/modules/bibliography/marcsru.php:343 #: admin/modules/bibliography/p2p.php:313 #: admin/modules/bibliography/p2p.php:369 -#: admin/modules/bibliography/pop_attach.php:204 +#: admin/modules/bibliography/pop_attach.php:211 #: admin/modules/bibliography/pop_author_edit.php:89 #: admin/modules/bibliography/pop_biblio_rel.php:90 #: admin/modules/bibliography/pop_biblio_rel.php:92 @@ -680,7 +680,7 @@ msgstr "Judul" #: admin/modules/reporting/customs/loan_history.php:153 #: admin/modules/reporting/customs/loan_history.php:238 #: admin/modules/reporting/customs/member_loan_list.php:191 -#: admin/modules/reporting/customs/overdued_list.php:197 +#: admin/modules/reporting/customs/overdued_list.php:210 #: lib/contents/download_current_loan.inc.php:63 #: lib/contents/download_loan_history.inc.php:63 #: lib/contents/member.inc.php:361 lib/contents/member.inc.php:407 @@ -696,7 +696,7 @@ msgstr "Tanggal Pinjam" #: admin/modules/reporting/customs/loan_history.php:154 #: admin/modules/reporting/customs/loan_history.php:239 #: admin/modules/reporting/customs/member_loan_list.php:191 -#: admin/modules/reporting/customs/overdued_list.php:197 +#: admin/modules/reporting/customs/overdued_list.php:210 #: lib/contents/download_current_loan.inc.php:64 #: lib/contents/member.inc.php:362 msgid "Due Date" @@ -733,7 +733,7 @@ msgstr "Tanggal Kembali" #: admin/modules/stock_take/current.php:194 #: admin/modules/stock_take/index.php:170 #: admin/modules/stock_take/st_log.php:112 -#: admin/modules/system/app_user.php:469 admin/modules/system/backup.php:193 +#: admin/modules/system/app_user.php:469 admin/modules/system/backup.php:185 #: admin/modules/system/content.php:298 #: admin/modules/system/custom_field.php:291 #: admin/modules/system/holiday.php:267 admin/modules/system/module.php:226 @@ -2135,7 +2135,7 @@ msgstr "Pilih berkas" msgid "Or download from url" msgstr "Atau unduh dari url" -#: admin/modules/bibliography/index.php:974 admin/modules/system/backup.php:184 +#: admin/modules/bibliography/index.php:974 admin/modules/system/backup.php:176 msgid "Download" msgstr "Unduh" @@ -2259,7 +2259,7 @@ msgid "Add Attachment" msgstr "Tambah Lampiran" #: admin/modules/bibliography/index.php:1017 -#: admin/modules/bibliography/pop_attach.php:258 +#: admin/modules/bibliography/pop_attach.php:267 #: admin/modules/master_file/label.php:227 #: admin/modules/master_file/label.php:232 #: template/akasia-dz/detail_template.php:170 @@ -2770,88 +2770,92 @@ msgstr "" "Maaf, dari %s tidak ada hasil ATAU kemungkinan hasil dan detail XML " "dinonaktifkan." -#: admin/modules/bibliography/pop_attach.php:99 +#: admin/modules/bibliography/pop_attach.php:101 msgid "Upload FAILED! Forbidden file type or file size too big!" msgstr "Unggah GAGAL! Jenis berkas terlarang atau ukuran terlalu besar!" -#: admin/modules/bibliography/pop_attach.php:149 +#: admin/modules/bibliography/pop_attach.php:156 msgid "File Attachment data updated!" msgstr "Data berkas lampiran berhasil diperbarui!" -#: admin/modules/bibliography/pop_attach.php:154 +#: admin/modules/bibliography/pop_attach.php:161 msgid "File Attachment data FAILED to update!" msgstr "Data berkas lampiran GAGAL diperbarui!" -#: admin/modules/bibliography/pop_attach.php:158 -#: admin/modules/bibliography/pop_attach.php:173 +#: admin/modules/bibliography/pop_attach.php:165 +#: admin/modules/bibliography/pop_attach.php:180 msgid "File Attachment uploaded succesfully!" msgstr "Berkas Lampiran berhasil diunggah!" -#: admin/modules/bibliography/pop_attach.php:163 +#: admin/modules/bibliography/pop_attach.php:170 msgid "File Attachment data FAILED to save!" msgstr "Berkas Lampiran GAGAL disimpan!" -#: admin/modules/bibliography/pop_attach.php:183 +#: admin/modules/bibliography/pop_attach.php:190 msgid "Upload Now" msgstr "Unggah Sekarang" -#: admin/modules/bibliography/pop_attach.php:213 +#: admin/modules/bibliography/pop_attach.php:220 msgid "Repository ROOT" msgstr "Repositori ROOT" -#: admin/modules/bibliography/pop_attach.php:223 +#: admin/modules/bibliography/pop_attach.php:230 msgid "Repo. Directory" msgstr "Direktori Repositori" -#: admin/modules/bibliography/pop_attach.php:234 +#: admin/modules/bibliography/pop_attach.php:241 msgid "File To Attach" msgstr "Berkas untuk dilampirkan" -#: admin/modules/bibliography/pop_attach.php:237 +#: admin/modules/bibliography/pop_attach.php:244 msgid "URL" msgstr "URL" -#: admin/modules/bibliography/pop_attach.php:240 +#: admin/modules/bibliography/pop_attach.php:247 msgid "Work for embedded link or video attachment" msgstr "Digunakan bersama tempelan pranala atau lampiran video" -#: admin/modules/bibliography/pop_attach.php:241 +#: admin/modules/bibliography/pop_attach.php:248 msgid "Link" msgstr "Pranala" -#: admin/modules/bibliography/pop_attach.php:241 +#: admin/modules/bibliography/pop_attach.php:248 msgid "Popup" msgstr "Pop-up" -#: admin/modules/bibliography/pop_attach.php:241 +#: admin/modules/bibliography/pop_attach.php:248 msgid "Embed" msgstr "Tempel" -#: admin/modules/bibliography/pop_attach.php:242 +#: admin/modules/bibliography/pop_attach.php:249 msgid "Placement" msgstr "Penempatan" -#: admin/modules/bibliography/pop_attach.php:245 +#: admin/modules/bibliography/pop_attach.php:252 #: admin/modules/reporting/customs/member_fines_list.php:188 #: admin/modules/reporting/customs/procurement_report.php:125 msgid "Description" msgstr "Deskripsi" -#: admin/modules/bibliography/pop_attach.php:247 +#: admin/modules/bibliography/pop_attach.php:254 +msgid "File Password" +msgstr "Kata sandi Berkas" + +#: admin/modules/bibliography/pop_attach.php:256 msgid "Public" msgstr "Publik" -#: admin/modules/bibliography/pop_attach.php:248 +#: admin/modules/bibliography/pop_attach.php:257 msgid "Private" msgstr "Tertutup" -#: admin/modules/bibliography/pop_attach.php:249 +#: admin/modules/bibliography/pop_attach.php:258 #: admin/modules/reporting/customs/dl_counter.php:113 #: admin/modules/reporting/customs/dl_counter.php:200 msgid "Access" msgstr "Akses" -#: admin/modules/bibliography/pop_attach.php:256 +#: admin/modules/bibliography/pop_attach.php:265 msgid "Access Limit by Member Type" msgstr "Pembatasan Akses berdasarkan Tipe Keanggotaan" @@ -2987,7 +2991,7 @@ msgid "Settings saved" msgstr "Setelan tersimpan" #: admin/modules/bibliography/print_settings.php:78 -#: admin/modules/system/holiday.php:334 admin/modules/system/index.php:237 +#: admin/modules/system/holiday.php:342 admin/modules/system/index.php:237 #: admin/modules/system/membercard_theme.php:107 #: admin/modules/system/theme.php:138 admin/modules/system/ucsetting.php:76 msgid "Save Settings" @@ -3598,6 +3602,7 @@ msgstr "Reservasi" #: admin/modules/circulation/circulation_action.php:564 #: admin/modules/circulation/circulation_action.php:566 +#: admin/modules/reporting/customs/overdued_list.php:209 msgid "Fines" msgstr "Denda" @@ -4940,7 +4945,7 @@ msgstr "Kontak" #: admin/modules/membership/index.php:510 #: admin/modules/reporting/customs/due_date_warning.php:152 #: admin/modules/reporting/customs/member_loan_list.php:185 -#: admin/modules/reporting/customs/overdued_list.php:190 +#: admin/modules/reporting/customs/overdued_list.php:194 #: files/membercard/classic/membercard.php:286 #: files/membercard/old/membercard.php:331 msgid "Phone Number" @@ -5044,7 +5049,7 @@ msgstr "Baris pertama adalah nama kolom" #: admin/modules/membership/index.php:98 msgid "Member ID, Name and Birthday cannot be empty" -msgstr "ID dan Nama Anggota dan Tanggal Lahit tidak boleh kosong" +msgstr "ID dan Nama Anggota dan Tanggal Lahir tidak boleh kosong" #: admin/modules/membership/index.php:101 admin/modules/system/app_user.php:99 #: lib/contents/login.inc.php:163 lib/contents/newpass.inc.php:57 @@ -5203,7 +5208,7 @@ msgstr "Foto" #: admin/modules/membership/index.php:711 #: admin/modules/reporting/customs/due_date_warning.php:152 #: admin/modules/reporting/customs/member_loan_list.php:185 -#: admin/modules/reporting/customs/overdued_list.php:190 +#: admin/modules/reporting/customs/overdued_list.php:194 #: files/membercard/old/membercard.php:322 msgid "E-mail" msgstr "Surel" @@ -5960,15 +5965,15 @@ msgstr "Tanggal Pendaftaran Sejak" msgid "Register Date Until" msgstr "Tanggal Pendaftaran Hingga" -#: admin/modules/reporting/customs/overdued_list.php:190 +#: admin/modules/reporting/customs/overdued_list.php:194 msgid "Send Notification e-mail" msgstr "Kirim surel Pemberitahuan" -#: admin/modules/reporting/customs/overdued_list.php:195 +#: admin/modules/reporting/customs/overdued_list.php:208 msgid "Book Price" msgstr "Harga Buku" -#: admin/modules/reporting/customs/overdued_list.php:196 +#: admin/modules/reporting/customs/overdued_list.php:209 msgid "day(s)" msgstr "hari" @@ -6110,6 +6115,7 @@ msgstr "" "Laporan Penghitung Pengunjung untuk tahun {selectedYear}" #: admin/modules/reporting/customs/visitor_report_day.php:61 +#: admin/modules/reporting/customs/visitor_report_day.php:128 msgid "Visitor Report by Day" msgstr "Laporan Pengunjung berdasarkan Hari" @@ -6945,23 +6951,23 @@ msgstr "Salinan Pangkalan Data" msgid "Start New Backup" msgstr "Mulai Salinan Baru" -#: admin/modules/system/backup.php:148 admin/modules/system/backup.php:156 +#: admin/modules/system/backup.php:147 msgid "Backup Executor" msgstr "Pelaksana Pencadangan" -#: admin/modules/system/backup.php:149 admin/modules/system/backup.php:157 +#: admin/modules/system/backup.php:148 msgid "Backup Time" msgstr "Waktu Pencadangan" -#: admin/modules/system/backup.php:150 admin/modules/system/backup.php:158 +#: admin/modules/system/backup.php:149 msgid "Backup File Location" msgstr "Lokasi Berkas Cadangan" -#: admin/modules/system/backup.php:151 admin/modules/system/backup.php:159 +#: admin/modules/system/backup.php:150 msgid "File Size" msgstr "Ukuran Berkas" -#: admin/modules/system/backup.php:176 +#: admin/modules/system/backup.php:168 msgid "File not found" msgstr "Berkas tidak ada" @@ -7354,6 +7360,15 @@ msgid "" "problem." msgstr "Informasi terkait sistem SLiMS. Digunakan untuk dukungan perbaikan." +#: admin/modules/system/holiday.php:58 admin/modules/system/holiday.php:63 +#: admin/modules/system/holiday.php:78 admin/modules/system/holiday.php:85 +#: admin/modules/system/holiday.php:92 admin/modules/system/holiday.php:99 +#: admin/modules/system/holiday.php:124 admin/modules/system/holiday.php:160 +#: admin/modules/system/holiday.php:163 admin/modules/system/holiday.php:174 +#: admin/modules/system/holiday.php:293 admin/modules/system/holiday.php:301 +msgid "Holiday Settings" +msgstr "Setelan Hari Libur" + #: admin/modules/system/holiday.php:58 msgid "Holiday description can't be empty!" msgstr "Keterangan hari mohon diisi!" @@ -7383,10 +7398,6 @@ msgstr "" msgid "Holiday FAILED to Save. Please Contact System Administrator" msgstr "Hari Libur GAGAL Disimpan. Hubungi administrator Sistem" -#: admin/modules/system/holiday.php:174 -msgid "Holiday Settings" -msgstr "Setelan Hari Libur" - #: admin/modules/system/holiday.php:179 admin/modules/system/submenu.php:52 msgid "Holiday Setting" msgstr "Setelan Hari Libur" @@ -7421,45 +7432,45 @@ msgstr "Anda akan menyunting hari libur" msgid "Day name" msgstr "Nama hari" -#: admin/modules/system/holiday.php:278 +#: admin/modules/system/holiday.php:279 msgid "Maximum 6 day can be set as holiday!" msgstr "Hari libur bisa diatur maksimal 6 hari!" -#: admin/modules/system/holiday.php:292 +#: admin/modules/system/holiday.php:293 admin/modules/system/holiday.php:301 msgid "Holiday settings saved" msgstr "Aturan hari libur tersimpan" -#: admin/modules/system/holiday.php:321 +#: admin/modules/system/holiday.php:329 #: simbio2/simbio_UTILS/simbio_date.inc.php:247 msgid "Monday" msgstr "Senin" -#: admin/modules/system/holiday.php:322 +#: admin/modules/system/holiday.php:330 #: simbio2/simbio_UTILS/simbio_date.inc.php:248 msgid "Tuesday" msgstr "Selasa" -#: admin/modules/system/holiday.php:323 +#: admin/modules/system/holiday.php:331 #: simbio2/simbio_UTILS/simbio_date.inc.php:249 msgid "Wednesday" msgstr "Rabu" -#: admin/modules/system/holiday.php:325 +#: admin/modules/system/holiday.php:333 #: simbio2/simbio_UTILS/simbio_date.inc.php:250 msgid "Thursday" msgstr "Kamis" -#: admin/modules/system/holiday.php:326 +#: admin/modules/system/holiday.php:334 #: simbio2/simbio_UTILS/simbio_date.inc.php:251 msgid "Friday" msgstr "Jumat" -#: admin/modules/system/holiday.php:327 +#: admin/modules/system/holiday.php:335 #: simbio2/simbio_UTILS/simbio_date.inc.php:252 msgid "Saturday" msgstr "Sabtu" -#: admin/modules/system/holiday.php:329 +#: admin/modules/system/holiday.php:337 #: simbio2/simbio_UTILS/simbio_date.inc.php:246 msgid "Sunday" msgstr "Minggu" From cea27fcbe4782e17e3c51f4aadab026df5ff6855 Mon Sep 17 00:00:00 2001 From: idoalit Date: Sat, 31 Jul 2021 20:07:12 +0700 Subject: [PATCH 14/73] Fix: PHP Warning Only the first byte will be assigned to the string offset in utility.inc.php, for compatibility with php-8 --- lib/utility.inc.php | 1337 ++++++++++++++++++++++--------------------- 1 file changed, 670 insertions(+), 667 deletions(-) diff --git a/lib/utility.inc.php b/lib/utility.inc.php index 84f35a7c..58ca5346 100755 --- a/lib/utility.inc.php +++ b/lib/utility.inc.php @@ -1,667 +1,670 @@ -'."\n"; - echo 'alert("'.$str_message.'")'."\n"; - echo ''."\n"; - } - - /** - * Static Method to send out toastr notification - * - * @param string $type [info, success, warning, error] - * @param string $str_message - * @return void - */ - public static function jsToastr($title, $str_message, $type = 'info') - { - if (!$str_message) { - return; - } - - $options = [ - 'closeButton' => true, - 'debug' => false, - 'newestOnTop' => false, - 'progressBar' => false, - 'positionClass' => 'toast-top-right', - 'preventDuplicates' => false, - 'onclick' => null, - 'showDuration' => 300, - 'hideDuration' => 1000, - 'timeOut' => 5000, - 'extendedTimeOut' => 1000, - 'showEasing' => 'swing', - 'hideEasing' => 'linear', - 'showMethod' => 'fadeIn', - 'hideMethod' => 'fadeOut' - ]; - - // replace newline with javascripts newline - $str_message = str_replace("\n", '\n', addslashes($str_message)); - echo ''."\n"; - } - - - /** - * Static Method to create random string - * - * @param int $int_num_string: number of randowm string to created - * @return void - */ - public static function createRandomString($int_num_string = 32) - { - $_random = ''; - $_salt = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $_saltlength = strlen($_salt); - for ($r = 0; $r < $int_num_string; $r++) { - $_random .= $_salt[rand(0, $_saltlength - 1)]; - } - - return $_random; - } - - - /** - * Static Method to load application settings from database - * - * @param object $obj_db - * @return void - */ - public static function loadSettings($obj_db) - { - global $sysconf; - $_setting_query = $obj_db->query('SELECT * FROM setting'); - if (!$obj_db->errno) { - while ($_setting_data = $_setting_query->fetch_assoc()) { - $_value = @unserialize($_setting_data['setting_value']); - if (is_array($_value)) { - foreach ($_value as $_idx=>$_curr_value) { - if (is_array($_curr_value)) { - $sysconf[$_setting_data['setting_name']][$_idx] = $_curr_value; - } else { - $sysconf[$_setting_data['setting_name']][$_idx] = stripslashes($_curr_value); - } - } - } else { - $sysconf[$_setting_data['setting_name']] = stripslashes($_value); - } - } - } - } - - - /** - * Static Method to check privileges of application module form current user - * - * @param string $str_module_name - * @param string $str_privilege_type - * @return boolean - */ - public static function havePrivilege($str_module_name, $str_privilege_type = 'r') - { - global $sysconf; - // checking checksum - if ($sysconf['load_balanced_env']) { - $server_addr = $_SERVER['REMOTE_ADDR']; - } else { - $server_addr = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : (isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : gethostbyname($_SERVER['SERVER_NAME'])); - } - - - $_checksum = defined('UCS_BASE_DIR')?md5($server_addr.UCS_BASE_DIR.'admin'):md5($server_addr.SB.'admin'); - if ($_SESSION['checksum'] != $_checksum) { - return false; - } - // check privilege type - if (!in_array($str_privilege_type, array('r', 'w'))) { - return false; - } - if (isset($_SESSION['priv'][$str_module_name][$str_privilege_type]) AND $_SESSION['priv'][$str_module_name][$str_privilege_type]) { - return true; - } - return false; - } - - - /** - * Static Method to write application activities logs - * - * @param object $obj_db - * @param string $str_log_type - * @param string $str_value_id - * @param string $str_location - * @param string $str_log_msg - * @return void - */ - public static function writeLogs($obj_db, $str_log_type, $str_value_id, $str_location, $str_log_msg, $str_log_submod=NULL, $str_log_action=NULL) - { - if (!$obj_db->error) { - // log table - $_log_date = date('Y-m-d H:i:s'); - $_log_table = 'system_log'; - // filter input - $str_log_type = $obj_db->escape_string(trim($str_log_type)); - $str_value_id = $obj_db->escape_string(trim($str_value_id)); - $str_location = $obj_db->escape_string(trim($str_location)); - $str_log_msg = $obj_db->escape_string(trim($str_log_msg)); - $str_log_submod = $obj_db->escape_string(trim($str_log_submod)); - $str_log_action = $obj_db->escape_string(trim($str_log_action)); - // insert log data to database - @$obj_db->query('INSERT INTO '.$_log_table.' - VALUES (NULL, \''.$str_log_type.'\', \''.$str_value_id.'\', \''.$str_location.'\','. - ' \''.$str_log_submod.'\''. - ', \''.$str_log_action.'\''. - ', \''.$str_log_msg.'\', \''.$_log_date.'\')'); - } - } - - - /** - * Static Method to get an ID of database table record - * - * @param object $obj_db - * @param string $str_table_name - * @param string $str_id_field - * @param string $str_value_field - * @param string $str_value - * @param array $arr_cache - * @return mixed - */ - public static function getID($obj_db, $str_table_name, $str_id_field, $str_value_field, $str_value, &$arr_cache = false) - { - $str_value = trim($str_value); - if ($arr_cache) { - if (isset($arr_cache[$str_value])) { - return $arr_cache[$str_value]; - } - } - if (!$obj_db->error) { - $id_q = $obj_db->query('SELECT '.$str_id_field.' FROM '.$str_table_name.' WHERE '.$str_value_field.'=\''.$obj_db->escape_string($str_value).'\''); - if ($id_q->num_rows > 0) { - $id_d = $id_q->fetch_row(); - unset($id_q); - // cache - if ($arr_cache) { - $arr_cache[$str_value] = $id_d[0]; - } - return $id_d[0]; - } else { - $_curr_date = date('Y-m-d'); - // if not found then we insert it as new value - $obj_db->query('INSERT IGNORE INTO '.$str_table_name.' ('.$str_value_field.', input_date, last_update) - VALUES (\''.$obj_db->escape_string($str_value).'\', \''.$_curr_date.'\', \''.$_curr_date.'\')'); - if (!$obj_db->error) { - // cache - if ($arr_cache) { - $arr_cache[$str_value] = $obj_db->insert_id; - } - return $obj_db->insert_id; - } - } - } - } - - - /** - * Static method to detect mobile browser - * - * @return boolean - * this script is taken from http://detectmobilebrowsers.com/ - **/ - public static function isMobileBrowser() - { - $_is_mobile_browser = false; - - if(preg_match('/android.+mobile|avantgo|bada\/|blackberry| - blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)| - iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i| - palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian| - treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)| - xda|xiino/i', - @$_SERVER['HTTP_USER_AGENT']) - || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s| - a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)| - amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw| - au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)| - br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc| - cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob| - do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8| - ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo| - go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)| - hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)| - i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno| - ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt | - kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])| - libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr| - me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do| - t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]| - n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)| - nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg| - pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox| - psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600| - raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)| - sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)| - sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)| - so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)| - ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)| - ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri| - vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc| - vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit| - wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i', - substr(@$_SERVER['HTTP_USER_AGENT'],0,4))) - $_is_mobile_browser = true; - - return $_is_mobile_browser; - } - - - /** - * Static method to check if member already logged in or not - * - * @return boolean - **/ - public static function isMemberLogin() - { - $_logged_in = false; - $_logged_in = isset($_SESSION['mid']) && isset($_SESSION['m_name']); - return $_logged_in; - } - - - /** - * Static method to filter data - * - * @param mixed $mix_input: input data - * @param string $str_input_type: input type - * @param boolean $bool_trim: are input string trimmed - * - * @return mixed - **/ - public static function filterData($mix_input, $str_input_type = 'get', $bool_escape_sql = true, $bool_trim = true, $bool_strip_html = false) { - global $dbs; - - if (extension_loaded('filter')) { - if ($str_input_type == 'var') { - $mix_input = filter_var($mix_input, FILTER_SANITIZE_STRING); - } else if ($str_input_type == 'post') { - $mix_input = filter_input(INPUT_POST, $mix_input); - } else if ($str_input_type == 'cookie') { - $mix_input = filter_input(INPUT_COOKIE, $mix_input); - } else if ($str_input_type == 'session') { - $mix_input = filter_input(INPUT_SESSION, $mix_input); - } else { - $mix_input = filter_input(INPUT_GET, $mix_input); - } - } else { - if ($str_input_type == 'get') { - $mix_input = $_GET[$mix_input]; - } else if ($str_input_type == 'post') { - $mix_input = $_POST[$mix_input]; - } else if ($str_input_type == 'cookie') { - $mix_input = $_COOKIE[$mix_input]; - } else if ($str_input_type == 'session') { - $mix_input = $_SESSION[$mix_input]; - } - } - - // trim whitespace on string - if ($bool_trim) { $mix_input = trim($mix_input); } - // strip html - if ($bool_strip_html) { $mix_input = strip_tags($mix_input); } - // escape SQL string - if ($bool_escape_sql) { $mix_input = $dbs->escape_string($mix_input); } - - return $mix_input; - } - - - /** - * Static method to convert XML entities - * Code taken and modified from: - * Matt Robinson at http://inanimatt.com/php-convert-entities.html - * - * @param string $str_xml_data: string of xml data to check - * - * @return string - **/ - public static function convertXMLentities($str_xml_data) { - static $_ent_table = array('quot' => '"', - 'amp' => '&', - 'lt' => '<', - 'gt' => '>', - 'OElig' => 'Œ', - 'oelig' => 'œ', - 'Scaron' => 'Š', - 'scaron' => 'š', - 'Yuml' => 'Ÿ', - 'circ' => 'ˆ', - 'tilde' => '˜', - 'ensp' => ' ', - 'emsp' => ' ', - 'thinsp' => ' ', - 'zwnj' => '‌', - 'zwj' => '‍', - 'lrm' => '‎', - 'rlm' => '‏', - 'ndash' => '–', - 'mdash' => '—', - 'lsquo' => '‘', - 'rsquo' => '’', - 'sbquo' => '‚', - 'ldquo' => '“', - 'rdquo' => '”', - 'bdquo' => '„', - 'dagger' => '†', - 'Dagger' => '‡', - 'permil' => '‰', - 'lsaquo' => '‹', - 'rsaquo' => '›', - 'euro' => '€', - 'fnof' => 'ƒ', - 'Alpha' => 'Α', - 'Beta' => 'Β', - 'Gamma' => 'Γ', - 'Delta' => 'Δ', - 'Epsilon' => 'Ε', - 'Zeta' => 'Ζ', - 'Eta' => 'Η', - 'Theta' => 'Θ', - 'Iota' => 'Ι', - 'Kappa' => 'Κ', - 'Lambda' => 'Λ', - 'Mu' => 'Μ', - 'Nu' => 'Ν', - 'Xi' => 'Ξ', - 'Omicron' => 'Ο', - 'Pi' => 'Π', - 'Rho' => 'Ρ', - 'Sigma' => 'Σ', - 'Tau' => 'Τ', - 'Upsilon' => 'Υ', - 'Phi' => 'Φ', - 'Chi' => 'Χ', - 'Psi' => 'Ψ', - 'Omega' => 'Ω', - 'alpha' => 'α', - 'beta' => 'β', - 'gamma' => 'γ', - 'delta' => 'δ', - 'epsilon' => 'ε', - 'zeta' => 'ζ', - 'eta' => 'η', - 'theta' => 'θ', - 'iota' => 'ι', - 'kappa' => 'κ', - 'lambda' => 'λ', - 'mu' => 'μ', - 'nu' => 'ν', - 'xi' => 'ξ', - 'omicron' => 'ο', - 'pi' => 'π', - 'rho' => 'ρ', - 'sigmaf' => 'ς', - 'sigma' => 'σ', - 'tau' => 'τ', - 'upsilon' => 'υ', - 'phi' => 'φ', - 'chi' => 'χ', - 'psi' => 'ψ', - 'omega' => 'ω', - 'thetasym' => 'ϑ', - 'upsih' => 'ϒ', - 'piv' => 'ϖ', - 'bull' => '•', - 'hellip' => '…', - 'prime' => '′', - 'Prime' => '″', - 'oline' => '‾', - 'frasl' => '⁄', - 'weierp' => '℘', - 'image' => 'ℑ', - 'real' => 'ℜ', - 'trade' => '™', - 'alefsym' => 'ℵ', - 'larr' => '←', - 'uarr' => '↑', - 'rarr' => '→', - 'darr' => '↓', - 'harr' => '↔', - 'crarr' => '↵', - 'lArr' => '⇐', - 'uArr' => '⇑', - 'rArr' => '⇒', - 'dArr' => '⇓', - 'hArr' => '⇔', - 'forall' => '∀', - 'part' => '∂', - 'exist' => '∃', - 'empty' => '∅', - 'nabla' => '∇', - 'isin' => '∈', - 'notin' => '∉', - 'ni' => '∋', - 'prod' => '∏', - 'sum' => '∑', - 'minus' => '−', - 'lowast' => '∗', - 'radic' => '√', - 'prop' => '∝', - 'infin' => '∞', - 'ang' => '∠', - 'and' => '∧', - 'or' => '∨', - 'cap' => '∩', - 'cup' => '∪', - 'int' => '∫', - 'there4' => '∴', - 'sim' => '∼', - 'cong' => '≅', - 'asymp' => '≈', - 'ne' => '≠', - 'equiv' => '≡', - 'le' => '≤', - 'ge' => '≥', - 'sub' => '⊂', - 'sup' => '⊃', - 'nsub' => '⊄', - 'sube' => '⊆', - 'supe' => '⊇', - 'oplus' => '⊕', - 'otimes' => '⊗', - 'perp' => '⊥', - 'sdot' => '⋅', - 'lceil' => '⌈', - 'rceil' => '⌉', - 'lfloor' => '⌊', - 'rfloor' => '⌋', - 'lang' => '〈', - 'rang' => '〉', - 'loz' => '◊', - 'spades' => '♠', - 'clubs' => '♣', - 'hearts' => '♥', - 'diams' => '♦', - 'nbsp' => ' ', - 'iexcl' => '¡', - 'cent' => '¢', - 'pound' => '£', - 'curren' => '¤', - 'yen' => '¥', - 'brvbar' => '¦', - 'sect' => '§', - 'uml' => '¨', - 'copy' => '©', - 'ordf' => 'ª', - 'laquo' => '«', - 'not' => '¬', - 'shy' => '­', - 'reg' => '®', - 'macr' => '¯', - 'deg' => '°', - 'plusmn' => '±', - 'sup2' => '²', - 'sup3' => '³', - 'acute' => '´', - 'micro' => 'µ', - 'para' => '¶', - 'middot' => '·', - 'cedil' => '¸', - 'sup1' => '¹', - 'ordm' => 'º', - 'raquo' => '»', - 'frac14' => '¼', - 'frac12' => '½', - 'frac34' => '¾', - 'iquest' => '¿', - 'Agrave' => 'À', - 'Aacute' => 'Á', - 'Acirc' => 'Â', - 'Atilde' => 'Ã', - 'Auml' => 'Ä', - 'Aring' => 'Å', - 'AElig' => 'Æ', - 'Ccedil' => 'Ç', - 'Egrave' => 'È', - 'Eacute' => 'É', - 'Ecirc' => 'Ê', - 'Euml' => 'Ë', - 'Igrave' => 'Ì', - 'Iacute' => 'Í', - 'Icirc' => 'Î', - 'Iuml' => 'Ï', - 'ETH' => 'Ð', - 'Ntilde' => 'Ñ', - 'Ograve' => 'Ò', - 'Oacute' => 'Ó', - 'Ocirc' => 'Ô', - 'Otilde' => 'Õ', - 'Ouml' => 'Ö', - 'times' => '×', - 'Oslash' => 'Ø', - 'Ugrave' => 'Ù', - 'Uacute' => 'Ú', - 'Ucirc' => 'Û', - 'Uuml' => 'Ü', - 'Yacute' => 'Ý', - 'THORN' => 'Þ', - 'szlig' => 'ß', - 'agrave' => 'à', - 'aacute' => 'á', - 'acirc' => 'â', - 'atilde' => 'ã', - 'auml' => 'ä', - 'aring' => 'å', - 'aelig' => 'æ', - 'ccedil' => 'ç', - 'egrave' => 'è', - 'eacute' => 'é', - 'ecirc' => 'ê', - 'euml' => 'ë', - 'igrave' => 'ì', - 'iacute' => 'í', - 'icirc' => 'î', - 'iuml' => 'ï', - 'eth' => 'ð', - 'ntilde' => 'ñ', - 'ograve' => 'ò', - 'oacute' => 'ó', - 'ocirc' => 'ô', - 'otilde' => 'õ', - 'ouml' => 'ö', - 'divide' => '÷', - 'oslash' => 'ø', - 'ugrave' => 'ù', - 'uacute' => 'ú', - 'ucirc' => 'û', - 'uuml' => 'ü', - 'yacute' => 'ý', - 'thorn' => 'þ', - 'yuml' => 'ÿ' - ); - - // Entity not found? Destroy it. - return isset($_ent_table[$str_xml_data[1]]) ? $_ent_table[$str_xml_data[1]] : ''; - } - - /** - * Static Method to load admin template - * - * @param object $obj_db - * @return void - */ - public static function loadUserTemplate($obj_db,$uid) - { - global $sysconf; - // load user template settings for override setting - $_q = $obj_db->query("SELECT admin_template FROM user WHERE user_id=$uid AND (admin_template!=NULL OR admin_template !='')"); - if($_q->num_rows>0){ - $template_settings = unserialize($_q->fetch_row()[0]); - foreach ($template_settings as $setting_name => $setting_value) { - $sysconf['admin_template'][$setting_name] = $setting_value; - } - } - } - - public static function dlCount($obj_db, $str_file_id, $str_member_id, $str_user_id) - { - if (!$obj_db->error) { - // log table - $_log_date = date('Y-m-d H:i:s'); - $_log_table = 'files_read'; - // filter input - $str_log_type = $obj_db->escape_string(trim($str_file_id)); - $str_value_id = $obj_db->escape_string(trim($str_member_id)); - $str_user_id = $obj_db->escape_string(trim($str_user_id)); - // insert log data to database - @$obj_db->query('INSERT INTO '.$_log_table.' - VALUES (NULL, \''.$str_file_id.'\', \''.$_log_date.'\', \''.$str_value_id.'\', \''.$str_user_id.'\', \''.$_SERVER[ - 'REMOTE_ADDR'].'\')'); - } - } -} +'."\n"; + echo 'alert("'.$str_message.'")'."\n"; + echo ''."\n"; + } + + /** + * Static Method to send out toastr notification + * + * @param string $type [info, success, warning, error] + * @param string $str_message + * @return void + */ + public static function jsToastr($title, $str_message, $type = 'info') + { + if (!$str_message) { + return; + } + + $options = [ + 'closeButton' => true, + 'debug' => false, + 'newestOnTop' => false, + 'progressBar' => false, + 'positionClass' => 'toast-top-right', + 'preventDuplicates' => false, + 'onclick' => null, + 'showDuration' => 300, + 'hideDuration' => 1000, + 'timeOut' => 5000, + 'extendedTimeOut' => 1000, + 'showEasing' => 'swing', + 'hideEasing' => 'linear', + 'showMethod' => 'fadeIn', + 'hideMethod' => 'fadeOut' + ]; + + // replace newline with javascripts newline + $str_message = str_replace("\n", '\n', addslashes($str_message)); + echo ''."\n"; + } + + + /** + * Static Method to create random string + * + * @param int $int_num_string: number of randowm string to created + * @return void + */ + public static function createRandomString($int_num_string = 32) + { + $_random = ''; + $_salt = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $_saltlength = strlen($_salt); + for ($r = 0; $r < $int_num_string; $r++) { + $_random .= $_salt[rand(0, $_saltlength - 1)]; + } + + return $_random; + } + + + /** + * Static Method to load application settings from database + * + * @param object $obj_db + * @return void + */ + public static function loadSettings($obj_db) + { + global $sysconf; + $_setting_query = $obj_db->query('SELECT * FROM setting'); + if (!$obj_db->errno) { + while ($_setting_data = $_setting_query->fetch_assoc()) { + $_value = @unserialize($_setting_data['setting_value']); + if (is_array($_value)) { + // make sure setting is available before + if (!isset($sysconf[$_setting_data['setting_name']])) + $sysconf[$_setting_data['setting_name']] = []; + + foreach ($_value as $_idx => $_curr_value) { + // convert default setting value into array + if (!is_array($sysconf[$_setting_data['setting_name']])) + $sysconf[$_setting_data['setting_name']] = [$sysconf[$_setting_data['setting_name']]]; + $sysconf[$_setting_data['setting_name']][$_idx] = $_curr_value; + } + } else { + $sysconf[$_setting_data['setting_name']] = stripcslashes($_value); + } + } + } + } + + + /** + * Static Method to check privileges of application module form current user + * + * @param string $str_module_name + * @param string $str_privilege_type + * @return boolean + */ + public static function havePrivilege($str_module_name, $str_privilege_type = 'r') + { + global $sysconf; + // checking checksum + if ($sysconf['load_balanced_env']) { + $server_addr = $_SERVER['REMOTE_ADDR']; + } else { + $server_addr = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : (isset($_SERVER['LOCAL_ADDR']) ? $_SERVER['LOCAL_ADDR'] : gethostbyname($_SERVER['SERVER_NAME'])); + } + + + $_checksum = defined('UCS_BASE_DIR')?md5($server_addr.UCS_BASE_DIR.'admin'):md5($server_addr.SB.'admin'); + if ($_SESSION['checksum'] != $_checksum) { + return false; + } + // check privilege type + if (!in_array($str_privilege_type, array('r', 'w'))) { + return false; + } + if (isset($_SESSION['priv'][$str_module_name][$str_privilege_type]) AND $_SESSION['priv'][$str_module_name][$str_privilege_type]) { + return true; + } + return false; + } + + + /** + * Static Method to write application activities logs + * + * @param object $obj_db + * @param string $str_log_type + * @param string $str_value_id + * @param string $str_location + * @param string $str_log_msg + * @return void + */ + public static function writeLogs($obj_db, $str_log_type, $str_value_id, $str_location, $str_log_msg, $str_log_submod=NULL, $str_log_action=NULL) + { + if (!$obj_db->error) { + // log table + $_log_date = date('Y-m-d H:i:s'); + $_log_table = 'system_log'; + // filter input + $str_log_type = $obj_db->escape_string(trim($str_log_type)); + $str_value_id = $obj_db->escape_string(trim($str_value_id)); + $str_location = $obj_db->escape_string(trim($str_location)); + $str_log_msg = $obj_db->escape_string(trim($str_log_msg)); + $str_log_submod = $obj_db->escape_string(trim($str_log_submod)); + $str_log_action = $obj_db->escape_string(trim($str_log_action)); + // insert log data to database + @$obj_db->query('INSERT INTO '.$_log_table.' + VALUES (NULL, \''.$str_log_type.'\', \''.$str_value_id.'\', \''.$str_location.'\','. + ' \''.$str_log_submod.'\''. + ', \''.$str_log_action.'\''. + ', \''.$str_log_msg.'\', \''.$_log_date.'\')'); + } + } + + + /** + * Static Method to get an ID of database table record + * + * @param object $obj_db + * @param string $str_table_name + * @param string $str_id_field + * @param string $str_value_field + * @param string $str_value + * @param array $arr_cache + * @return mixed + */ + public static function getID($obj_db, $str_table_name, $str_id_field, $str_value_field, $str_value, &$arr_cache = false) + { + $str_value = trim($str_value); + if ($arr_cache) { + if (isset($arr_cache[$str_value])) { + return $arr_cache[$str_value]; + } + } + if (!$obj_db->error) { + $id_q = $obj_db->query('SELECT '.$str_id_field.' FROM '.$str_table_name.' WHERE '.$str_value_field.'=\''.$obj_db->escape_string($str_value).'\''); + if ($id_q->num_rows > 0) { + $id_d = $id_q->fetch_row(); + unset($id_q); + // cache + if ($arr_cache) { + $arr_cache[$str_value] = $id_d[0]; + } + return $id_d[0]; + } else { + $_curr_date = date('Y-m-d'); + // if not found then we insert it as new value + $obj_db->query('INSERT IGNORE INTO '.$str_table_name.' ('.$str_value_field.', input_date, last_update) + VALUES (\''.$obj_db->escape_string($str_value).'\', \''.$_curr_date.'\', \''.$_curr_date.'\')'); + if (!$obj_db->error) { + // cache + if ($arr_cache) { + $arr_cache[$str_value] = $obj_db->insert_id; + } + return $obj_db->insert_id; + } + } + } + } + + + /** + * Static method to detect mobile browser + * + * @return boolean + * this script is taken from http://detectmobilebrowsers.com/ + **/ + public static function isMobileBrowser() + { + $_is_mobile_browser = false; + + if(preg_match('/android.+mobile|avantgo|bada\/|blackberry| + blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)| + iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i| + palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian| + treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)| + xda|xiino/i', + @$_SERVER['HTTP_USER_AGENT']) + || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s| + a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)| + amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw| + au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)| + br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc| + cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob| + do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8| + ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo| + go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)| + hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)| + i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno| + ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt | + kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])| + libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr| + me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do| + t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]| + n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)| + nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg| + pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox| + psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600| + raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)| + sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)| + sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)| + so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)| + ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)| + ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri| + vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc| + vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit| + wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i', + substr(@$_SERVER['HTTP_USER_AGENT'],0,4))) + $_is_mobile_browser = true; + + return $_is_mobile_browser; + } + + + /** + * Static method to check if member already logged in or not + * + * @return boolean + **/ + public static function isMemberLogin() + { + $_logged_in = false; + $_logged_in = isset($_SESSION['mid']) && isset($_SESSION['m_name']); + return $_logged_in; + } + + + /** + * Static method to filter data + * + * @param mixed $mix_input: input data + * @param string $str_input_type: input type + * @param boolean $bool_trim: are input string trimmed + * + * @return mixed + **/ + public static function filterData($mix_input, $str_input_type = 'get', $bool_escape_sql = true, $bool_trim = true, $bool_strip_html = false) { + global $dbs; + + if (extension_loaded('filter')) { + if ($str_input_type == 'var') { + $mix_input = filter_var($mix_input, FILTER_SANITIZE_STRING); + } else if ($str_input_type == 'post') { + $mix_input = filter_input(INPUT_POST, $mix_input); + } else if ($str_input_type == 'cookie') { + $mix_input = filter_input(INPUT_COOKIE, $mix_input); + } else if ($str_input_type == 'session') { + $mix_input = filter_input(INPUT_SESSION, $mix_input); + } else { + $mix_input = filter_input(INPUT_GET, $mix_input); + } + } else { + if ($str_input_type == 'get') { + $mix_input = $_GET[$mix_input]; + } else if ($str_input_type == 'post') { + $mix_input = $_POST[$mix_input]; + } else if ($str_input_type == 'cookie') { + $mix_input = $_COOKIE[$mix_input]; + } else if ($str_input_type == 'session') { + $mix_input = $_SESSION[$mix_input]; + } + } + + // trim whitespace on string + if ($bool_trim) { $mix_input = trim($mix_input); } + // strip html + if ($bool_strip_html) { $mix_input = strip_tags($mix_input); } + // escape SQL string + if ($bool_escape_sql) { $mix_input = $dbs->escape_string($mix_input); } + + return $mix_input; + } + + + /** + * Static method to convert XML entities + * Code taken and modified from: + * Matt Robinson at http://inanimatt.com/php-convert-entities.html + * + * @param string $str_xml_data: string of xml data to check + * + * @return string + **/ + public static function convertXMLentities($str_xml_data) { + static $_ent_table = array('quot' => '"', + 'amp' => '&', + 'lt' => '<', + 'gt' => '>', + 'OElig' => 'Œ', + 'oelig' => 'œ', + 'Scaron' => 'Š', + 'scaron' => 'š', + 'Yuml' => 'Ÿ', + 'circ' => 'ˆ', + 'tilde' => '˜', + 'ensp' => ' ', + 'emsp' => ' ', + 'thinsp' => ' ', + 'zwnj' => '‌', + 'zwj' => '‍', + 'lrm' => '‎', + 'rlm' => '‏', + 'ndash' => '–', + 'mdash' => '—', + 'lsquo' => '‘', + 'rsquo' => '’', + 'sbquo' => '‚', + 'ldquo' => '“', + 'rdquo' => '”', + 'bdquo' => '„', + 'dagger' => '†', + 'Dagger' => '‡', + 'permil' => '‰', + 'lsaquo' => '‹', + 'rsaquo' => '›', + 'euro' => '€', + 'fnof' => 'ƒ', + 'Alpha' => 'Α', + 'Beta' => 'Β', + 'Gamma' => 'Γ', + 'Delta' => 'Δ', + 'Epsilon' => 'Ε', + 'Zeta' => 'Ζ', + 'Eta' => 'Η', + 'Theta' => 'Θ', + 'Iota' => 'Ι', + 'Kappa' => 'Κ', + 'Lambda' => 'Λ', + 'Mu' => 'Μ', + 'Nu' => 'Ν', + 'Xi' => 'Ξ', + 'Omicron' => 'Ο', + 'Pi' => 'Π', + 'Rho' => 'Ρ', + 'Sigma' => 'Σ', + 'Tau' => 'Τ', + 'Upsilon' => 'Υ', + 'Phi' => 'Φ', + 'Chi' => 'Χ', + 'Psi' => 'Ψ', + 'Omega' => 'Ω', + 'alpha' => 'α', + 'beta' => 'β', + 'gamma' => 'γ', + 'delta' => 'δ', + 'epsilon' => 'ε', + 'zeta' => 'ζ', + 'eta' => 'η', + 'theta' => 'θ', + 'iota' => 'ι', + 'kappa' => 'κ', + 'lambda' => 'λ', + 'mu' => 'μ', + 'nu' => 'ν', + 'xi' => 'ξ', + 'omicron' => 'ο', + 'pi' => 'π', + 'rho' => 'ρ', + 'sigmaf' => 'ς', + 'sigma' => 'σ', + 'tau' => 'τ', + 'upsilon' => 'υ', + 'phi' => 'φ', + 'chi' => 'χ', + 'psi' => 'ψ', + 'omega' => 'ω', + 'thetasym' => 'ϑ', + 'upsih' => 'ϒ', + 'piv' => 'ϖ', + 'bull' => '•', + 'hellip' => '…', + 'prime' => '′', + 'Prime' => '″', + 'oline' => '‾', + 'frasl' => '⁄', + 'weierp' => '℘', + 'image' => 'ℑ', + 'real' => 'ℜ', + 'trade' => '™', + 'alefsym' => 'ℵ', + 'larr' => '←', + 'uarr' => '↑', + 'rarr' => '→', + 'darr' => '↓', + 'harr' => '↔', + 'crarr' => '↵', + 'lArr' => '⇐', + 'uArr' => '⇑', + 'rArr' => '⇒', + 'dArr' => '⇓', + 'hArr' => '⇔', + 'forall' => '∀', + 'part' => '∂', + 'exist' => '∃', + 'empty' => '∅', + 'nabla' => '∇', + 'isin' => '∈', + 'notin' => '∉', + 'ni' => '∋', + 'prod' => '∏', + 'sum' => '∑', + 'minus' => '−', + 'lowast' => '∗', + 'radic' => '√', + 'prop' => '∝', + 'infin' => '∞', + 'ang' => '∠', + 'and' => '∧', + 'or' => '∨', + 'cap' => '∩', + 'cup' => '∪', + 'int' => '∫', + 'there4' => '∴', + 'sim' => '∼', + 'cong' => '≅', + 'asymp' => '≈', + 'ne' => '≠', + 'equiv' => '≡', + 'le' => '≤', + 'ge' => '≥', + 'sub' => '⊂', + 'sup' => '⊃', + 'nsub' => '⊄', + 'sube' => '⊆', + 'supe' => '⊇', + 'oplus' => '⊕', + 'otimes' => '⊗', + 'perp' => '⊥', + 'sdot' => '⋅', + 'lceil' => '⌈', + 'rceil' => '⌉', + 'lfloor' => '⌊', + 'rfloor' => '⌋', + 'lang' => '〈', + 'rang' => '〉', + 'loz' => '◊', + 'spades' => '♠', + 'clubs' => '♣', + 'hearts' => '♥', + 'diams' => '♦', + 'nbsp' => ' ', + 'iexcl' => '¡', + 'cent' => '¢', + 'pound' => '£', + 'curren' => '¤', + 'yen' => '¥', + 'brvbar' => '¦', + 'sect' => '§', + 'uml' => '¨', + 'copy' => '©', + 'ordf' => 'ª', + 'laquo' => '«', + 'not' => '¬', + 'shy' => '­', + 'reg' => '®', + 'macr' => '¯', + 'deg' => '°', + 'plusmn' => '±', + 'sup2' => '²', + 'sup3' => '³', + 'acute' => '´', + 'micro' => 'µ', + 'para' => '¶', + 'middot' => '·', + 'cedil' => '¸', + 'sup1' => '¹', + 'ordm' => 'º', + 'raquo' => '»', + 'frac14' => '¼', + 'frac12' => '½', + 'frac34' => '¾', + 'iquest' => '¿', + 'Agrave' => 'À', + 'Aacute' => 'Á', + 'Acirc' => 'Â', + 'Atilde' => 'Ã', + 'Auml' => 'Ä', + 'Aring' => 'Å', + 'AElig' => 'Æ', + 'Ccedil' => 'Ç', + 'Egrave' => 'È', + 'Eacute' => 'É', + 'Ecirc' => 'Ê', + 'Euml' => 'Ë', + 'Igrave' => 'Ì', + 'Iacute' => 'Í', + 'Icirc' => 'Î', + 'Iuml' => 'Ï', + 'ETH' => 'Ð', + 'Ntilde' => 'Ñ', + 'Ograve' => 'Ò', + 'Oacute' => 'Ó', + 'Ocirc' => 'Ô', + 'Otilde' => 'Õ', + 'Ouml' => 'Ö', + 'times' => '×', + 'Oslash' => 'Ø', + 'Ugrave' => 'Ù', + 'Uacute' => 'Ú', + 'Ucirc' => 'Û', + 'Uuml' => 'Ü', + 'Yacute' => 'Ý', + 'THORN' => 'Þ', + 'szlig' => 'ß', + 'agrave' => 'à', + 'aacute' => 'á', + 'acirc' => 'â', + 'atilde' => 'ã', + 'auml' => 'ä', + 'aring' => 'å', + 'aelig' => 'æ', + 'ccedil' => 'ç', + 'egrave' => 'è', + 'eacute' => 'é', + 'ecirc' => 'ê', + 'euml' => 'ë', + 'igrave' => 'ì', + 'iacute' => 'í', + 'icirc' => 'î', + 'iuml' => 'ï', + 'eth' => 'ð', + 'ntilde' => 'ñ', + 'ograve' => 'ò', + 'oacute' => 'ó', + 'ocirc' => 'ô', + 'otilde' => 'õ', + 'ouml' => 'ö', + 'divide' => '÷', + 'oslash' => 'ø', + 'ugrave' => 'ù', + 'uacute' => 'ú', + 'ucirc' => 'û', + 'uuml' => 'ü', + 'yacute' => 'ý', + 'thorn' => 'þ', + 'yuml' => 'ÿ' + ); + + // Entity not found? Destroy it. + return isset($_ent_table[$str_xml_data[1]]) ? $_ent_table[$str_xml_data[1]] : ''; + } + + /** + * Static Method to load admin template + * + * @param object $obj_db + * @return void + */ + public static function loadUserTemplate($obj_db,$uid) + { + global $sysconf; + // load user template settings for override setting + $_q = $obj_db->query("SELECT admin_template FROM user WHERE user_id=$uid AND (admin_template!=NULL OR admin_template !='')"); + if($_q->num_rows>0){ + $template_settings = unserialize($_q->fetch_row()[0]); + foreach ($template_settings as $setting_name => $setting_value) { + $sysconf['admin_template'][$setting_name] = $setting_value; + } + } + } + + public static function dlCount($obj_db, $str_file_id, $str_member_id, $str_user_id) + { + if (!$obj_db->error) { + // log table + $_log_date = date('Y-m-d H:i:s'); + $_log_table = 'files_read'; + // filter input + $str_log_type = $obj_db->escape_string(trim($str_file_id)); + $str_value_id = $obj_db->escape_string(trim($str_member_id)); + $str_user_id = $obj_db->escape_string(trim($str_user_id)); + // insert log data to database + @$obj_db->query('INSERT INTO '.$_log_table.' + VALUES (NULL, \''.$str_file_id.'\', \''.$_log_date.'\', \''.$str_value_id.'\', \''.$str_user_id.'\', \''.$_SERVER[ + 'REMOTE_ADDR'].'\')'); + } + } +} From b0d71323615a25ed1055c101171c3dda94b0b28d Mon Sep 17 00:00:00 2001 From: idoalit Date: Sat, 31 Jul 2021 20:10:47 +0700 Subject: [PATCH 15/73] Make parameter as optional Because Optional parameter is provide before required, for compatibility with php-8 --- lib/content.inc.php | 272 ++++++++++++++++++++++---------------------- 1 file changed, 136 insertions(+), 136 deletions(-) diff --git a/lib/content.inc.php b/lib/content.inc.php index 45ddeef5..e85c666c 100755 --- a/lib/content.inc.php +++ b/lib/content.inc.php @@ -1,136 +1,136 @@ - 1) { - $offset = ($page*$max_each_page)-$max_each_page; - } - - // language - $_lang = strtolower($sysconf['default_lang']); - - // query content - $_sql_content = "SELECT SQL_CALC_FOUND_ROWS * FROM content WHERE is_news=1"; - if ($search_query) { - $search_query = $obj_db->escape_string(trim($search_query)); - $_sql_content .= " AND MATCH(`content_title`, `content_desc`) AGAINST('$search_query' IN BOOLEAN MODE)"; - } - $_sql_content .= " ORDER BY `last_update` DESC"; - $_sql_content .= " LIMIT $max_each_page OFFSET $offset"; - - $_content_q = $obj_db->query($_sql_content); - // echo $_sql_content; - - // get total rows - $_total_rows = $obj_db->query('SELECT FOUND_ROWS()'); - $_total_rows_d = $_total_rows->fetch_row(); - $total = $_total_rows_d[0]; - - // get content data - while ($_content_d = $_content_q->fetch_assoc()) { - $contents[] = $_content_d; - } - - return $contents; - } - - public function get($obj_db, $str_path = '') - { - global $sysconf; - $_path = strtolower(trim($str_path)); - if (!$_path) { - return; - } - - if (preg_match('@^admin.+@i', $_path)) { - $_unauthorized = !isset($_SESSION['uid']) AND !isset($_SESSION['uname']) AND !isset($_SESSION['realname']); - if ($_unauthorized) { - return; - } - } - - // language - $_lang = strtolower($sysconf['default_lang']); - $_path_lang = $_path.'_'.$_lang; - - // check for language - $_sql_check = sprintf('SELECT COUNT(*) FROM content WHERE content_path=\'%s\'', $obj_db->escape_string($_path_lang)); - $_check_q = $obj_db->query($_sql_check); - $_check_d = $_check_q->fetch_row(); - if ($_check_d[0] > 0) { - $_path = $_path_lang; - } - - // query content - $_sql_content = sprintf('SELECT * FROM content WHERE content_path=\'%s\'', $obj_db->escape_string($_path)); - $_content_q = $obj_db->query($_sql_content); - // get content data - $_content_d = $_content_q->fetch_assoc(); - if (!isset($_content_d['content_title']) OR !isset($_content_d['content_path'])) { - return false; - } else { - $_content['Title'] = $_content_d['content_title']; - $_content['Path'] = $_content_d['content_path']; - $_content['Content'] = $_content_d['content_desc']; - // strip html - if ($this->strip_html) { - $_content['Content'] = strip_tags($_content['Content'], $this->allowed_tags); - } - - return $_content; - } - } -} + 1) { + $offset = ($page*$max_each_page)-$max_each_page; + } + + // language + $_lang = strtolower($sysconf['default_lang']); + + // query content + $_sql_content = "SELECT SQL_CALC_FOUND_ROWS * FROM content WHERE is_news=1"; + if ($search_query) { + $search_query = $obj_db->escape_string(trim($search_query)); + $_sql_content .= " AND MATCH(`content_title`, `content_desc`) AGAINST('$search_query' IN BOOLEAN MODE)"; + } + $_sql_content .= " ORDER BY `last_update` DESC"; + $_sql_content .= " LIMIT $max_each_page OFFSET $offset"; + + $_content_q = $obj_db->query($_sql_content); + // echo $_sql_content; + + // get total rows + $_total_rows = $obj_db->query('SELECT FOUND_ROWS()'); + $_total_rows_d = $_total_rows->fetch_row(); + $total = $_total_rows_d[0]; + + // get content data + while ($_content_d = $_content_q->fetch_assoc()) { + $contents[] = $_content_d; + } + + return $contents; + } + + public function get($obj_db, $str_path = '') + { + global $sysconf; + $_path = strtolower(trim($str_path)); + if (!$_path) { + return; + } + + if (preg_match('@^admin.+@i', $_path)) { + $_unauthorized = !isset($_SESSION['uid']) AND !isset($_SESSION['uname']) AND !isset($_SESSION['realname']); + if ($_unauthorized) { + return; + } + } + + // language + $_lang = strtolower($sysconf['default_lang']); + $_path_lang = $_path.'_'.$_lang; + + // check for language + $_sql_check = sprintf('SELECT COUNT(*) FROM content WHERE content_path=\'%s\'', $obj_db->escape_string($_path_lang)); + $_check_q = $obj_db->query($_sql_check); + $_check_d = $_check_q->fetch_row(); + if ($_check_d[0] > 0) { + $_path = $_path_lang; + } + + // query content + $_sql_content = sprintf('SELECT * FROM content WHERE content_path=\'%s\'', $obj_db->escape_string($_path)); + $_content_q = $obj_db->query($_sql_content); + // get content data + $_content_d = $_content_q->fetch_assoc(); + if (!isset($_content_d['content_title']) OR !isset($_content_d['content_path'])) { + return false; + } else { + $_content['Title'] = $_content_d['content_title']; + $_content['Path'] = $_content_d['content_path']; + $_content['Content'] = $_content_d['content_desc']; + // strip html + if ($this->strip_html) { + $_content['Content'] = strip_tags($_content['Content'], $this->allowed_tags); + } + + return $_content; + } + } +} From 30b555ff784b57d8ae1ed66d3e2cfac14065d38d Mon Sep 17 00:00:00 2001 From: idoalit Date: Sun, 1 Aug 2021 18:53:32 +0700 Subject: [PATCH 16/73] Fix: constanta already defined --- lib/Config.php | 4 ++-- lib/contents/member.inc.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Config.php b/lib/Config.php index ced9dc11..be35154a 100644 --- a/lib/Config.php +++ b/lib/Config.php @@ -34,7 +34,7 @@ class Config public function __construct() { // load default config folder - $this->load(__DIR__ . '/../config'); + $this->load(__DIR__ . '/../config', ['sysconfig.local.inc.php', 'sysconfig.local.inc-sample.php']); } /** @@ -77,7 +77,7 @@ function loadFromDatabase() { $query = DB::getInstance()->query('SELECT setting_name, setting_value FROM setting'); while ($data = $query->fetch(PDO::FETCH_OBJ)) { - $value = unserialize($data->setting_value); + $value = @unserialize($data->setting_value); if (is_array($value)) { foreach ($value as $id => $current_value) { $this->configs[$data->setting_name][$id] = $current_value; diff --git a/lib/contents/member.inc.php b/lib/contents/member.inc.php index 9ef7d1d7..8d722192 100644 --- a/lib/contents/member.inc.php +++ b/lib/contents/member.inc.php @@ -902,7 +902,7 @@ class="fas fa-sign-out-alt mr-2"> ?>
-
+
From f8e79226e47130021c3744209e5c31e68c4ec9e2 Mon Sep 17 00:00:00 2001 From: idoalit Date: Sun, 1 Aug 2021 18:58:21 +0700 Subject: [PATCH 17/73] Fix: notice empty array --- lib/module.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/module.inc.php b/lib/module.inc.php index a73cede8..d19e05ac 100755 --- a/lib/module.inc.php +++ b/lib/module.inc.php @@ -168,7 +168,7 @@ public function getSubMenuItems($str_module = '') $tmp_menu = []; if (isset($menu) && count($menu) > 0) { foreach ($menu as $item) { - if ($item[0] === 'Header' || in_array(md5($item[1]), $_SESSION['priv'][$str_module]['menus'])) $tmp_menu[] = $item; + if ($item[0] === 'Header' || in_array(md5($item[1]), $_SESSION['priv'][$str_module]['menus'] ?? [])) $tmp_menu[] = $item; } } $menu = $tmp_menu; From f2880deaacb42ac249e6a46b095c25de30ab7438 Mon Sep 17 00:00:00 2001 From: idoalit Date: Sun, 1 Aug 2021 19:01:38 +0700 Subject: [PATCH 18/73] Fix: deprecated order params --- simbio2/simbio_GUI/table/simbio_table.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simbio2/simbio_GUI/table/simbio_table.inc.php b/simbio2/simbio_GUI/table/simbio_table.inc.php index 4098e57f..bf530c5a 100755 --- a/simbio2/simbio_GUI/table/simbio_table.inc.php +++ b/simbio2/simbio_GUI/table/simbio_table.inc.php @@ -199,7 +199,7 @@ public function getColumnContent($int_row, $int_column, $str_column_content) * @param string $str_column_attr * @return void */ - public function setCellAttr($int_row = 0, $int_column = null, $str_column_attr) + public function setCellAttr($int_row = 0, $int_column = null, $str_column_attr = null) { if (is_null($int_column)) { $this->row_attr[$int_row] = $str_column_attr; From b2281a0b7f638e2247d12877a2105a7f9111c1be Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Fri, 13 Aug 2021 20:18:04 +0700 Subject: [PATCH 19/73] Update import.php Fix query when import biblio data with header. --- admin/modules/bibliography/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/modules/bibliography/import.php b/admin/modules/bibliography/import.php index e6767b9b..3faeb605 100755 --- a/admin/modules/bibliography/import.php +++ b/admin/modules/bibliography/import.php @@ -164,7 +164,7 @@ // first field is header if (isset($_POST['header']) && $n < 1) { - $n++; + $n++; continue; } else { // send query $dbs->query($sql_str); From 97b1c52b7e91b0fa2e3cebfd846719c579a09800 Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 13 Aug 2021 20:49:24 +0700 Subject: [PATCH 20/73] Fix: unrelated item after import csv --- admin/modules/bibliography/item_import.php | 33 ++++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/admin/modules/bibliography/item_import.php b/admin/modules/bibliography/item_import.php index 42a12552..8956fc03 100755 --- a/admin/modules/bibliography/item_import.php +++ b/admin/modules/bibliography/item_import.php @@ -140,23 +140,32 @@ $invoice_date = $field[15]?'\''.$field[15].'\'':'NULL'; $input_date = '\''.$field[16].'\''; $last_update = '\''.$field[17].'\''; - - // sql insert string - $sql_str = "INSERT INTO item (item_code, call_number, coll_type_id, - inventory_code, received_date, supplier_id, - order_no, location_id, order_date, item_status_id, site, - source, invoice, price, price_currency, invoice_date, - input_date, last_update) - VALUES ($item_code, $call_number, $coll_type, - $inventory_code, $received_date, $supplier, - $order_no, $location, $order_date, $item_status, $site, - $source, $invoice, $price, $price_currency, $invoice_date, - $input_date, $last_update)"; + $title = $field[18]; // first field is header if (isset($_POST['header']) && $n < 1) { $n++; + continue; } else { + + // get biblio_id + $b_q = $dbs->query(sprintf("select biblio_id from biblio where title = '%s'", $title)); + if($b_q->num_rows < 1) continue; + $b_d = $b_q->fetch_row(); + $biblio_id = $b_d[0]; + + // sql insert string + $sql_str = "INSERT INTO item (biblio_id, item_code, call_number, coll_type_id, + inventory_code, received_date, supplier_id, + order_no, location_id, order_date, item_status_id, site, + source, invoice, price, price_currency, invoice_date, + input_date, last_update) + VALUES ($biblio_id, $item_code, $call_number, $coll_type, + $inventory_code, $received_date, $supplier, + $order_no, $location, $order_date, $item_status, $site, + $source, $invoice, $price, $price_currency, $invoice_date, + $input_date, $last_update)"; + // send query // die($sql_str); $dbs->query($sql_str); From 57f2b8465aa68f4c6487eb0f9476b05cca9acab5 Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Fri, 13 Aug 2021 21:31:40 +0700 Subject: [PATCH 21/73] Update item_import.php Improve import item field content. --- admin/modules/bibliography/item_import.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/admin/modules/bibliography/item_import.php b/admin/modules/bibliography/item_import.php index 8956fc03..f0531f3a 100755 --- a/admin/modules/bibliography/item_import.php +++ b/admin/modules/bibliography/item_import.php @@ -133,13 +133,13 @@ $item_status = utility::getID($dbs, 'mst_item_status', 'item_status_id', 'item_status_name', $field[9], $stat_id_cache); $item_status = $item_status?'\''.$item_status.'\'':'NULL'; $site = $field[10]?'\''.$field[10].'\'':'NULL'; - $source = $field[11]?'\''.$field[11].'\'':'NULL'; + $source = $field[11]?'\''.$field[11].'\'':'0'; $invoice = $field[12]?'\''.$field[12].'\'':'NULL'; $price = $field[13]?'\''.$field[13].'\'':'NULL'; $price_currency = $field[14]?'\''.$field[14].'\'':'NULL'; $invoice_date = $field[15]?'\''.$field[15].'\'':'NULL'; - $input_date = '\''.$field[16].'\''; - $last_update = '\''.$field[17].'\''; + $input_date = $field[16]?'\''.$field[16].'\'':'\''.date('Y-m-d H:i:s').'\''; + $last_update = $field[17]?'\''.$field[17].'\'':'\''.date('Y-m-d H:i:s').'\''; $title = $field[18]; // first field is header From 3198acd39c367e706737a990a88b416a79f54b13 Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 13 Aug 2021 21:41:18 +0700 Subject: [PATCH 22/73] Fix: search marc export --- admin/modules/bibliography/marcexport.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/modules/bibliography/marcexport.php b/admin/modules/bibliography/marcexport.php index 8fbf72cb..7729472e 100644 --- a/admin/modules/bibliography/marcexport.php +++ b/admin/modules/bibliography/marcexport.php @@ -216,14 +216,14 @@ require LIB.'biblio_list_index.inc.php'; } // table spec - $table_spec = 'search_biblio'; + $table_spec = 'search_biblio AS `index`'; $datagrid->setSQLColumn('biblio_id', 'title AS \''.__('Title').'\'', 'author AS \''.__('Author').'\''); } else { require LIB.'biblio_list.inc.php'; // table spec - $table_spec = 'search_biblio'; + $table_spec = 'search_biblio AS `index`'; $datagrid->setSQLColumn('biblio_id', 'title AS \''.__('Title').'\'', 'author AS \''.__('Author').'\''); From 67075336399bde890868378980848e4595bb01dd Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 13 Aug 2021 22:01:28 +0700 Subject: [PATCH 23/73] Prevent hidden biblio to show in home page --- api/v1/controllers/BiblioController.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/v1/controllers/BiblioController.php b/api/v1/controllers/BiblioController.php index d27f11d7..d952253c 100644 --- a/api/v1/controllers/BiblioController.php +++ b/api/v1/controllers/BiblioController.php @@ -41,7 +41,7 @@ public function getPopular() FROM loan AS l LEFT JOIN item AS i ON l.item_code=i.item_code LEFT JOIN biblio AS b ON i.biblio_id=b.biblio_id - WHERE b.title IS NOT NULL + WHERE b.title IS NOT NULL AND b.opac_hide < 1 GROUP BY b.biblio_id ORDER BY total DESC LIMIT {$limit}"; @@ -58,7 +58,7 @@ public function getPopular() $need = $limit; } - $sql = "SELECT biblio_id, title, image FROM biblio ORDER BY last_update DESC LIMIT {$need}"; + $sql = "SELECT biblio_id, title, image FROM biblio WHERE opac_hide < 1 ORDER BY last_update DESC LIMIT {$need}"; $query = $this->db->query($sql); while ($data = $query->fetch_assoc()) { $data['image'] = $this->getImagePath($data['image']); @@ -74,7 +74,7 @@ public function getLatest() { $limit = 6; $sql = "SELECT biblio_id, title, image - FROM biblio + FROM biblio WHERE opac_hide < 1 ORDER BY last_update DESC LIMIT {$limit}"; @@ -90,7 +90,7 @@ public function getLatest() { public function getTotalAll() { - $query = $this->db->query("SELECT COUNT(biblio_id) FROM biblio"); + $query = $this->db->query("SELECT COUNT(biblio_id) FROM biblio WHERE opac_hide < 1"); parent::withJson([ 'data' => ($query->fetch_row())[0] ]); @@ -100,7 +100,7 @@ public function getByGmd($gmd) { $limit = 3; $sql = "SELECT b.biblio_id, b.title, b.image, b.notes FROM biblio AS b, mst_gmd AS g - WHERE b.gmd_id=g.gmd_id AND g.gmd_name='$gmd' + WHERE b.gmd_id=g.gmd_id AND g.gmd_name='$gmd' AND b.opac_hide < 1 ORDER BY b.last_update DESC LIMIT {$limit}"; $query = $this->db->query($sql); @@ -117,7 +117,7 @@ public function getByCollType($coll_type) { $limit = 3; $sql = "SELECT b.biblio_id, b.title, b.image, b.notes FROM biblio AS b, item AS i, mst_coll_type AS c - WHERE b.biblio_id=i.biblio_id AND i.coll_type_id=c.coll_type_id AND c.coll_type_name='$coll_type' + WHERE b.biblio_id=i.biblio_id AND i.coll_type_id=c.coll_type_id AND c.coll_type_name='$coll_type' AND b.opac_hide < 1 ORDER BY b.last_update DESC LIMIT {$limit}"; $query = $this->db->query($sql); From eae9ba41ad26561d0005dd3d27d2058e71cb25ab Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Fri, 13 Aug 2021 22:16:52 +0700 Subject: [PATCH 24/73] Update changes.txt Update changes information for upcoming release. --- changes.txt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/changes.txt b/changes.txt index 97d197f7..bd000bd9 100644 --- a/changes.txt +++ b/changes.txt @@ -44,6 +44,20 @@ Code enhancement: John Antony (john.antony@iamplus.com) THANKS TO OUR USERS AND COMMUNITIES, YOU ARE DEVELOPERS TOO! +SLiMS 9.x.x (Bulian) +======================================================================== +Added : Popup visitor report by day +Added : Fines value in overdue list +Fixed : Image path for Minigalnano +Updated : Server for quote in Visitor Counter page +Fixed : Ignore holiday fines calculation +Fixed : Unable to download backup file result from user not admin +Fixed : Holiday setting +Fixed : Query when import biblio data header +Fixed : Unrelated field after import item data from CSV +Fixed : MARC export search +Fixex : Prevent hidden biblio to show in home page + SLiMS 9.4.2 (Bulian) ======================================================================== Fixed : Stock take report detail From 1a5ab5b035ea18da1a625a86d19155fc4c2403df Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 13 Aug 2021 22:46:22 +0700 Subject: [PATCH 25/73] Show line break at comment --- lib/comment.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/comment.inc.php b/lib/comment.inc.php index 7ac49fbe..dae08614 100755 --- a/lib/comment.inc.php +++ b/lib/comment.inc.php @@ -60,7 +60,7 @@ function showComment($_detail_id) while ($_data = $commlist->fetch_assoc()) { $_list_comment .= '
'; $_list_comment .= '
'.$_data['member_name']. __(' at ') . $_data['input_date']. __(' write'). '
'; - $_list_comment .= '
'. $_data['comment'] . '
'; + $_list_comment .= '
'. $_data['comment'] . '
'; $_list_comment .= '
'; } $_list_comment .= '
'.simbio_paging::paging($_all_recs, $_recs_each_page, $int_pages_each_set = 10, '', '_self').'
'; From 72b1fb12fab64ee29d5fad92964d7a2fb574d997 Mon Sep 17 00:00:00 2001 From: idoalit Date: Fri, 13 Aug 2021 22:46:45 +0700 Subject: [PATCH 26/73] Alter table on next upgrade --- install/Upgrade.inc.php | 4 +++- install/tables.php | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/install/Upgrade.inc.php b/install/Upgrade.inc.php index af04f33d..72ed14d3 100644 --- a/install/Upgrade.inc.php +++ b/install/Upgrade.inc.php @@ -1014,11 +1014,13 @@ function upgrade_role_30() } /** - * Upgrade role to v9.4.3 + * Upgrade role to v9.x.x */ function upgrade_role_31() { $sql['alter'][] = "ALTER TABLE `files` ADD `file_key` text COLLATE 'utf8_unicode_ci' NULL AFTER `file_desc`;"; + $sql['alter'][] = "ALTER TABLE `biblio` DROP `update_date`;"; + $sql['alter'][] = "ALTER TABLE `mst_topic` CHANGE `classification` `classification` varchar(50) COLLATE 'utf8_unicode_ci' NULL COMMENT 'Classification Code' AFTER `auth_list`;"; return $this->slims->query($sql, ['alter']); } diff --git a/install/tables.php b/install/tables.php index d3c71181..0157e2d5 100644 --- a/install/tables.php +++ b/install/tables.php @@ -201,7 +201,7 @@ 'default' => '' ], [ - 'field' => 'update_date', + 'field' => 'last_update', 'type' => 'datetime', 'null' => true, 'default' => '' From e48709be83d44e58609e0f2b89bf63451330cf01 Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Wed, 8 Sep 2021 10:44:32 +0700 Subject: [PATCH 27/73] Update translation Update translation for Bahasa Indonesia. --- lib/lang/locale/id_ID/LC_MESSAGES/messages.mo | Bin 136365 -> 136388 bytes lib/lang/locale/id_ID/LC_MESSAGES/messages.po | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo b/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo index bb23403c777b13b2995410db34a570cf6879adec..f314673a5440c081091fd3e40614359711a5025d 100644 GIT binary patch delta 4160 zcmXZfdwkDT9LMqR?>B6&n+?&JpE0wT&1~3QW9<>TcoXml&iR}(Hmwiazdmep?gY1; z<2aS&9;Z1vCp=C=h{Q;2i)v58D7+I};Ao7%hcN*cVhpac?fX&V9>vD^54OZx7=|rR zdYt+gbJF8F%_wxD;Wq4v{ct#j;CWY9S3O%y$u} z@8Yl?rl7{_UE!LEM$n+h#-bwjTLY*G7g(RcSn6v~EBFi>;4ah-9KbGk4i#Y2QywP{ zV^KSKH)hQB6I(xoT1kbiSEBm=ZR@vCI~x9r z2{azHutd~&>8S7Bp%gk&7=shA5WC}XY=ohw%?cv14fQ_Q4M(C@;cP?iBjdFav$~K5Bqc)LH(3iu4S|<0VvbwyHEcmw@`NH)`N4 zRI=WOns_p%;sR8^5>()OFpl}1A1UZeuAz=1{H*z~9crLt)IgcG{vc|AM{WCJ)WENz z0@#RJz*baF?Lv)HYCVD4$v^cw^E(aCnInkABi1r&PToN)|l z2YR8B@-7^J!%^38x&8e^R1R!M1-K7gH5{g(9VoXy)Sw2cLv6k1S7S5Oy^qGbup8cv zvr);m5_LP)p|ZXVhu|gDcPST4K=UkHq|N3wj4Ow^&HE`G8%tVi2PwGohTfPl- zt;$dVXQL2dO|RR70q`wARL{Tg>P3 zUU&)>V9Sf<3_D_5>Pe_%x(7AjG}Ms=tc9ptcm@aIK~w;tf0)4CL<-uP!Kf9C#`ZV| zm2@wn2HuJFaS!T&Dz)w3qaLE;sB2b%3OMqT$H~B1WG*V#!y6C6Wr z@hNK!>WsaAnkTh6s$&K!kWAFX!>sq)-$$X&cp~~R9~HnV>qn@5-(tA#{}BqiX*h>k zadC}#0lz`L>DN&MwE4^IP&(?tdI0<48oU?3M}6P^Z;!JK2cT|48Kz)0DoJDh@i?O} z0f#cbvxtI{sSI_Nr%@}sZgno3ooRqN+t$`NRKO{y@5iBT$3yn_x#*+57zg6JsI0HV z1gt|>4^G?_6WM6g{hoxM<722JN&MGj??BWJ<<3g``$p>))P&nn*YrEo z4qZkcM%8lv)iJf!d^i$yU-M8qu>^g%7US?s)Ieu38bhy|fIFgoPeqNFgSu|>QGbqK zwDm90NBtNo@T*t3|5{1Lk%2TXKu^= z)`_Sy4`2vxvTi{g@u#Q-xCbdH;-63}xrn;QAvess&<7RqaMVtXK@B_u73hc7ZK!12 zj~cid)3FWVJT|BpHUN5VG`Ebdi*W3 zqBPX|kcIkvgsne`+PUSZ+$cgVv;;fr{vV*Ae^^{ZZA}Zu8_d!;)D~x=u1f$r;47#t z-+^iPE9y41^?02-um@_Q@u=?$ZG9~&>2{*V{XxGozf(s+1Ge*eokSdlO1}B19e4p1 zaWU#TeU3x%2r9{9LcGC0N_|l~G#&e30jhrqY6ri<;59_`zl^RTA5hO5eBrWD*J=*x zZ^A0nzg*tMFx+PAyHPpwBdUKD_Q#v3751y|b^JIAgUO3}a`&RLz7(~f!}YyxaH8`x zXa}z1c#Lb{bvoe^REH0+7nYy~I*(cSJL+le5$X*lX)fNN{wV6q9|`jYZ_#Y@Qg=~1 zv;;L?QJ8DCq?87&xEi&xo2Un+MMGl->Rp(GI^(C1>~%`8Jsw3LUO@%ks*%Z|zNjtF zvGql$aoojCYLl&hiwdm9wnsHF^)%E|I~KLl zd6l0B&myI#H|AiE^qSt~AWH~mWeiZePRH7n|j5I54joR{# zs2#~d^`D3eY$58pJ&#Jdx2*4=lCK!`LO_f_AUpzyC=uBLVHKiMuoP`+w6bU*E|AhgOSOWQ*A07I zpwh!JmD*yZmV%(6?Ex!-P%IurXb%mwETJq>K(J7&7z|6l-*@M)&&<4gXMXdW-(135 zt8><^&Z(=OmTn(K(b4^hs2zTWS77#mMC5oobi5~CiDlRUCtv~IgMDx=`uy@Rz7D(6 z--5Y#5U;`$n1h$FC1xK?q@#QqZ4M@)tFa4?z(JUe-^R8$A3Nd`*alxj1F6G2{A(EB zgU)vt-N+gAx%23A`3;FE3yaYCQVr>Np>hU{Yz!LlgkUAQ;Edp0ETO*;-NA3L6|TZ! zd&e*(>D6B=m2zvGP+qVtuY&!-2_=s{yNPQ#ga18&3CcoyA3Gj_u6hZ9j>9FEq; zgV+KW-~?QVzV{9qa6J~{$6-9{NW8JOSkC&<)ig%(z#W*vpP>`fp=Y@Xjr3jYjqjty zb{WlF`=jx5DKumK&|)2eE_@pf!Wrm$wP@gLuovq`Z_w~ej-nGbp%1n?7Eja(ov1YQ zZ$>A$D~!)ZpZ_5mz%q0L&!aW93Js_(_!gSUfB8G>N1xE}2%51Uc56&TgK-je$3=Jz zt_uC#Xh3JtGtT}X&OkTxtZ%?kI0(Il^TO{-(c*pq4R9@{9oR_23~UcS>_aDNL{tA! z@N@LuXMLE6Zo#XtGfqJRc^JJNOVFBGj}`bn`drcRIG{58D*egFx&J=6ih)~k7dml= z6Y)ZK<3Rc~Xv$Zh*J?dl8#~a7)E`u;s({2?4o|4B3h@1h(20KNaY=~MC9 zwnukbjze$`diF128NQ7McnLkSywi!O3wA_zJQ$sD5_)8n!I@|+%*C7VRWyLJXeQHz zAIGV=9^Jtx?1od(qI(RTcqO*PHRuPbE{wm9eu%cA*K7wGa5E0W0so2Tn}Y_v7=8aa zWCQ7FB@GwYil+GO;6C(>PobaGFVGizoQVS|MHe0z9E$!v5_T_E_-yd z2Vgx~q}l&VM3b>Sj%WSo0U8$5dh{&cK~sG!coNOb8T4!upT_2+0T-dqk44Y)OX2rv zn4&)$N8?jy)$hbU*obLAIQgH&k&Qy{_jufdccTjzo{OvZT6CcbbfNKR;M39Cc{u#O zEVvw9@CEdm{u#|s1E%o8IqttNcKtkla5#EjC!?9D!4xjSUidq7qW7=}&!Pe6HO0So zMdzzPuUi#bJCB9_OPHd+6%G7I6ZhX8o@c-pbI-?T)&~vX%jh+`A3eJtqt|c=T4c|o z0k1_D+>YM=L+E>-qVu==BK}vi2RhH~Xwgqe)9}R^Vc`4d0zW~|`se7iS%IehWxNsB zqdPl_eKEH=zAZz8U!xmHze>Z1-$Zw^7rn=)(NAXg3vtAQ(4CA% zC%yv>bZKw}T8!(^iR-Z(8*u>^UyMIM&!HRIk364_KBVD=wz)KT18(4Bd`HaXR{bEt7N8)jGhrL=RqbeMUnc_u1xi6ztUx#jJ zW6NYZv(Rn^%)k+xiutXQQBSNvUw8(~uoj(YH{Oc>KtHXWvy+)?H4!h+zY9I{ujeE) zw`d9`=|6~Os0N*Heoi`0NgV_3xE|fvarA?8G1%jZWaPJeJbK38M5;Hc#csF-Q+Nms z{4!cYJzK}~SD^g|(0Lz6-&>mwjrY)^IUV|~bK?oGLyPaW(0>Rms%Jz0H8ik&Vf;eq z7w5$bjzM>NFVhj17cT^V1yN_3*x zXtggucd`vF((O1F_n`rH=@1uH3HGNy7X1!<_m6$%6g9LSQaYf2s(;zAfj4ga%7n!7 qXL4rDnpc&oo;A0&d4FO}!Q@%hRW+&1*qr<3+&6FIwgZV4<^KmM2Bx9_ diff --git a/lib/lang/locale/id_ID/LC_MESSAGES/messages.po b/lib/lang/locale/id_ID/LC_MESSAGES/messages.po index 09b5c109..5c24bde8 100755 --- a/lib/lang/locale/id_ID/LC_MESSAGES/messages.po +++ b/lib/lang/locale/id_ID/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgstr "" "Project-Id-Version: Senayan3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-07-21 16:29+0700\n" -"PO-Revision-Date: 2021-07-21 16:30+0700\n" +"PO-Revision-Date: 2021-09-08 10:44+0700\n" "Last-Translator: Arif Syamsudin Budi W. \n" "Language-Team: Arie Nugraha; Hendro Wicaksono; Wardiyono \n" @@ -8466,11 +8466,11 @@ msgstr "Tidak ada judul untuk dipesan" #: lib/contents/member.inc.php:631 msgid "Reservation not allowed" -msgstr "Tidak bisa dipesan" +msgstr "Tidak diizinkan untuk memesan" #: lib/contents/member.inc.php:639 msgid "Reserve limit reached" -msgstr "Tidak bisa memesan" +msgstr "Sudah mencapai batas pemesanan" #: lib/contents/member.inc.php:640 #, php-format From 33248fa446ba6a3d5e840e6f593ff26e9ac372ca Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Wed, 8 Sep 2021 11:27:31 +0700 Subject: [PATCH 28/73] Update translation Update translation for Bahasa Indonesia. --- lib/lang/locale/id_ID/LC_MESSAGES/messages.mo | Bin 136388 -> 136398 bytes lib/lang/locale/id_ID/LC_MESSAGES/messages.po | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo b/lib/lang/locale/id_ID/LC_MESSAGES/messages.mo index f314673a5440c081091fd3e40614359711a5025d..45fad14c3677dc81440406e2b29131f56f8b7567 100644 GIT binary patch delta 4147 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\n" "Language-Team: Arie Nugraha; Hendro Wicaksono; Wardiyono \n" @@ -8466,11 +8466,11 @@ msgstr "Tidak ada judul untuk dipesan" #: lib/contents/member.inc.php:631 msgid "Reservation not allowed" -msgstr "Tidak diizinkan untuk memesan" +msgstr "Anda tidak diizinkan untuk memesan" #: lib/contents/member.inc.php:639 msgid "Reserve limit reached" -msgstr "Sudah mencapai batas pemesanan" +msgstr "Pemesanan Anda sudah melebihi batas" #: lib/contents/member.inc.php:640 #, php-format From 6082b09fe84f943ffa2e928f3ebda108b0d25bdc Mon Sep 17 00:00:00 2001 From: Drajat Hasan <38057222+drajathasan@users.noreply.github.com> Date: Mon, 13 Sep 2021 20:10:10 +0700 Subject: [PATCH 29/73] Add : Rule to prevent git-dumper etc Bismillah. .git folder may be harmful if not protected, there are tool named git-dumper can scan it, although not all .git folder can accessed. If "Options -Indexes" is active, but thats not block to access file inside of it. --- .htaccess | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.htaccess b/.htaccess index 429bb6d4..52320155 100755 --- a/.htaccess +++ b/.htaccess @@ -6,6 +6,13 @@ Order allow,deny + + RewriteEngine On + # Protect hidden directory from vulnerability scanner + RewriteRule (^|/)\.([^/]+)(/|$) - [L,F] + RewriteRule (^|/)([^/]+)~(/|$) - [L,F] + + # Don't show directory listings for URLs which map to a directory. Options -Indexes From b62def957a71f3b1867d7ef28ac72d1fa482fbc3 Mon Sep 17 00:00:00 2001 From: "A.K.M. Nurul Alam" Date: Fri, 24 Sep 2021 11:24:14 +0600 Subject: [PATCH 30/73] Update import.php --- admin/modules/bibliography/import.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/admin/modules/bibliography/import.php b/admin/modules/bibliography/import.php index e6767b9b..75b4fa55 100755 --- a/admin/modules/bibliography/import.php +++ b/admin/modules/bibliography/import.php @@ -246,7 +246,7 @@

- Official Website'); ?> + Official Website'); ?>
@@ -294,4 +294,4 @@ let fileName = $(this).val().replace(/\\/g, '/').replace(/.*\//, ''); $(this).parent('.custom-file').find('.custom-file-label').text(fileName); }); - \ No newline at end of file + From 8cb854be80e541a2a4b6d81e9138cfe05e32077c Mon Sep 17 00:00:00 2001 From: Drajat Hasan <38057222+drajathasan@users.noreply.github.com> Date: Fri, 8 Oct 2021 10:46:54 +0700 Subject: [PATCH 31/73] Add : Escape string in publish year Some data from other system while migration have one quote and make it failed to indexed. --- admin/modules/system/biblio_indexer.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/modules/system/biblio_indexer.inc.php b/admin/modules/system/biblio_indexer.inc.php index 24fc0b27..138bafe7 100755 --- a/admin/modules/system/biblio_indexer.inc.php +++ b/admin/modules/system/biblio_indexer.inc.php @@ -139,7 +139,7 @@ public function makeIndex($int_biblio_id) { $data['publish_place'] = $this->obj_db->escape_string($rb_id['publish_place']); $data['isbn_issn'] = $this->obj_db->escape_string($rb_id['isbn_issn']); $data['language'] = $this->obj_db->escape_string($rb_id['language']); - $data['publish_year'] = $rb_id['publish_year']; + $data['publish_year'] = $this->obj_db->escape_string($rb_id['publish_year']); $data['classification'] = $this->obj_db->escape_string($rb_id['classification']); $data['spec_detail_info'] = $this->obj_db->escape_string($rb_id['spec_detail_info']); $data['call_number'] = $this->obj_db->escape_string($rb_id['call_number']); From 50271a05f19c7569364c2a52d5347d20b2351797 Mon Sep 17 00:00:00 2001 From: Drajat Hasan <38057222+drajathasan@users.noreply.github.com> Date: Wed, 13 Oct 2021 08:02:45 +0700 Subject: [PATCH 32/73] Fix : Undefined index: destination in dev mode --- lib/contents/member.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/contents/member.inc.php b/lib/contents/member.inc.php index 9ef7d1d7..0200a04b 100644 --- a/lib/contents/member.inc.php +++ b/lib/contents/member.inc.php @@ -902,7 +902,7 @@ class="fas fa-sign-out-alt mr-2"> ?>
- +
From 8750d43e0f2e84ea621fe0a19db1ebcdc4a3a326 Mon Sep 17 00:00:00 2001 From: Drajat Hasan <38057222+drajathasan@users.noreply.github.com> Date: Thu, 14 Oct 2021 14:58:49 +0700 Subject: [PATCH 33/73] Add : filter to escape some character --- install/SLiMS.inc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/install/SLiMS.inc.php b/install/SLiMS.inc.php index da7ec6a8..d490e691 100644 --- a/install/SLiMS.inc.php +++ b/install/SLiMS.inc.php @@ -374,6 +374,7 @@ function queryTrigger($array) function updateAdmin($username, $password) { + $username = $this->db->escape_string($username); $sql_update = " UPDATE user set username = '" . $username . "', passwd = '" . password_hash($password, PASSWORD_BCRYPT) . "', @@ -431,4 +432,4 @@ function rollbackSqlMode() { return $this->db->query(sprintf("SET @@sql_mode := '%s' ;", $this->sql_mode)); } -} \ No newline at end of file +} From 8ce14fbfb30c3fa8810f5ea1824210ad1cce875d Mon Sep 17 00:00:00 2001 From: idoalit Date: Sun, 24 Oct 2021 21:37:20 +0700 Subject: [PATCH 34/73] set environment to development --- sysconfig.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysconfig.inc.php b/sysconfig.inc.php index e276f823..b7b188fe 100755 --- a/sysconfig.inc.php +++ b/sysconfig.inc.php @@ -32,7 +32,7 @@ * * In production mode, the system error message will be disabled */ -define('ENVIRONMENT', 'production'); +define('ENVIRONMENT', 'development'); switch (ENVIRONMENT) { case 'development': From 68453aafae867a1753bbaacba24fa3d5ee6e1137 Mon Sep 17 00:00:00 2001 From: idoalit Date: Sun, 24 Oct 2021 21:53:50 +0700 Subject: [PATCH 35/73] check uncommon keyword to prevent sql injection --- lib/contents/default.inc.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/contents/default.inc.php b/lib/contents/default.inc.php index 8c93bd0f..89e5d20a 100755 --- a/lib/contents/default.inc.php +++ b/lib/contents/default.inc.php @@ -175,6 +175,15 @@ } $search_result_info .= '
'; + // check uncommon keyword to prevent sql injection + $checked_words = ['information_schema', 'concat', 'unhex']; + foreach($checked_words as $cw) { + if(strpos(strtolower($search_result_info), $cw) !== false) { + header('location: index.php'); + exit; + } + } + // show promoted titles if (isset($sysconf['enable_promote_titles']) && $sysconf['enable_promote_titles']) { $biblio_list->only_promoted = true; From 758fee70a407661def75ed7d800debfce5d13e12 Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Mon, 25 Oct 2021 22:10:57 +0700 Subject: [PATCH 36/73] Update changes.txt Update changes for upcoming release. --- changes.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changes.txt b/changes.txt index bd000bd9..50d1f6e8 100644 --- a/changes.txt +++ b/changes.txt @@ -44,10 +44,11 @@ Code enhancement: John Antony (john.antony@iamplus.com) THANKS TO OUR USERS AND COMMUNITIES, YOU ARE DEVELOPERS TOO! -SLiMS 9.x.x (Bulian) +SLiMS 9.5.0 (Bulian) ======================================================================== Added : Popup visitor report by day Added : Fines value in overdue list +Added : Password field for encrypted attachment Fixed : Image path for Minigalnano Updated : Server for quote in Visitor Counter page Fixed : Ignore holiday fines calculation From 1babb7c8e7ae797180af030013b2f6e08db729ae Mon Sep 17 00:00:00 2001 From: Arif Syamsudin Date: Mon, 25 Oct 2021 22:16:27 +0700 Subject: [PATCH 37/73] Update changes.txt Update changes for upcoming release. --- changes.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/changes.txt b/changes.txt index 50d1f6e8..a398ac00 100644 --- a/changes.txt +++ b/changes.txt @@ -49,6 +49,8 @@ SLiMS 9.5.0 (Bulian) Added : Popup visitor report by day Added : Fines value in overdue list Added : Password field for encrypted attachment +Updated : Check uncommon keyword to prevent sql injection +Fixed : Unable to import biblio data on first header Fixed : Image path for Minigalnano Updated : Server for quote in Visitor Counter page Fixed : Ignore holiday fines calculation @@ -57,7 +59,7 @@ Fixed : Holiday setting Fixed : Query when import biblio data header Fixed : Unrelated field after import item data from CSV Fixed : MARC export search -Fixex : Prevent hidden biblio to show in home page +Fixed : Prevent hidden biblio to show in home page SLiMS 9.4.2 (Bulian) ======================================================================== From 5d8fe2825b177c9b0e496e2addac1a518d8f828c Mon Sep 17 00:00:00 2001 From: idoalit Date: Mon, 25 Oct 2021 22:36:59 +0700 Subject: [PATCH 38/73] Resolve #26 Can not delete password for attachment --- admin/modules/bibliography/pop_attach.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/modules/bibliography/pop_attach.php b/admin/modules/bibliography/pop_attach.php index d9641d63..487b6913 100755 --- a/admin/modules/bibliography/pop_attach.php +++ b/admin/modules/bibliography/pop_attach.php @@ -149,7 +149,7 @@ $update1 = $sql_op->update('biblio_attachment', array('access_type' => $data['access_type'], 'access_limit' => $data['access_limit'], 'placement' => $data['placement']), 'biblio_id='.$updateBiblioID.' AND file_id='.$fileID); // file description update $file_desc_update = array('file_title' => $title, 'file_url' => $url, 'file_desc' => $dbs->escape_string(trim($_POST['fileDesc']))); - if(isset($_POST['fileKey']) && trim($_POST['fileKey']) !== '') + if(isset($_POST['fileKey'])) $file_desc_update['file_key'] = $dbs->escape_string(trim(strip_tags($_POST['fileKey']))); $update2 = $sql_op->update('files', $file_desc_update, 'file_id='.$fileID); if ($update1) { From c9da9579500b50176c7d82cbc8cd063ead3f91be Mon Sep 17 00:00:00 2001 From: Waris Agung Widodo Date: Tue, 26 Oct 2021 06:47:00 +0700 Subject: [PATCH 39/73] At least it is not easy to see --- js/pdfjs/build/ObjectPdf.js | 1 + js/pdfjs/mobile/index.php | 1 + js/pdfjs/mobile/js/viewer.js | 11 ++++++----- js/pdfjs/web/viewer.js | 7 +++---- js/pdfjs/web/viewer.php | 1 + lib/contents/fstream.inc.php | 11 ++++++++++- 6 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 js/pdfjs/build/ObjectPdf.js diff --git a/js/pdfjs/build/ObjectPdf.js b/js/pdfjs/build/ObjectPdf.js new file mode 100644 index 00000000..f482d216 --- /dev/null +++ b/js/pdfjs/build/ObjectPdf.js @@ -0,0 +1 @@ +var ObjectPdf={t:"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+"abcdefghijklmnopqrstuvwxyz0123456789+/=",decode:function(t){var i="";var e,r,n;var c,a,s,h;var f=0;t=t.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f>4;r=(a&15)<<4|s>>2;n=(s&3)<<6|h;i=i+String.fromCharCode(e);if(s!=64){i=i+String.fromCharCode(r)}if(h!=64){i=i+String.fromCharCode(n)}}i=this.i(i);return i},i:function(t){var i="";var e=0;var r=c1=c2=0;while(e191&&r<224){c2=t.charCodeAt(e+1);i+=String.fromCharCode((r&31)<<6|c2&63);e+=2}else{c2=t.charCodeAt(e+1);c3=t.charCodeAt(e+2);i+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);e+=3}}return i},create:async function(t){let i=new FormData;i.append("init",t);const e=await fetch(`index.php?p=fstream&initialize=true`,{method:"post",body:i});let r=await e.text();const n=Object.create(null);n.password=this.decode(this.decode(r).replace(t,""));return n}}; \ No newline at end of file diff --git a/js/pdfjs/mobile/index.php b/js/pdfjs/mobile/index.php index 50db5b02..0d304f85 100644 --- a/js/pdfjs/mobile/index.php +++ b/js/pdfjs/mobile/index.php @@ -23,6 +23,7 @@ + + '; + exit; +} + +if (isset($_POST['testMail'])) +{ + include_once $configPath; + $mail = new PHPMailer(true); + try { + ob_start(); + //Server settings + $mail->SMTPDebug = $sysconf['mail']['debug']; // Enable verbose debug output + $mail->isSMTP(); // Send using SMTP + $mail->Host = $sysconf['mail']['server']; // Set the SMTP server to send through + $mail->SMTPAuth = $sysconf['mail']['auth_enable']; // Enable SMTP authentication + $mail->Username = $sysconf['mail']['auth_username']; // SMTP username + $mail->Password = $sysconf['mail']['auth_password']; // SMTP password + if ($sysconf['mail']['SMTPSecure'] === 'tls') { // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged + $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; + } else if ($sysconf['mail']['SMTPSecure'] === 'ssl') { + $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; + } + $mail->Port = $sysconf['mail']['server_port']; // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above + + //Recipients + $mail->setFrom($sysconf['mail']['from'], $sysconf['mail']['from_name']); + $mail->addReplyTo($sysconf['mail']['reply_to'], $sysconf['mail']['reply_to_name']); + $mail->addAddress($_POST['receiveraddress'], $_POST['receivername']); + + $mail->isHTML(true); // Set email format to HTML + $mail->Subject = 'SLiMS :: Outgoing Mail Testing'; + $mail->msgHTML($_POST['dummyMessage']); + $mail->AltBody = strip_tags($_POST['dummyMessage']); + + $mail->send(); + $result = ob_get_clean(); + + utility::jsToastr(__('Success'), 'Mail testing has been sent', 'success'); + } catch (Exception $exception) { + utility::jsToastr(__('Success'), 'Mail testing could not be sent. Mailer Error: ' . $mail->ErrorInfo, 'success'); + } + exit; +} + +// create new instance +$form = new simbio_form_table_AJAX('mainForm', $_SERVER['PHP_SELF'], 'post'); + +// form table attributes +$form->table_attr = 'id="dataList" class="s-table table"'; +$form->table_header_attr = 'class="alterCell font-weight-bold"'; +$form->table_content_attr = 'class="alterCell2"'; + +?> + +submit_button_attr = 'name="saveData" value="'.__('Save Settings').'" class="btn btn-default"'; + +// edit mode +if ($isConfigExists) $form->addHidden('edit', true); + +// Debug +$DebugOptions = [ + [SMTP::DEBUG_OFF, __('Production')], + [SMTP::DEBUG_SERVER, __('Development')] +]; +$form->addSelectList('debug', __('Environment'), $DebugOptions, (int)setValue('debug') ,'class="form-control col-3"'); + +// SMTPSecure +$form->addTextField('text', 'SMTPSecure', __('SMTP Encryption'), setValue('SMTPSecure'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('SMTPSecure').'"'); + +// Server +$form->addTextField('text', 'server', __('SMTP Server address'), setValue('server'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('server').'"'); + +// Server Port +$form->addTextField('text', 'serverport', __('SMTP Port'), setValue('server_port'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('server_port').'"'); + +// set field username +$form->addTextField('text', 'authusername', __('Authentication Username'), setValue('auth_username'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('auth_username').'"',); + +// set field password +$form->addTextField('password', 'authpassword', __('Authentication Password'), '', 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('auth_password').'"', __('Password does not appearance for security reason. If you want to look it, open sysconfig.mail.inc.php file.')); + +// set email sender address +$form->addTextField('text', 'from', __('Email Sender Address'), setValue('from'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('from').'"'); + +// set email sender label +$form->addTextField('text', 'fromname', __('Email Sender Label'), setValue('from_name'), 'style="width: 60%;" class="form-control" placeholder="'.setPlaceholder('from_name').'"'); + +// test mail +if ($isConfigExists) +{ + $BtnLabel = __('Do Test'); + $Url = $_SERVER['PHP_SELF'] . '?section=test'; + $html = << + + {$BtnLabel} + + HTML; + $form->addAnything('Test Mail Configuration', $html); +} +// print out the object +echo $form->printOut(); +// End main configuration +else: +// Dummy content +$content = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book"; +// start test page +$form->submit_button_attr = 'name="testMail" value="'.__('Send Mail').'" class="btn btn-default"'; +$form->addTextField('text', 'receivername', __('Receiver Name'),'', 'style="width: 60%;" class="form-control"'); +$form->addTextField('text', 'receiveraddress', __('Receiver Address'), '', 'style="width: 60%;" class="form-control"'); +$form->addTextField('textarea', 'dummyMessage', __('Dummy Content'), $content, 'style="margin-top: 0px; margin-bottom: 0px; height: 149px;" class="form-control"'); +// print out the object +echo $form->printOut(); +// end test page +endif; +?> + \ No newline at end of file diff --git a/admin/modules/system/submenu.php b/admin/modules/system/submenu.php index 6f22836f..71cfedc1 100755 --- a/admin/modules/system/submenu.php +++ b/admin/modules/system/submenu.php @@ -34,6 +34,7 @@ $menu[] = array(__('Theme'), MWB.'system/theme.php', __('Configure theme Preferences')); $menu[] = array(__('Plugins'), MWB . 'system/plugins.php'); $menu[] = array(__('Custom Field'), MWB.'system/custom_field.php', __('Configure custom field')); + $menu[] = array(__('E-Mail Setting'), MWB.'system/mailsetting.php', __('Configure E-Mail Preferences')); } $menu[] = array(__('Content'), MWB.'system/content.php', __('Content')); // only administrator have privileges for below menus diff --git a/config/sysconfig.mail.inc-sample.php b/config/sysconfig.mail.inc-sample.php new file mode 100644 index 00000000..f49f241e --- /dev/null +++ b/config/sysconfig.mail.inc-sample.php @@ -0,0 +1,29 @@ + Date: Wed, 27 Oct 2021 19:09:49 +0700 Subject: [PATCH 45/73] Add : System Environment Settings --- admin/modules/system/envinfo.php | 1 + admin/modules/system/envsetting.php | 145 ++++++++++++++++++++++++++++ admin/modules/system/submenu.php | 1 + config/sysconfig.env.inc.php | 33 +++++++ sysconfig.inc.php | 5 +- 5 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 admin/modules/system/envsetting.php create mode 100644 config/sysconfig.env.inc.php diff --git a/admin/modules/system/envinfo.php b/admin/modules/system/envinfo.php index abd4e1a1..54b79058 100644 --- a/admin/modules/system/envinfo.php +++ b/admin/modules/system/envinfo.php @@ -47,6 +47,7 @@ // require SIMBIO.'simbio_DB/simbio_dbop.inc.php'; $environment = array( + array('title' => __('SLiMS Environment Mode'), 'desc' => ucfirst(ENVIRONMENT)), array('title' => __('SLiMS Version'), 'desc' => SENAYAN_VERSION_TAG), array('title' => __('Operating System'), 'desc' => php_uname('a')), array('title' => __('OS Architecture'), 'desc' => php_uname('m').' '.(8 * PHP_INT_SIZE).' bit'), diff --git a/admin/modules/system/envsetting.php b/admin/modules/system/envsetting.php new file mode 100644 index 00000000..41b24ce1 --- /dev/null +++ b/admin/modules/system/envsetting.php @@ -0,0 +1,145 @@ +setTimeout(() => {parent.$(\'#mainContent\').simbioAJAX(\'' . $_SERVER['PHP_SELF'] . '\')}, 5000)'; + // utility::jsAlert(json_encode($write)); + exit; +} + +?> + + + +submit_button_attr = 'name="saveData" value="'.__('Save Settings').'" class="btn btn-default"'; + +// form table attributes +$form->table_attr = 'id="dataList" class="s-table table"'; +$form->table_header_attr = 'class="alterCell font-weight-bold"'; +$form->table_content_attr = 'class="alterCell2"'; + +// Your Environment +if ($BasedIp) +{ + $thisEnv = ucfirst((!in_array(getCurrentIp(), $RangeIp) ? $Environment : $ConditionEnvironment)); + $HTML = <<{$thisEnv} + HTML; + $form->addAnything('Your Environment Mode', $HTML); + + $Environment = $ConditionEnvironment; +} + +// Environment List +$EnvOptions = [ + [1, __('Production')], + [0, __('Development')] + ]; +$form->addSelectList('env', __('System Environment Mode'), $EnvOptions, ( $Environment == 'production' ? 1 : 0 ) ,'class="form-control col-3"'); +$BasedIpOptions = [ + [0, __('Disable')], + [1, __('Enable')] +]; +$form->addSelectList('basedIp', __('Environment for some IP?'), $BasedIpOptions, ( $BasedIp ? 1 : 0 ) ,'class="form-control col-3"'); +$form->addTextField('textarea', 'rangeIp', __('Range Ip wil be impacted with Environment. Example : 10.120.33.40;20.100.34.10. '), implode(';', $RangeIp), 'style="margin-top: 0px; margin-bottom: 0px; height: 149px;" class="form-control" placeholder="Leave it empty, if you want to set environment to impact for all IP"'); +// print out the object +echo $form->printOut(); \ No newline at end of file diff --git a/admin/modules/system/submenu.php b/admin/modules/system/submenu.php index 71cfedc1..64235737 100755 --- a/admin/modules/system/submenu.php +++ b/admin/modules/system/submenu.php @@ -30,6 +30,7 @@ if ($_SESSION['uid'] == 1) { $menu[] = array(__('System Configuration'), MWB.'system/index.php', __('Configure Global System Preferences')); $menu[] = array(__('System Environment'), MWB.'system/envinfo.php', __('Information about System Environment')); + $menu[] = array(__('System Environment Setting'), MWB.'system/envsetting.php', __('Configure System Environment Mode')); $menu[] = array(__('UCS Setting'), MWB.'system/ucsetting.php', __('Configure UCS Preferences')); $menu[] = array(__('Theme'), MWB.'system/theme.php', __('Configure theme Preferences')); $menu[] = array(__('Plugins'), MWB . 'system/plugins.php'); diff --git a/config/sysconfig.env.inc.php b/config/sysconfig.env.inc.php new file mode 100644 index 00000000..c7f7e92f --- /dev/null +++ b/config/sysconfig.env.inc.php @@ -0,0 +1,33 @@ + Date: Thu, 28 Oct 2021 12:49:36 +0700 Subject: [PATCH 46/73] Add : load hook at after and before content load --- index.php | 8 ++++++++ template/akasia-dz/partials/meta.php | 5 +++++ template/akasia/partials/meta.php | 5 +++++ template/default/parts/header.php | 5 +++++ template/lightweight/partials/meta.php | 5 +++++ 5 files changed, 28 insertions(+) diff --git a/index.php b/index.php index 4eb99bd4..41ccd9cf 100755 --- a/index.php +++ b/index.php @@ -48,6 +48,8 @@ $header_info = ''; // HTML metadata $metadata = ''; +// JS +$js = ''; // searched words for javascript highlight $searched_words_js_array = ''; @@ -56,6 +58,9 @@ $header_info .= ''; } +// Load hook before content load +SLiMS\Plugins::getInstance()->execute('before_content_load'); + // start the output buffering for main content ob_start(); require LIB.'contents/common.inc.php'; @@ -116,5 +121,8 @@ // main content grab $main_content = ob_get_clean(); +// Load hook after content load +SLiMS\Plugins::getInstance()->execute('after_content_load'); + // template output require $sysconf['template']['dir'].'/'.$sysconf['template']['theme'].'/index_template.inc.php'; diff --git a/template/akasia-dz/partials/meta.php b/template/akasia-dz/partials/meta.php index 5d8e2c64..a642db56 100644 --- a/template/akasia-dz/partials/meta.php +++ b/template/akasia-dz/partials/meta.php @@ -78,6 +78,11 @@ + diff --git a/template/akasia/partials/meta.php b/template/akasia/partials/meta.php index e751ea25..7f482f7f 100644 --- a/template/akasia/partials/meta.php +++ b/template/akasia/partials/meta.php @@ -78,6 +78,11 @@ + diff --git a/template/default/parts/header.php b/template/default/parts/header.php index 027817aa..3700d78f 100644 --- a/template/default/parts/header.php +++ b/template/default/parts/header.php @@ -95,6 +95,11 @@ + diff --git a/template/lightweight/partials/meta.php b/template/lightweight/partials/meta.php index c0411179..e58db038 100644 --- a/template/lightweight/partials/meta.php +++ b/template/lightweight/partials/meta.php @@ -81,6 +81,11 @@ --> +