';
$(menu).each((i, atom) => {
if (Object.keys(atom).length === 0) {
- smenu += '
';
ma = ' ms-sm-2';
} else {
if (atom.i == 'butTutup') { atom.v='Tutup', atom.c='danger', atom.d='' };
@@ -286,18 +286,29 @@ var FoniaJS = {
FormDecorated: function() {
$('input.form-control[class*=integer], input.form-control[class*=angka]').each((i, el) => {
const elm = $(el);
- elm.on('keypress keyup blur paste', (e) => {
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
+ elm.on('keypress keyup paste', (e) => {
elm.val(elm.val().replace(/[^\d].+/, ""));
if ((e.which < 48 || e.which > 57)) e.preventDefault();
});
});
$('input.form-control[class*=double]').each((i, el) => {
const elm = $(el);
- elm.on('keypress keyup blur paste', (e) => {
- elm.val(elm.val().replace(/[^0-9\.]/g,''));
- if (e.type === 'blur') elm.val( FoniaJS.FloatToStr(elm.val(), 2) );
- if ((e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
+ elm.on('keypress keyup input', (e) => {
+ if (e.type === 'keypress') {
+ if ((e.which != 45 || elm.val().indexOf('-') != -1) && (e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
+ } else {
+ var _val = elm.val().replace(/[^0-9.-]/g, '');
+ if (_val.indexOf('-') > 0) _val = _val.charAt(0) + _val.slice(1).replace(/-/g, '');
+ var _parts = _val.split('.');
+ if (_parts.length > 2) _val = _parts[0] + '.' + _parts.slice(1).join('');
+ elm.val(_val);
+ }
});
+ elm.on('blur', () => elm.val( FoniaJS.FloatToStr(elm.val(), 2) ));
elm.on('focus', (e) => {
elm.val( FoniaJS.StrToFloat(elm.val()) );
elm.select();
@@ -306,9 +317,18 @@ var FoniaJS = {
});
$('input.form-control[type=number]').each((i, el) => {
const elm = $(el);
- elm.on('keypress keyup blur paste', (e) => {
- elm.val(elm.val().replace(/[^0-9]/g,''));
- if ((e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
+ elm.on('keypress keyup input', (e) => {
+ if (e.type === 'keypress') {
+ if ((e.which != 45 || elm.val().indexOf('-') != -1) && (e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
+ } else {
+ var _val = elm.val().replace(/[^0-9.-]/g, '');
+ if (_val.indexOf('-') > 0) _val = _val.charAt(0) + _val.slice(1).replace(/-/g, '');
+ var _parts = _val.split('.');
+ if (_parts.length > 2) _val = _parts[0] + '.' + _parts.slice(1).join('');
+ elm.val(_val);
+ }
});
});
$('input.form-control, textarea.form-control, select.form-select').each((i, el) => {
@@ -316,6 +336,8 @@ var FoniaJS = {
const okyup = elm.attr('okyup') ?? '';
const oblur = elm.attr('oblur') ?? '';
const ochan = elm.attr('ochan') ?? '';
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
elm.on('keyup blur change', (e) => {
if (e.type === 'keyup' && okyup) {
var fnc = okyup.split('.');
@@ -340,6 +362,8 @@ var FoniaJS = {
});
$('input.form-check-input[type=radio]').each((i, el) => {
const elm = $(el);
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
elm.on('click', () => {
const oclic = elm.attr('ochan') ?? '';
const elp = $('#'+elm.attr('name'));
@@ -354,6 +378,8 @@ var FoniaJS = {
});
$('input.form-check-input[type=checkbox]').each((i, el) => {
const elm = $(el);
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
elm.on('change', () => {
const odata = JSON.parse(elm.attr('odata') ?? '[]');
const ochan = elm.attr('ochan') ?? '';
@@ -393,49 +419,47 @@ var FoniaJS = {
}
if ('function' == typeof autosize) autosize($('textarea'));
},
-
RequestParam: function(aparam) {
- var tmp_hasil = [];
- var tmp_array = aparam;
- var tmp_cblist = {};
+ var _cblist = {};
+ var _ohasil = {};
$('tbody input[id*="cbox"][type="checkbox"]:checked').map((i, b) => {
const arr = b.id.split('_');
- if (!tmp_cblist[arr[0]]) tmp_cblist[arr[0]] = [];
- tmp_cblist[arr[0]].push(arr[2]);
- // for compatible only
- tmp_array.push(b.id + '=' + b.value);
+ if (!_cblist[arr[0]]) _cblist[arr[0]] = [];
+ _cblist[arr[0]].push(arr[2]);
});
- $.each(tmp_cblist, (i, b) => {
- tmp_array.push('List_CB_' + i + '=' + b.join());
+ $.each(_cblist, (i, b) => {
+ _ohasil['List_CB_' + i] = b.join();
});
- tmp_array.map(nilai => {
- if (typeof nilai === "string") {
- var tmp_value = "";
- if (nilai.indexOf("=") == -1) {
- if ($('#'+nilai).length) {
- tmp_value = $('#'+nilai).val();
- if (typeof tmp_value === 'undefined') {
- tmp_value = ($('#'+nilai).is('.integer, .number, .double')) ? '0' : '';
+ if (typeof aparam === 'object') {
+ aparam.map(_par => {
+ if (typeof _par !== "string") this.return;
+ var _key = _par, _val = "";
+ const _ind = _par.indexOf('=');
+ if (_ind !== -1) {
+ _key = _par.slice(0, _ind);
+ _val = _par.slice(_ind + 1);
+ } else {
+ if ($('#'+_par).length) {
+ _val = $('#'+_par).val();
+ if (typeof _val === 'undefined') {
+ _val = ($('#'+_par).is('.integer, .number, .double')) ? 0 : '';
} else {
- tmp_value = ($('#'+nilai).is('.integer, .number, .double')) ? this.StrToFloat(tmp_value) : encodeURIComponent(tmp_value);
+ _val = ($('#'+_par).is('.integer, .number, .double')) ? this.StrToFloat(_val) : encodeURIComponent(_val);
}
}
- tmp_value = nilai + "=" + tmp_value;
- } else {
- tmp_value = nilai;
}
- tmp_hasil.push(tmp_value);
- }
- });
- tmp_hasil.push('SID=' + parseInt(Math.random() * 99999999));
- return tmp_hasil;
+ _ohasil[_key] = _val;
+ });
+ }
+ _ohasil['SID'] = parseInt(Math.random() * 99999999);
+ return _ohasil;
},
StrToFloat: function(str_val) {
var nstr = str_val + "";
var hasil = "";
var fkali = 1;
- if (nstr.substr(0, 3) == "Rp.") {
- nstr = nstr.substr(3);
+ if (nstr.slice(0, 4) == "Rp.") {
+ nstr = nstr.slice(4);
}
for (var i = 0; i < nstr.length; i++) {
if ((parseFloat(nstr.charAt(i))) || (nstr.charAt(i) == "0") || (nstr.charAt(i) == ".")) {
@@ -604,13 +628,12 @@ var FoniaJS = {
}
},
AutoComplete: function(elm, turl, aparam, func_comp, func_key){
- var arrData = [], objComp = {};
- if ('string' !== typeof aparam) arrData = this.RequestParam(aparam);
+ var objComp = {};
objComp = {
preventEnter: true,
resolverSettings: {
url: turl,
- extraData: arrData.reduce(function(o, val) { var t = val.split('='); o[t[0]] = t[1]; return o; }, {})
+ param: (typeof aparam === 'object') ? aparam : []
}
};
if ('object' === typeof func_comp){
@@ -652,11 +675,11 @@ class _Request {
console.log(this.options.sendParam + ", cek url php!");
return false;
}
- this.options.data = FoniaJS.RequestParam(this.options.sendParam);
+ this.options.data = $.extend(this.options.data, FoniaJS.RequestParam(this.options.sendParam));
$.ajax({
type: 'POST',
url: this.options.url,
- data: (this.options.data).join('&'),
+ data: this.options.data,
success: (typeof this.options.onSuccess === "function") ? this.options.onSuccess : () => {},
error: (typeof this.options.onFailure === "function") ? this.options.onFailure : () => {},
complete: FoniaJS.FormDecorated,
@@ -800,20 +823,17 @@ class _Request_JSONF extends _Request {
var opsi = { responsive: true, columnDefs: [{responsivePriority:1,targets:0},{responsivePriority:2,targets:1},{responsivePriority:0,targets:-1}], lengthMenu: [], dom: '<"row"<"col-sm-12"tr>><"row"<"col-sm-12 col-lg-auto"<"toolbar">><"col-sm-3 col-lg-auto ms-lg-auto"l><"col-sm-9 col-lg-auto"p>>', autoWidth: false, processing: true, searching: false, columns: aSortCol, order: [[iCol, (ini.config.sort_dir=='A'?'asc':'desc')]], pageLength: ini.config.row_count, stateSave: true, stateSaveCallback: function(sett,data){localStorage.setItem(ini.id,JSON.stringify(data));}, stateLoadCallback: function(sett){try{var data=JSON.parse(localStorage.getItem(ini.id))??{};data.length=ini.config.row_count;return data;}catch(e){console.log(e)}} };
/** start live db **/
if (ini.config.live){
- var post_data = {};
- $(this.options.data).map((key, item) => {
- var keyval = item.split("=");
- if (keyval[0] == 'SID') keyval[1] = parseInt(Math.random() * 99999999);
+ $(this.options.data).map((key, val) => {
+ if (key === 'SID') val = parseInt(Math.random() * 99999999);
// fixed bug for duplicate saving
- if (keyval[0] == 'mode_detail') keyval[1] = 'live-data';
- if ((''+keyval[1]).indexOf('%') != -1) keyval[1] = decodeURIComponent(keyval[1]);
- return post_data[keyval[0]] = keyval[1];
+ if (key === 'mode_detail') val = 'live-data';
+ //if ((''+val).indexOf('%') != -1) val = decodeURIComponent(val);
});
opsi.serverSide = true;
opsi.ajax = {
url: this.options.url,
type: 'POST',
- data: post_data,
+ data: this.options.data,
dataFilter: (data) => {
var json = {}, jsono = {'draw':0,'recordsTotal':0,'recordsFiltered':0,'data':[]};
try {
@@ -931,7 +951,10 @@ class _Request_JSONF extends _Request {
// apply select function
if (ini.config.func_select){
$('#'+ini.id+'Tabel tbody').on('click', 'tr', (e) => {
- var dta = otabel.row(e.currentTarget).data();
+ var elm = $(e.currentTarget);
+ if ((elm.attr('o3') ?? '') !== '') return;
+ elm.attr('o3', '1');
+ var dta = otabel.row(elm).data();
var fnc = ini.config.func_select.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function') { window[fnc[0]][fnc[1]](dta); }
else console.warn('fungsi '+ini.config.func_select+' tidak ada !');
@@ -945,16 +968,19 @@ class _Request_JSONF extends _Request {
$(ini.option).map((key, val) => {
if (val.type == 'checkbox'){
$('#'+ini.id+'Tabel thead input[type=checkbox][id*=_cbhead_]').on('change', (e) => {
- var _chek = e.currentTarget.is(':checked');
- e.currentTarget.val(e.currentTarget.is(':checked') ? val.avalue[0] : val.avalue[1]);
+ var _etarg = $(e.currentTarget);
+ var _chek = _etarg.is(':checked');
+ _etarg.val(_chek ? val.avalue[0] : val.avalue[1]);
$('#'+ini.id+'Tabel tbody input[type=checkbox][id*='+val.field+'_cbox_]').each((i, el) => {
- el.prop('checked', _chek);
- el.val(el.is(':checked') ? val.avalue[0] : val.avalue[1]);
+ var _el = $(el);
+ _el.prop('checked', _chek);
+ _el.val(_el.is(':checked') ? val.avalue[0] : val.avalue[1]);
});
});
$('#'+ini.id+'Tabel tbody input[type=checkbox][id*=_cbox_]').on('change', (e) => {
- e.currentTarget.val(e.currentTarget.val() == val.avalue[1] ? val.avalue[0] : val.avalue[1]);
- e.currentTarget.prop('checked', e.currentTarget.val() == val.avalue[0]);
+ var _ctarg = $(e.currentTarget);
+ _ctarg.val(_ctarg.val() == val.avalue[1] ? val.avalue[0] : val.avalue[1]);
+ _ctarg.prop('checked', _ctarg.val() == val.avalue[0]);
});
} else if (val.type == 'button'){
$('#'+ini.id+'Tabel tbody').on('click', '.'+val.icon, (e) => {
diff --git a/assets/js/pdf.js b/assets/js/pdf.js
index 4e1afaf..e52c2b4 100644
--- a/assets/js/pdf.js
+++ b/assets/js/pdf.js
@@ -35,11 +35,10 @@ var cPDF = function(url, options){
console.warn(vars.param + ", cek url php!");
return false;
}
- vars.data = FoniaJS.RequestParam(vars.param);
$.ajax({
type: 'POST',
url: vars.url,
- data: (vars.data).join('&'),
+ data: FoniaJS.RequestParam(vars.param),
success: (typeof vars.onSuccess === "function") ? vars.onSuccess : null,
error: (typeof vars.onFailure === "function") ? vars.onFailure : null,
}).always(FoniaJS.FormDecorated);
@@ -47,7 +46,7 @@ var cPDF = function(url, options){
};
this.showPDF = function(){
var _proto = window.location.protocol + '//';
- var _src = _proto + FoniaJS.WEB_HOST + vars.url + '?' + (FoniaJS.RequestParam(vars.param)).join('&') + '#zoom='+vars.zoom+',0,0&page=1';
+ var _src = _proto + FoniaJS.WEB_HOST + vars.url + '?' + $.param(FoniaJS.RequestParam(vars.param)) + '#zoom='+vars.zoom+',0,0&page=1';
var _wtxt =
'
'+
'
'+
diff --git a/assets/js/print.js b/assets/js/print.js
index 70ff9e1..f4f40af 100644
--- a/assets/js/print.js
+++ b/assets/js/print.js
@@ -4,7 +4,7 @@
Desc. : JS Class Printer & Printer POS
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 27th, 2007.
- Last Modified : August 21st, 2026.
+ Last Modified : September 21st, 2026.
(c) 3FONIA Software; WWW.3FONIA.COM.
@@ -35,11 +35,10 @@ var cPRINTER = function(url, options){
console.warn(vars.param + ", cek url php!");
return false;
}
- vars.data = FoniaJS.RequestParam(vars.param);
$.ajax({
type: 'POST',
url: vars.url,
- data: (vars.data).join('&'),
+ data: FoniaJS.RequestParam(vars.param),
success: (txt) => {
var $printData = $('#dataPrint');
if (!$printData.length) {
@@ -54,11 +53,10 @@ var cPRINTER = function(url, options){
};
this.doPreview = function(){
if (!vars.url) console.warn(vars.param + ", cek url php!");
- vars.data = FoniaJS.RequestParam(vars.param);
$.ajax({
type: 'POST',
url: vars.url,
- data: (vars.data).join('&'),
+ data: FoniaJS.RequestParam(vars.param),
success: (txt) => {
if ('' == txt) {
FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !');
@@ -162,7 +160,7 @@ var cPRINTERPOS = function(url, options) {
};
this.do_print = function(nama_p, url, params) {
var qzcfg = qz.configs.create(nama_p);
- new Request.JSON({
+ new Request({
url: url,
sendParam: params,
onSuccess: (ajson) => {
@@ -181,7 +179,9 @@ var cPRINTERPOS = function(url, options) {
ohead.push("\x1B\x40");
ohead.push("\x1B\x61\x01");
if (adata.config.logo != null) {
- ohead.push({type:'raw',format:'image',data:adata.config.logo,options:{language:'ESCPOS',dotDensity:'double'}});
+ //ohead.push({type:'raw',format:'image',data:adata.config.logo,options:{language:'ESCPOS',dotDensity:'double'}});
+ //ohead.push("\x1B\x32");
+ ohead.push({type:'raw',format:'image',flavor:'base64',data:adata.config.logo,options:{language:'ESCPOS',dotDensity:'double'}});
ohead.push("\x1B\x32");
}
if (parseInt(adata.config.fontsize) == 2) {
diff --git a/assets/js/share.js b/assets/js/share.js
index b36aa95..3d0bf57 100644
--- a/assets/js/share.js
+++ b/assets/js/share.js
@@ -39,7 +39,7 @@ var cSHARE = function(url, options) {
return false;
}
var _pro = (window.location.protocol=='https:') ? 'https://' : 'http://';
- var _src = _pro+FoniaJS.WEB_HOST + _options.url + '?' + (FoniaJS.RequestParam(_params)).join('&');
+ var _src = _pro+FoniaJS.WEB_HOST + _options.url + '?' + $.param(FoniaJS.RequestParam(_params));
try {
const response = await fetch(_src)
diff --git a/assets/js/simulator.js b/assets/js/simulator.js
index f7cfc96..b00a7c5 100644
--- a/assets/js/simulator.js
+++ b/assets/js/simulator.js
@@ -28,11 +28,10 @@ var cSIMULATOR = function(url, options){
},
this.doPreview = function(){
if (!vars.url) console.warn(vars.param + ", cek url php!");
- vars.data = FoniaJS.RequestParam(vars.param);
$.ajax({
type: 'POST',
url: vars.url,
- data: (vars.data).join('&'),
+ data: FoniaJS.RequestParam(vars.param),
success: function(data){
if (data.length == 0) {
FoniaJS.showInfo('Tidak ada data !');
diff --git a/composer.json b/composer.json
index 1bd09c0..4961f62 100644
--- a/composer.json
+++ b/composer.json
@@ -22,9 +22,7 @@
"flightphp/session": "^0.3",
"mpdf/mpdf": ">=8.0",
"matthiasmullie/minify": ">=1.3",
- "endroid/qr-code": ">=4.4",
- "phpoffice/phpspreadsheet": ">=1.29",
- "shuchkin/simplexlsxgen": "^1.3"
+ "endroid/qr-code": ">=4.4"
},
"autoload": {
"classmap": ["src/"],
diff --git a/src/DB/SQL.php b/src/DB/SQL.php
index 37ddbd8..d8d997b 100644
--- a/src/DB/SQL.php
+++ b/src/DB/SQL.php
@@ -5,7 +5,7 @@
Module : /DB/SQL.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 2nd, 2007.
- Last Modified : August 21st, 2026.
+ Last Modified : September 11th, 2026.
(c) 3FONIA Software; WWW.3FONIA.COM.
@@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Webapp\DB;
+use ErrorException;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
@@ -68,7 +69,7 @@ final class SQL {
public function add_param_date(string $param = "", string|null $value = null): void {
$this->_afield[] = [
'field' => $param,
- 'value' => tgl_sql2str(is_null($value) ? Param::Get($param) : $value),
+ 'value' => tgl_sql2str(is_null($value) ? Param::Get($param, '00-00-0000') : $value),
'numbe' => false,
];
}
@@ -185,8 +186,8 @@ final class SQL {
$this->db->runQuery($tsql, $__aexec);
}
- public function LastInsertID(): int {
- return $this->db->lastInsertId();
+ public function LastInsertID(?string $name = null): mixed {
+ return $this->db->lastInsertId($name);
}
}
diff --git a/src/Data/Cache.php b/src/Data/Cache.php
index 2d3aeea..da69647 100644
--- a/src/Data/Cache.php
+++ b/src/Data/Cache.php
@@ -136,8 +136,7 @@ final class Cache {
$_ajs = ['system/profile', 'system/chpasswd'];
$amenu = array_values($this->web_user['Merge_Menu'] ?? []);
$_ops = $this->db->fetchColumn("SELECT Link FROM app_menu WHERE Kode IN (?) AND Link<>'' ORDER BY Kode", [$amenu]);
- if ($_ops) $_ajs += $_ops;
-
+ if ($_ops) $_ajs = array_merge($_ajs, $_ops);
$dirIterator = new \RecursiveDirectoryIterator($this->jsapp, \RecursiveDirectoryIterator::SKIP_DOTS);
$dirFilter = new \RecursiveCallbackFilterIterator($dirIterator, fn($curr, $key, $iter) => !($curr->isDir() && in_array($curr->getFilename(), ['locale'])));
$iterator = new \RecursiveIteratorIterator($dirFilter);
diff --git a/src/Data/SimpleXLS.php b/src/Data/SimpleXLS.php
deleted file mode 100644
index dcb9e3b..0000000
--- a/src/Data/SimpleXLS.php
+++ /dev/null
@@ -1,164 +0,0 @@
-__wbook = new \Shuchkin\SimpleXLSXGen();
- $this->__wbook
- ->setAuthor($_SESSION['WEB_APP']['APP_NAME']." v".$_SESSION['WEB_APP']['APP_VER'])
- ->setLastModifiedBy($_SESSION['WEB_APP']['APP_NAME']." v".$_SESSION['WEB_APP']['APP_VER'])
- ->setTitle($oprop['title'] ?? "")
- ->setSubject($oprop['subject'] ?? $_SESSION['WEB_APP']['REG_NAME'])
- ->setDescription($oprop['desc'] ?? "")
- ->setCompany($_SESSION['WEB_APP']['REG_NAME'])
- ->setDefaultFont("Calibri")
- ->setDefaultFontSize(11);
- }
-
- private function coord2cell($x, $y) {
- $c = '';
- for ($i = $x; $i >= 0; $i = ((int)($i / 26)) - 1) {
- $c = chr(ord('A') + $i % 26) . $c;
- }
- return $c . ($y + 1);
- }
-
- private function create_style($tstyle="L") {
- $_astyle = explode(",", $tstyle);
- $_s_style = ""; $_e_style = "";
- foreach ($_astyle as $_key => $_val) {
- if ($_val == "L") {$_s_style .= ''; $_e_style .= '';}
- if ($_val == "R") {$_s_style .= ''; $_e_style .= '';}
- if ($_val == "C") {$_s_style .= '
'; $_e_style .= '';}
- if ($_val == "W") {$_s_style .= ''; $_e_style .= '';}
- if ($_val == "B") {$_s_style .= ''; $_e_style .= '';}
- if ($_val == "I") {$_s_style .= ''; $_e_style .= '';}
- if ($_val == "S") {$_s_style .= "\0"; $_e_style .= '';}
- if ($_val == "N") {$_s_style .= '';}
- if ($_val == "N0") {$_s_style .= '';}
- }
- return ['s'=>$_s_style, 'e'=>$_e_style];
- }
-
- public function clear_field() {
- $this->__atabel = [];
- }
-
- public function add_header($tjudul="") {
- if ($tjudul=="") return;
- $this->__aheader[] = $tjudul;
- }
-
- public function add_empty_row($nrow=1) {
- $_jkolom = count($this->__atabel);
- for ($i=0; $i<$nrow; $i++) {
- $this->__avalue[] = array_fill(0,$_jkolom,"");
- }
- }
-
- public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="") {
- $this->__atabel[] = [$tnama, $nlebar, $ffunc];
- $this->__astyle[] = $this->create_style($talign);
- }
-
- public function add_sheet($tnama_sheet="BARU", $bw_header=true) {
- $this->__tsheet = $tnama_sheet;
- $_jkolom = count($this->__atabel);
- foreach ($this->__aheader as $_key => $_val) {
- $a_out = ['"];
- $this->__amerge[] = $this->coord2cell(0, count($this->__avalue)) . ":" . $this->coord2cell($_jkolom-1, count($this->__avalue));
- $this->__avalue[] = $a_out;
- }
- if ($bw_header==true) $this->show_headers();
- }
-
- public function add_value() {
- $tmp_arr = func_get_args();
- if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
- $a_out = [];
- for ($i=0; $i__atabel); $i++) {
- $tmp_val = $tmp_arr[$i];
- if (is_array($this->__atabel[$i][2]) && trim($tmp_val)<>"") {
- $tmp_val = $this->__atabel[$i][2][$tmp_val];
- } else if (function_exists($this->__atabel[$i][2]) && trim($tmp_val)<>"") {
- $tmp_val = call_user_func($this->__atabel[$i][2], $tmp_val);
- }
- $a_out[] = $this->__astyle[$i]['s'] . $tmp_val . $this->__astyle[$i]['e'];
- }
- $this->__avalue[] = $a_out;
- }
-
- public function add_span() {
- $tmp_arr = func_get_args();
- $a_out = [];
- for ($i=0; $i"") {
- $tmp_val[0] = call_user_func($tmp_val[3], $tmp_val[0]);
- }
- }
- $tmp_style = $this->create_style($tmp_val[2]);
- if ($tmp_val[1]>1) $this->__amerge[] = $this->coord2cell(count($a_out), count($this->__avalue)) . ":" . $this->coord2cell((count($a_out)+$tmp_val[1])-1, count($this->__avalue));
- $a_out[] = $tmp_style['s'] . $tmp_val[0] . $tmp_style['e'];
- for ($k=1; $k<$tmp_val[1]; $k++) $a_out[] = null;
- }
- $this->__avalue[] = $a_out;
- }
-
- public function add_stamp($ctk_ke=1, $bnama=false) {
- $this->__avalue[] = ["".$_SESSION['WEB_APP']['APP_NAME']."v".$_SESSION['WEB_APP']['APP_VER'].date("\@ymd.His")."-".user_id(3).(($bnama==true)?"/".strtoupper(user_user()):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):"").""];
- }
-
- public function get_stamp($ctk_ke=1, $bnama=false) {
- return $_SESSION['WEB_APP']['APP_NAME']."v".$_SESSION['WEB_APP']['APP_VER'].date("\@ymd.His")."-".user_id(3).(($bnama==true)?"/".strtoupper(user_user()):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):"");
- }
-
- public function show_headers() {
- $a_out = [];
- for ($i=0; $i__atabel); $i++) {
- $a_out[] = '';
- }
- $this->__avalue[] = $a_out;
- }
-
- public function send($tnama_file="File_Excel") {
- $this->__wbook->addSheet($this->__avalue, $this->__tsheet);
- for ($i=0; $i__atabel); $i++) {
- $this->__wbook->setColWidth(($i+1), $this->__atabel[$i][1]);
- }
- for ($i=0; $i__amerge); $i++) {
- $this->__wbook->mergeCells($this->__amerge[$i]);
- }
- $this->__wbook->downloadAs($tnama_file);
- }
-
-}
-
-?>
diff --git a/src/Data/XLS.php b/src/Data/XLS.php
deleted file mode 100644
index 9d4cc25..0000000
--- a/src/Data/XLS.php
+++ /dev/null
@@ -1,156 +0,0 @@
-__tnamafile = $tnama_file;
- $this->__wbook = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
- $this->__wbook->getProperties()
- ->setCreator($_SESSION['WEB_APP']['APP_NAME']." v".$_SESSION['WEB_APP']['APP_VER'])
- ->setLastModifiedBy($_SESSION['WEB_APP']['APP_NAME']." v".$_SESSION['WEB_APP']['APP_VER'])
- ->setTitle($oprop['title'] ?? "")
- ->setSubject($oprop['subject'] ?? "")
- ->setDescription($oprop['desc'] ?? "")
- ->setCompany($_SESSION['WEB_APP']['REG_NAME']);
- $this->__wsheet = $this->__wbook->getActiveSheet();
- $this->__fhead = [
- 'font' => ['bold' => true],
- 'alignment' => ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, 'wrapText' => true],
- 'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb'=>"D0D0D0"]],
- 'borders' => ['allBorders' => ['borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['rgb'=>"C0C0C0"]]]
- ];
- }
-
- public function create_style($tstyle="L") {//oke
- $_astyle = explode(",", $tstyle);
- $_tmp_style = [];
- $_bline = $this->__bline;
- foreach ($_astyle as $_key => $_val) {
- if ($_val == "L") $_tmp_style['alignment'] = ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_LEFT];
- if ($_val == "R") $_tmp_style['alignment'] = ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_RIGHT];
- if ($_val == "C") $_tmp_style['alignment'] = ['horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER];
- if ($_val == "W") $_tmp_style['alignment'] = ['wrapText' => true];
- if ($_val == "B") $_tmp_style['font'] = ['bold' => true];
- if ($_val == "S") $_tmp_style['numberFormat'] = ['formatCode' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_TEXT];
- if ($_val == "N") $_tmp_style['numberFormat'] = ['formatCode' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2];
- if ($_val == "N0") $_tmp_style['numberFormat'] = ['formatCode' => \PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED2];
- if ($_val == "NL") $_bline = false;
- if ($_val == "H") {
- $_bline = false;
- $_tmp_style = $this->__fhead;
- }
- }
- return $_tmp_style;
- }
-
- public function clear_field() {//up : 2014-06-19
- $this->__atabel = [];
- $this->__astyle = [];
- }
-
- public function set_pos($nbaris=0, $nkolom=0) {
- $this->__baris = $nbaris;
- $this->__kolom = $nkolom;
- }
-
- public function set_garis_bawah($bgaris=true) {}//todo: deleted
-
- public function add_header($tjudul="") {//oke
- if ($tjudul=="") return;
- $this->__aheader[] = $tjudul;
- }
-
- public function add_empty_row($nrow=1) {//oke
- $this->__baris += $nrow;
- }
-
- public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="") {//oke
- $this->__atabel[] = [$tnama, $nlebar, $ffunc];
- $this->__astyle[] = $this->create_style($talign);
- }
-
- public function add_sheet($tnama_sheet="BARU", $bw_header=true) {//not yet !!!
- if ($this->__isheet > 0) {
- $this->__wbook->createSheet();
- $this->__wsheet = $this->__wbook->setActiveSheetIndex(++$this->__isheet);
- }
- $this->__wsheet->setTitle($tnama_sheet);
- for ($i=0; $i__atabel); $i++) {
- //sampai disini dulu !!
- $this->__wsheet->getColumnDimension($this->__kolom+$i)->setWidth($this->__atabel[$i][1]);
- }
- $_fjudul = $this->__wbook->addFormat();
- $_fjudul->setBold();
- $_fjudul->setAlign("center");
- $_jkolom = count($this->__atabel);
- if ($_jkolom>0) $_jkolom--;
- foreach ($this->__aheader as $_key => $_val) {
- $this->__wsheet->write($this->__baris,$this->__kolom,$_val,$_fjudul);
- $this->__wsheet->setMerge($this->__baris,$this->__kolom,$this->__baris,$this->__kolom+$_jkolom);
- $this->__baris++;
- }
- $this->__baris++;
- if ($bw_header==true) $this->show_headers();
- }
-
- public function add_value() {
- $tmp_arr = func_get_args();
- if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
- $tmp_out = "";
- for ($i=0; $i__atabel); $i++) {
- $tmp_val = $tmp_arr[$i];
- if (is_array($this->__atabel[$i][1]) && trim($tmp_val)<>"") {
- $tmp_val = $this->__atabel[$i][1][$tmp_val];
- } else if (function_exists($this->__atabel[$i][1]) && trim($tmp_val)<>"") {
- $tmp_val = call_user_func($this->__atabel[$i][1], $tmp_val);
- }
- $tmp_out .= DELI_CSV . $tmp_val;
- }
- $tmp_out = substr($tmp_out, 1);
- $this->__avalue[] = $tmp_out;
- }
-
- public function send($tnama_file="File_Excel") {//oke
- $this->__wsheet->setActiveSheetIndex(0);
- header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
- header('Content-Disposition: attachment;filename="'.$tnama_file.'"');
- header('Cache-Control: max-age=0');
- $writer = IOFactory::createWriter($this->__wsheet, 'Xlsx');
- $writer->save('php://output');
- }
-
-}
-
-?>
diff --git a/src/Printer/PrintPOS.php b/src/Printer/PrintPOS.php
index 55a1f16..ec118ce 100644
--- a/src/Printer/PrintPOS.php
+++ b/src/Printer/PrintPOS.php
@@ -5,7 +5,7 @@
Module : /Printer/PrintPOS.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008.
- Last Modified : August 21st, 2026.
+ Last Modified : September 21st, 2026.
(c) 3FONIA Software; WWW.3FONIA.COM.
@@ -70,8 +70,9 @@ class PrintPOS {
}
public function set_header_logo(string $logo_file = ""): void {
- if (!empty($logo_file) && file_exists(PROJECT_ROOT."assets/images/".$logo_file)) {
- $this->_config['logo'] = PROJECT_BASE."assets/images/".$logo_file;
+ if (!empty($logo_file) && file_exists(PROJECT_ROOT."public/assets/images/".$logo_file)) {
+ //$this->_config['logo'] = PROJECT_BASE."assets/images/".$logo_file;
+ $this->_config['logo'] = base64_encode(file_get_contents(PROJECT_ROOT."public/assets/images/".$logo_file));
}
}
diff --git a/src/Web/Param.php b/src/Web/Param.php
index 63aea17..769d674 100644
--- a/src/Web/Param.php
+++ b/src/Web/Param.php
@@ -5,7 +5,7 @@
Module : /Web/Param.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : November 14th, 2013.
- Last Modified : August 22nd, 2026.
+ Last Modified : September 16th, 2026.
(c) 3FONIA Software; WWW.3FONIA.COM.
@@ -38,40 +38,50 @@ final class Param {
private static function __data(): void {
global $app;
if (empty($app)) $app = \Flight::app();
- //$_asumber = array_merge($app->request()->query->getData(), $app->request()->data->getData());
$_asumber = $app->request()->query->getData() + $app->request()->data->getData();
foreach ($_asumber as $__key => $__val) {
- self::$__ahasil[$__key] = is_string($__val) ? self::safeSQL($__val) : $__val;
+ if (in_array($__val, ['true','false'])) { $__val = ($__val === 'true'); }
+ else if (is_string($__val)) $__val = urldecode(self::safeSQL($__val));
+ self::$__ahasil[$__key] = $__val;
}
}
public static function safeSQL(string $str = ""): string {
- $_se = array("\\","\0","\n","\r","\x1a","'",'"');
- $_re = array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
+ $_se = ["\\","\0","\n","\r","\x1a","'",'"'];
+ $_re = ["\\\\","\\0","\\n","\\r","\Z","\'",'\"'];
return str_replace($_se, $_re, $str);
}
public static function Get(string $key = "", mixed $def = null): mixed {
- if (count(self::$__ahasil)==0) self::__data();
- if (isset(self::$__ahasil[$key]) && self::$__ahasil[$key]) return self::$__ahasil[$key];
+ if (empty(self::$__ahasil)) self::__data();
+ if (isset(self::$__ahasil[$key])) return self::$__ahasil[$key];
return $def;
}
- public static function Get_Text(string $key, mixed $def = null): mixed {
- if (count(self::$__ahasil)==0) self::__data();
- $_str = (isset(self::$__ahasil[$key])) ? self::$__ahasil[$key] : $def;
- $_str = str_replace("\\r", "", $_str);
- $_str = str_replace("\\n", " ", $_str);
- $_str = str_replace("\\t", " ", $_str);
- return (trim($_str));
+ public static function Int(string $key = "", int $def = 0): int {
+ if (empty(self::$__ahasil)) self::__data();
+ if (isset(self::$__ahasil[$key])) return (int) self::$__ahasil[$key];
+ return $def;
}
- public static function Get_Array(): array {
+ public static function Float(string $key = "", float $def = 0): float {
+ if (empty(self::$__ahasil)) self::__data();
+ if (isset(self::$__ahasil[$key])) return (float) self::$__ahasil[$key];
+ return $def;
+ }
+
+ public static function Get_All(): array {
if (count(self::$__ahasil)==0) self::__data();
return self::$__ahasil;
}
- public static function Get_ArrayCBOX() {//delete
+ //delete
+ public static function Get_Text(string $key, mixed $def = null): mixed {
+ return self::Get($key, $def);
+ }
+
+ //delete
+ public static function Get_ArrayCBOX() {
return [];
}
}
diff --git a/src/Web/Table.php b/src/Web/Table.php
index c62e8a0..8a520e8 100644
--- a/src/Web/Table.php
+++ b/src/Web/Table.php
@@ -5,7 +5,7 @@
Module : /Web/Table.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 16th, 2008.
- Last Modified : August 27th, 2026.
+ Last Modified : September 16th, 2026.
(c) 3FONIA Software; WWW.3FONIA.COM.
@@ -208,6 +208,11 @@ final class Table {
$tval = $row[$col['a']];
if (is_array($col['f'])) {
$tval = $col['f'][$tval];
+ } else if (!is_null($col['f']) && str_contains($col['f'], '::')) {
+ $tclass = explode("::", $col['f']);
+ if (class_exists($tclass[0]) && method_exists($tclass[0], $tclass[1])) {
+ $tval = call_user_func($col['f'], $tval);
+ }
} else if (!is_null($col['f']) && function_exists($col['f'])) {
$tval = call_user_func($col['f'], $tval);
} else if (is_string($tval)) {
@@ -291,6 +296,11 @@ final class Table {
$tval = $row[$col['a']];
if (is_array($col['f'])) {
$tval = $col['f'][$tval];
+ } else if (!is_null($col['f']) && str_contains($col['f'], '::')) {
+ $tclass = explode("::", $col['f']);
+ if (class_exists($tclass[0]) && method_exists($tclass[0], $tclass[1])) {
+ $tval = call_user_func($col['f'], $tval);
+ }
} else if (!is_null($col['f']) && function_exists($col['f'])) {
$tval = call_user_func($col['f'], $tval);
} else if (is_string($tval)) {