5 Commits
35 changed files with 905 additions and 641 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
[![Software License][ico-license]](LICENSE.md)
[![Total Downloads][ico-downloads]][link-downloads]
webapp adalah framework webbase aplikasi yang dibuat dengan basis kode PHP dan digabungkan dengan beberapa repo lain, sehingga menghasilkan webbase framework yang efisien dan efektif.
Webapp adalah framework webbase aplikasi yang dibuat dengan basis kode PHP dan digabungkan dengan beberapa repo lain, sehingga menghasilkan webbase framework yang efisien dan efektif.
Maintenance versi repo tambahan, akan dilakukan secara periodik dengan mempertimbangkan kesiapan infrastruktur framework secara utuh.
+12 -1
View File
@@ -6,7 +6,7 @@
Created Date : December 20th, 2007.
Last Modified : February 7th, 2026.
(c) 2009 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
@@ -493,3 +493,14 @@ input.double, input.integer, input.number {
background-color: #d8dbe0;
opacity: 1;
}
/** bashboard **/
.my-bashboard {
height: auto;
}
@media (min-width: 992px) {
.my-bashboard {
height: 500px;
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : October 7th, 2008.
Last Modified : November 24th, 2020.
(c) 2008 - 2020, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,12 +1,12 @@
/*******************************************************************
Module : /modules/js/export.js
Module : /assets/js/export.js
Desc. : Fungsi-fungsi export data & laporan
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 1st, 2011.
Last Modified : January 19th, 2026.
(c) 2011 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
+3 -4
View File
@@ -6,7 +6,7 @@
Created Date : June 19th, 2009.
Last Modified : February 10th, 2026.
(c) 2009 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
@@ -373,7 +373,7 @@ var FoniaJS = {
});
$('.option-tags').each((i, el) => {
const elm = $(el);
if (!jQuery.isFunction(jQuery.fn.select2)) return;
if (typeof jQuery.fn.select2 !== 'function') return;
var _opts = {tags: false, dropdownAutoWidth: true, width: 'auto', theme: 'bootstrap-5', language: 'id'};
var _dmodal = elm.closest('div.modal');
if (_dmodal.length) _opts.dropdownParent = _dmodal;
@@ -798,7 +798,7 @@ class _Request_JSONF extends _Request {
strBody += '</tbody>';
$(divData).append(strTab + strHead + strBody + strFoot + '</table>');
var opsi = { responsive: true, columnDefs: [{responsivePriority:1,targets:0},{responsivePriority:2,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)}} };
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 = {};
@@ -1009,7 +1009,6 @@ class _Request_JSONF extends _Request {
tr.addClass('dt-hasChild parent');
}
});
// disnini
}
var otabel = $('#'+ini.id+'Tabel').DataTable(opsi);
}
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : April 6th, 2015.
Last Modified : October 18th, 2020.
(c) 2015 - 2020, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
+1 -1
View File
@@ -5,7 +5,7 @@
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : October 12th, 2025.
(c) 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
+11 -11
View File
@@ -4,9 +4,9 @@
Desc. : JS Class Printer & Printer POS
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 27th, 2007.
Last Modified : December 26th, 2025.
Last Modified : August 21st, 2026.
(c) 2007 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
@@ -40,10 +40,10 @@ var cPRINTER = function(url, options){
type: 'POST',
url: vars.url,
data: (vars.data).join('&'),
success: function(txt){
success: (txt) => {
var $printData = $('#dataPrint');
if (!$printData.length) {
var $printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
$printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
}
$printData.html(txt);
window.print();
@@ -59,7 +59,7 @@ var cPRINTER = function(url, options){
type: 'POST',
url: vars.url,
data: (vars.data).join('&'),
success: function(txt){
success: (txt) => {
if ('' == txt) {
FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !');
return false;
@@ -72,17 +72,17 @@ var cPRINTER = function(url, options){
'<div class="modal-body print-body" id="divPrintP">'+txt+'</div>'+
'</div></div></div>';
if ($('#winAPPPrint')) $('#winAPPPrint').modal('dispose').remove();
$(_wtxt).on('shown.bs.modal', function(e){
$('#winAPPPrint').find('#tombCetak').click(function(){
$(_wtxt).on('shown.bs.modal', (e) => {
$('#winAPPPrint').find('#tombCetak').click(() => {
var $printData = $('#dataPrint');
if (!$printData.length) {
var $printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
$printData = $('<div/>', {id:'dataPrint','class':'d-none d-print-block print-body'}).appendTo('body');
}
$printData.html($('#divPrintP').html());
FoniaJS.closeWindow($('#winAPPPrint'));
window.print();
});
}).on('hidden.bs.modal', function(e){
}).on('hidden.bs.modal', (e) => {
$(this).remove();
}).modal('show');
},
@@ -165,14 +165,14 @@ var cPRINTERPOS = function(url, options) {
new Request.JSON({
url: url,
sendParam: params,
onSuccess: function(ajson) {
onSuccess: (ajson) => {
if (typeof ajson === "object") {
var hasil_cetak = (ajson.type == "escp") ? this.gen_escp(ajson) : this.gen_epl(ajson);
qz.print(qzcfg, hasil_cetak);
} else {
FoniaJS.showInfo('Error dalam proses Cetak.');
}
}.bind(this)
}
}).send();
};
this.gen_escp = function(adata) {
+36 -34
View File
@@ -1,19 +1,43 @@
/*******************************************************************
Module : /js/qz/qz-start.js
Desc. : JS Setup QZ Connection
Module : /assets/js/qz/qz-start.js
Desc. : Setup QZ Connection
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 27th, 2007.
Last Modified : February 8th, 2026.
Last Modified : August 22nd, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
const _divStatus = '#divQZStatus';
if (typeof qz !== 'undefined') {
qz.security.setSignatureAlgorithm("SHA512");
qz.security.setCertificatePromise((resolve, reject) => {
jQuery.ajax({url:'qz/cert', cache:false, dataType:'text'}).then(resolve, reject);
});
qz.security.setSignaturePromise((toSign) => {
return (resolve, reject) => {
jQuery.ajax('qz/sign/'+toSign).then(resolve, reject);
};
});
qz.websocket.setClosedCallbacks((evt) => {
_updateState('Inactive');
if (evt.reason) console.info("Connection closed: " + evt.reason);
});
qz.websocket.setErrorCallbacks((evt) => {
_updateState('Error');
if (evt.target != undefined) {
var err = (evt.target.readyState >= 2) ? "Connection to QZ Tray was closed" : "A connection error occurred, check log for details";
console.info(err)
}
});
}
function launchQZ() {
if (!qz.websocket.isActive()) {
window.location.assign("qz:launch");
//Retry 5 times, pausing 1 second between each attempt
startConnection({ retries: 5, delay: 1 });
}
}
@@ -22,10 +46,10 @@ function startConnection(config) {
config = config ? config : {};
if (!qz.websocket.isActive()) {
_updateState('Waiting');
qz.websocket.connect(config).then(() => {
qz.websocket.connect({...config, host: 'localhost'}).then(() => {
_updateState('Active');
_findDefaultPrinter();
});
}).catch(() => _updateState('Error'));
} else {
console.info('An active connection with QZ already exists.');
}
@@ -35,7 +59,7 @@ function endConnection(){
if (qz.websocket.isActive()) {
qz.websocket.disconnect().then(() => {
_updateState('Inactive');
});
}).catch(() => _updateState('Error'));
} else {
console.info('No active connection with QZ exists.');
}
@@ -64,30 +88,8 @@ function _updateState(text){
} else {
$(_divStatus).addClass('border-warning');
}
}
const _divStatus = '#divQZStatus';
if (typeof qz !== 'undefined') {
qz.security.setSignatureAlgorithm("SHA512");
qz.security.setCertificatePromise((resolve, reject) => {
jQuery.ajax({url:'qz/cert', cache:false, dataType:'text'}).then(resolve, reject);
});
qz.security.setSignaturePromise((toSign) => {
return (resolve, reject) => {
jQuery.ajax('qz/sign/'+toSign).then(resolve, reject);
};
});
qz.websocket.setClosedCallbacks((evt) => {
_updateState('Inactive');
if (evt.reason) console.info("Connection closed: " + evt.reason);
});
qz.websocket.setErrorCallbacks((evt) => {
_updateState('Error');
if (evt.target != undefined) {
var err = (evt.target.readyState >= 2) ? "Connection to QZ Tray was closed" : "A connection error occurred, check log for details";
console.info(err)
}
});
startConnection();
$('li#qzL, li#qzS, li#qzZ').removeClass('d-none');
if (text !== "Error") {
$('li#qzL').addClass('d-none');
} else $('li#qzS, li#qzZ').addClass('d-none');
}
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : May 27th, 2007.
Last Modified : January 19th, 2026.
(c) 2007 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : March 18th, 2021.
Last Modified : December 26th, 2025.
(c) 2021 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
+5 -2
View File
@@ -17,7 +17,9 @@
}
],
"require": {
"php" : "^8.3",
"php": ">=8.3",
"flightphp/core": "^3.18",
"flightphp/session": "^0.3",
"mpdf/mpdf": ">=8.0",
"matthiasmullie/minify": ">=1.3",
"endroid/qr-code": ">=4.4",
@@ -25,8 +27,9 @@
"shuchkin/simplexlsxgen": "^1.3"
},
"autoload": {
"classmap": ["src/"],
"psr-4": {
"siaupheng\\webapp\\": "src/"
"Webapp\\": "src/"
},
"files": [
"src/Function/Auth.php",
+33 -23
View File
@@ -3,34 +3,44 @@
/*******************************************************************
Module : /DB/CheckSQL.php
Desc. : Class Check SQL / Repair Database
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 11th, 2011.
Last Modified : August 13th, 2026.
Last Modified : August 21st, 2026.
(c) 2011 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\DB;
namespace Webapp\DB;
use Exception;
use flight\Engine;
use flight\Session;
use flight\database\SimplePdo;
use \Exception;
use \flight\Engine;
use \flight\database\SimplePdo;
/**
* Class CheckSQL
*
* Check Database Mysql/MariaDB dan Repair.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\DB
*/
final class CheckSQL {
private Array $__atabel = [];
protected Engine $app;
protected SimplePdo $db;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->app = $app;
$this->db = $app->db();
$nama_db = $this->db->fetchField('SELECT DATABASE()');
$arow = $this->db->fetchAll("SELECT TABLE_NAME,ENGINE,TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='".$nama_db."' AND TABLE_TYPE='BASE TABLE'");
foreach ($arow as $row) {
@@ -38,14 +48,14 @@ final class CheckSQL {
}
}
public function ignore_table() {
public function ignore_table(): void {
$tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$farray = array_filter($this->__atabel, fn($child) => !in_array($child[0], $tmp_arr));
$this->__atabel = array_values($farray);
}
private function _check_db(array $atabel=[]) {
private function _check_db(array $atabel=[]): string {
$pesan = '<span style="color:blue;">OK</span>';
$row = $this->db->runQuery('CHECK TABLE '.$atabel[0].' QUICK')->fetch(SimplePdo::FETCH_ASSOC);
if (($row['Msg_text'] ?? '') !== 'OK') {
@@ -57,24 +67,24 @@ final class CheckSQL {
$pesan .= ' -> Auto Repair <span style="color:red;">' . $e->getMessage() . '</span>';
}
}
return $atabel[0] . $atabel[3] ." ... ". $pesan ."<br>";
return $atabel[0] . $atabel[3] ." ... ". $pesan;
}
private function _opti_db(array $atabel=[]) {
private function _opti_db(array $atabel=[]): string {
$pesan = '<span style="color:orange;">SKIP</span>';
if ($atabel[1] === 'MyISAM') {
$pesan = '<span style="color:blue;">OK</span>';
$row = $this->db->runQuery('OPTIMIZE TABLE '.$atabel[0])->fetch(SimplePdo::FETCH_ASSOC);
if (!in_array(strtoupper($row['Msg_text'] ?? ''), ['OK','TABLE IS ALREADY UP TO DATE'])) $pesan = '<span style="color:red;">ERROR</span>';
}
return $atabel[0] . $atabel[2] ." ... ". $pesan ."<br>";
return $atabel[0] . $atabel[2] ." ... ". $pesan;
}
public function count_db() {
public function count_db(): int {
return count($this->__atabel);
}
public function check_db() {
public function check_db(): string {
$hasil = "=== CEK DATABASE ===<br>";
for ($n=0; $n<count($this->__atabel); $n++) {
$hasil .= $this->_check_db($this->__atabel[$n]);
@@ -82,11 +92,11 @@ final class CheckSQL {
return $hasil;
}
public function check_db_step($n) {
public function check_db_step(int $n): string {
return $this->_check_db($this->__atabel[$n]);
}
public function optimize_db() {
public function optimize_db(): string {
$hasil = "=== OPTIMALISASI DATABASE ===<br>";
for ($n=0;$n<count($this->__atabel);$n++) {
$hasil .= $this->_opti_db($this->__atabel[$n]);
@@ -94,7 +104,7 @@ final class CheckSQL {
return $hasil;
}
public function optimize_db_step($n) {
public function optimize_db_step(int $n): string {
return $this->_opti_db($this->__atabel[$n]);
}
}
+8 -7
View File
@@ -8,13 +8,14 @@
Created Date : May 11th, 2011.
Last Modified : May 8th, 2021.
(c) 2011 - 2021, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//todo: deprecated
declare(strict_types=1);
namespace siaupheng\webapp\DB;
namespace Webapp\DB;
final class DumpSQL {
private $__adata = array();
@@ -23,7 +24,7 @@ final class DumpSQL {
public function __construct($db = null){
if (is_resource($db)) { $this->__db = $db; }
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); }
else { $this->__db = new Webapp\DB\MySQL(); }
$this->__adata = $this->__db->getConfig();
}
@@ -55,7 +56,7 @@ final class DumpSQL {
public function create_backup($folder="backups") {
$namafile = date("Ymd").".gz";
$folder = $_SESSION['__WEB_APP']['REAL_PATH'].$folder."/".date("Y");
$folder = PROJECT_ROOT.$folder."/".date("Y");
if (!is_dir($folder)) mkdir($folder);
if (file_exists($folder."/".$namafile)) unlink($folder."/".$namafile);
$_cmd = "mysqldump -C --hex-blob -h ".$this->__adata['host']." -P ".$this->__adata['port']." -u ".$this->__adata['user']." -p".$this->__adata['pwd']." ".$this->__adata['db'];
@@ -96,8 +97,8 @@ final class DumpSQL {
}
public function disk_space() {
$_free = disk_free_space($_SESSION['__WEB_APP']['REAL_PATH']);
$_tot = disk_total_space($_SESSION['__WEB_APP']['REAL_PATH']);
$_free = disk_free_space(PROJECT_ROOT);
$_tot = disk_total_space(PROJECT_ROOT);
$_used = $_tot - $_free;
$_aret = array();
$_aret['TOTAL'] = $this->format_bytes($_tot);
@@ -109,7 +110,7 @@ final class DumpSQL {
}
public function update_list($folder="backups") {
$folder = $_SESSION['__WEB_APP']['REAL_PATH'].$folder;
$folder = PROJECT_ROOT.$folder;
$this->__db->Query("TRUNCATE TABLE app_backup");
$afile = $this->get_file_list($folder);
foreach($afile as $_key => $_val) {
+37 -19
View File
@@ -3,24 +3,33 @@
/*******************************************************************
Module : /DB/SQL.php
Desc. : Class Query database
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 2nd, 2007.
Last Modified : August 14th, 2026.
Last Modified : August 21st, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\DB;
namespace Webapp\DB;
use flight\Engine;
use flight\Session;
use flight\database\SimplePdo;
use siaupheng\webapp\Web\Param;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
use Webapp\Web\Param;
/**
* Class SQL
*
* Database CRUD dengan data dari GET/POST.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\DB
*/
final class SQL {
private string $_ttable;
@@ -28,13 +37,19 @@ final class SQL {
private array $_awhere = [];
protected Engine $app;
protected SimplePdo $db;
protected array webuser;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
/**
* @param Engine $app
*/
public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'UNIX'=>0]);
}
public function SafeSQL($ttext = "") {//delete
//todo: deprecated
public function SafeSQL($ttext = "") {
return $ttext;
}
@@ -43,17 +58,19 @@ final class SQL {
}
public function add_param(string $param = "", string|int|null $value = null, bool $nomor = false): void {
$req = Param::Get($param);
$this->_afield[] = [
'field' => $param,
'value' => (is_null($value) && !empty(Param::Get($param))) ? Param::Get($param) : $value,
'value' => (is_null($value) && !empty($req)) ? $req : $value,
'numbe' => $nomor,
];
}
public function add_param_date(string $param = "", string|null $value = null): void {
$req = Param::Get($param);
$this->_afield[] = [
'field' => $param,
'value' => tgl_sql2str((is_null($value) && !empty(Param::Get($param))) ? Param::Get($param) : $value),
'value' => tgl_sql2str((is_null($value) && !empty($req)) ? $req : $value),
'numbe' => false,
];
}
@@ -69,7 +86,7 @@ final class SQL {
public function add_param_unix(): void {
$this->_afield[] = [
'field' => 'Unix',
'value' => user_unix(),
'value' => $this->webuser['UNIX'],
'numbe' => false,
];
}
@@ -77,7 +94,7 @@ final class SQL {
public function add_param_userid(string $param = "UserID"): void {
$this->_afield[] = [
'field' => $param,
'value' => user_id(),
'value' => $this->webuser['UserID'],
'numbe' => false,
];
}
@@ -85,7 +102,7 @@ final class SQL {
public function add_where_unix(): void {
$this->_awhere[] = [
'field' => 'Unix',
'value' => user_id(),
'value' => $this->webuser['UNIX'],
'numbe' => false,
];
}
@@ -99,9 +116,10 @@ final class SQL {
}
public function add_where(string $field = "", string|int|null $value = null, bool $nomor = false): void {
$req = Param::Get($param);
$this->_awhere[] = [
'field' => $field,
'value' => (is_null($value) && !empty(Param::Get($field))) ? Param::Get($field) : $value,
'value' => (is_null($value) && !empty($req)) ? $req : $value,
'numbe' => $nomor,
];
}
+18 -8
View File
@@ -3,31 +3,41 @@
/*******************************************************************
Module : /Data/CSV.php
Desc. : Class pembuatan file CSV
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 2rd, 2011.
Last Modified : July 25th, 2026.
Last Modified : August 21st, 2026.
(c) 2011 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Data;
namespace Webapp\Data;
define( DELI_CSV, ";" );
define( CRLF_CSV, "\r\n" );
/**
* Class CSV
*
* Membuat file CSV.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Data
*/
final class CSV {
private $__avalue = [];
private $__atabel = [];
public function add_field($tnama="", $ffunc="") {
$this->__atabel[] = [$tnama, $ffunc];
public function add_field(string $nama, string $func=""): void {
$this->__atabel[] = [ $nama, $func ];
}
public function add_value() {
public function add_value(): void {
$tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = "";
@@ -44,7 +54,7 @@ final class CSV {
$this->__avalue[] = $tmp_out;
}
public function download($nama_file="export.csv") {
public function download(string $nama_file="export.csv"): void {
$out = ""; $tmp_out = "";
// add header
for ($i=0; $i<count($this->__atabel); $i++) {
+48 -28
View File
@@ -3,24 +3,34 @@
/*******************************************************************
Module : /Data/Cache.php
Desc. : Class cache css dan js aplikasi
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : March 16th, 2008.
Last Modified : August 19th, 2026.
Last Modified : August 21st, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Data;
namespace Webapp\Data;
use flight\Engine;
use FilesystemIterator;
use MatthiasMullie\Minify;
use SplFileInfo;
use \flight\Engine;
use \flight\Session;
use \FilesystemIterator;
use \MatthiasMullie\Minify;
use \SplFileInfo;
/**
* Class Cache
*
* Membuat Cache gabungan CSS dan JS sesuai dengan session.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Data
*/
final class Cache {
private $__cachedir = "";
@@ -31,15 +41,20 @@ final class Cache {
private $__rootdir = "";
private $__ini = [];
protected Engine $app;
protected Session $session;
protected array $__asset = [];
public function __construct(?Engine $app = null, array $asset = []) {
$this->app = (empty($app) === true) ? Flight::app() : $app;
$this->__asset = $asset;
$rootdir = (defined('PROJECT_ROOT')) ? PROJECT_ROOT : $this->app->get('flight.root_dir');
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->app = $app;
$this->session = $app->session();
$rootdir = (defined('PROJECT_ROOT')) ? PROJECT_ROOT : $this->app->get('app.project_root');
$this->__cachedir = $rootdir . '/public/chunks/';
$this->__localedir = $rootdir . '/app/locale/';
$this->__jsapp = $rootdir . '/app/scripts/';
$this->__localedir = $rootdir . '/app/Scripts/locale/';
$this->__jsapp = $rootdir . '/app/Scripts/';
$this->__cssdir = __DIR__ . '/../../assets/css/';
$this->__jsdir = __DIR__ . '/../../assets/js/';
$this->__rootdir = $rootdir . '/';
@@ -54,7 +69,11 @@ final class Cache {
} else $this->__ini = parse_ini_file($this->__cachedir . "cache.ini", true);
}
private function gen_file($mode = "index", $type = "css") {
public function set_asset(array $asset = []): void {
$this->__asset = $asset;
}
private function gen_file(string $mode = "index", string $type = "css"): array {
$itime = 0;
$afile = [];
if ($type == "css") {
@@ -65,8 +84,8 @@ final class Cache {
$afile[] = $_file->getRealPath();
$itime += $_file->getMTime();
}
if (is_dir($this->__rootdir . 'app/css/')) {
$iterator = new FilesystemIterator($this->__rootdir . 'app/css/', FilesystemIterator::SKIP_DOTS);
if (is_dir($this->__rootdir . 'app/Styles/')) {
$iterator = new FilesystemIterator($this->__rootdir . 'app/Styles/', FilesystemIterator::SKIP_DOTS);
foreach ($iterator as $_file) {
if ($_file->isFile()) {
$afile[] = $_file->getRealPath();
@@ -83,7 +102,7 @@ final class Cache {
$itime += $_file->getMTime();
}
// add locale file
$ljs = ($this->app->session()->get('__WEB_USER')['LOCALE'] ?? $this->app->session()->get('__WEB_APP')['DEF_LOCALE']).'.js';
$ljs = ($this->session->get('__WEB_USER')['LOCALE'] ?? $this->session->get('__WEB_APP')['DEF_LOCALE']).'.js';
if (is_dir($this->__localedir)) {
$iterator = new \FilesystemIterator($this->__localedir, \FilesystemIterator::SKIP_DOTS);
foreach ($iterator as $_file) {
@@ -97,7 +116,8 @@ final class Cache {
if ($mode === 'index') {
if (is_dir($this->__jsapp)) {
$dirIterator = new \RecursiveDirectoryIterator($this->__jsapp, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($dirIterator);
$dirFilter = new \RecursiveCallbackFilterIterator($dirIterator, fn($curr, $key, $iter) => !($curr->isDir() && in_array($curr->getFilename(), ['locale'])));
$iterator = new \RecursiveIteratorIterator($dirFilter);
foreach ($iterator as $_file) {
if ($_file->isFile() && !in_array($_file->getFilename(), ['login.js','display.js'])) {
$afile[] = $_file->getRealPath();
@@ -116,7 +136,7 @@ final class Cache {
return [ $afile, $itime ];
}
private function create_cache($type = "css", $afile = [], $cachefile = "") {
private function create_cache(string $type = "css", array $afile = [], string $cachefile = ""): void {
$contents = ''; $smini = null;
$bpublic = ($this->app->request()->ip === '127.0.0.1') ? false : true;
if ($bpublic == true) {
@@ -139,7 +159,7 @@ final class Cache {
file_put_contents($this->__cachedir . $cachefile, $contents);
}
private function save_ini() {
private function save_ini(): void {
$content = "";
foreach ($this->__ini as $key => $elem) {
$content .= ($content==""?"":"\n"). "[".$key."]\n";
@@ -151,7 +171,7 @@ final class Cache {
file_put_contents($this->__cachedir . "cache.ini", $content);
}
public function Cache($mode = "index") {
public function Cache(string $mode = "index"): array {
$is_modif = false;
foreach (['css','js','app'] as $type) {
[ $afile, $lastmod ] = $this->gen_file($mode, $type);
@@ -174,17 +194,17 @@ final class Cache {
}
}
$session = $this->app->session();
$aoption = $session->get('__WEB_APP');
$auser = $session->get('__WEB_USER');
$aoption = $this->session->get('__WEB_APP');
$auser = $this->session->get('__WEB_USER');
$nonce = $this->app->get('csp_nonce');
$islog = user_logged($this->session);
$_secret = $aoption['APP_CODE'] .";". $aoption['APP_SID'] .";". $this->app->request()->getVar('HTTP_HOST') .";". "http://".$this->app->request()->getVar('HTTP_HOST') .";". isMobile() .";". ($aoption['AUTH_LEVEL']?$aoption['AUTH_LEVEL']:0);
$_suser = (user_logged()) ? $auser['Username'] .";". $auser['UserID'] .";". $auser['Grup_MenuID'] .";". $auser['Level'] : "nobody;999;999;9";
$_suser = ($islog) ? $auser['Username'] .";". $auser['UserID'] .";". $auser['Grup_MenuID'] .";". $auser['Level'] : "nobody;999;999;9";
$acache['JSX'][] = '<script nonce="'.$nonce.'" type="text/javascript">';
$acache['JSX'][] = 'FoniaJS.setConfig("'.base64_encode($_secret).'", "'.base64_encode($_suser).'");';
$acache['JSX'][] = '$(document).ready(function(){';
if (user_logged()) $acache['JSX'][] = 'FoniaJS.loadMenu();';
if ($islog) $acache['JSX'][] = 'FoniaJS.loadMenu();';
$acache['JSX'][] = '});';
$acache['JSX'][] = '</script>';
+54 -35
View File
@@ -3,35 +3,54 @@
/*******************************************************************
Module : /Data/PDF.php
Desc. : Class pembuatan file PDF
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 18th, 2015.
Last Modified : July 25th, 2026.
Last Modified : August 21st, 2026.
(c) 2015 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Data;
namespace Webapp\Data;
use Mpdf;
use \flight\Engine;
use \Mpdf;
/**
* Class PDF
*
* Membuat file PDF.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Data
*/
final class PDF {
private $__avalue = [];
private $__atabel = [];
private $__theader = "";
private $__tcolname = "";
protected array $webapp;
protected array $webuser;
public function __construct() {
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->webapp = $app->session()->get('__WEB_APP', ['REG_NAME'=>'', 'APP_NAME'=>'', 'APP_VER'=>'']);
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'Username'=>'']);
}
public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="", $nkol=1) {
$this->__atabel[] = array($tnama, $nlebar.'%', $ffunc, $talign, $nkol);
public function add_field(string $nama, string|int $lebar=0, string $align="L", string $func="", int $kol=1): void {
$this->__atabel[] = [ $nama, (string)$lebar.'%', $func, $align, $kol ];
}
public function show_fields() {
public function show_fields(): void {
$tmp_out = "<thead><tr>";
for ($i=0; $i<count($this->__atabel); $i++) {
if ($this->__atabel[$i][4]==0) continue;
@@ -41,21 +60,21 @@ final class PDF {
$this->__tcolname = $tmp_out;
}
public function clear() {
public function clear(): void {
$this->__avalue = [];
$this->__theader = "";
$this->__tcolname = "";
}
public function set_header($tlapor="", $tperiod="") {
$thasil = '<div style="text-align:center;font-size:12pt;"><b>'.strtoupper($_SESSION['__WEB_APP']['REG_NAME']);
$thasil .= (($tlapor=="") ? "" : '<br>'.$tlapor) . '</b>';
$thasil .= ($tperiod=="") ? "" : '<br><span style="font-size:11pt;">'.$tperiod.'</span>';
public function set_header(string $lapor, string $period): void {
$thasil = '<div style="text-align:center;font-size:12pt;"><b>'.strtoupper($this->webapp['REG_NAME']);
$thasil .= (($lapor=="") ? "" : '<br>'.$lapor) . '</b>';
$thasil .= ($period=="") ? "" : '<br><span style="font-size:11pt;">'.$period.'</span>';
$thasil .= '</div><br>';
$this->__theader = $thasil;
}
public function add_value() {
public function add_value(): void {
$tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = "<tr>";
@@ -73,7 +92,7 @@ final class PDF {
$this->__avalue[] = $tmp_out;
}
public function add_span() {
public function add_span(): void {
$tmp_arr = func_get_args();
$tmp_out = "<tr>";
for ($i=0; $i<count($tmp_arr); $i++) {
@@ -88,19 +107,19 @@ final class PDF {
$this->__avalue[] = $tmp_out;
}
public function add_empty() {
public function add_empty(): void {
$this->__avalue[] = $this->set_align("&nbsp;", 0, "L,NB", true);
}
public function add_stamp($ctk_ke=1, $bnama=false) {
$this->__avalue[] = $this->set_align($_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):""), 0, "L,NB", true);
public function add_stamp(int $ctk_ke=1, bool $tampil_nama=false): void {
$this->__avalue[] = $this->set_align($this->get_stamp($ctk_ke, $tampil_nama), 0, "L,NB", true);
}
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 get_stamp(int $ctk_ke=1, bool $tampil_nama=false): string {
return $this->webapp['APP_NAME']."v".$this->webapp['APP_VER'].date("\@ymd.His")."-".isi_nol($this->webuser['UserID'], 3).(($tampil_nama)?"/".strtoupper($this->webuser['Username']):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):"");
}
public function createPDF($nama_file = "Nama_File.pdf", $nfontz = 8, $orien = "P") {
public function createPDF(string $nama_file = "Nama_File.pdf", int $fontz = 8, string $orien = "P"): void {
$html = '
<style>
#pdf_area {
@@ -148,33 +167,33 @@ final class PDF {
$html .= $this->__avalue[$i];
}
$html .= '</tbody></table></div></div></body>';
$mpdf = new mPDF('c', 'A4'.($orien=="L"?"-L":""), $nfontz, '', 5, 5, 5, 10, 5, 5);
$mpdf = new mPDF('c', 'A4'.($orien==="L"?"-L":""), $fontz, '', 5, 5, 5, 10, 5, 5);
$mpdf->useSubstitutions = false;
$mpdf->WriteHTML($html);
$mpdf->Output($nama_file.".pdf", "I");
}
public function set_align($ttext, $nlen, $tdir="L", $bline=false, $bhead=false, $ncol=1) {
$tstyle = $this->create_style($tdir);
if (strpos(strtolower($ttext), "<tr>")===false) { //jika tidak ada <tr> up 2011-04-14
if ($bline===true) {
return '<tr><td colspan="'.count($this->__atabel).'" class="'.$tstyle.'">'.$ttext."</td></tr>";
public function set_align(string $text, string|int $width, string $dir="L", bool $line=false, bool $head=false, int $col=1): string {
$tstyle = $this->create_style($dir);
if (strpos(strtolower($text), "<tr>")===false) {
if ($line===true) {
return '<tr><td colspan="'.count($this->__atabel).'" class="'.$tstyle.'">'.$text."</td></tr>";
} else {
return (($bhead===true)?"<th":"<td").(($ncol>1)?' colspan="'.$ncol.'"':"").' class="'.$tstyle.'" '.(($bhead===true)?'width="'.$nlen.'"':"").">".$ttext.(($bhead===true)?"</th>":"</td>");
return (($head===true)?"<th":"<td").(($col>1)?' colspan="'.(string)$col.'"':"").' class="'.$tstyle.'" '.(($head===true)?'width="'.(string)$width.'"':"").">".$text.(($head===true)?"</th>":"</td>");
}
} else {
return (($bline===true) ? $ttext : (($bhead===true)?"<th":"<td").(($ncol>1)?" colspan=\"".$ncol."\"":"")." class=\"".$tstyle." \" ".(($bhead===true)?"width=\"".$nlen."\"":"").">".$ttext.(($bhead===true)?"</th>":"</td>"));
return (($line===true) ? $text : (($head===true)?"<th":"<td").(($col>1)?" colspan=\"".(string)$col."\"":"")." class=\"".$tstyle." \" ".(($head===true)?"width=\"".(string)$width."\"":"").">".$text.(($head===true)?"</th>":"</td>"));
}
}
private function create_style($tstyle="L") {
private function create_style(string $style="L"): string {
$apad = ["L"=>"left", "R"=>"right", "C"=>"center", "NB"=>"nb", "NL"=>"noleft", "NR"=>"noright", "B"=>"bold", "I"=>"italic"];
$_astyle = explode(",", $tstyle);
$thasil = "";
$_astyle = explode(",", $style);
$ahasil = [];
foreach ($_astyle as $_key => $_val) {
$thasil .= " ".$apad[$_val];
$ahasil[] = $apad[$_val];
}
return substr($thasil,1);
return implode(' ', $ahasil);
}
}
+3 -2
View File
@@ -8,13 +8,14 @@
Created Date : November 18th, 2012.
Last Modified : September 30th, 2025.
(c) 2012 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//todo: deprecated
declare(strict_types=1);
namespace siaupheng\webapp\Data;
namespace Webapp\Data;
final class SimpleXLS {
private $__wbook = null;
+3 -2
View File
@@ -8,13 +8,14 @@
Created Date : November 18th, 2012.
Last Modified : October 26th, 2023.
(c) 2012 - 2023, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//todo: deprecated
declare(strict_types=1);
namespace siaupheng\webapp\Data;
namespace Webapp\Data;
use PhpOffice\PhpSpreadsheet\IOFactory;
+19 -19
View File
@@ -8,56 +8,56 @@
Created Date : January 27th, 2008.
Last Modified : January 21st, 2024.
(c) 2008 - 2024, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
use \flight\Session;
if (!function_exists('user_level')) {
function user_level($level = 9) {
if (Flight::session()->get('__WEB_USER', ['Level'=>9]) <= $level) return true;
function user_level(Session $session, int $level = 9): bool {
if ($session->get('__WEB_USER', ['Level'=>9])['Level'] <= $level) return true;
return false;
}
}
if (!function_exists('user_level_not')) {
function user_level_not($level = 9) {
if (Flight::session()->get('__WEB_USER', ['Level'=>9]) !== $level) return true;
function user_level_not(Session $session, int $level = 9): bool {
if ($session->get('__WEB_USER', ['Level'=>9])['Level'] !== $level) return true;
return false;
}
}
if (!function_exists('user_logged')) {
function user_logged() {
return !empty(Flight::session()->get('__WEB_USER'));
function user_logged(Session $session): bool {
return !empty($session->get('__WEB_USER'));
}
}
if (!function_exists('user_id')) {
function user_id($idigit = 0) {
if ($idigit > 0) return isi_nol((int)Flight::session()->get('__WEB_USER', ['UserID'=>0])['UserID'], $idigit);
return (int)Flight::session()->get('__WEB_USER', ['UserID'=>0])['UserID'];
function user_id(Session $session, int $digit = 0): string|int {
$id_user = (int)$session->get('__WEB_USER', ['UserID'=>0])['UserID'];
if ($digit > 0) return isi_nol($id_user, $digit);
return $id_user;
}
}
if (!function_exists('user_user')) {
function user_user() {
return (string)Flight::session()->get('__WEB_USER', ['Username'=>''])['Username'];
function user_user(Session $session): string {
return (string)$session->get('__WEB_USER', ['Username'=>''])['Username'];
}
}
if (!function_exists('user_unix')) {
function user_unix() {
return (string)Flight::session()->get('__WEB_USER', ['UNIX'=>'0'])['UNIX'];
function user_unix(Session $session): string {
return (string)$session->get('__WEB_USER', ['UNIX'=>'0'])['UNIX'];
}
}
if (!function_exists('user_nama')) {
function user_nama() {
return (string)Flight::session()->get('__WEB_USER', ['Nama'=>''])['Nama'];
function user_nama(Session $session): string {
return (string)$session->get('__WEB_USER', ['Nama'=>''])['Nama'];
}
}
?>
+85 -83
View File
@@ -6,9 +6,9 @@
Desc. : Fungsi Custom Lain Lain
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 27th, 2008.
Last Modified : December 26th, 2025.
Last Modified : August 21st, 2026.
(c) 2008 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
@@ -16,97 +16,99 @@ declare(strict_types=1);
/*************************** FORMAT ANGKA / CURRENCY *****************************/
if (!function_exists('rupiah')) {//oke
function rupiah(string|float $angka = 0, int $desi = 0) {
if (!function_exists('rupiah')) {
function rupiah(mixed $angka = 0, int $desi = 0): string {
return number_format((float) $angka, $desi, ",", ".");
}
}
if (!function_exists('rupiah2')) {
function rupiah2($angka = 0) {
function rupiah2(mixed $angka = 0): string {
return rupiah($angka, 2);
}
}
/* todo: deprecated
if (!function_exists('rupiah30')) {
function rupiah30($angka = 0) {
function rupiah30($angka = 0): string {
$nilai = explode(".", $angka);
$hasil = (intval($nilai[1])==0) ? rupiah($angka, 0) : rupiah($angka, 3);
return $hasil;
}
}
}*/
if (!function_exists('kurung_rup')) {
function kurung_rup($angka = 0, $desi = 0) {
$thasil = rupiah(abs($angka), $desi);
if ($angka<0) return "(".$thasil.")";
function kurung_rup(mixed $angka = 0, int $desi = 0): string {
$thasil = rupiah(abs((float) $angka), $desi);
if ((float) $angka < 0) return "(".$thasil.")";
return $thasil." ";
}
}
if (!function_exists('kurung')) {
function kurung($angka = 0, $desi = 0) {
$thasil = uang(abs($angka), $desi);
if ($angka<0) return "(".$thasil.")";
function kurung(mixed $angka = 0, int $desi = 0): string {
$thasil = uang(abs((float) $angka), $desi);
if ((float) $angka < 0) return "(".$thasil.")";
return $thasil." ";
}
}
if (!function_exists('kurung2')) {
function kurung2($angka = 0) {
function kurung2(mixed $angka = 0): string {
return kurung($angka, 2);
}
}
if (!function_exists('uang')) {//oke
function uang(string|float $angka = '0', int $desi = 0) {
if (!function_exists('uang')) {
function uang(mixed $angka = 0, int $desi = 0): string {
$angka = str_replace(",", "", (string) $angka);
return number_format((float) $angka, $desi);
}
}
if (!function_exists('uang2')) {
function uang2($angka = 0) {
function uang2(mixed $angka = 0): string {
return uang($angka, 2);
}
}
/* todo: deprecated
if (!function_exists('koma30')) {
function koma30($angka = 0) {
$nilai = explode(".", $angka);
$hasil = (intval($nilai[1])==0) ? uang($angka, 0) : uang($angka, 3);
return $hasil;
}
}
}*/
if (!function_exists('items')) {
function items($item = 0) {
function items(mixed $item = 0): string {
return rupiah($item)." Items";
}
}
if (!function_exists('records')) {
function records($item = 0) {
function records(mixed $item = 0): string {
return rupiah($item)." Records";
}
}
if (!function_exists('baris')) {
function baris($item = 0) {
function baris(mixed $item = 0): string {
return rupiah($item)." Baris";
}
}
if (!function_exists('npwp')) {
function npwp($nomor = "000000000000000") {
function npwp(string $nomor = "000000000000000"): string {
return substr($nomor,0,2).".".substr($nomor,2,3).".".substr($nomor,5,3).".".substr($nomor,8,1)."-".substr($nomor,9,3).".".substr($nomor,12,3);
}
}
if (!function_exists('romawi')) {
function romawi($n) {
function romawi(int $n): string {
$hasil = "";
$iromawi = array("","I","II","III","IV","V","VI","VII","VIII","IX","X",20=>"XX",30=>"XXX",40=>"XL",50=>"L",60=>"LX",70=>"LXX",80=>"LXXX",90=>"XC",100=>"C",200=>"CC",300=>"CCC",400=>"CD",500=>"D",600=>"DC",700=>"DCC",800=>"DCCC",900=>"CM",1000=>"M",2000=>"MM",3000=>"MMM");
$iromawi = ["","I","II","III","IV","V","VI","VII","VIII","IX","X",20=>"XX",30=>"XXX",40=>"XL",50=>"L",60=>"LX",70=>"LXX",80=>"LXXX",90=>"XC",100=>"C",200=>"CC",300=>"CCC",400=>"CD",500=>"D",600=>"DC",700=>"DCC",800=>"DCCC",900=>"CM",1000=>"M",2000=>"MM",3000=>"MMM"];
if (array_key_exists($n, $iromawi)) {
$hasil = $iromawi[$n];
} else if ($n >= 11 && $n <= 99) {
@@ -124,7 +126,7 @@ if (!function_exists('romawi')) {
}
if (!function_exists('abjad')) {
function abjad($n) {
function abjad(int $n): string {
$_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return substr($_str, ($n-1), 1);
}
@@ -133,8 +135,8 @@ if (!function_exists('abjad')) {
/*************************** FORM CONTROL *****************************/
if (!function_exists('checkbox')) {
function checkbox($nilai = 0) {
$thasil = ((is_string($nilai) && ($nilai=="N" || $nilai=="0")) or (is_numeric($nilai) && $nilai==0) or (is_bool($nilai) && $nilai==false)) ? "circle text-secondary" : "check-circle text-info";
function checkbox(mixed $nilai): string {
$thasil = (empty($nilai) or (is_string($nilai) && ($nilai=="N" || $nilai=="0")) or (is_numeric($nilai) && $nilai==0) or (is_bool($nilai) && $nilai==false)) ? "circle text-secondary" : "check-circle text-info";
return '<i class="fs-6 bi-'.$thasil.'"></i>';
}
}
@@ -142,32 +144,32 @@ if (!function_exists('checkbox')) {
/*************************** FORMAT TANGGAL / KALENDER *****************************/
if (!function_exists('sqltgl')) {
function sqltgl($waktu = "0") {
function sqltgl(string $waktu): string {
return tgl_sql2str($waktu);
}
}
if (!function_exists('sqltgls')) {
function sqltgls($waktu = "0") {
function sqltgls(string $waktu): string {
return tgl_sql2str($waktu, false, true);
}
}
if (!function_exists('sqljam')) {
function sqljam($waktu = "0") {
function sqljam(string $waktu): string {
return tgl_sql2str($waktu, true);
}
}
if (!function_exists('sqljams')) {
function sqljams($waktu = "0") {
function sqljams(string $waktu): string {
return tgl_sql2str($waktu, true, true);
}
}
if (!function_exists('tgl_sql2str')) {
function tgl_sql2str($waktu = "0", $jam = false, $short = false) {
if ($waktu=="0" || $waktu=="") return;
function tgl_sql2str(string $waktu, bool $jam = false, bool $short = false): string {
if (empty($waktu)) return '';
$atgl = explode(" ", $waktu);
$sjam = ($jam) ? ((empty($atgl[1])) ? date("H:i:s") : $atgl[1]) : "";
$atgl = explode("-", $atgl[0]);
@@ -178,66 +180,66 @@ if (!function_exists('tgl_sql2str')) {
}
if (!function_exists('tgl_ymd')) {
function tgl_ymd($jam = false) {
function tgl_ymd(bool $jam = false): string {
return (($jam) ? date("Y-m-d H:i:s") : date("Y-m-d"));
}
}
if (!function_exists('tgl_dmy')) {
function tgl_dmy($jam = false) {
function tgl_dmy(bool $jam = false): string {
return (($jam) ? date("d-m-Y H:i:s") : date("d-m-Y"));
}
}
if (!function_exists('tgl_operasi')) {
function tgl_operasi($dtgl = "", $nhari = 0, $nbln = 0, $nthn = 0) {
$atgl = explode("-", $dtgl);
return date("d-m-Y", mktime(0,0,0, $atgl[1]+$nbln, $atgl[0]+$nhari, $atgl[2]+$nthn));
function tgl_operasi(string $tgl, int $hari = 0, int $bln = 0, int $thn = 0): string {
$atgl = explode("-", $tgl);
return date("d-m-Y", mktime(0,0,0, (int) $atgl[1]+$bln, (int) $atgl[0]+$hari, (int) $atgl[2]+$thn));
}
}
if (!function_exists('tgl_range_hari')) {
function tgl_range_hari($dftgl="", $dttgl="", $bhitung_awal=false) {
$_start = strtotime(tgl_sql2str($dftgl));
$_end = strtotime(tgl_sql2str($dttgl));
return ceil(abs($_end - $_start) / 86400) + (($bhitung_awal==true)?1:0);
function tgl_range_hari(string $tgl_from, string $tgl_to, bool $hitung_awal = false): float {
if (empty($tgl_to) or empty($tgl_from)) return 0;
$_start = strtotime(tgl_sql2str($tgl_from));
$_end = strtotime(tgl_sql2str($tgl_to));
return ceil(abs($_end - $_start) / 86400) + (($hitung_awal)?1:0);
}
}
if (!function_exists('tgl_akhbln')) {
function tgl_akhbln($tgl) {
function tgl_akhbln(string $tgl): string {
if (empty($tgl)) return '';
$atgl = explode("-", $tgl);
$ablna = array(31,28,31,30,31,30,31,31,30,31,30,31);
$ablna = ['31','28','31','30','31','30','31','31','30','31','30','31'];
// jika tahun masehi dan bulan 2
if ( (round($atgl[2]/4)==($atgl[2]/4)) && intval($atgl[1])==2 ) return "29-02-".$atgl[2];
return $ablna[(intval($atgl[1])-1)]."-".isi_nol($atgl[1],2)."-".$atgl[2];
if ((round((int) $atgl[2]/4) === ((int) $atgl[2]/4)) && (int) $atgl[1] === 2) return "29-02-".$atgl[2];
return $ablna[(int) $atgl[1]-1]."-".isi_nol($atgl[1],2)."-".$atgl[2];
}
}
if (!function_exists('tgl_panjang')) {
function tgl_panjang($dtgl = "") {
if (trim($dtgl)=="") $dtgl = tgl_dmy();
$atgl = explode("-", $dtgl);
function tgl_panjang(string $tgl): string {
if (empty($tgl)) $tgl = tgl_dmy();
$atgl = explode("-", $tgl);
$abulan = bulan_array();
return $atgl[0]." ".$abulan[intval($atgl[1])]." ".$atgl[2];
return $atgl[0]." ".$abulan[$atgl[1]]." ".$atgl[2];
}
}
if (!function_exists('tgl_hari')) {
function tgl_hari($dtgl = "") {
function tgl_hari(string $tgl): string {
$nhari = date("w");
if (trim($dtgl)!="") {
//$atgl = getdate($dtgl);
//$nhari = $atgl[wday];
$nhari = date("w", strtotime(tgl_sql2str($dtgl)));
if (!empty($tgl)) {
$nhari = date("w", strtotime(tgl_sql2str($tgl)));
}
$ahari = array("0"=>"Minggu","1"=>"Senin","2"=>"Selasa","3"=>"Rabu","4"=>"Kamis","5"=>"Jum'at","6"=>"Sabtu");
$ahari = ["0"=>"Minggu","1"=>"Senin","2"=>"Selasa","3"=>"Rabu","4"=>"Kamis","5"=>"Jum'at","6"=>"Sabtu"];
return $ahari[$nhari];
}
}
if (!function_exists('tgl_triwulan')) {
function tgl_triwulan($dtgl = "") {
if ($dtgl == "") {
function tgl_triwulan(string $tgl): int {
if (empty($tgl)) {
$dtgl = date("m");
} else {
$atgl = explode("-", $tgl);
@@ -253,13 +255,13 @@ if (!function_exists('tgl_triwulan')) {
}
if (!function_exists('bulan_array')) {
function bulan_array() {
return array("1"=>"Januari","2"=>"Februari","3"=>"Maret","4"=>"April","5"=>"Mei","6"=>"Juni","7"=>"Juli","8"=>"Agustus","9"=>"September","10"=>"Oktober","11"=>"November","12"=>"Desember");
function bulan_array(): array {
return ["1"=>"Januari","2"=>"Februari","3"=>"Maret","4"=>"April","5"=>"Mei","6"=>"Juni","7"=>"Juli","8"=>"Agustus","9"=>"September","10"=>"Oktober","11"=>"November","12"=>"Desember"];
}
}
if (!function_exists('triwulan_array')) {
function triwulan_array() {
function triwulan_array(): array {
return ["1"=>"Triwulan 1","2"=>"Triwulan 2","3"=>"Triwulan 3","4"=>"Triwulan 4"];
}
}
@@ -267,32 +269,33 @@ if (!function_exists('triwulan_array')) {
/*************************** FORMAT TAMPILAN & ERROR *****************************/
if (!function_exists('subjudul')) {
function subjudul($tjudul) {
return '<table border="0" align="center" valign="middle" width="100%" height="26px"><tr><td width="50%"><hr /></td><td>&nbsp;&nbsp;<span style="text-align:center;font-weight:bold;white-space:nowrap;">'.$tjudul.'</span>&nbsp;&nbsp;</td><td width="50%"><hr /></td></tr></table>';
function subjudul(string $judul): string {
return '<table border="0" align="center" valign="middle" width="100%" height="26px"><tr><td width="50%"><hr /></td><td>&nbsp;&nbsp;<span style="text-align:center;font-weight:bold;white-space:nowrap;">'.$judul.'</span>&nbsp;&nbsp;</td><td width="50%"><hr /></td></tr></table>';
}
}
/* todo: deprecated
if (!function_exists('showerror')) {
function showerror($terror) {
echo '<input type="hidden" id="_Error" class="error" value="'.$terror.'!" />';
}
function showerror(string $error): void {
echo '<input type="hidden" id="_Error" class="error" value="'.$error.'!" />';
}
}*/
if (!function_exists('br2nl')) {
function br2nl($string) {
function br2nl(string $string): string {
return preg_replace('/\<br(\s*)?\/?\>/i', "\n\r", $string);
}
}
if (!function_exists('isi_nol')) {
function isi_nol($nilai = "0", $panjang = 1) {
$nilai = strval($nilai);
function isi_nol(string|int $nilai = 0, int $panjang = 1): string {
$nilai = (string)$nilai;
return ($panjang>strlen($nilai) ? str_repeat("0", $panjang-strlen($nilai)):'').$nilai;
}
}
if (!function_exists('isMobile')) {
function isMobile() {
function isMobile(): bool {
$agen = $_SERVER['HTTP_USER_AGENT'];
$amobile = ['Android', 'webOS', 'iPhone', 'iPad', 'iPod', 'BlackBerry', 'Windows Phone', 'Mobile'];
foreach ($amobile as $keyword) {
@@ -303,7 +306,7 @@ if (!function_exists('isMobile')) {
}
if (!function_exists('isLinux')) {
function isLinux() {
function isLinux(): bool {
$agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen, 'linux') !== false) return true;
return false;
@@ -311,7 +314,7 @@ if (!function_exists('isLinux')) {
}
if (!function_exists('isIE')) {
function isIE() {
function isIE(): bool {
$agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen, 'msie') !== false) return true;
return false;
@@ -319,7 +322,7 @@ if (!function_exists('isIE')) {
}
if (!function_exists('isChrome')) {
function isChrome() {
function isChrome(): bool {
$agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen, 'chrome') !== false) return true;
return false;
@@ -327,22 +330,23 @@ if (!function_exists('isChrome')) {
}
if (!function_exists('isFirefox')) {
function isFirefox() {
function isFirefox(): bool {
$agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen, 'firefox') !== false) return true;
return false;
}
}
/* todo: deprecated
if (!function_exists('potong')) {
function potong($nilai) {//utk rkpd
return substr($nilai, 0, 60);
}
}
}*/
if (!function_exists('format_bytes')) {
function format_bytes($bytes) {
if ($bytes < 1024) return $bytes.' B';
function format_bytes(int $bytes): string {
if ($bytes < 1024) return (string) $bytes.' B';
elseif ($bytes < 1048576) return uang2($bytes / 1024).' KB';
elseif ($bytes < 1073741824) return uang2($bytes / 1048576).' MB';
elseif ($bytes < 1099511627776) return uang2($bytes / 1073741824).' GB';
@@ -351,12 +355,10 @@ if (!function_exists('format_bytes')) {
}
if (!function_exists('random_color')) {
function random_color($trans = "0.6") {
$col_r = mt_rand( 0, 255 );
$col_g = mt_rand( 0, 255 );
$col_b = mt_rand( 0, 255 );
function random_color(string $trans = "0.6"): string {
$col_r = (string) mt_rand( 0, 255 );
$col_g = (string) mt_rand( 0, 255 );
$col_b = (string) mt_rand( 0, 255 );
return "rgba(".$col_r.",".$col_g.",".$col_b.",".$trans.")";
}
}
?>
+53 -36
View File
@@ -2,64 +2,79 @@
/*******************************************************************
Module : /Printing/PrintHTML.php
Desc. : Class cetak HTML
Module : /Printer/PrintHTML.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008.
Last Modified : September 30th, 2025.
Last Modified : August 26th, 2026.
(c) 2008 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Printer;
namespace Webapp\Printer;
use \flight\Engine;
/**
* Class PrintHTML
*
* Menghasilkan bentuk laporan dalam format HTML.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Printer
*/
final class PrintHTML {
private $__avalue = [];
private $__atabel = [];
private $__css = "table";
private $__tstamp = "";
protected array $webapp;
protected array $webuser;
public function __construct() {
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->webapp = $app->session()->get('__WEB_APP', ['APP_NAME'=>'', 'APP_VER'=>'']);
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'Username'=>'']);
}
public function set_css($style = "") {
if ($style=="") return;
$this->__css = $style;
public function set_css(string $style): void {
if (!empty($style)) $this->__css = $style;
}
public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="", $nkol=1) {//up 2012-03-07
$this->__atabel[] = [$tnama, $nlebar, $ffunc, $talign, $nkol];
public function add_field(string $nama, int $lebar=0, string $align="L", string $func="", int $kol=1): void {
$this->__atabel[] = [ $nama, $lebar, $func, $align, $kol ];
}
public function show_fields() {//todo: deleted
}
public function clear() {
public function clear(): void {
$this->__avalue = [];
}
public function add_value() {
public function add_value(): void {
$tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0]; //up 2009-09-27
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = "<tr>";
for ($i=0; $i<count($this->__atabel); $i++) {
$tmp_val = $tmp_arr[$i];
if (is_array($this->__atabel[$i][2]) && trim("".$tmp_val)<>"") { //up 2010-05-28
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);
}
$tmp_val = $this->set_align($tmp_val, $this->__atabel[$i][1], $this->__atabel[$i][3]);
$tmp_val = $this->set_align((string) $tmp_val, $this->__atabel[$i][1], $this->__atabel[$i][3]);
$tmp_out .= $tmp_val;
}
$tmp_out .= "</tr>";
$this->__avalue[] = $tmp_out;
}
public function add_span() {
public function add_span(): void {
$tmp_arr = func_get_args();
$tmp_out = "<tr>";
for ($i=0; $i<count($tmp_arr); $i++) {
@@ -79,15 +94,15 @@ final class PrintHTML {
$this->__avalue[] = $tmp_out;
}
public function add_stamp($ctk_ke=1, $bnama=false) {//up 2023-10-13
$this->__tstamp = $this->get_stamp($ctk_ke, $bnama);
public function add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$this->__tstamp = $this->get_stamp($ctk_ke, $cetak_nama);
}
public function get_stamp($ctk_ke=1, $bnama=false) {//up 2012-10-11
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 get_stamp(int $ctk_ke=1, bool $cetak_nama=false): string {
return $this->webapp['APP_NAME']."v".$this->webapp['APP_VER'].date("\@ymd.His")."-".isi_nol($this->webuser['UserID'], 3).(($cetak_nama)?"/".strtoupper($this->webuser['Username']):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):"");
}
public function show($jumlah_ctk=1) {//up 2012-10-11
public function show(int $jumlah_ctk=1) {
$out = "<table class=\"".$this->__css."\"><thead>";
// header out
@@ -111,27 +126,29 @@ final class PrintHTML {
for ($i=1; $i<=$jumlah_ctk; $i++) echo $out;
}
public function set_align($ttext, $nlen, $tdir="L", $bline=false, $bhead=false, $ncol=1, $textra="") {//up 2011-04-14
$tstyle = $this->create_style($tdir);
if ($bline===true) {
return "<tr><td colspan=\"".count($this->__atabel)."\" class=\"".$tstyle." ".$textra."\">".$ttext."</td></tr>";
public function set_align(string $text, int $width=0, string $dir="L", bool $line=false, bool $head=false, int $col=1, string $extra=""): string {
$tstyle = $this->create_style($dir);
if ($line===true) {
return "<tr><td colspan=\"".count($this->__atabel)."\" class=\"".$tstyle." ".$extra."\">".$text."</td></tr>";
} else {
return (($bhead===true)?"<th":"<td").(($ncol>1)?" colspan=\"".$ncol."\"":"")." class=\"".$tstyle." ".$textra."\" ".(($bhead===true)?"width=\"".$nlen."\"":"").">".$ttext.(($bhead===true)?"</th>":"</td>");
return (($head===true)?"<th":"<td").(($col>1)?" colspan=\"".(string)$col."\"":"")." class=\"".$tstyle." ".$extra."\" ".(($head===true)?"width=\"".(string)$width."\"":"").">".$text.(($head===true)?"</th>":"</td>");
}
}
private function create_style($tstyle="L") { //up 2014-10-12
private function create_style(string $style="L"): string {
// style = Left Right Center No-Border No-Left No-Right Bold Italic
$apad = ["L"=>"l", "R"=>"r", "C"=>"c", "NB"=>"nb", "NL"=>"noleft", "NR"=>"noright", "B"=>"b", "I"=>"i"];
$_astyle = explode(",", $tstyle);
$thasil = "";
$_astyle = explode(",", $style);
$ahasil = [];
foreach ($_astyle as $_key => $_val) {
$thasil .= " ".$apad[$_val];
$ahasil[] = $apad[$_val];
}
return substr($thasil,1);
return implode(' ', $ahasil);
}
public function add_pagebreak() {}//delete: not used anymore
//todo: deprecated
public function show_fields() {}
public function add_pagebreak() {}
}
?>
+66 -49
View File
@@ -2,22 +2,33 @@
/*******************************************************************
Module : /Printing/PrintPOS.php
Desc. : Class cetak POS
Module : /Printer/PrintPOS.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008.
Last Modified : December 3rd, 2025.
Last Modified : August 21st, 2026.
(c) 2008 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Printer;
namespace Webapp\Printer;
/* VERSI BARU DENGAN MULTI SHEET */
class PrintPOS {//up: 20251203
use \flight\Engine;
/**
* Class PrintPOS
*
* Pembuatan Nota/Struk untuk cetak ke Printer POS.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Printer
*/
class PrintPOS {
private $_header = [];
private $_avalue = [];
private $_astyle = [];
@@ -27,37 +38,44 @@ class PrintPOS {//up: 20251203
'fontsize' => 1,
'opendraw' => false,
'cutpaper' => false,
'logo' => null ];
'logo' => null,
];
private array $webapp;
private array $webuser;
protected Engine $app;
public function __construct() {
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->app = $app;
$this->webapp = $app->session()->get('__WEB_APP', ['APP_NAME'=>'', 'APP_VER'=>'']);
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'Username'=>'']);
}
public function set_opendrawer() {
public function set_opendrawer(): void {
$this->_config['opendraw'] = true;
}
public function set_cutpaper() {
public function set_cutpaper(): void {
$this->_config['cutpaper'] = true;
}
public function set_maxchr($nmax = 0) {//up: 2015-03-22
if ($nmax > 0) $this->_maxchr = $nmax;
public function set_maxchr(int $max = 0): void {
if ($max > 0) $this->_maxchr = $max;
}
public function set_fontsize($nsize = 1) {//up: 2015-09-30
if ($nsize > 0) $this->_config['fontsize'] = $nsize;
public function set_fontsize(int $size = 1): void {
if ($size > 0) $this->_config['fontsize'] = $size;
}
public function set_printnv_logo() {}//delete
public function set_header_logo($logo_file = "") {//up: 2019-01-08
if ($logo_file=="") return;
if (file_exists($_SESSION['__WEB_APP']['REAL_PATH']."assets/images/".$logo_file)) {
$this->_config['logo'] = $_SESSION['__WEB_APP']['WEB_PATH']."assets/images/".$logo_file;
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;
}
}
public function add_header() {//up: 2025-12-03
public function add_header(): void {
$extra = func_get_args();
if (count($extra) > 0) {
foreach ($extra as $_val) {
@@ -66,11 +84,11 @@ class PrintPOS {//up: 20251203
}
}
public function add_sheet() {//up: 20170321
public function add_sheet(): void {
$this->_ncont++;
}
public function add() {//up: 20180524
public function add(): void {
$val_arr = func_get_args(); $ttext = ""; $tstyle = "L";
if (is_array($val_arr[0])) {
foreach($val_arr as $aval) {
@@ -84,32 +102,32 @@ class PrintPOS {//up: 20251203
$this->_astyle[$this->_ncont][] = $tstyle;
}
public function addl($ttext = "") {
$this->add($ttext);
public function addl(string $text = ""): void {
$this->add($text);
}
public function addr($ttext = "") {
$this->add($ttext, "R");
public function addr(string $text = ""): void {
$this->add($text, "R");
}
public function addc($ttext = "") {
$this->add($ttext, "C");
public function addc(string $text = ""): void {
$this->add($text, "C");
}
public function add_line($tmp = "-") {
$this->add("__LINE ".$tmp);
public function add_line(string $line = "-"): void {
$this->add("__LINE ".$line);
}
public function add_empty($nrep = 1) {
for ($i=0;$i<$nrep;$i++) $this->add("");
public function add_empty(int $baris = 1): void {
for ($i=0; $i<$baris; $i++) $this->add("");
}
public function add_stamp($ctk_ke=1, $bnama=false) {
$this->add($_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 add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$this->add($this->webapp['APP_NAME']."v".$this->webapp['APP_VER'].date("\@ymd.His")."-".isi_nol($this->webuser['UserID'], 3).(($cetak_nama)?"/".strtoupper($this->webuser['Username']):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):""));
}
private function _json_out() {//up: 2016-11-12
$acontent = array();
public function show(int $jumlah_ctk=1): void {
$acontent = [];
$nmax = $this->_maxchr;
for ($s=0; $s<count($this->_avalue); $s++) {
@@ -123,24 +141,23 @@ class PrintPOS {//up: 20251203
}
}
$aout = array('type' => "escp");
$this->_config['times'] = $jumlah_ctk;
$aout = ['type' => "escp"];
$aout['config'] = $this->_config;
$aout['header'] = $this->_header;
$aout['content'] = $acontent;
send_json($aout);
$this->app->json($aout);
}
public function show($jumlah_ctk=1) {
$this->_config['times'] = $jumlah_ctk;
$this->_json_out();
public function set_align(string $text, int $len=0, string $dir="L"): string {
$apad = ["L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH];
$nlen = ($len==0) ? strlen($text) : $len;
$ttext = (strlen($text)>$len) ? substr($text, 0, $len) : $text;
return str_pad($text, $len, " ", $apad[$dir]);
}
public function set_align($ttext, $nlen=0, $tdir="L") {//up: 20180524
$apad = array("L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH);
$nlen = ($nlen==0) ? strlen($ttext) : $nlen;
$ttext = (strlen($ttext)>$nlen) ? substr($ttext, 0, $nlen) : $ttext;
return str_pad($ttext, $nlen, " ", $apad[$tdir]);
}
//todo: deprecated
public function set_printnv_logo() {}//delete
}
?>
+60 -47
View File
@@ -2,19 +2,31 @@
/*******************************************************************
Module : /Printing/PrintRAW.php
Desc. : Class cetak RAW
Module : /Printer/PrintRAW.php
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008.
Last Modified : November 1st, 2023.
(c) 2008 - 2023, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Printer;
namespace Webapp\Printer;
use \flight\Engine;
/**
* Class PrintRAW
*
* Pembuatan Laporan dalam bentuk RAW / Natural.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Printer
*/
class PrintRAW {
private $_header = [];
@@ -27,54 +39,59 @@ class PrintRAW {
'fontsize' => "01",
'nvlogo' => false,
'opendraw' => false,
'opendrawbegin' => false,
'cutpaper' => false ];
'cutpaper' => false,
];
private array $webapp;
private array $webuser;
protected Engine $app;
public function __construct() {
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->app = $app;
$this->webapp = $app->session()->get('__WEB_APP', ['APP_NAME'=>'', 'APP_VER'=>'']);
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'Username'=>'']);
}
public function set_opendrawer($bbegin = true) {
public function set_opendrawer(): void {
$this->_config['opendraw'] = true;
$this->_config['opendrawbegin'] = $bbegin;
}
public function set_cutpaper() {
public function set_cutpaper(): void {
$this->_config['cutpaper'] = true;
}
public function set_maxchr($nmax = 0) {//up: 2015-03-22
if ($nmax > 0) $this->_maxchr = $nmax;
public function set_maxchr(int $max = 0): void {
if ($max > 0) $this->_maxchr = $max;
}
public function set_fontsize($nsize = 1) {//up: 2015-09-30
if ($nsize > 0) $this->_config['fontsize'] = str_pad($nsize, 2, "0", STR_PAD_LEFT);
public function set_fontsize(int $size = 1): void {
if ($size > 0) $this->_config['fontsize'] = str_pad((string)$size, 2, "0", STR_PAD_LEFT);
}
public function set_printnv_logo() {//up: 2015-03-23
public function set_printnv_logo(): void {
$this->_config['nvlogo'] = true;
}
public function add_header($nvlogo = false, $extra = []) {//up: 2016-11-12
public function add_header(bool $nvlogo = false, array $extra = []): void {
$this->_config['nvlogo'] = $nvlogo;
$this->_header[] = $_SESSION['__WEB_APP']['REG_NAME'];
if (count($extra) > 0) {
foreach ($extra as $_val) {
$this->_header[] = $_val;
}
}
$this->_header[] = $_SESSION['__WEB_APP']['REG_CITY'];
}
public function add_sheet() {//up: 20170321
public function add_sheet(): void {
$this->_ncont++;
}
public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="") {
$this->_atabel[] = [$tnama, $nlebar, $ffunc, $talign];
public function add_field(string $nama, int $lebar=0, string $align="L", string $func=""): void {
$this->_atabel[] = [ $nama, $lebar, $func, $align ];
}
public function show_fields() {
public function show_fields(): void {
$tmp_out = "<b>";
for ($i=0; $i<count($this->_atabel); $i++) {
$tmp_out .= $this->set_align($this->_atabel[$i][0], $this->_atabel[$i][1], "C");
@@ -86,13 +103,13 @@ class PrintRAW {
$this->_avalue[$this->_ncont][] = "__LINE -";
}
public function add_value() {
public function add_value(): void {
$tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0]; //up 2009-09-27
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = "";
for ($i=0; $i<count($this->_atabel); $i++) {
$tmp_val = $tmp_arr[$i];
if (is_array($this->_atabel[$i][2]) && trim($tmp_val)<>"") { //up 2010-05-28
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);
@@ -104,24 +121,24 @@ class PrintRAW {
$this->_avalue[$this->_ncont][] = $tmp_out;
}
public function add($ttext = "") {
$this->_avalue[$this->_ncont][] = $ttext;
public function add(string $text): void {
$this->_avalue[$this->_ncont][] = $text;
}
public function add_line($tmp = "-") {
$this->add("__LINE ".$tmp);
public function add_line(string $line = "-"): void {
$this->add("__LINE ".$line);
}
public function add_empty($nrep = 1) {
for ($i=0;$i<$nrep;$i++) $this->add("");
public function add_empty(int $rep = 1): void {
for ($i=0;$i<$rep;$i++) $this->add("");
}
public function add_stamp($ctk_ke=1, $bnama=false) {
$this->add($_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 add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$this->add($this->webapp['APP_NAME']."v".$this->webapp['APP_VER'].date("\@ymd.His")."-".isi_nol($this->webuser['UserID'], 3).(($cetak_nama)?"/".strtoupper($this->webuser['Username']):"").(($ctk_ke>0)?"#".isi_nol($ctk_ke,2):""));
}
private function _json_out() {//up: 2016-11-12
$acontent = array();
public function show(int $jumlah_ctk=1): void {
$acontent = [];
$nmax = $this->_maxchr;
for ($s=0; $s<count($this->_avalue); $s++) {
@@ -135,22 +152,18 @@ class PrintRAW {
}
}
$aout = array('type' => "escp");
$this->_config['times'] = $jumlah_ctk;
$aout = ['type' => "escp"];
$aout['config'] = $this->_config;
$aout['header'] = $this->_header;
$aout['content'] = $acontent;
send_json($aout);
$this->app->json($aout);
}
public function show($jumlah_ctk=1) {
$this->_config['times'] = $jumlah_ctk;
$this->_json_out();
}
public function set_align($ttext, $nlen, $tdir="L") {
$apad = array("L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH);
$ttext = (strlen($ttext)>$nlen) ? substr($ttext, 0, $nlen) : $ttext;
return str_pad($ttext, $nlen, " ", $apad[$tdir]);
public function set_align(string $text, int $len, string $dir="L"): string {
$apad = ["L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH];
$ttext = (strlen($text)>$len) ? substr($text, 0, $len) : $text;
return str_pad($text, $len, " ", $apad[$dir]);
}
}
+48 -35
View File
@@ -3,23 +3,32 @@
/*******************************************************************
Module : /Web/Auth.php
Desc. : Class login dan user checking
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : March 16th, 2008.
Last Modified : April 3rd, 2022.
Last Modified : August 22nd, 2026.
(c) 2008 - 2022, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use flight\Session;
use flight\database\SimplePdo;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
/**
* Class Auth
*
* Kontrol dan Manajemen User Session.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Auth {
private int $__id_reg = 0;
@@ -27,23 +36,26 @@ final class Auth {
protected SimplePdo $db;
protected Session $session;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
$this->session = $this->app->session();
/**
* @param Engine $app
*/
public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->session = $app->session();
$this->__id_reg = (int)$this->session->get('__WEB_APP', ['REG_ID'=>0])['REG_ID'];
}
public function set_id_reg($id = 0) {
public function set_id_reg(int|string $id = 0): void {
if ($id > 0) $this->__id_reg = (int)$id;
}
public function user_check($user, $pass) {
$i_hasil = $this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Password=MD5(?) AND Aktif=1', [$user, $pass]);
public function user_check(string $user, string $pass): bool {
$i_hasil = (int)$this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Password=MD5(?) AND Aktif=1', [$user, $pass]);
return ($i_hasil > 0 ? true : false);
}
public function user_data($user) {
public function user_data(string $user): array {
$adata = $this->db->fetchRow('SELECT *,DECODE(Menu,?) Menu2 FROM app_operator WHERE Username=?', [$this->__id_reg, $user])->getData();
$adata['Menu'] = $adata['Menu2'];
unset($adata['Menu2']);
@@ -53,13 +65,14 @@ final class Auth {
$this->session->set('APP_TOKEN', $_token);
$this->db->insert('app_token', [ 'Token' => $_token, 'UserID' => $adata['UserID'], 'IP' => $this->app->request()->ip ]);
}
if ((int)$adata['Grup_MenuID'] > 0) $adata['Menu_Grup'] = $this->user_allmenu($adata['Grup_MenuID']);
if ((int)$adata['Grup_MenuID'] > 0) $adata['Menu_Grup'] = $this->user_allmenu((int)$adata['Grup_MenuID']);
$adata['UNIX'] = time();
$adata['LOCALE'] = $this->session->get('__WEB_APP', ['DEF_LOCALE'=>'id'])['DEF_LOCALE'];
$adata['MENU_MODUL'] = [];
return $adata;
}
public function gen_module_menu() {
public function gen_module_menu(): void {
$amodul = []; $aallow = []; $tallow = '';
if ($this->session->get('__WEB_APP', ['APP_MODULE'=>0])['APP_MODULE']) {
$tallow = $this->db->fetchField('SELECT Modul_Akses FROM app_menu_grup WHERE Grup_MenuID=?', [$this->session->get('__WEB_USER', ['Grup_MenuID'=>0])['Grup_MenuID']]);
@@ -78,55 +91,55 @@ final class Auth {
$this->session->set('__WEB_USER', $auser);
}
public function user_allmenu(int $id_grup = 0) {
public function user_allmenu(int $id_grup = 0): string {
$allmenu = $this->db->fetchField('SELECT DECODE(Menu,?) MenuX FROM app_menu_grup WHERE Grup_MenuID=?', [$this->__id_reg, $id_grup]);
return $allmenu;
}
public function user_check_level($user, $level = 9) {
$i_hasil = $this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Level<=? AND Aktif=1', [$user, $level]);
public function user_check_level(string $user, int $level = 9): bool {
$i_hasil = (int)$this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Level<=? AND Aktif=1', [$user, $level]);
return ($i_hasil > 0 ? true : false);
}
public function user_log() {
$a_hasil = $this->db->fetchRow('SELECT * FROM app_logs WHERE UserID=? ORDER BY Last_Date DESC LIMIT 1', [user_id()])->getData();
public function user_log(): void {
$_user_id = $this->session->get('__WEB_USER')['UserID'] ?? 0;
if ($_user_id === 0) return;
$a_hasil = $this->db->fetchRow('SELECT * FROM app_logs WHERE UserID=? ORDER BY Last_Date DESC LIMIT 1', [$_user_id])->getData();
if (count($a_hasil) > 0) {
$this->db->update('app_operator', [ 'Last_IP' => $a_hasil['Last_IP'], 'Last_Date' => $a_hasil['Last_Date'] ], 'UserID=?', [user_id()]);
$this->db->update('app_operator', [ 'Last_IP' => $a_hasil['Last_IP'], 'Last_Date' => $a_hasil['Last_Date'] ], 'UserID=?', [$_user_id]);
}
$this->db->runQuery('INSERT IGNORE INTO app_logs SELECT UserID,Token,IP,DateStamp FROM app_token WHERE Token=?', [$this->session->get('APP_TOKEN')]);
}
public function logout() {
public function logout(): void {
$this->db->delete('app_token', 'Token=?', [$this->session->get('APP_TOKEN')]);
}
public function token_check(string $token) {
public function token_check(string $token): bool {
$hasil = (bool)$this->db->fetchField('SELECT 1 FROM app_token WHERE Token=?', [$token ?? $this->session->get('APP_TOKEN')]);
if ($hasil === true) $this->db->update('app_token', ['DateStamp' => 'NOW()'], 'Token=?', [$token ?? $this->session->get('APP_TOKEN')]);
return $hasil;
}
public function token_update() {
$this->db->update('app_token', ['DateStamp' => 'NOW()'], 'Token=?', [$app->session->get('APP_TOKEN')]);
public function token_update(): void {
$this->db->update('app_token', ['DateStamp' => 'NOW()'], 'Token=?', [$this->session->get('APP_TOKEN')]);
}
public function redirect(string $appUrl) {
public function redirect(string $appUrl): string {
$source = parse_url($appUrl);
$desti = "";
$hasil = (bool)$this->db->fetchField('SELECT 1 FROM app_host WHERE Nama_Host=?', [$source['host']]);
if ($hasil === true) {
$desti = $source['scheme'].$source['host'].$source['path'].'?'.'auth='.$app->session->get('APP_TOKEN');
}
if ($hasil) $desti = $source['scheme'].$source['host'].$source['path'].'?'.'auth='.$this->session->get('APP_TOKEN');
return $desti;
}
private function genToken(int $length = 16) {
private function genToken(int $length = 16): string {
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}
public function getUserByToken(string $token) {
$hasil = $this->db->fetchField('SELECT Username FROM app_operator WHERE UserID IN (SELECT UserID FROM app_token WHERE Token=?) LIMIT 1', [$token ??$app->session->get('APP_TOKEN')]);
public function getUserByToken(string $token): string {
$hasil = $this->db->fetchField('SELECT Username FROM app_operator WHERE UserID IN (SELECT UserID FROM app_token WHERE Token=?) LIMIT 1', [$token ?? $this->session->get('APP_TOKEN')]);
return $hasil;
}
}
+35 -24
View File
@@ -3,58 +3,69 @@
/*******************************************************************
Module : /Web/Button.php
Desc. : Button Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 27th, 2008.
Last Modified : January 22nd, 2024.
Last Modified : August 22nd, 2026.
(c) 2008 - 2024, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
/**
* Class Button
*
* Pembuatan tombol aplikasi (jQuery & Bootstrap).
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
class Button {
private $__abutton =[];
public function __construct() {}
private function add($type="info", $id="", $label="", $bmiss=false) {
if ($id=="") $id = "random".rand(1000, 10000);
$this->__abutton[] = ['type'=>$type, 'id'=>$id, 'label'=>$label, 'bmiss'=>$bmiss];
private function add(string $type="info", string $id="", string $label="", bool $miss=false): void {
if (empty($id)) $id = "random".(string)rand(1000, 10000);
$this->__abutton[] = [ 'type' => $type, 'id' => $id, 'label' => $label, 'miss' => $miss ];
}
public function separator() {
public function separator(): void {
$this->__abutton[] = [ 'type' => "separator" ];
}
public function primary($id="", $label="", $bmiss=false) {
$this->add("primary", $id, $label, $bmiss);
public function primary(string $id="", string $label="", bool $miss=false): void {
$this->add("primary", $id, $label, $miss);
}
public function info($id="", $label="", $bmiss=false) {
$this->add("info", $id, $label, $bmiss);
public function info(string $id="", string $label="", bool $miss=false): void {
$this->add("info", $id, $label, $miss);
}
public function danger($id="", $label="", $bmiss=false) {
$this->add("danger", $id, $label, $bmiss);
public function danger(string $id="", string $label="", bool $miss=false): void {
$this->add("danger", $id, $label, $miss);
}
public function warning($id="", $label="", $bmiss=false) {
$this->add("warning", $id, $label, $bmiss);
public function warning(string $id="", string $label="", bool $miss=false): void {
$this->add("warning", $id, $label, $miss);
}
public function success($id="", $label="", $bmiss=false) {
$this->add("success", $id, $label, $bmiss);
public function success(string $id="", string $label="", bool $miss=false): void {
$this->add("success", $id, $label, $miss);
}
public function secondary($id="", $label="", $bmiss=false) {
$this->add("secondary", $id, $label, $bmiss);
public function secondary(string $id="", string $label="", bool $miss=false): void {
$this->add("secondary", $id, $label, $miss);
}
public function Button($size=2) {
if (0==count($this->__abutton)) return "";
public function Button(int $size=2): string {
if (0===count($this->__abutton)) return "";
$_out = '<div class="row mb-1"><div class="col-12 col-sm-6 my-0 mx-sm-0 text-center text-sm-start">'; $_ma = ' me-sm-2';
foreach ($this->__abutton as $item) {
if ("separator" == $item['type']) {
if ("separator" === $item['type']) {
$_out .= '</div><div class="col-12 col-sm-6 my-0 mx-sm-0 text-center text-sm-end">'; $_ma = ' ms-sm-2';
} else {
$_out .= '<button type="button" class="btn btn-'.$item['type'].' mb-2 mb-sm-0'.$_ma.' col-10 col-sm-auto shadow-none" id="'.$item['id'].'"'.(true==$item['bmiss']?' data-bs-dismiss="modal"':'').'>'.$item['label'].'</button>';
$_out .= '<button type="button" class="btn btn-'.$item['type'].' mb-2 mb-sm-0'.$_ma.' col-10 col-sm-auto shadow-none" id="'.$item['id'].'"'.(true===$item['miss']?' data-bs-dismiss="modal"':'').'>'.$item['label'].'</button>';
}
}
$_out .= '</div></div>';
+49 -38
View File
@@ -3,23 +3,32 @@
/*******************************************************************
Module : /Web/Form.php
Desc. : Form Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 27th, 2008.
Last Modified : August 19th, 2026.
Last Modified : August 22nd, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use flight\Session;
use flight\database\SimplePdo;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
/**
* Class Form
*
* Pembuatan form (jQuery & Bootstrap).
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Form {
private $__aform = [];
@@ -28,13 +37,16 @@ final class Form {
protected SimplePdo $db;
protected Session $session;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
$this->session = $this->app->session();
/**
* @param Engine $app
*/
public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->session = $app->session();
}
public function option(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null, bool $multi=false, bool $group=false): string {//oke
public function option(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null, bool $multi=false, bool $group=false): string {
$_opsi = '';
if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
if ($enable===false) $_opsi .= ' disabled=true';
@@ -70,12 +82,12 @@ final class Form {
return $tout;
}
public function option_db(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, ?string $table=null, ?array $afield=null, ?string $where=null, ?array $aarray=null, ?string $help=null, ?string $change=null, bool $multi=false): string {//oke
public function option_db(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, ?string $table=null, ?array $afield=null, ?string $where=null, ?array $aarray=null, ?string $help=null, ?string $change=null, bool $multi=false): string {
$_twhere = '';
if (!is_array($afield)) $afield = ["ID", "Nama", "Label"];
if (!empty($where)) {
$_twhere = ' WHERE '.$where;
$_twhere .= (stripos($twhere,"ORDER BY")===false) ? ' ORDER BY '.$afield[1] : '';
$_twhere .= (stripos($where,"ORDER BY")===false) ? ' ORDER BY '.$afield[1] : '';
}
$ahasil = [];
if (is_array($aarray)) $ahasil[$aarray[0]] = (!isset($afield[2])) ? $aarray[1] : [$aarray[1], $aarray[2]];
@@ -88,7 +100,7 @@ final class Form {
return $this->option($label, $field, $value, $enable, $req, $ahasil, $help, $change, $multi);
}
public function option_que(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, ?string $query=null, ?array $afield=null, ?array $aarray=null, ?string $help=null, ?string $change=null): string {//oke
public function option_que(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, ?string $query=null, ?array $afield=null, ?array $aarray=null, ?string $help=null, ?string $change=null): string {
if (!is_array($afield)) $afield = ["ID", "Nama", "Label"];
$ahasil = [];
if (is_array($aarray)) $ahasil[$aarray[0]] = (!isset($afield[2])) ? $aarray[1] : [$aarray[1], $aarray[2]];
@@ -101,15 +113,15 @@ final class Form {
return $this->option($label, $field, $value, $enable, $req, $ahasil, $help, $change);
}
public function option_jkl(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {//oke
public function option_jkl(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
return $this->option($label, $field, $value, $enable, $req, ["L" => "Laki-Laki", "P" => "Perempuan"], $help, $change);
}
public function option_ulevel(string $label, string $field, int $value=9, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {//oke
public function option_ulevel(string $label, string $field, int $value=9, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
return $this->option($label, $field, $value, $enable, $req, $this->session->get('__WEB_APP')['USER_LEVEL'], $help, $change);
}
public function radio(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {//oke
public function radio(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {
$_val = array_values($arr);
if (empty($value)) $value = $_val[0];
$_opsi = '';
@@ -128,16 +140,16 @@ final class Form {
return $tout;
}
public function radio_jkl(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {//oke
public function radio_jkl(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
return $this->radio($label, $field, $value, $enable, $req, ["L" => "Laki-Laki", "P" => "Perempuan"], $help, $change);
}
public function radio_gd(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {//oke
public function radio_gd(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
if (!empty($value)) $value = 'X';
return $this->radio($label, $field, $value, $enable, $req, ["A"=>"A", "B"=>"B", "AB"=>"AB", "O"=>"O", "X"=>"NONE"], $help, $change);
}
public function checkbox(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {//oke
public function checkbox(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {
$_val = array_values($arr);
if (empty($value)) $value = $_val[1];
$_opsi = ' odata="'.htmlspecialchars(json_encode($arr)).'"';
@@ -151,7 +163,7 @@ final class Form {
return $tout;
}
public function switch(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {//oke
public function switch(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, array $arr=[], ?string $help=null, ?string $change=null): string {
$_val = array_values($arr);
if (empty($value)) $value = $_val[1];
$_opsi = ' odata="'.htmlspecialchars(json_encode($arr)).'"';
@@ -165,7 +177,7 @@ final class Form {
return $tout;
}
public function textbox(string $label, string $field, string|int|null $value=null, bool $enable=true, bool $req=false, string $type="text", ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {//oke
public function textbox(string $label, string $field, mixed $value=null, bool $enable=true, bool $req=false, string $type="text", ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {
$_opsi = '';
if (!empty($keyup)) $_opsi .= ' okyup="'.$keyup.'"';
if (!empty($blur)) $_opsi .= ' oblur="'.$blur.'"';
@@ -179,12 +191,12 @@ final class Form {
if ($type === 'double') $value = uang2($value);
$type = "text";
}
$tout = '<input type="'.$type.'" class="form-control'.$_tclass.'" id="'.$field.'" name="'.$field.'" value="'.$value.'"'.$_opsi.' />';
$tout = '<input type="'.$type.'" class="form-control'.$_tclass.'" id="'.$field.'" name="'.$field.'" value="'.(string)$value.'"'.$_opsi.' />';
$this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout ];
return $tout;
}
public function textauto(string $label, string $field, array $avalue=['value'=>0,'text'=>""], bool $enable=true, bool $req=false, ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null): string {//oke
public function textauto(string $label, string $field, array $avalue=['value'=>0,'text'=>""], bool $enable=true, bool $req=false, ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null): string {
$_opsi = '';
if (!empty($holdtxt)) $_opsi .= ' placeholder="'.$holdtxt.'"';
if (!empty($maxsize)) $_opsi .= ' maxlength="'.$maxsize.'"';
@@ -195,7 +207,7 @@ final class Form {
return $tout;
}
public function datebox(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {//oke
public function datebox(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {
if (!empty($value)) $value = tgl_sql2str($value);
$tout = '<div class="input-group date">';
$tout .= $this->textbox($label, $field, $value, $enable, $req, "pickdate", "dd-mm-yyyy", null, $help, $keyup, $blur);
@@ -204,11 +216,11 @@ final class Form {
return $tout;
}
public function timebox(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {//oke
public function timebox(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {
return $this->textbox($label, $field, $value, $enable, $req, "picktime", "hh:mm:ss", 10, $help, $keyup, $blur);
}
public function textarea(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, int $rows=1, ?string $holdtxt=null, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {//oke
public function textarea(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, int $rows=1, ?string $holdtxt=null, ?string $help=null, ?string $keyup=null, ?string $blur=null): string {
$_opsi = '';
if (!empty($keyup)) $_opsi .= ' okyup="'.$keyup.'"';
if (!empty($blur)) $_opsi .= ' oblur="'.$blur.'"';
@@ -220,17 +232,17 @@ final class Form {
return $tout;
}
public function plaintext(string $label, string $field, string|int|null $value=null): string {//oke
public function plaintext(string $label, string $field, mixed $value=null): string {
$tout = '<input type="text" class="form-control-plaintext" id="'.$field.'" name="'.$field.'" value="'.$value.'" readonly />';
$this->__aform[$field] = ['label' => $label, 'help' => "", 'form' => $tout];
return $tout;
}
public function password(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null, ?string $keyup=null): string {//oke
public function password(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $holdtxt=null, ?int $maxsize=null, ?string $help=null, ?string $keyup=null): string {
return $this->textbox($label, $field, $value, $enable, $req, "password", $holdtxt, $maxsize, $help, $keyup, null);
}
public function color(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {//oke
public function color(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
$_opsi = '';
if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
if ($enable===false) $_opsi .= ' disabled=true';
@@ -240,20 +252,19 @@ final class Form {
return $tout;
}
public function hidden(string $field, string|int|null $value=null, string $class="text"): string {//oke
public function hidden(string $field, mixed $value=null, string $class="text"): string {
$tout = '<input type="hidden" id="'.$field.'" value="'.$value.'" class="'.$class.'" />';
$this->__ahide[$field] = $tout;
return $tout;
}
public function clear() {
public function clear(): void {
$this->__aform = [];
}
public function show($tstr) {
if ($tstr === 0) $tstr = 4;//default
$col_left = 'col-sm-' . ($tstr+2) . ' col-lg-' . $tstr;
$col_right = 'col-sm-' . (10-$tstr) . ' col-lg-' . (12-$tstr);
public function show(int $lebar_kolom = 4): string {
$col_left = 'col-sm-' . ($lebar_kolom+2) . ' col-lg-' . $lebar_kolom;
$col_right = 'col-sm-' . (10-$lebar_kolom) . ' col-lg-' . (12-$lebar_kolom);
$tres = '';
foreach ($this->__aform as $_key => $_val) {
$tres .= sprintf('<div class="row mb-1"><label class="%s col-form-label" for="%s">%s</label><div class="%s">%s %s</div></div>', $col_left, $_key, $_val['label'], $col_right, $_val['form'], (empty($_val['help'])?'':'<span class="help-block"><small>'.$_val['help'].'</small></span>'));
+67 -25
View File
@@ -3,40 +3,56 @@
/*******************************************************************
Module : /Web/Menu.php
Desc. : Class menu
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 16th, 2008.
Last Modified : December 26th, 2025.
Last Modified : August 22nd, 2026.
(c) 2008 - 2025, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use flight\Session;
use flight\database\SimplePdo;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
/**
* Class Menu
*
* Manajemen Menu aplikasi.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Menu {
private array $webapp;
private array $webuser;
protected Engine $app;
protected SimplePdo $db;
protected Session $session;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
$this->session = $this->app->session();
/**
* @param Engine $app
*/
public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->session = $app->session();
$this->webapp = $this->session->get('__WEB_APP', ['APP_MODULE'=>'', 'PARENT_SITE'=>'', 'PARENT_SUB'=>false]);
$this->webuser = $this->session->get('__WEB_USER', ['Menu'=>'', 'Menu_Grup'=>'', 'MENU_MODUL'=>[]]);
}
public function Menu_Sidebar() {
public function Sidebar(): string {
$a_modul = [];
$is_modul = ($this->session->get('__WEB_APP', ['APP_MODULE'=>''])['APP_MODULE'] <> '') ? true : false;
$is_modul = ($this->webapp['APP_MODULE'] !== '') ? true : false;
if ($is_modul == true) {
$a_modul[] = $this->session->get('__WEB_APP')['APP_MODULE'];
$a_modul[] = $this->webapp['APP_MODULE'];
} else {
$atmp = $this->db->fetchAll('SELECT * FROM app_menu WHERE Level=0 AND Aktif=1 AND Modul<>"IND" ORDER BY Urut');
foreach ($atmp as $tmp) {
@@ -44,7 +60,7 @@ final class Menu {
}
}
$my_menu = array_unique(array_filter(explode(",", $this->session->get('__WEB_USER', ['Menu_Grup'=>''])['Menu_Grup'].",".$this->session->get('__WEB_USER', ['Menu'=>''])['Menu'])));
$my_menu = array_unique(array_filter(explode(",", $this->webuser['Menu_Grup'].",".$this->webuser['Menu'])));
$tsql = 'SELECT * FROM app_menu WHERE Aktif=1 AND Modul IN (?) AND Kode IN (?)';
if ($is_modul == true) $tsql .= ' AND Level>0';
@@ -70,12 +86,12 @@ final class Menu {
return $thasil;
}
public function Menu_Header() {
public function Header(): string {
$a_modul = [];
$is_modul = ($this->session->get('__WEB_APP', ['APP_MODULE'=>''])['APP_MODULE'] <> '') ? true : false;
$is_modul = ($this->webapp['APP_MODULE'] !== '') ? true : false;
$mulai_level = 0;
if ($is_modul == true) {
$a_modul[] = $this->session->get('__WEB_APP')['APP_MODULE'];
$a_modul[] = $this->webapp['APP_MODULE'];
$mulai_level = 1;
} else {
$atmp = $this->db->fetchAll('SELECT * FROM app_menu WHERE Level=0 AND Aktif=1 AND Modul<>"IND" ORDER BY Urut');
@@ -84,7 +100,7 @@ final class Menu {
}
}
$my_menu = array_unique(array_filter(explode(",", $this->session->get('__WEB_USER', ['Menu_Grup'=>''])['Menu_Grup'].",".$this->session->get('__WEB_USER', ['Menu'=>''])['Menu'])));
$my_menu = array_unique(array_filter(explode(",", $this->webuser['Menu_Grup'].",".$this->webuser['Menu'])));
$tsql = 'SELECT * FROM app_menu WHERE Aktif=1 AND Modul IN (?) AND Kode IN (?)';
if ($is_modul == true) $tsql .= ' AND Level>0';
@@ -116,9 +132,35 @@ final class Menu {
return $thasil;
}
static function MenuJSON($db = null, $page = "", $tquery = "") {
$_mdb = (empty($db) === true) ? new SimplePdo() : $db;
$_query = ($tquery=="") ? "" : ",'".$tquery."'";
public function Modul(): string {
$t_modul = '';
if (is_array($this->webuser['MENU_MODUL']) && count($this->webuser['MENU_MODUL'])>0) {
$t_modul = '<div class="dropdown-divider"></div>';
if ($this->app->request()->getVar('SERVER_ADDR') === '127.0.0.1') {
$href1 = '//127.0.0.1/';
$href2 = "";
} else {
$_host = $this->app->request()->getVar('HTTP_ORIGIN') ?? $this->app->request()->getVar('HTTP_HOST') ?? $this->webapp['PARENT_SITE'];
$_host = str_replace(['http://','https://'], "", $_host);
if ($this->webapp['PARENT_SUB'] === true) {
$_subs = explode('.', $_host);
if (count($_subs) > 2) array_shift($_subs);
$href1 = "//";
$href2 = "." . implode('.', $_subs);
} else {
$href1 = "//" . $_host . '/';
$href2 = "";
}
}
foreach ($this->webuser['MENU_MODUL'] as $modul) {
$href = $href1 . $modul['APP_PATH'] . $href2 . '/' . $this->session->get('APP_TOKEN');
$t_modul .= '<a class="dropdown-item slink" href="'.$href.'"><i class="'.$modul['Icon'].' me-2"></i> '.$modul['Judul'].'</a>';
}
}
return $t_modul;
}
static function MenuJSON(SimplePdo $db, string $page = "", string $q = ""): array {
$ajson = ['login' => true];
$apage = ['Link' => ""];
@@ -130,14 +172,14 @@ final class Menu {
if ($acus_page[$page] ?? false) {
$apage = $acus_page[$page];
} else if ($page <> "") {
$apage = $_mdb->fetchRow('SELECT * FROM app_menu WHERE Kode=?', [$page]);
$apage = $db->fetchRow('SELECT * FROM app_menu WHERE Kode=?', [$page]);
$apage['Width'] = (int)$apage['Width'];
}
$ajson['iswindow'] = ($apage['Width'] > 0) ? true : false;
$ajson['width'] = $apage['Width'];
$ajson['title'] = $apage['Judul'];
$ajson['button'] = is_json($apage['Button']) ? json_decode($apage['Button']) : $apage['Button'];
$ajson['button'] = json_validate($apage['Button']) ? json_decode($apage['Button']) : $apage['Button'];
$ajson['php'] = $apage['Link'];
$ajson['func'] = $apage['JS'];
$ajson['kode'] = $apage['Kode'];
+24 -15
View File
@@ -3,22 +3,31 @@
/*******************************************************************
Module : /Web/Param.php
Desc. : Class data parameter dari client side
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : November 14th, 2013.
Last Modified : August 8th, 2026.
Last Modified : August 22nd, 2026.
(c) 2013 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use \flight\Engine;
/**
* Class Param
*
* Manajemen Variable Request dari GET / POST.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Param {
private static $__ahasil = [];
@@ -26,37 +35,37 @@ final class Param {
if (count(self::$__ahasil)==0) self::__data();
}
private static function __data() {
private static function __data(): void {
global $app;
if (empty($app)) $app = \Flight::app();
$_asumber = array_merge($app->request()->query->getData(), $app->request()->data->getData());
foreach ($_asumber as $__key => $__val) {
self::$__ahasil[$__key] = self::safeSQL($__val);
self::$__ahasil[$__key] = is_string($__val) ? self::safeSQL($__val) : $__val;
}
}
public static function safeSQL($tstr = "") {
public static function safeSQL(string $str = ""): string {
$_se = array("\\","\0","\n","\r","\x1a","'",'"');
$_re = array("\\\\","\\0","\\n","\\r","\Z","\'",'\"');
return str_replace($_se, $_re, $tstr);
return str_replace($_se, $_re, $str);
}
public static function Get($tkey = "", $tdef = null) {
public static function Get(string $key = "", mixed $def = null): mixed {
if (count(self::$__ahasil)==0) self::__data();
if (isset(self::$__ahasil[$tkey]) && self::$__ahasil[$tkey]) return self::$__ahasil[$tkey];
return $tdef;
if (isset(self::$__ahasil[$key]) && self::$__ahasil[$key]) return self::$__ahasil[$key];
return $def;
}
public static function Get_Text($tkey = "", $tdef = null) {
public static function Get_Text(string $key, mixed $def = null): mixed {
if (count(self::$__ahasil)==0) self::__data();
$_str = (isset(self::$__ahasil[$tkey])) ? self::$__ahasil[$tkey] : $tdef;
$_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 Get_Array() {
public static function Get_Array(): array {
if (count(self::$__ahasil)==0) self::__data();
return self::$__ahasil;
}
+26 -23
View File
@@ -3,51 +3,54 @@
/*******************************************************************
Module : /Web/Register.php
Desc. : Class Registrasi Aplikasi
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : November 23th, 2011.
Last Modified : August 11th, 2026.
Last Modified : August 22nd, 2026.
(c) 2011 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use flight\database\SimplePdo;
use \flight\Engine;
use \flight\Session;
use \flight\database\SimplePdo;
/**
* Class Register
*
* Registrasi aplikasi.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Register {
protected Engine $app;
protected SimplePdo $db;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
public function __construct(){
}
public static function reg_id() {
$webapp = (array)\Flight::app()->session()->get('__WEB_APP');
$id = (string)$webapp['REG_ID'] ?? '';
public static function reg_id(Session $session) {
$id = (string)$session->get('__WEB_APP', ['REG_ID'=>''])['REG_ID'];
return (substr($id,0,3).".".substr($id,3,3).".".substr($id,6));
}
public static function reg_code() {
$webapp = (array)\Flight::app()->session()->get('__WEB_APP');
$id = (string)$webapp['REG_CODE'] ?? '';
public static function reg_code(Session $session) {
$id = (string)$session->get('__WEB_APP', ['REG_CODE'=>''])['REG_CODE'];
return (substr($id,0,6)."-".substr($id,6,5)."-".substr($id,11,5)."-".substr($id,16,5)."-".substr($id,21,5)."-".substr($id,26,6));
}
public static function reg_check() {
$webapp = (array)\Flight::app()->session()->get('__WEB_APP');
public static function reg_check(Session $session) {
$webapp = $session->get('__WEB_APP');
return (bool)(isset($webapp['REG_STATUS']) && $webapp['REG_STATUS']) ?? false;
}
public function reg_status(array $apps) {
$kode_db = (bool)$this->db->fetchField('SELECT UPPER(CONVERT(MD5(CONCAT(REG_YEAR,CONVERT(MD5(CONCAT(REG_ID,REG_NAME)) using latin1),REG_ID,REG_NAME)) using latin1))=REG_CODE FROM app_config WHERE REG_ID=?', [$apps['APP_CODE'] ?? '']);
public static function reg_status(SimplePdo $db, array $apps) {
$kode_db = (bool)$db->fetchField('SELECT UPPER(CONVERT(MD5(CONCAT(REG_YEAR,CONVERT(MD5(CONCAT(REG_ID,REG_NAME)) using latin1),REG_ID,REG_NAME)) using latin1))=REG_CODE FROM app_config WHERE REG_ID=?', [$apps['APP_CODE'] ?? '']);
return [ 'REG_STATUS' => $kode_db === true ];
}
}
+23 -11
View File
@@ -3,22 +3,31 @@
/*******************************************************************
Module : /Web/Table.php
Desc. : HTML Table (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 16th, 2008.
Last Modified : August 16th, 2026.
Last Modified : August 22nd, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use flight\database\SimplePdo;
use \flight\Engine;
use \flight\database\SimplePdo;
/**
* Class Table
*
* Pembuatan DataTable (jQuery & Bootstrap).
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Table {
private $__ttable = "";
@@ -46,9 +55,12 @@ final class Table {
protected SimplePdo $db;
protected array $data;
public function __construct(?Engine $app = null) {
$this->app = (empty($app) === true) ? \Flight::app() : $app;
$this->db = $this->app->db();
/**
* @param Engine $app
*/
public function __construct(Engine $app) {
$this->app = $app;
$this->db = $app->db();
$this->data = $this->app->request()->data->getData();
}
@@ -82,7 +94,7 @@ final class Table {
}
public function set_row_color(string $field = "", string $val = "", string $css = ""): void {
if (epmty($field)) return;
if (empty($field)) return;
$this->__arowcol[] = [ 'F' => $field, 'V' => $val, 'C' => $css ];
}
+21 -11
View File
@@ -3,28 +3,38 @@
/*******************************************************************
Module : /Web/Terbilang.php
Desc. : Class Format Angka & Terbilang
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 12th, 2009.
Last Modified : May 6th, 2021.
Last Modified : August 22nd, 2026.
(c) 2009 - 2021, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
/**
* Class Terbilang
*
* Pembuatan text terbilang.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Terbilang {
private $numb = array("","Satu","Dua","Tiga","Empat","Lima","Enam","Tujuh","Delapan","Sembilan");
private $numb = ["","Satu","Dua","Tiga","Empat","Lima","Enam","Tujuh","Delapan","Sembilan"];
public function __construct() {}
public function Terbilang($nilai=0, $muang="Rupiah") {
public function Terbilang(float $nilai=0, string $muang="Rupiah"): string {
$number = 0;
$hasil = "";
$int = trim($nilai);
$int = (string)$nilai;
if (is_int(strpos($int,"-"))) {
$number = substr($int,strpos($int,"-")+1,strlen($int));
$hasil = "Minus";
@@ -36,11 +46,11 @@ final class Terbilang {
$xpos = strpos($number,".");
if (is_int($xpos)) {
# round : Untuk pembulatan angka desimal, strlen : untuk menghitung jumlah karakter
$pecahan = round(substr($number,$xpos,strlen($number)),2);
$pecahan = round((float)substr($number,$xpos,strlen($number)),2);
$last = substr($number,0,$xpos);
} else {
$pecahan = "";
$last = $number;
$last = (float)$number;
}
if ($last==0 || $number==0) {
return $hasil."NOL ".$muang;
@@ -71,11 +81,11 @@ final class Terbilang {
return $hasil . $kata;
}
private function mod($a, $b) {
private function mod(float $a, float $b): float {
return $a-$b*floor($a/$b);
}
private function tigadigit($amount, $suffix="") {
private function tigadigit(float $amount, string $suffix=""): string {
$last = (int)$amount;
$kata = "";
if ($last == 1 && $suffix=="Ribu") {
+29 -20
View File
@@ -3,37 +3,47 @@
/*******************************************************************
Module : /Web/Update.php
Desc. : Class Update Aplikasi Otomatis
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 14th, 2013.
Last Modified : August 12th, 2026.
Last Modified : August 22nd, 2026.
(c) 2013 - 2026, 3FONIA Software; WWW.3FONIA.COM.
(c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
//OK
declare(strict_types=1);
namespace siaupheng\webapp\Web;
namespace Webapp\Web;
use flight\Engine;
use \flight\Engine;
/**
* Class Update
*
* Update Otomatis Aplikasi berbasis GIT.
*
* @license MIT, https://www.3fonia.com
* @copyright Copyright (c) 2008-2026, Siau Pheng <siaupheng@3fonia.com>
*
* @package Webapp\Web
*/
final class Update {
protected Array $__conf = [];
protected Bool $is_git = false;
private Array $__conf = [];
private Bool $is_git = false;
protected Engine $app;
public function __construct(?Engine $app = null){
$this->app = (empty($app) === true) ? \Flight::app() : $app;
/**
* @param Engine $app
*/
public function __construct(Engine $app){
$this->app = $app;
$this->__conf = $app->session()->get('__WEB_APP');
$this->current();
}
public function current() {
$_target = $this->__conf['REAL_PATH'];
if (isset($_target)) chdir($_target);
public function current(): void {
if (defined('PROJECT_ROOT')) chdir(PROJECT_ROOT);
try {
$output = shell_exec("git log -1 --pretty=format:\"%H||%s||%ci\" --abbrev-commit 2>&1");
if ($output) {
@@ -57,7 +67,7 @@ final class Update {
}
}
public function check() {
public function check(): array {
$_ainfo['cur_version'] = $this->__conf['APP_BUILD'];
$_ainfo['cur_sha'] = substr($this->__conf['GIT_SHA1'], 0, 10);
$_ainfo['cur_sha1'] = $this->__conf['GIT_SHA1'];
@@ -89,14 +99,13 @@ final class Update {
return $_ainfo;
}
public function go() {
$_target = $this->__conf['REAL_PATH'];
public function go(): array {
$_branch = $this->__conf['GIT_BRANCH'] ?? "main";
if (isset($_target)) {
chdir($_target);
if (defined('PROJECT_ROOT')) {
chdir(PROJECT_ROOT);
$output = shell_exec("git reset --hard HEAD && git pull origin {$_branch} 2>&1");
return ['success'=>true,'message'=>$output];
} else return ['success'=>false,'message'=>"Tanpa REAL_PATH !"];
} else return ['success'=>false,'message'=>"Tanpa PROJECT_ROOT !"];
}
public function mysql() {