7 Commits
51 changed files with 2081 additions and 8094 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
[![Software License][ico-license]](LICENSE.md) [![Software License][ico-license]](LICENSE.md)
[![Total Downloads][ico-downloads]][link-downloads] [![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. Maintenance versi repo tambahan, akan dilakukan secara periodik dengan mempertimbangkan kesiapan infrastruktur framework secara utuh.
-506
View File
@@ -1,506 +0,0 @@
.CodeMirror {
font-family: monospace;
height: 300px;
color: #000;
direction: ltr
}
.CodeMirror-lines {
padding: 4px 0
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
padding: 0 4px
}
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
background-color: #fff
}
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap
}
.CodeMirror-guttermarker {
color: #000
}
.CodeMirror-guttermarker-subtle {
color: #999
}
.CodeMirror-cursor {
border-left: 1px solid #000;
border-right: none;
width: 0
}
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0!important;
background: #7e7
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, .5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7
}
@-moz-keyframes blink {
0% {}
50% {
background-color: transparent
}
100% {}
}
@-webkit-keyframes blink {
0% {}
50% {
background-color: transparent
}
100% {}
}
@keyframes blink {
0% {}
50% {
background-color: transparent
}
100% {}
}
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab {
display: inline-block;
text-decoration: inherit
}
.CodeMirror-rulers {
position: absolute;
left: 0;
right: 0;
top: -50px;
bottom: 0;
overflow: hidden
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0;
bottom: 0;
position: absolute
}
.cm-s-default .cm-header {
color: blue
}
.cm-s-default .cm-quote {
color: #090
}
.cm-negative {
color: #d44
}
.cm-positive {
color: #292
}
.cm-header,
.cm-strong {
font-weight: 700
}
.cm-em {
font-style: italic
}
.cm-link {
text-decoration: underline
}
.cm-strikethrough {
text-decoration: line-through
}
.cm-s-default .cm-keyword {
color: #708
}
.cm-s-default .cm-atom {
color: #219
}
.cm-s-default .cm-number {
color: #164
}
.cm-s-default .cm-def {
color: #00f
}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {
color: #05a
}
.cm-s-default .cm-variable-3,
.cm-s-default .cm-type {
color: #085
}
.cm-s-default .cm-comment {
color: #a50
}
.cm-s-default .cm-string {
color: #a11
}
.cm-s-default .cm-string-2 {
color: #f50
}
.cm-s-default .cm-meta {
color: #555
}
.cm-s-default .cm-qualifier {
color: #555
}
.cm-s-default .cm-builtin {
color: #30a
}
.cm-s-default .cm-bracket {
color: #997
}
.cm-s-default .cm-tag {
color: #170
}
.cm-s-default .cm-attribute {
color: #00c
}
.cm-s-default .cm-hr {
color: #999
}
.cm-s-default .cm-link {
color: #00c
}
.cm-s-default .cm-error {
color: red
}
.cm-invalidchar {
color: red
}
.CodeMirror-composing {
border-bottom: 2px solid
}
div.CodeMirror span.CodeMirror-matchingbracket {
color: #0b0
}
div.CodeMirror span.CodeMirror-nonmatchingbracket {
color: #a22
}
.CodeMirror-matchingtag {
background: rgba(255, 150, 0, .3)
}
.CodeMirror-activeline-background {
background: #e8f2ff
}
.CodeMirror {
position: relative;
overflow: hidden;
background: #fff
}
.CodeMirror-scroll {
overflow: scroll!important;
margin-bottom: -30px;
margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none;
position: relative
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent
}
.CodeMirror-vscrollbar,
.CodeMirror-hscrollbar,
.CodeMirror-scrollbar-filler,
.CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none
}
.CodeMirror-vscrollbar {
right: 0;
top: 0;
overflow-x: hidden;
overflow-y: scroll
}
.CodeMirror-hscrollbar {
bottom: 0;
left: 0;
overflow-y: hidden;
overflow-x: scroll
}
.CodeMirror-scrollbar-filler {
right: 0;
bottom: 0
}
.CodeMirror-gutter-filler {
left: 0;
bottom: 0
}
.CodeMirror-gutters {
position: absolute;
left: 0;
top: 0;
min-height: 100%;
z-index: 3
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: 0 0!important;
border: none!important
}
.CodeMirror-gutter-background {
position: absolute;
top: 0;
bottom: 0;
z-index: 4
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4
}
.CodeMirror-gutter-wrapper::selection {
background-color: transparent
}
.CodeMirror-gutter-wrapper::-moz-selection {
background-color: transparent
}
.CodeMirror-lines {
cursor: text;
min-height: 1px
}
.CodeMirror pre.CodeMirror-line,
.CodeMirror pre.CodeMirror-line-like {
-moz-border-radius: 0;
-webkit-border-radius: 0;
border-radius: 0;
border-width: 0;
background: 0 0;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual
}
.CodeMirror-wrap pre.CodeMirror-line,
.CodeMirror-wrap pre.CodeMirror-line-like {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal
}
.CodeMirror-linebackground {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 0
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
padding: .1px
}
.CodeMirror-widget {}
.CodeMirror-rtl pre {
direction: rtl
}
.CodeMirror-code {
outline: none
}
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none
}
.CodeMirror-measure pre {
position: static
}
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3
}
div.CodeMirror-dragcursors {
visibility: visible
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible
}
.CodeMirror-selected {
background: #d9d9d9
}
.CodeMirror-focused .CodeMirror-selected {
background: #d7d4f0
}
.CodeMirror-crosshair {
cursor: crosshair
}
.CodeMirror-line::selection,
.CodeMirror-line>span::selection,
.CodeMirror-line>span>span::selection {
background: #d7d4f0
}
.CodeMirror-line::-moz-selection,
.CodeMirror-line>span::-moz-selection,
.CodeMirror-line>span>span::-moz-selection {
background: #d7d4f0
}
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4)
}
.cm-force-border {
padding-right: .1px
}
@media print {
.CodeMirror div.CodeMirror-cursors {
visibility: hidden
}
}
.cm-tab-wrap-hack:after {
content: ''
}
span.CodeMirror-selectedtext {
background: 0 0
}
File diff suppressed because one or more lines are too long
+12 -1
View File
@@ -6,7 +6,7 @@
Created Date : December 20th, 2007. Created Date : December 20th, 2007.
Last Modified : February 7th, 2026. 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; background-color: #d8dbe0;
opacity: 1; 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. Created Date : October 7th, 2008.
Last Modified : November 24th, 2020. Last Modified : November 24th, 2020.
(c) 2008 - 2020, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
-217
View File
@@ -1,217 +0,0 @@
[data-simplebar] {
position: relative;
flex-direction: column;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
}
.simplebar-wrapper {
overflow: hidden;
width: inherit;
height: inherit;
max-width: inherit;
max-height: inherit;
}
.simplebar-mask {
direction: inherit;
position: absolute;
overflow: hidden;
padding: 0;
margin: 0;
left: 0;
top: 0;
bottom: 0;
right: 0;
width: auto !important;
height: auto !important;
z-index: 0;
}
.simplebar-offset {
direction: inherit !important;
box-sizing: inherit !important;
resize: none !important;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
padding: 0;
margin: 0;
-webkit-overflow-scrolling: touch;
}
.simplebar-content-wrapper {
direction: inherit;
box-sizing: border-box !important;
position: relative;
display: block;
height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */
width: auto;
max-width: 100%; /* Not required for horizontal scroll to trigger */
max-height: 100%; /* Needed for vertical scroll to trigger */
scrollbar-width: none;
-ms-overflow-style: none;
}
.simplebar-content-wrapper::-webkit-scrollbar,
.simplebar-hide-scrollbar::-webkit-scrollbar {
width: 0;
height: 0;
}
.simplebar-content:before,
.simplebar-content:after {
content: ' ';
display: table;
}
.simplebar-placeholder {
max-height: 100%;
max-width: 100%;
width: 100%;
pointer-events: none;
}
.simplebar-height-auto-observer-wrapper {
box-sizing: inherit !important;
height: 100%;
width: 100%;
max-width: 1px;
position: relative;
float: left;
max-height: 1px;
overflow: hidden;
z-index: -1;
padding: 0;
margin: 0;
pointer-events: none;
flex-grow: inherit;
flex-shrink: 0;
flex-basis: 0;
}
.simplebar-height-auto-observer {
box-sizing: inherit;
display: block;
opacity: 0;
position: absolute;
top: 0;
left: 0;
height: 1000%;
width: 1000%;
min-height: 1px;
min-width: 1px;
overflow: hidden;
pointer-events: none;
z-index: -1;
}
.simplebar-track {
z-index: 1;
position: absolute;
right: 0;
bottom: 0;
pointer-events: none;
overflow: hidden;
}
[data-simplebar].simplebar-dragging .simplebar-content {
pointer-events: none;
user-select: none;
-webkit-user-select: none;
}
[data-simplebar].simplebar-dragging .simplebar-track {
pointer-events: all;
}
.simplebar-scrollbar {
position: absolute;
left: 0;
right: 0;
min-height: 10px;
}
.simplebar-scrollbar:before {
position: absolute;
content: '';
background: black;
border-radius: 7px;
left: 2px;
right: 2px;
opacity: 0;
transition: opacity 0.2s linear;
}
.simplebar-scrollbar.simplebar-visible:before {
/* When hovered, remove all transitions from drag handle */
opacity: 0.5;
transition: opacity 0s linear;
}
.simplebar-track.simplebar-vertical {
top: 0;
width: 11px;
}
.simplebar-track.simplebar-vertical .simplebar-scrollbar:before {
top: 2px;
bottom: 2px;
}
.simplebar-track.simplebar-horizontal {
left: 0;
height: 11px;
}
.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before {
height: 100%;
left: 2px;
right: 2px;
}
.simplebar-track.simplebar-horizontal .simplebar-scrollbar {
right: auto;
left: 0;
top: 2px;
height: 7px;
min-height: 0;
min-width: 10px;
width: auto;
}
/* Rtl support */
[data-simplebar-direction='rtl'] .simplebar-track.simplebar-vertical {
right: auto;
left: 0;
}
.hs-dummy-scrollbar-size {
direction: rtl;
position: fixed;
opacity: 0;
visibility: hidden;
height: 500px;
width: 500px;
overflow-y: hidden;
overflow-x: scroll;
}
.simplebar-hide-scrollbar {
position: fixed;
left: 0;
visibility: hidden;
overflow-y: scroll;
scrollbar-width: none;
-ms-overflow-style: none;
}
.simplebar-content {
display: flex;
flex-direction: column;
min-height: 100%;
}
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
-402
View File
@@ -1,402 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var htmlConfig = {
autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true},
implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true},
contextGrabbers: {
'dd': {'dd': true, 'dt': true},
'dt': {'dd': true, 'dt': true},
'li': {'li': true},
'option': {'option': true, 'optgroup': true},
'optgroup': {'optgroup': true},
'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true},
'rp': {'rp': true, 'rt': true},
'rt': {'rp': true, 'rt': true},
'tbody': {'tbody': true, 'tfoot': true},
'td': {'td': true, 'th': true},
'tfoot': {'tbody': true},
'th': {'td': true, 'th': true},
'thead': {'tbody': true, 'tfoot': true},
'tr': {'tr': true}
},
doNotIndent: {"pre": true},
allowUnquoted: true,
allowMissing: true,
caseFold: true
}
var xmlConfig = {
autoSelfClosers: {},
implicitlyClosed: {},
contextGrabbers: {},
doNotIndent: {},
allowUnquoted: false,
allowMissing: false,
allowMissingTagName: false,
caseFold: false
}
CodeMirror.defineMode("xml", function(editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
for (var prop in config_) config[prop] = config_[prop]
// Return variables for tokenizers
var type, setStyle;
function inText(stream, state) {
function chain(parser) {
state.tokenize = parser;
return parser(stream, state);
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
state.tokenize = inTag;
return "tag bracket";
}
} else if (ch == "&") {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
}
return ok ? "atom" : "error";
} else {
stream.eatWhile(/[^&<]/);
return null;
}
}
inText.isInText = true;
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
return null;
} else if (ch == "<") {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
}
}
function inAttribute(quote) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
break;
}
stream.next();
}
return style;
}
}
function doctype(depth) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
if (depth == 1) {
state.tokenize = inText;
break;
} else {
state.tokenize = doctype(depth - 1);
return state.tokenize(stream, state);
}
}
}
return "meta";
};
}
function Context(state, tagName, startOfLine) {
this.prev = state.context;
this.tagName = tagName;
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
this.noIndent = true;
}
function popContext(state) {
if (state.context) state.context = state.context.prev;
}
function maybePopContext(state, nextTagName) {
var parentTagName;
while (true) {
if (!state.context) {
return;
}
parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
return;
}
popContext(state);
}
}
function baseState(type, stream, state) {
if (type == "openTag") {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
state.tagName = stream.current();
setStyle = "tag";
return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return attrState(type, stream, state);
} else {
setStyle = "error";
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName))
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
return closeState;
} else {
setStyle = "tag error";
return closeStateErr;
}
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
return closeState(type, stream, state);
} else {
setStyle = "error";
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(tagName)) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
}
return baseState;
}
setStyle = "error";
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!config.allowMissing) setStyle = "error";
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && config.allowUnquoted) {setStyle = "string"; return attrState;}
setStyle = "error";
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function(baseIndent) {
var state = {tokenize: inText,
state: baseState,
indented: baseIndent || 0,
tagName: null, tagStart: null,
context: null}
if (baseIndent != null) state.baseIndent = baseIndent
return state
},
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
}
return style;
},
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0;
// Indent the starts of attribute names.
if (state.tagName) {
if (config.multilineTagIndentPastTag !== false)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
}
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
while (context) {
var grabbers = config.contextGrabbers[context.tagName];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
context = context.prev;
else
break;
}
}
while (context && context.prev && !context.startOfLine)
context = context.prev;
if (context) return context.indent + indentUnit;
else return state.baseIndent || 0;
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
configuration: config.htmlMode ? "html" : "xml",
helperType: config.htmlMode ? "html" : "xml",
skipAttribute: function(state) {
if (state.state == attrValueState)
state.state = attrState
}
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true});
});
+2 -2
View File
@@ -1,12 +1,12 @@
/******************************************************************* /*******************************************************************
Module : /modules/js/export.js Module : /assets/js/export.js
Desc. : Fungsi-fungsi export data & laporan Desc. : Fungsi-fungsi export data & laporan
Created By : Siau Pheng ([email protected]). Created By : Siau Pheng ([email protected]).
Created Date : April 1st, 2011. Created Date : April 1st, 2011.
Last Modified : January 19th, 2026. Last Modified : January 19th, 2026.
(c) 2011 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
+136 -98
View File
@@ -6,7 +6,7 @@
Created Date : June 19th, 2009. Created Date : June 19th, 2009.
Last Modified : February 10th, 2026. Last Modified : February 10th, 2026.
(c) 2009 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
@@ -17,7 +17,6 @@ var FoniaJS = {
APP_ID: 0, APP_ID: 0,
APP_SID: "", APP_SID: "",
WEB_HOST: "", WEB_HOST: "",
WEB_PATH: "",
WEB_FULLPATH: "", WEB_FULLPATH: "",
WEB_MOBILE: 0, WEB_MOBILE: 0,
AUTH_LEVEL: 9, AUTH_LEVEL: 9,
@@ -35,11 +34,10 @@ var FoniaJS = {
this.APP_ID = _adata[0]; this.APP_ID = _adata[0];
this.APP_SID = _adata[1]; this.APP_SID = _adata[1];
this.WEB_HOST = _adata[2]; this.WEB_HOST = _adata[2];
this.WEB_PATH = _adata[3]; this.WEB_FULLPATH = _adata[3];
this.WEB_FULLPATH = _adata[4]; this.WEB_MOBILE = _adata[4];
this.WEB_MOBILE = _adata[5]; this.AUTH_LEVEL = parseInt(_adata[5]);
this.AUTH_LEVEL = parseInt(_adata[6]); this.phpversion = '';
this.phpversion = _adata[7];
} }
if (typeof(skey) === 'string' && skey !== '') { if (typeof(skey) === 'string' && skey !== '') {
_hasil = $.base64.decode(skey); _hasil = $.base64.decode(skey);
@@ -62,38 +60,36 @@ var FoniaJS = {
var apar = ["p=" + p]; var apar = ["p=" + p];
if (q != null) apar.push("q=" + q); if (q != null) apar.push("q=" + q);
new Request.JSON({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/menu",
sendParam: apar, sendParam: apar,
onSuccess: (apop) => { onSuccess: (apop) => {
if (apop.login == false) { if (apop.login == false) {
this.showErrorLocale("Fonia.sess_expire"); this.showErrorLocale("Fonia.sess_expire");
setTimeout(function(){self.location = FoniaJS.WEB_PATH;}, 1600); setTimeout(() => { self.location = self.location.href; }, 1600);
return false; return false;
} }
if (apop.php == "" || !window[apop.func]) { if (apop.php == "" || !window[apop.func]) {
this.showErrorLocale("Fonia.page404"); this.showErrorLocale("Fonia.page404");
return false; return false;
} }
window[apop.func]['PHP'] = this.WEB_PATH + "apps/php/" + apop.php; window[apop.func]['PHP'] = apop.php;
window[apop.func]['KODE'] = apop.kode; window[apop.func]['KODE'] = apop.kode;
if (apop.iswindow == true) { if (apop.iswindow == true) {
if (IndexJS.loading) IndexJS.loading(); if (IndexJS.loading) IndexJS.loading();
new Request({ new Request.JSON({
url: this.WEB_PATH + "apps/php/" + apop.php, url: apop.php + '/index',
sendParam: ["data=default"], onSuccess: (ajson) => {
onSuccess: (txt) => { this.showWindow(apop.kode, apop.title, ajson.html, apop.width, apop.button, () => {
this.showWindow(apop.kode, apop.title, txt, apop.width, apop.button, function(){
if (typeof window[apop.func]['loading'] === 'function') window[apop.func]['loading'](q); if (typeof window[apop.func]['loading'] === 'function') window[apop.func]['loading'](q);
}); });
} }
}).send(); }).send();
} else { } else {
$("#pageToolbarBot").html(this.genToolButton(apop.button)); $("#pageToolbarBot").html(this.genToolButton(apop.button));
new Request({ new Request.JSON({
url: this.WEB_PATH + "apps/php/" + apop.php, url: apop.php + '/index',
sendParam: ["data=default"], onSuccess: (ajson) => {
onSuccess: (txt) => { $('#pageContent').html(ajson.html);
$('#pageContent').html(txt);
if (typeof window[apop.func]['loading'] === 'function') window[apop.func]['loading'](q); if (typeof window[apop.func]['loading'] === 'function') window[apop.func]['loading'](q);
} }
}).send(); }).send();
@@ -122,13 +118,12 @@ var FoniaJS = {
if ($('#ExitLink').length) { if ($('#ExitLink').length) {
$('#ExitLink').click(() => { $('#ExitLink').click(() => {
new Request.JSON({ new Request.JSON({
url: this.WEB_PATH + "apps/php/login.php", url: "auth/logout",
sendParam: ["mode=logout"],
onFailure: () => { onFailure: () => {
self.location = (['localhost','127.0.0.1'].indexOf(location.hostname) >= 0) ? this.WEB_PATH : "/"; self.location = self.location.href;
}, },
onSuccess: (respon) => { onSuccess: (respon) => {
var _nurl = (['localhost','127.0.0.1'].indexOf(location.hostname) >= 0) ? this.WEB_PATH : "/"; var _nurl = self.location.href;
if (typeof respon !== 'undefined' && respon.nexthost !== '/') _nurl = respon.nexthost; if (typeof respon !== 'undefined' && respon.nexthost !== '/') _nurl = respon.nexthost;
self.location = _nurl; self.location = _nurl;
} }
@@ -167,8 +162,8 @@ var FoniaJS = {
$('#butSOK').click(() => { $('#butSOK').click(() => {
$('#butSOK').prop('disabled', true); $('#butSOK').prop('disabled', true);
new Request.JSON({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/supervisi",
sendParam: ["mode=auth", "data=super-check", "UID", "PWD", "SUPER=" + _bsuper, "UOVER=" + _buover], sendParam: ["data=super-check", "UID", "PWD", "SUPER=" + _bsuper, "UOVER=" + _buover],
onSuccess: (adata) => { onSuccess: (adata) => {
if (adata.status == 1) { if (adata.status == 1) {
fungcall(); fungcall();
@@ -182,9 +177,9 @@ var FoniaJS = {
$('#butSBatal').click(() => { $('#butSBatal').click(() => {
if (_ceksuper) { if (_ceksuper) {
clearInterval(_ceksuper); clearInterval(_ceksuper);
new Request({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/supervisi",
sendParam: ["mode=auth", "data=super-cancel", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid] sendParam: ["data=super-cancel", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid]
}).send(); }).send();
} }
}); });
@@ -194,26 +189,26 @@ var FoniaJS = {
$('#Auth_SP2').addClass('d-none'); $('#Auth_SP2').addClass('d-none');
$('#Auth_SP3').removeClass('d-none'); $('#Auth_SP3').removeClass('d-none');
$('#butSOK').prop('disabled', true); $('#butSOK').prop('disabled', true);
new Request({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/supervisi",
sendParam: ["mode=auth", "data=super-request", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid, "MSG=" + tmsg] sendParam: ["data=super-request", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid, "MSG=" + tmsg]
}).send(); }).send();
var _cobalagi = 5; var _cobalagi = 5;
_ceksuper = setInterval(() => { _ceksuper = setInterval(() => {
$('#butSBatal').html(this.locale("Fonia.cancel") + " (" + _cobalagi + ")"); $('#butSBatal').html(this.locale("Fonia.cancel") + " (" + _cobalagi + ")");
if (_cobalagi == 0) { if (_cobalagi == 0) {
clearInterval(_ceksuper); clearInterval(_ceksuper);
new Request({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/supervisi",
sendParam: ["mode=auth", "data=super-cancel", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid] sendParam: ["data=super-cancel", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid]
}).send(); }).send();
this.closeWindow(this.winSAuth); this.closeWindow(this.winSAuth);
this.showErrorLocale("Fonia.auth_fail"); this.showErrorLocale("Fonia.auth_fail");
return false; return false;
} }
new Request.JSON({ new Request.JSON({
url: this.WEB_PATH + "auth.php", url: "auth/supervisi",
sendParam: ["mode=auth", "data=request-check", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid], sendParam: ["data=request-check", "KODE=" + ocall.KODE, "REQ_SID=" + this.APP_SID, "REQ=" + _tsid],
onSuccess: (adata) => { onSuccess: (adata) => {
if (adata.status == 1) { if (adata.status == 1) {
clearInterval(_ceksuper); clearInterval(_ceksuper);
@@ -290,52 +285,95 @@ var FoniaJS = {
return smenu; return smenu;
}, },
FormDecorated: function() { FormDecorated: function() {
$('input').each((i, el) => { $('input.form-control[class*=integer], input.form-control[class*=angka]').each((i, el) => {
const elm = $(el); const elm = $(el);
// 16:shift 17:ctrl 18:alt 35:end 36:home 37:left 38:up 39:right 40:down 9:tab 13:enter 27:esc elm.on('keypress keyup blur paste', (e) => {
// 8:backspace 46:delete 45:delete 48-57/96-105:num 110/190:dot 109/189/173:minus 107/187/61:plus elm.val(elm.val().replace(/[^\d].+/, ""));
if (elm.hasClass('integer') || elm.hasClass('angka')) { if ((e.which < 48 || e.which > 57)) e.preventDefault();
elm.keydown((e) => {
var key = e.keyCode ?? e.which;
return (jQuery.inArray(key,[8,9,13,46,110,190])!==-1 || (key>=16 && key<=18) || (key>=35 && key<=40) || (key>=48 && key<=57) || (key>=96 && key<=105));
}); });
} else if (elm.hasClass('number')) {
elm.keydown((e) => {
var key = e.keyCode ?? e.which;
return (jQuery.inArray(key,[8,9,13,46,110,190,109,189,173])!==-1 || (key>=16 && key<=18) || (key>=35 && key<=40) || (key>=48 && key<=57) || (key>=96 && key<=105));
}); });
elm.focus((e) => { $('input.form-control[class*=double]').each((i, el) => {
$(e.currentTarget).val( FoniaJS.StrToFloat($(e.currentTarget).val()) ); const elm = $(el);
elm.on('keypress keyup blur paste', (e) => {
elm.val(elm.val().replace(/[^0-9\.]/g,''));
if (e.type === 'blur') elm.val( FoniaJS.FloatToStr(elm.val(), 2) );
if ((e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
}); });
elm.blur((e) => { elm.on('focus', (e) => {
$(e.currentTarget).val( FoniaJS.FloatToStr($(e.currentTarget).val(), 0) ); elm.val( FoniaJS.StrToFloat(elm.val()) );
elm.select();
e.preventDefault();
}); });
} else if (elm.hasClass('double')) {
elm.keydown((e) => {
var key = e.keyCode ?? e.which;
return (jQuery.inArray(key,[8,9,13,46,110,190,109,189,173])!==-1 || (key>=16 && key<=18) || (key>=35 && key<=40) || (key>=48 && key<=57) || (key>=96 && key<=105));
}); });
elm.focus((e) => { $('input.form-control[type=number]').each((i, el) => {
$(e.currentTarget).val( FoniaJS.StrToFloat($(e.currentTarget).val()) ); const elm = $(el);
$(e.currentTarget).select(); elm.on('keypress keyup blur paste', (e) => {
elm.val(elm.val().replace(/[^0-9]/g,''));
if ((e.which != 46 || elm.val().indexOf('.') != -1) && (e.which < 48 || e.which > 57)) e.preventDefault();
}); });
elm.blur((e) => {
$(e.currentTarget).val( FoniaJS.FloatToStr($(e.currentTarget).val(), 2) );
}); });
} else if (elm.hasClass('phone')) { $('input.form-control, textarea.form-control, select.form-select').each((i, el) => {
elm.keyup((e) => { const elm = $(el);
var key = e.keyCode ?? e.which; const okyup = elm.attr('okyup') ?? '';
return (jQuery.inArray(key,[8,9,13,46,110,190,109,189,173,107,187,61])!==-1 || (key>=16 && key<=18) || (key>=35 && key<=40) || (key>=48 && key<=57) || (key>=96 && key<=105)); const oblur = elm.attr('oblur') ?? '';
}); const ochan = elm.attr('ochan') ?? '';
} else if (elm.hasClass('error') && elm.val()) { elm.on('keyup blur change', (e) => {
var tmp_str = elm.val(); if (e.type === 'keyup' && okyup) {
elm.val(''); var fnc = okyup.split('.');
FoniaJS.showError(tmp_str); if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+okyup+' tidak ada !');
} }
if (e.type === 'blur' && oblur) {
var fnc = oblur.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+oblur+' tidak ada !');
}
if (e.type === 'change' && ochan) {
var fnc = ochan.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+ochan+' tidak ada !');
}
e.preventDefault();
});
});
$('input.form-check-input[type=radio]').each((i, el) => {
const elm = $(el);
elm.on('click', () => {
const oclic = elm.attr('ochan') ?? '';
const elp = $('#'+elm.attr('name'));
if (elm.is(':checked')) elp.val(elm.val());
if (oclic) {
var fnc = oclic.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+oclic+' tidak ada !');
}
});
});
$('input.form-check-input[type=checkbox]').each((i, el) => {
const elm = $(el);
elm.on('change', () => {
const odata = JSON.parse(elm.attr('odata') ?? '[]');
const ochan = elm.attr('ochan') ?? '';
elm.val(elm.is(':checked') ? odata[0] : odata[1]);
if (ochan) {
var fnc = ochan.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+ochan+' tidak ada !');
}
});
});
$('input[class*=error][type=hidden]').each((i, el) => {
const elm = $(el);
this.showError(elm.val());
}); });
$('.option-tags').each((i, el) => { $('.option-tags').each((i, el) => {
const elm = $(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 _opts = {tags: false, dropdownAutoWidth: true, width: 'auto', theme: 'bootstrap-5', language: 'id'};
var _dmodal = elm.closest('div.modal'); var _dmodal = elm.closest('div.modal');
if (_dmodal.length) _opts.dropdownParent = _dmodal; if (_dmodal.length) _opts.dropdownParent = _dmodal;
@@ -345,7 +383,7 @@ var FoniaJS = {
}); });
$('[data-toggle="tooltip"]').tooltip(); $('[data-toggle="tooltip"]').tooltip();
if('function' == typeof jQuery.fn.datepicker){ if('function' == typeof jQuery.fn.datepicker){
$('.pickdate').datepicker({ $('.input-group.date').datepicker({
format: 'dd-mm-yyyy', format: 'dd-mm-yyyy',
weekStart: 1, weekStart: 1,
language: 'id', language: 'id',
@@ -360,11 +398,6 @@ var FoniaJS = {
RequestParam: function(aparam) { RequestParam: function(aparam) {
var tmp_hasil = []; var tmp_hasil = [];
var tmp_array = aparam; var tmp_array = aparam;
/*$('input').each((i, el) => {
if (el.id.indexOf('_db')!==-1){
tmp_array.push(el.id);
}
});*/
var tmp_cblist = {}; var tmp_cblist = {};
$('tbody input[id*="cbox"][type="checkbox"]:checked').map((i, b) => { $('tbody input[id*="cbox"][type="checkbox"]:checked').map((i, b) => {
const arr = b.id.split('_'); const arr = b.id.split('_');
@@ -387,15 +420,6 @@ var FoniaJS = {
} else { } else {
tmp_value = ($('#'+nilai).is('.integer, .number, .double')) ? this.StrToFloat(tmp_value) : encodeURIComponent(tmp_value); tmp_value = ($('#'+nilai).is('.integer, .number, .double')) ? this.StrToFloat(tmp_value) : encodeURIComponent(tmp_value);
} }
/*if ($('#'+nilai).hasClass("cgrpbox")) {//not used !
var _tmp_value = "";
$('input').each((i, el) => {
if (el.id.indexOf(nilai + "_cgrpbox")!==-1 && el.checked) {
_tmp_value += "," + el.value;
}
});
tmp_value = _tmp_value.substr(1);
}*/
} }
tmp_value = nilai + "=" + tmp_value; tmp_value = nilai + "=" + tmp_value;
} else { } else {
@@ -774,7 +798,7 @@ class _Request_JSONF extends _Request {
strBody += '</tbody>'; strBody += '</tbody>';
$(divData).append(strTab + strHead + strBody + strFoot + '</table>'); $(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 **/ /** start live db **/
if (ini.config.live){ if (ini.config.live){
var post_data = {}; var post_data = {};
@@ -794,7 +818,7 @@ class _Request_JSONF extends _Request {
dataFilter: (data) => { dataFilter: (data) => {
var json = {}, jsono = {'draw':0,'recordsTotal':0,'recordsFiltered':0,'data':[]}; var json = {}, jsono = {'draw':0,'recordsTotal':0,'recordsFiltered':0,'data':[]};
try { try {
json = jQuery.parseJSON(data); json = JSON.parse(data);
if (!jQuery.isEmptyObject(json) && json.length > 0){ if (!jQuery.isEmptyObject(json) && json.length > 0){
$(json).each((i, lini) => { $(json).each((i, lini) => {
if (lini.type == 'table-live' && lini.id == ini.id) { if (lini.type == 'table-live' && lini.id == ini.id) {
@@ -841,7 +865,7 @@ class _Request_JSONF extends _Request {
} }
/** end live db **/ /** end live db **/
if (ini.option.length > 0) opsi.columnDefs.push({responsivePriority:3,targets:-1}, {orderable:false,targets:-1}); if (ini.option.length > 0) opsi.columnDefs.push({responsivePriority:3,targets:-1}, {orderable:false,targets:-1});
if (ini.navi.func_navi == '') opsi.paging = false; if (ini.navi.no_navi == true) opsi.paging = false;
if (ini.config.scrollbar == true) { if (ini.config.scrollbar == true) {
opsi.scrollY = ini.config.scroll_height; opsi.scrollY = ini.config.scroll_height;
@@ -858,12 +882,26 @@ class _Request_JSONF extends _Request {
} }
_navibar += '<div class="row"><div class="col">'; _navibar += '<div class="row"><div class="col">';
$(ini.navi.button).map((key, val) => { $(ini.navi.button).map((key, val) => {
_navibar += '<button type="button" class="btn rounded-pill '+_bcss+' me-2"'+_dis+' onclick="'+val.func+'();">'+val.label+'</button>'; _navibar += '<button type="button" class="btn rounded-pill '+_bcss+' me-2 navi-btn-'+key+'"'+_dis+'>'+val.label+'</button>';
}); });
_navibar += '</div></div>'; _navibar += '</div></div>';
} }
opsi.initComplete = function(settings,json){ opsi.initComplete = function(settings,json){
if (ini.navi.button) $('#'+ini.id+'Tabel_wrapper div.toolbar').html(_navibar); if (ini.navi.button) {
$('#'+ini.id+'Tabel_wrapper div.toolbar').html(_navibar);
// apply navi button
if (ini.navi.button.length > 0){
$(ini.navi.button).map((key, val) => {
$('#'+ini.id+'Tabel_wrapper div.toolbar button[class*=navi-btn-'+key+']').on('click', (e) => {
e.preventDefault();
var fnc = val.func.split('.');
if (typeof window[fnc[0]][fnc[1]] === 'function'){
window[fnc[0]][fnc[1]]();
} else console.warn('fungsi '+val.func+' tidak ada !');
});
});
}
}
} }
opsi.drawCallback = function(settings){ opsi.drawCallback = function(settings){
// apply rowcss to tr/row // apply rowcss to tr/row
@@ -908,16 +946,16 @@ class _Request_JSONF extends _Request {
$(ini.option).map((key, val) => { $(ini.option).map((key, val) => {
if (val.type == 'checkbox'){ if (val.type == 'checkbox'){
$('#'+ini.id+'Tabel thead input[type=checkbox][id*=_cbhead_]').on('change', (e) => { $('#'+ini.id+'Tabel thead input[type=checkbox][id*=_cbhead_]').on('change', (e) => {
var _chek = e.currentTarget.checked; var _chek = e.currentTarget.is(':checked');
e.currentTarget.value = (e.currentTarget.checked ? val.avalue[0] : val.avalue[1]); e.currentTarget.val(e.currentTarget.is(':checked') ? val.avalue[0] : val.avalue[1]);
$('#'+ini.id+'Tabel tbody input[type=checkbox][id*='+val.field+'_cbox_]').each((i, el) => { $('#'+ini.id+'Tabel tbody input[type=checkbox][id*='+val.field+'_cbox_]').each((i, el) => {
el.checked = _chek; el.prop('checked', _chek);
el.value = (el.checked ? val.avalue[0] : val.avalue[1]); el.val(el.is(':checked') ? val.avalue[0] : val.avalue[1]);
}); });
}); });
$('#'+ini.id+'Tabel tbody input[type=checkbox][id*=_cbox_]').on('change', (e) => { $('#'+ini.id+'Tabel tbody input[type=checkbox][id*=_cbox_]').on('change', (e) => {
e.currentTarget.value = (e.currentTarget.value == val.avalue[1] ? val.avalue[0] : val.avalue[1]); e.currentTarget.val(e.currentTarget.val() == val.avalue[1] ? val.avalue[0] : val.avalue[1]);
e.currentTarget.checked = e.currentTarget.value == val.avalue[0]; e.currentTarget.prop('checked', e.currentTarget.val() == val.avalue[0]);
}); });
} else if (val.type == 'button'){ } else if (val.type == 'button'){
$('#'+ini.id+'Tabel tbody').on('click', '.'+val.icon, (e) => { $('#'+ini.id+'Tabel tbody').on('click', '.'+val.icon, (e) => {
@@ -981,7 +1019,7 @@ var Request = function (options) {
}; };
Request.JSON = function (options) { Request.JSON = function (options) {
const _options = Object.assign({}, options, {'dataType':'json'}); const _options = Object.assign({}, options, { 'dataType': 'json' });
return new _Request(_options); return new _Request(_options);
}; };
-448
View File
@@ -1,448 +0,0 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var ua = navigator.userAgent,
iPhone = /iphone/i.test(ua),
chrome = /chrome/i.test(ua),
android = /android/i.test(ua),
caretTimeoutId;
$.mask = {
//Predefined character definitions
definitions: {
'9': "[0-9]",
'a': "[A-Za-z]",
'*': "[A-Za-z0-9]"
},
autoclear: true,
dataName: "rawMaskFn",
placeholder: '_'
};
$.fn.extend({
//Helper Function for Caret positioning
caret: function(begin, end) {
var range;
if (this.length === 0 || this.is(":hidden") || this.get(0) !== document.activeElement) {
return;
}
if (typeof begin == 'number') {
end = (typeof end === 'number') ? end : begin;
return this.each(function() {
if (this.setSelectionRange) {
this.setSelectionRange(begin, end);
} else if (this.createTextRange) {
range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', begin);
range.select();
}
});
} else {
if (this[0].setSelectionRange) {
begin = this[0].selectionStart;
end = this[0].selectionEnd;
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
begin = 0 - range.duplicate().moveStart('character', -100000);
end = begin + range.text.length;
}
return { begin: begin, end: end };
}
},
unmask: function() {
return this.trigger("unmask");
},
mask: function(mask, settings) {
var input,
defs,
tests,
partialPosition,
firstNonMaskPos,
lastRequiredNonMaskPos,
len,
oldVal;
if (!mask && this.length > 0) {
input = $(this[0]);
var fn = input.data($.mask.dataName)
return fn?fn():undefined;
}
settings = $.extend({
autoclear: $.mask.autoclear,
placeholder: $.mask.placeholder, // Load default placeholder
completed: null
}, settings);
defs = $.mask.definitions;
tests = [];
partialPosition = len = mask.length;
firstNonMaskPos = null;
mask = String(mask);
$.each(mask.split(""), function(i, c) {
if (c == '?') {
len--;
partialPosition = i;
} else if (defs[c]) {
tests.push(new RegExp(defs[c]));
if (firstNonMaskPos === null) {
firstNonMaskPos = tests.length - 1;
}
if(i < partialPosition){
lastRequiredNonMaskPos = tests.length - 1;
}
} else {
tests.push(null);
}
});
return this.trigger("unmask").each(function() {
var input = $(this),
buffer = $.map(
mask.split(""),
function(c, i) {
if (c != '?') {
return defs[c] ? getPlaceholder(i) : c;
}
}),
defaultBuffer = buffer.join(''),
focusText = input.val();
function tryFireCompleted(){
if (!settings.completed) {
return;
}
for (var i = firstNonMaskPos; i <= lastRequiredNonMaskPos; i++) {
if (tests[i] && buffer[i] === getPlaceholder(i)) {
return;
}
}
settings.completed.call(input);
}
function getPlaceholder(i){
if(i < settings.placeholder.length)
return settings.placeholder.charAt(i);
return settings.placeholder.charAt(0);
}
function seekNext(pos) {
while (++pos < len && !tests[pos]);
return pos;
}
function seekPrev(pos) {
while (--pos >= 0 && !tests[pos]);
return pos;
}
function shiftL(begin,end) {
var i,
j;
if (begin<0) {
return;
}
for (i = begin, j = seekNext(end); i < len; i++) {
if (tests[i]) {
if (j < len && tests[i].test(buffer[j])) {
buffer[i] = buffer[j];
buffer[j] = getPlaceholder(j);
} else {
break;
}
j = seekNext(j);
}
}
writeBuffer();
input.caret(Math.max(firstNonMaskPos, begin));
}
function shiftR(pos) {
var i,
c,
j,
t;
for (i = pos, c = getPlaceholder(pos); i < len; i++) {
if (tests[i]) {
j = seekNext(i);
t = buffer[i];
buffer[i] = c;
if (j < len && tests[j].test(t)) {
c = t;
} else {
break;
}
}
}
}
function androidInputEvent(e) {
var curVal = input.val();
var pos = input.caret();
if (oldVal && oldVal.length && oldVal.length > curVal.length ) {
// a deletion or backspace happened
checkVal(true);
while (pos.begin > 0 && !tests[pos.begin-1])
pos.begin--;
if (pos.begin === 0)
{
while (pos.begin < firstNonMaskPos && !tests[pos.begin])
pos.begin++;
}
input.caret(pos.begin,pos.begin);
} else {
var pos2 = checkVal(true);
var lastEnteredValue = curVal.charAt(pos.begin);
if (pos.begin < len){
if(!tests[pos.begin]){
pos.begin++;
if(tests[pos.begin].test(lastEnteredValue)){
pos.begin++;
}
}else{
if(tests[pos.begin].test(lastEnteredValue)){
pos.begin++;
}
}
}
input.caret(pos.begin,pos.begin);
}
tryFireCompleted();
}
function blurEvent(e) {
checkVal();
if (input.val() != focusText)
input.change();
}
function keydownEvent(e) {
if (input.prop("readonly")){
return;
}
var k = e.which || e.keyCode,
pos,
begin,
end;
oldVal = input.val();
//backspace, delete, and escape get special treatment
if (k === 8 || k === 46 || (iPhone && k === 127)) {
pos = input.caret();
begin = pos.begin;
end = pos.end;
if (end - begin === 0) {
begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
end=k===46?seekNext(end):end;
}
clearBuffer(begin, end);
shiftL(begin, end - 1);
e.preventDefault();
} else if( k === 13 ) { // enter
blurEvent.call(this, e);
} else if (k === 27) { // escape
input.val(focusText);
input.caret(0, checkVal());
e.preventDefault();
}
}
function keypressEvent(e) {
if (input.prop("readonly")){
return;
}
var k = e.which || e.keyCode,
pos = input.caret(),
p,
c,
next;
if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
return;
} else if ( k && k !== 13 ) {
if (pos.end - pos.begin !== 0){
clearBuffer(pos.begin, pos.end);
shiftL(pos.begin, pos.end-1);
}
p = seekNext(pos.begin - 1);
if (p < len) {
c = String.fromCharCode(k);
if (tests[p].test(c)) {
shiftR(p);
buffer[p] = c;
writeBuffer();
next = seekNext(p);
if(android){
//Path for CSP Violation on FireFox OS 1.1
var proxy = function() {
$.proxy($.fn.caret,input,next)();
};
setTimeout(proxy,0);
}else{
input.caret(next);
}
if(pos.begin <= lastRequiredNonMaskPos){
tryFireCompleted();
}
}
}
e.preventDefault();
}
}
function clearBuffer(start, end) {
var i;
for (i = start; i < end && i < len; i++) {
if (tests[i]) {
buffer[i] = getPlaceholder(i);
}
}
}
function writeBuffer() { input.val(buffer.join('')); }
function checkVal(allow) {
//try to place characters where they belong
var test = input.val(),
lastMatch = -1,
i,
c,
pos;
for (i = 0, pos = 0; i < len; i++) {
if (tests[i]) {
buffer[i] = getPlaceholder(i);
while (pos++ < test.length) {
c = test.charAt(pos - 1);
if (tests[i].test(c)) {
buffer[i] = c;
lastMatch = i;
break;
}
}
if (pos > test.length) {
clearBuffer(i + 1, len);
break;
}
} else {
if (buffer[i] === test.charAt(pos)) {
pos++;
}
if( i < partialPosition){
lastMatch = i;
}
}
}
if (allow) {
writeBuffer();
} else if (lastMatch + 1 < partialPosition) {
if (settings.autoclear || buffer.join('') === defaultBuffer) {
// Invalid value. Remove it and replace it with the
// mask, which is the default behavior.
if(input.val()) input.val("");
clearBuffer(0, len);
} else {
// Invalid value, but we opt to show the value to the
// user and allow them to correct their mistake.
writeBuffer();
}
} else {
writeBuffer();
input.val(input.val().substring(0, lastMatch + 1));
}
return (partialPosition ? i : firstNonMaskPos);
}
input.data($.mask.dataName,function(){
return $.map(buffer, function(c, i) {
return tests[i]&&c!=getPlaceholder(i) ? c : null;
}).join('');
});
input
.one("unmask", function() {
input
.off(".mask")
.removeData($.mask.dataName);
})
.on("focus.mask", function() {
if (input.prop("readonly")){
return;
}
clearTimeout(caretTimeoutId);
var pos;
focusText = input.val();
pos = checkVal();
caretTimeoutId = setTimeout(function(){
if(input.get(0) !== document.activeElement){
return;
}
writeBuffer();
if (pos == mask.replace("?","").length) {
input.caret(0, pos);
} else {
input.caret(pos);
}
}, 10);
})
.on("blur.mask", blurEvent)
.on("keydown.mask", keydownEvent)
.on("keypress.mask", keypressEvent)
.on("input.mask paste.mask", function() {
if (input.prop("readonly")){
return;
}
setTimeout(function() {
var pos=checkVal(true);
input.caret(pos);
tryFireCompleted();
}, 0);
});
if (chrome && android)
{
input
.off('input.mask')
.on('input.mask', androidInputEvent);
}
checkVal(); //Perform initial check for existing values
});
}
});
}));
+2 -2
View File
@@ -1,6 +1,6 @@
/*! /*!
autosize 5.0.1 autosize 6.0.1
license: MIT license: MIT
http://www.jacklmoore.com/autosize http://www.jacklmoore.com/autosize
*/ */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e||self).autosize=t()}(this,function(){var e,t,n="function"==typeof Map?new Map:(e=[],t=[],{has:function(t){return e.indexOf(t)>-1},get:function(n){return t[e.indexOf(n)]},set:function(n,o){-1===e.indexOf(n)&&(e.push(n),t.push(o))},delete:function(n){var o=e.indexOf(n);o>-1&&(e.splice(o,1),t.splice(o,1))}}),o=function(e){return new Event(e,{bubbles:!0})};try{new Event("test")}catch(e){o=function(e){var t=document.createEvent("Event");return t.initEvent(e,!0,!1),t}}function r(e){var t=n.get(e);t&&t.destroy()}function i(e){var t=n.get(e);t&&t.update()}var l=null;return"undefined"==typeof window||"function"!=typeof window.getComputedStyle?((l=function(e){return e}).destroy=function(e){return e},l.update=function(e){return e}):((l=function(e,t){return e&&Array.prototype.forEach.call(e.length?e:[e],function(e){return function(e){if(e&&e.nodeName&&"TEXTAREA"===e.nodeName&&!n.has(e)){var t,r=null,i=null,l=null,d=function(){e.clientWidth!==i&&c()},u=function(t){window.removeEventListener("resize",d,!1),e.removeEventListener("input",c,!1),e.removeEventListener("keyup",c,!1),e.removeEventListener("autosize:destroy",u,!1),e.removeEventListener("autosize:update",c,!1),Object.keys(t).forEach(function(n){e.style[n]=t[n]}),n.delete(e)}.bind(e,{height:e.style.height,resize:e.style.resize,overflowY:e.style.overflowY,overflowX:e.style.overflowX,wordWrap:e.style.wordWrap});e.addEventListener("autosize:destroy",u,!1),"onpropertychange"in e&&"oninput"in e&&e.addEventListener("keyup",c,!1),window.addEventListener("resize",d,!1),e.addEventListener("input",c,!1),e.addEventListener("autosize:update",c,!1),e.style.overflowX="hidden",e.style.wordWrap="break-word",n.set(e,{destroy:u,update:c}),"vertical"===(t=window.getComputedStyle(e,null)).resize?e.style.resize="none":"both"===t.resize&&(e.style.resize="horizontal"),r="content-box"===t.boxSizing?-(parseFloat(t.paddingTop)+parseFloat(t.paddingBottom)):parseFloat(t.borderTopWidth)+parseFloat(t.borderBottomWidth),isNaN(r)&&(r=0),c()}function a(t){var n=e.style.width;e.style.width="0px",e.style.width=n,e.style.overflowY=t}function s(){if(0!==e.scrollHeight){var t=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push({node:e.parentNode,scrollTop:e.parentNode.scrollTop}),e=e.parentNode;return t}(e),n=document.documentElement&&document.documentElement.scrollTop;e.style.height="",e.style.height=e.scrollHeight+r+"px",i=e.clientWidth,t.forEach(function(e){e.node.scrollTop=e.scrollTop}),n&&(document.documentElement.scrollTop=n)}}function c(){s();var t=Math.round(parseFloat(e.style.height)),n=window.getComputedStyle(e,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):e.offsetHeight;if(r<t?"hidden"===n.overflowY&&(a("scroll"),s(),r="content-box"===n.boxSizing?Math.round(parseFloat(window.getComputedStyle(e,null).height)):e.offsetHeight):"hidden"!==n.overflowY&&(a("hidden"),s(),r="content-box"===n.boxSizing?Math.round(parseFloat(window.getComputedStyle(e,null).height)):e.offsetHeight),l!==r){l=r;var i=o("autosize:resized");try{e.dispatchEvent(i)}catch(e){}}}}(e)}),e}).destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],r),e},l.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],i),e}),l}); !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e||self).autosize=t()}(this,function(){var e=new Map;function t(t){var o=e.get(t);o&&o.destroy()}function o(t){var o=e.get(t);o&&o.update()}var r=null;return"undefined"==typeof window?((r=function(e){return e}).destroy=function(e){return e},r.update=function(e){return e}):((r=function(t,o){return t&&Array.prototype.forEach.call(t.length?t:[t],function(t){return function(t){if(t&&t.nodeName&&"TEXTAREA"===t.nodeName&&!e.has(t)){var o,r=null,n=window.getComputedStyle(t),i=(o=t.value,function(){s({testForHeightReduction:""===o||!t.value.startsWith(o),restoreTextAlign:null}),o=t.value}),l=function(o){t.removeEventListener("autosize:destroy",l),t.removeEventListener("autosize:update",a),t.removeEventListener("input",i),window.removeEventListener("resize",a),Object.keys(o).forEach(function(e){return t.style[e]=o[e]}),e.delete(t)}.bind(t,{height:t.style.height,resize:t.style.resize,textAlign:t.style.textAlign,overflowY:t.style.overflowY,overflowX:t.style.overflowX,wordWrap:t.style.wordWrap});t.addEventListener("autosize:destroy",l),t.addEventListener("autosize:update",a),t.addEventListener("input",i),window.addEventListener("resize",a),t.style.overflowX="hidden",t.style.wordWrap="break-word",e.set(t,{destroy:l,update:a}),a()}function s(e){var o,i,l=e.restoreTextAlign,a=void 0===l?null:l,d=e.testForHeightReduction,u=void 0===d||d,f=n.overflowY;if(0!==t.scrollHeight&&("vertical"===n.resize?t.style.resize="none":"both"===n.resize&&(t.style.resize="horizontal"),u&&(o=function(e){for(var t=[];e&&e.parentNode&&e.parentNode instanceof Element;)e.parentNode.scrollTop&&t.push([e.parentNode,e.parentNode.scrollTop]),e=e.parentNode;return function(){return t.forEach(function(e){var t=e[0],o=e[1];t.style.scrollBehavior="auto",t.scrollTop=o,t.style.scrollBehavior=null})}}(t),t.style.height=""),i="content-box"===n.boxSizing?t.scrollHeight-(parseFloat(n.paddingTop)+parseFloat(n.paddingBottom)):t.scrollHeight+parseFloat(n.borderTopWidth)+parseFloat(n.borderBottomWidth),"none"!==n.maxHeight&&i>parseFloat(n.maxHeight)?("hidden"===n.overflowY&&(t.style.overflow="scroll"),i=parseFloat(n.maxHeight)):"hidden"!==n.overflowY&&(t.style.overflow="hidden"),t.style.height=i+"px",a&&(t.style.textAlign=a),o&&o(),r!==i&&(t.dispatchEvent(new Event("autosize:resized",{bubbles:!0})),r=i),f!==n.overflow&&!a)){var c=n.textAlign;"hidden"===n.overflow&&(t.style.textAlign="start"===c?"end":"start"),s({restoreTextAlign:c,testForHeightReduction:!0})}}function a(){s({testForHeightReduction:!0,restoreTextAlign:null})}}(t)}),t}).destroy=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],t),e},r.update=function(e){return e&&Array.prototype.forEach.call(e.length?e:[e],o),e}),r});
+4 -4
View File
@@ -284,7 +284,7 @@
}; };
for (var i = 0; i < images.length; i++) { for (var i = 0; i < images.length; i++) {
if ($.isArray(images[i])) { if (Array.isArray(images[i])) {
images[i] = widthInsertSort(images[i]); images[i] = widthInsertSort(images[i]);
var chosen = selectBest(containerWidth, containerHeight, images[i]); var chosen = selectBest(containerWidth, containerHeight, images[i]);
chosenImages.push(chosen); chosenImages.push(chosen);
@@ -338,7 +338,7 @@
if (typeof sources === 'undefined') { if (typeof sources === 'undefined') {
return; return;
} }
if (!$.isArray(sources)) { if (!Array.isArray(sources)) {
sources = [sources]; sources = [sources];
} }
@@ -424,7 +424,7 @@
if (typeof images[i] === 'string') { if (typeof images[i] === 'string') {
processed.push({url: images[i]}); processed.push({url: images[i]});
} }
else if ($.isArray(images[i])) { else if (Array.isArray(images[i])) {
processed.push(processImagesArray(images[i])); processed.push(processImagesArray(images[i]));
} }
else { else {
@@ -556,7 +556,7 @@
* e.g. $.backstretch('/path/to/image.jpg') * e.g. $.backstretch('/path/to/image.jpg')
* So, we need to turn this back into an array. * So, we need to turn this back into an array.
*/ */
this.images = processImagesArray($.isArray(images) ? images : [images]); this.images = processImagesArray(Array.isArray(images) ? images : [images]);
/** /**
* Paused-Option * Paused-Option
+2 -2
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : April 6th, 2015. Created Date : April 6th, 2015.
Last Modified : October 18th, 2020. 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 By : Siau Pheng (siaupheng@3fonia.com).
Created Date : October 12th, 2025. 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 Desc. : JS Class Printer & Printer POS
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 27th, 2007. 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', type: 'POST',
url: vars.url, url: vars.url,
data: (vars.data).join('&'), data: (vars.data).join('&'),
success: function(txt){ success: (txt) => {
var $printData = $('#dataPrint'); var $printData = $('#dataPrint');
if (!$printData.length) { 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); $printData.html(txt);
window.print(); window.print();
@@ -59,7 +59,7 @@ var cPRINTER = function(url, options){
type: 'POST', type: 'POST',
url: vars.url, url: vars.url,
data: (vars.data).join('&'), data: (vars.data).join('&'),
success: function(txt){ success: (txt) => {
if ('' == txt) { if ('' == txt) {
FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !'); FoniaJS.showInfo('Tidak ada data untuk pembuatan laporan !');
return false; return false;
@@ -72,17 +72,17 @@ var cPRINTER = function(url, options){
'<div class="modal-body print-body" id="divPrintP">'+txt+'</div>'+ '<div class="modal-body print-body" id="divPrintP">'+txt+'</div>'+
'</div></div></div>'; '</div></div></div>';
if ($('#winAPPPrint')) $('#winAPPPrint').modal('dispose').remove(); if ($('#winAPPPrint')) $('#winAPPPrint').modal('dispose').remove();
$(_wtxt).on('shown.bs.modal', function(e){ $(_wtxt).on('shown.bs.modal', (e) => {
$('#winAPPPrint').find('#tombCetak').click(function(){ $('#winAPPPrint').find('#tombCetak').click(() => {
var $printData = $('#dataPrint'); var $printData = $('#dataPrint');
if (!$printData.length) { 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()); $printData.html($('#divPrintP').html());
FoniaJS.closeWindow($('#winAPPPrint')); FoniaJS.closeWindow($('#winAPPPrint'));
window.print(); window.print();
}); });
}).on('hidden.bs.modal', function(e){ }).on('hidden.bs.modal', (e) => {
$(this).remove(); $(this).remove();
}).modal('show'); }).modal('show');
}, },
@@ -165,14 +165,14 @@ var cPRINTERPOS = function(url, options) {
new Request.JSON({ new Request.JSON({
url: url, url: url,
sendParam: params, sendParam: params,
onSuccess: function(ajson) { onSuccess: (ajson) => {
if (typeof ajson === "object") { if (typeof ajson === "object") {
var hasil_cetak = (ajson.type == "escp") ? this.gen_escp(ajson) : this.gen_epl(ajson); var hasil_cetak = (ajson.type == "escp") ? this.gen_escp(ajson) : this.gen_epl(ajson);
qz.print(qzcfg, hasil_cetak); qz.print(qzcfg, hasil_cetak);
} else { } else {
FoniaJS.showInfo('Error dalam proses Cetak.'); FoniaJS.showInfo('Error dalam proses Cetak.');
} }
}.bind(this) }
}).send(); }).send();
}; };
this.gen_escp = function(adata) { this.gen_escp = function(adata) {
+37 -35
View File
@@ -1,19 +1,43 @@
/******************************************************************* /*******************************************************************
Module : /js3/qz/qz-start.js Module : /assets/js/qz/qz-start.js
Desc. : JS Setup QZ Connection Desc. : Setup QZ Connection
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 27th, 2007. 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.
*******************************************************************/ *******************************************************************/
function launchQZ() { 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()) { if (!qz.websocket.isActive()) {
window.location.assign("qz:launch"); window.location.assign("qz:launch");
//Retry 5 times, pausing 1 second between each attempt
startConnection({ retries: 5, delay: 1 }); startConnection({ retries: 5, delay: 1 });
} }
} }
@@ -22,10 +46,10 @@ function startConnection(config) {
config = config ? config : {}; config = config ? config : {};
if (!qz.websocket.isActive()) { if (!qz.websocket.isActive()) {
_updateState('Waiting'); _updateState('Waiting');
qz.websocket.connect(config).then(() => { qz.websocket.connect({...config, host: 'localhost'}).then(() => {
_updateState('Active'); _updateState('Active');
_findDefaultPrinter(); _findDefaultPrinter();
}); }).catch(() => _updateState('Error'));
} else { } else {
console.info('An active connection with QZ already exists.'); console.info('An active connection with QZ already exists.');
} }
@@ -35,7 +59,7 @@ function endConnection(){
if (qz.websocket.isActive()) { if (qz.websocket.isActive()) {
qz.websocket.disconnect().then(() => { qz.websocket.disconnect().then(() => {
_updateState('Inactive'); _updateState('Inactive');
}); }).catch(() => _updateState('Error'));
} else { } else {
console.info('No active connection with QZ exists.'); console.info('No active connection with QZ exists.');
} }
@@ -64,30 +88,8 @@ function _updateState(text){
} else { } else {
$(_divStatus).addClass('border-warning'); $(_divStatus).addClass('border-warning');
} }
} $('li#qzL, li#qzS, li#qzZ').removeClass('d-none');
if (text !== "Error") {
const _divStatus = '#divQZStatus'; $('li#qzL').addClass('d-none');
} else $('li#qzS, li#qzZ').addClass('d-none');
if (typeof qz !== 'undefined') {
qz.security.setSignatureAlgorithm("SHA512");
qz.security.setCertificatePromise((resolve, reject) => {
jQuery.ajax({url:FoniaJS.WEB_PATH+'assets/signing/cert.pem', cache:false, dataType:'text'}).then(resolve, reject);
});
qz.security.setSignaturePromise((toSign) => {
return (resolve, reject) => {
jQuery.post(FoniaJS.WEB_PATH+"assets/signing/sign.php?req="+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();
} }
+435 -41
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : May 27th, 2007. Created Date : May 27th, 2007.
Last Modified : January 19th, 2026. Last Modified : January 19th, 2026.
(c) 2007 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -6,7 +6,7 @@
Created Date : March 18th, 2021. Created Date : March 18th, 2021.
Last Modified : December 26th, 2025. Last Modified : December 26th, 2025.
(c) 2021 - 2025, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
+6 -4
View File
@@ -1,7 +1,7 @@
{ {
"name": "siaupheng/webapp", "name": "siaupheng/webapp",
"type": "library", "type": "library",
"description": "Fonia Web Application Framework", "description": "Web Application Framework for FlightPHP",
"keywords": [ "keywords": [
"siaupheng", "siaupheng",
"webapp" "webapp"
@@ -17,7 +17,9 @@
} }
], ],
"require": { "require": {
"php" : ">=8.3", "php": ">=8.3",
"flightphp/core": "^3.18",
"flightphp/session": "^0.3",
"mpdf/mpdf": ">=8.0", "mpdf/mpdf": ">=8.0",
"matthiasmullie/minify": ">=1.3", "matthiasmullie/minify": ">=1.3",
"endroid/qr-code": ">=4.4", "endroid/qr-code": ">=4.4",
@@ -25,12 +27,12 @@
"shuchkin/simplexlsxgen": "^1.3" "shuchkin/simplexlsxgen": "^1.3"
}, },
"autoload": { "autoload": {
"classmap": ["src/"],
"psr-4": { "psr-4": {
"siaupheng\\webapp\\": "src/" "Webapp\\": "src/"
}, },
"files": [ "files": [
"src/Function/Auth.php", "src/Function/Auth.php",
"src/Function/JSON.php",
"src/Function/Misc.php" "src/Function/Misc.php"
] ]
}, },
-172
View File
@@ -1,172 +0,0 @@
<?php
/*******************************************************************
Module : /App.php
Desc. : HTML5 Page Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 10th, 2008.
Last Modified : July 25th, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp;
final class App {
public $version = "4.1.0";
private $apps = [];
private $auser = [];
private $cache = null;
private $menu = null;
private $reg = null;
protected $__db = null;
protected $__form = null;
public function __construct($db = null){
if (is_resource($db)) { $this->__db = $db; }
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); }
$this->__form = new \siaupheng\webapp\Web\Form($this->__db);
$this->apps = $_SESSION['__WEB_APP'];
if (isset($_SESSION['__WEB_USER'])) {
$this->apps['TEMPLATE'] = "index.php";
$this->auser = $_SESSION['__WEB_USER'];
$this->auser['user_img'] = "profiles/profile.png";
if (file_exists($this->apps['REAL_PATH']."assets/images/profiles/".$this->auser['UserID'].".png")) {
$this->auser['user_img'] = "profiles/".$this->auser['UserID'].".png";
}
}
$this->reg = new \siaupheng\webapp\Web\Register($this->__db);
$this->cache = new \siaupheng\webapp\Data\Cache($this->__db);
$this->menu = new \siaupheng\webapp\Web\Menu($this->__db);
}
public function TampilApp($aoption = []) {
if ($this->reg->reg_check()) {
if (!user_logged()) {
$this->apps['TEMPLATE'] = "login.php";
}
} else {
$this->apps['TEMPLATE'] = "404.php";
}
// gunakan template khusus sesuai request
if (($aoption['PAGE_404']['value'] ?? 0) == 1) {
$this->apps['TEMPLATE'] = "404.php";
}
// loading template file {{}}
$buffer = "";
if (file_exists($this->apps['REAL_PATH']."assets/templates/".$this->apps['TEMPLATE'])) {
$buffer = file_get_contents($this->apps['REAL_PATH']."assets/templates/".$this->apps['TEMPLATE']);
$buffer = preg_replace("/(?:(?:\\/\\*(?:[^*]|(?:\\*+[^*\\/]))*\\*+\\/)|(?:(?<!\\:)\\/\\/. *))/", "", $buffer);
}
$aoption = [...$this->apps, 'CSS_JS' => ""];
// penambahan file css + js + app-js
$aoption['CSS_JS'] = '<link rel="stylesheet" type="text/css" href="'.$this->cache->Main("css").'">'."\n";
$aoption['CSS_JS'] .= '<script type="text/javascript" src="'.$this->cache->Main("js").'"></script>'."\n";
if (user_logged()) $aoption['CSS_JS'] .= '<script type="text/javascript" src="'.$this->cache->Apps().'"></script>'."\n";
$_secret = $aoption['APP_CODE'] .";". $aoption['APP_SID'] .";". $_SERVER['HTTP_HOST'] .";". $aoption['WEB_PATH'] .";". "http://".$_SERVER['HTTP_HOST'].$aoption['WEB_PATH'] .";". isMobile() .";". ($aoption['AUTH_LEVEL']?$aoption['AUTH_LEVEL']:0) .";". $this->version;
$_suser = (user_logged()) ? $this->auser['Username'] .";". $this->auser['UserID'] .";". $this->auser['Grup_MenuID'] .";". $this->auser['Level'] : "nobody;999;999;9";
$aoption['CSS_JS'] .= '<script type="text/javascript" language="javascript">'."\n";
$aoption['CSS_JS'] .= 'FoniaJS.setConfig("'.base64_encode($_secret).'", "'.base64_encode($_suser).'");';
$aoption['CSS_JS'] .= '$(document).ready(function(){';
$tnaviside = ""; $tnavihead = "";
if (user_logged()) {
$aoption['CSS_JS'] .= 'FoniaJS.loadMenu();';
$tnaviside = $this->menu->Menu_Sidebar();
$tnavihead = $this->menu->Menu_Header();
}
$aoption['CSS_JS'] .= '});';
$aoption['CSS_JS'] .= '</script>'."\n";
// informasi tahun aplikasi dan pembuatan menu
if (strpos($buffer, '{{CREATOR_YEAR}}')===false) {
$aoption['REG_YEAR'] = ($aoption['REG_YEAR']!=date('Y')) ? $aoption['REG_YEAR']." - ".date('Y') : $aoption['REG_YEAR'];
} else {
$aoption['CREATOR_YEAR'] = ($aoption['CREATOR_YEAR']!=date('Y')) ? $aoption['CREATOR_YEAR']." - ".date('Y') : $aoption['CREATOR_YEAR'];
}
// perubahan variabel dari data konfigurasi
$aoption['APP_NAME_VER'] = $aoption['APP_NAME']." v".$aoption['APP_VER'];
$aoption['APP_NAMES_VER'] = $aoption['APP_NAMES']." v".$aoption['APP_VER'];
$aoption['APP_NAMES_UP'] = strtoupper($aoption['APP_NAMES'] ?? "");
$aoption['REG_ID'] = $this->reg->reg_id();
$aoption['REG_NAME_UP'] = strtoupper($aoption['REG_NAME'] ?? "");
$aoption['REG_CITY_UP'] = strtoupper($aoption['REG_CITY'] ?? "");
$aoption['USER_IMG'] = $this->auser['user_img'] ?? "";
$aoption['NAVI_SIDEBAR'] = $tnaviside;
$aoption['NAVI_HEADER'] = $tnavihead;
if (isset($this->auser) && is_array($this->auser)) {
$aoption['USER_ID'] = $this->auser['UserID'] ?? "";
$aoption['USER_USER'] = $this->auser['Username'] ?? "";
$aoption['USER_NAME'] = $this->auser['Nama'] ?? "";
$aoption['USER_POSISI'] = $this->auser['Posisi'] ?? "";
// menu modul
$t_modul = "";
if (isset($this->auser['MENU_MODUL']) && is_array($this->auser['MENU_MODUL']) && count($this->auser['MENU_MODUL'])>0) {
$t_modul = '<div class="dropdown-divider"></div>';
if ($_SERVER['SERVER_ADDR'] == "127.0.0.1") {
$href1 = $this->apps['WEB_PATH'].'../';
$href2 = "";
} else {
$_host = $_SERVER['HTTP_ORIGIN'] ?? $_SERVER['HTTP_HOST'] ?? $this->apps['PARENT_SITE'];
$_host = str_replace(['http://','https://'], "", $_host);
if ($this->apps['PARENT_SUB']==true) {
$_subs = explode('.', $_host);
if (count($_subs) > 2) array_shift($_subs);
$href1 = "//";
$href2 = "." . implode('.', $_subs);
} else {
$href1 = "//" . $_host . '/';
$href2 = "";
}
}
foreach ($this->auser['MENU_MODUL'] as $modul) {
$href = $href1.$modul['APP_PATH'].$href2;
$href .= '/?auth='.$_SESSION['APP_TOKEN'];
$t_modul .= '<a class="dropdown-item slink" href="'.$href.'"><i class="'.$modul['Icon'].' me-2"></i> '.$modul['Judul'].'</a>';
}
}
// menu extra
$amodul_ext = $aoption['MENU_MODUL'] ?? [];
if (count($amodul_ext) > 0) {
$t_modul .= '<div class="dropdown-divider"></div>';
foreach ($amodul_ext as $modul) {
$t_modul .= '<a class="dropdown-item slink" id="'.$modul['Id'].'"><i class="'.$modul['Icon'].' me-2"></i> '.$modul['Judul'].'</a>';
}
}
$aoption['MENU_MODUL'] = $t_modul;
}
// penyisipan option (pilihan tahun, tanggal login, dll)
if (count($aoption) > 0) {
foreach ($aoption as $__key => $val) {
$opt_var = $val['value'];
if (strpos($__key, "OPTION")!==false) {
$opt_var = $this->__form->option("_", $__key, $val['value'], true, true, $val['option']);
} else if (strpos($__key, "RADIO")!==false) {
$opt_var = $this->__form->radio("_", $__key, $val['value'], true, true, $val['radio']);
} else if (strpos($__key, "PICKDATE")!==false) {
$opt_var = $this->__form->datebox("_", $__key, $val['value'], true, true);
}
$aoption[$__key] = $opt_var;
}
}
$output = preg_replace_callback('/\{\{([a-zA-Z0-9_]+)\}\}/', fn($matches) => isset($aoption[$matches[1]]) ? $aoption[$matches[1]] : "", $buffer);
echo $output;
}
}
?>
+66 -62
View File
@@ -3,106 +3,110 @@
/******************************************************************* /*******************************************************************
Module : /DB/CheckSQL.php Module : /DB/CheckSQL.php
Desc. : Class Check SQL / Repair Database
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : May 11th, 2011. Created Date : May 11th, 2011.
Last Modified : May 8th, 2021. Last Modified : August 21st, 2026.
(c) 2011 - 2021, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\DB; namespace Webapp\DB;
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 { final class CheckSQL {
private $__atabel = []; private Array $__atabel = [];
private $__aignore = []; protected Engine $app;
protected $__db = null; protected SimplePdo $db;
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__db = $db; } * @param Engine $app
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); } */
public function __construct(Engine $app) {
$this->__db->Query("SELECT TABLE_NAME,ENGINE,TABLE_ROWS FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='".$this->__db->getDBName()."' AND TABLE_TYPE='BASE TABLE'"); $this->app = $app;
while ($this->__db->Next()) { $this->db = $app->db();
$this->__atabel[] = array($this->__db->Row("TABLE_NAME"), ' <i>('.$this->__db->Row("ENGINE").')</i>',' <i>('.uang($this->__db->Row("TABLE_ROWS")).' Records)</i>'); $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) {
$this->__atabel[] = [ $row['TABLE_NAME'], $row['ENGINE'], ' <i>('.$row['ENGINE'].')</i>',' <i>('.$row['TABLE_ROWS'].' Records)</i>' ];
} }
} }
public function ignore_table() { public function ignore_table(): void {
$tmp_arr = func_get_args(); $tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0]; if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$this->__aignore = $tmp_arr; $farray = array_filter($this->__atabel, fn($child) => !in_array($child[0], $tmp_arr));
$this->__atabel = array_values($farray);
} }
private function _check_db($atabel=array()) { private function _check_db(array $atabel=[]): string {
$hasil = ""; $pesan = '<span style="color:blue;">OK</span>';
if (!in_array($atabel[0], $this->__aignore)) { $row = $this->db->runQuery('CHECK TABLE '.$atabel[0].' QUICK')->fetch(SimplePdo::FETCH_ASSOC);
$pesan = "<span style=\"color:blue;\">OK</span>"; if (($row['Msg_text'] ?? '') !== 'OK') {
$this->__db->Query("CHECK TABLE ".$atabel[0]); $pesan = '<span style="color:red;">ERROR</span>';
if ($this->__db->Next()) { try {
if (strtoupper($this->__db->Row("Msg_text"))<>"OK") { $row2 = $this->db->runQuery('REPAIR TABLE '.$atabel[0])->fetch(SimplePdo::FETCH_ASSOC);
$pesan = "<span style=\"color:red;\">ERROR</span>"; $pesan .= ' -> Auto Repair <span style="color:blue;">'. (($row2['Msg_text'] ?? '') === 'OK' ? 'FIXED' : 'ERROR') .'</span>';
$this->__db->Query("REPAIR TABLE ".$atabel[0]); } catch (Exception $e) {
if ($this->__db->Next()) { $pesan .= ' -> Auto Repair <span style="color:red;">' . $e->getMessage() . '</span>';
if (strtoupper($this->__db->Row("Msg_text"))=="OK") {
$pesan .= " -> <span style=\"color:blue;\">FIXED</span>";
} }
} }
} return $atabel[0] . $atabel[3] ." ... ". $pesan;
}
$hasil = $atabel[0] . $atabel[2] ." ... ". $pesan ."<br>";
}
return $hasil;
} }
public function count_db() { 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;
}
public function count_db(): int {
return count($this->__atabel); return count($this->__atabel);
} }
public function check_db() { public function check_db(): string {
$hasil = "=== CEK DATABASE ===<br>"; $hasil = "=== CEK DATABASE ===<br>";
for ($n=0;$n<count($this->__atabel);$n++) { for ($n=0; $n<count($this->__atabel); $n++) {
$hasil .= $this->_check_db($this->__atabel[$n]); $hasil .= $this->_check_db($this->__atabel[$n]);
} }
return $hasil; return $hasil;
} }
public function check_db_step($n) { public function check_db_step(int $n): string {
$hasil .= $this->_check_db($this->__atabel[$n]); return $this->_check_db($this->__atabel[$n]);
} }
public function repair_db() { public function optimize_db(): string {
$hasil = "=== REPAIR DATABASE ===<br>";
for ($n=0;$n<count($this->__atabel);$n++) {
if (!in_array($this->__atabel[$n][0], $this->__aignore)) {
$pesan = "<span style=\"color:blue;\">OK</span>";
$this->__db->Query("REPAIR TABLE ".$this->__atabel[$n][0]);
while ($this->__db->Next()) {
$pesan = (strtoupper($this->__db->Row("Msg_text"))=="OK") ? "<span style=\"color:blue;\">OK</span>" : "<span style=\"color:red;\">ERROR</span>";
}
$hasil .= $this->__atabel[$n][0] . $this->__atabel[$n][1] ." ... ". $pesan ."<br>";
}
}
return $hasil;
}
public function optimize_db() {
$hasil = "=== OPTIMALISASI DATABASE ===<br>"; $hasil = "=== OPTIMALISASI DATABASE ===<br>";
for ($n=0;$n<count($this->__atabel);$n++) { for ($n=0;$n<count($this->__atabel);$n++) {
if (!in_array($this->__atabel[$n][0], $this->__aignore)) { $hasil .= $this->_opti_db($this->__atabel[$n]);
$pesan = "<span style=\"color:blue;\">OK</span>";
$this->__db->Query("OPTIMIZE TABLE ".$this->__atabel[$n][0]);
while ($this->__db->Next()) {
$pesan = (strtoupper($this->__db->Row("Msg_text"))=="OK" || strtoupper($this->__db->Row("Msg_text"))=="TABLE IS ALREADY UP TO DATE") ? "<span style=\"color:blue;\">OK</span>" : "<span style=\"color:red;\">ERROR</span>";
}
$hasil .= $this->__atabel[$n][0] . $this->__atabel[$n][1] ." ... ". $pesan ."<br>";
}
} }
return $hasil; return $hasil;
} }
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. Created Date : May 11th, 2011.
Last Modified : May 8th, 2021. 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); declare(strict_types=1);
namespace siaupheng\webapp\DB; namespace Webapp\DB;
final class DumpSQL { final class DumpSQL {
private $__adata = array(); private $__adata = array();
@@ -23,7 +24,7 @@ final class DumpSQL {
public function __construct($db = null){ public function __construct($db = null){
if (is_resource($db)) { $this->__db = $db; } 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(); $this->__adata = $this->__db->getConfig();
} }
@@ -55,7 +56,7 @@ final class DumpSQL {
public function create_backup($folder="backups") { public function create_backup($folder="backups") {
$namafile = date("Ymd").".gz"; $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 (!is_dir($folder)) mkdir($folder);
if (file_exists($folder."/".$namafile)) unlink($folder."/".$namafile); 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']; $_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() { public function disk_space() {
$_free = disk_free_space($_SESSION['__WEB_APP']['REAL_PATH']); $_free = disk_free_space(PROJECT_ROOT);
$_tot = disk_total_space($_SESSION['__WEB_APP']['REAL_PATH']); $_tot = disk_total_space(PROJECT_ROOT);
$_used = $_tot - $_free; $_used = $_tot - $_free;
$_aret = array(); $_aret = array();
$_aret['TOTAL'] = $this->format_bytes($_tot); $_aret['TOTAL'] = $this->format_bytes($_tot);
@@ -109,7 +110,7 @@ final class DumpSQL {
} }
public function update_list($folder="backups") { public function update_list($folder="backups") {
$folder = $_SESSION['__WEB_APP']['REAL_PATH'].$folder; $folder = PROJECT_ROOT.$folder;
$this->__db->Query("TRUNCATE TABLE app_backup"); $this->__db->Query("TRUNCATE TABLE app_backup");
$afile = $this->get_file_list($folder); $afile = $this->get_file_list($folder);
foreach($afile as $_key => $_val) { foreach($afile as $_key => $_val) {
-228
View File
@@ -1,228 +0,0 @@
<?php
/*******************************************************************
Module : /DB/MySQL.php
Desc. : Class database MySQL / MariaDB
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 2nd, 2007.
Last Modified : October 19th, 2023.
(c) 2008 - 2023, 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp\DB;
final class MySQL {
private $cnn;
private $rs = 0;
private $rec = array();
private $row = 0;
private $halt_on_error = 1; //1: halt w message, 2: not halt w message, 3: not halt no message
private $auto_free = 1; //1: free query automatically, 0: must call free method to free query
private $db_config = null;
private $err_num = 0;
private $err_msg = '';
private $debug_msg = 1;
private $ischangingdb = false;
public function __construct() {
if (!is_array($this->db_config)) $this->setConfig();
$this->debug_msg = ($_SERVER['SERVER_ADDR'] == "127.0.0.1") ? 1 : 0;
}
private function setConfig() {
global $APP_DATA;
if (!is_array($APP_DATA)) {
if (file_exists($_SESSION['__WEB_APP']['REAL_PATH']."apps/cfg/mysql.php"))
require_once($_SESSION['__WEB_APP']['REAL_PATH']."apps/cfg/mysql.php");
}
$this->db_config = $APP_DATA;
}
public function getConfig() {
return $this->db_config;
}
function Connect() {
if (!$this->cnn) {
$this->cnn = @mysqli_connect($this->db_config['host'], $this->db_config['user'], $this->db_config['pwd'], $this->db_config['db'], intval($this->db_config['port']), $this->db_config['sock']);
if (!$this->cnn) {
$this->ErrHandler("Connection failed!");
return 0;
} else {
@mysqli_query($this->cnn, "SET NAMES utf8");
@mysqli_query($this->cnn, "SET CHARACTER SET utf8");
@mysqli_query($this->cnn, "SET character_set_connection=utf8");
}
}
return $this->cnn;
}
function Connection() {
return $this->cnn;
}
function ResultSet() {
return $this->rs;
}
function Free() {
if (is_resource($this->rs)) @mysqli_free_result($this->rs);
$this->rs = 0;
$this->row = 0;
$this->rec = array();
$this->err_num = 0;
$this->err_msg = '';
}
function SafeSQL($str) {
if (!$this->cnn) $this->Connect();
return mysqli_real_escape_string($this->cnn, strval($str));
}
function &Query($stqry = "", $dbname = "") {
if ($stqry == "") return 0;
if (!$this->Connect()) return 0;
if ($dbname != "" || $this->ischangingdb) {
if ($dbname != "") {
if (!@mysqli_select_db($this->cnn, $dbname)) {
$this->ErrHandler("Cannot select database!");
return 0;
}
$this->ischangingdb = true;
} else {
if (!@mysqli_select_db($this->cnn, $this->db_config['db'])) {
$this->ErrHandler("Cannot select database!");
return 0;
}
$this->ischangingdb = false;
}
}
if ($this->rs) $this->Free();
$this->rs = @mysqli_query($this->cnn, $stqry);
$this->row = 0;
$this->err_msg = @mysqli_error($this->cnn);
if (!$this->rs) $this->ErrHandler("Invalid SQL!: ".$stqry);
return $this->rs;
}
function Next() {
if (!$this->rs) {
$this->ErrHandler("Cannot move cursor to next record!");
return 0;
}
$this->rec = @mysqli_fetch_array($this->rs, MYSQLI_ASSOC);
$this->row += 1;
$this->err_msg = @mysqli_error($this->cnn);
$result = is_array($this->rec);
if (!$result && $this->auto_free) $this->Free();
return $result;
}
function Reset() {
@mysqli_data_seek($this->rs, 0);
}
function Seek($rownum = 0) {
return @mysqli_data_seek($this->rs, $rownum);
}
function Row($name = "", $defval = "") {
if (isset($this->rec[$name])) {
return (($this->rec[$name] == "") ? $defval : $this->rec[$name]);
} else {
return (($defval != "") ? $defval : "");
}
}
function RowNumeric($name = "", $defval = 0) {
$defval = is_numeric($defval) ? $defval : 0;
if (isset($this->rec[$name])) {
if (is_numeric($this->rec[$name])) return $this->rec[$name];
return $defval;
} else return $defval;
}
function RowFloat($name = "", $defval = 0) {
$defval = is_numeric($defval) ? $defval : 0;
if (isset($this->rec[$name])) {
if ($this->rec[$name]) $defval = $this->rec[$name];
}
return floatval($defval);
}
function AllRow() {
return $this->rec;
}
function ValueArray($colname = "") {
$currrow = $this->row;
@mysqli_data_seek($this->rs, 0);
$result = array();
while ($__row = mysqli_fetch_array($this->rs))
if (isset($__row[$colname])) array_push($result, $__row[$colname]);
@mysqli_data_seek($this->rs, $currrow);
return $result;
}
function ValueArrayFormater($colname = "", $formater = "") {
$currrow = $this->row;
$formater = $formater == ""?$formater = "return \$__row[\$colname];":"return ".str_replace("<value>", "\$__row[\$colname]", $formater).";";
@mysqli_data_seek($this->rs, 0);
$result = array();
while ($__row = mysqli_fetch_array($this->rs))
if (isset($__row[$colname])) array_push($result, eval($formater));
@mysqli_data_seek($this->rs, $currrow);
return $result;
}
function ValueList($colname = "", $delim = ",") {
$result = @$this->ValueArray($colname);
return @implode($delim, $result);
}
function CurrentRow() {
return $this->row;
}
function AffectedRows() {
return @mysqli_affected_rows($this->cnn);
}
function RecordCount() {
return @mysqli_num_rows($this->rs);
}
function NumFields() {
return @mysqli_num_fields($this->rs);
}
function LastInsertID() {
$lastinsertid = -1;
$crs = @mysqli_query($this->cnn, "SELECT LAST_INSERT_ID() AS lastinsertid");
$crow = @mysqli_fetch_array($crs);
if (isset($crow["lastinsertid"])) if (is_numeric($crow["lastinsertid"])) $lastinsertid = $crow["lastinsertid"];
return $lastinsertid;
}
function ErrHandler($err_msg = "") {
$this->err_msg = @mysqli_error($this->cnn);
if ($this->halt_on_error == 3) return;
if ($err_msg == "") $err_msg = "Undefined error!";
if ($this->debug_msg) {
printf('<span style="font-size:1.2em;"><b>MySQL Error : %s</b> %s</span><br>', $this->db_config['db'], $this->err_msg);
printf('<span style="font-size:1.2em;"><b>Database error : </b> %s</span><br>', $err_msg);
}
if ($this->halt_on_error == 1) die("");
}
function getDBName() {
return $this->db_config['db'];
}
}
?>
+141 -76
View File
@@ -3,128 +3,193 @@
/******************************************************************* /*******************************************************************
Module : /DB/SQL.php Module : /DB/SQL.php
Desc. : Class Query database
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 2nd, 2007. Created Date : February 2nd, 2007.
Last Modified : December 17th, 2023. Last Modified : August 21st, 2026.
(c) 2008 - 2023, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\DB; namespace Webapp\DB;
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 { final class SQL {
private $__ttable = ""; private string $_ttable;
private $__afield = array(); private array $_afield = [];
private $__avalue = array(); private array $_awhere = [];
private $__anomor = array(); protected Engine $app;
private $__twhere = ""; protected SimplePdo $db;
protected $__db = null; protected array webuser;
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__db = $db; } * @param Engine $app
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); } */
public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->webuser = $app->session()->get('__WEB_USER', ['UserID'=>0, 'UNIX'=>0]);
} }
//todo: deprecated
public function SafeSQL($ttext = "") { public function SafeSQL($ttext = "") {
return $this->__db->SafeSQL($ttext); return $ttext;
} }
public function set_table($ttable = "") { public function set_table(string $table = ""): void {
$this->__ttable = $ttable; $this->_ttable = $table;
} }
public function add_param($tparam = "", $tvalue = null, $bnomor = false) { public function add_param(string $param = "", string|int|null $value = null, bool $nomor = false): void {
$this->__afield[] = $tparam; $req = Param::Get($param);
$this->__avalue[] = (is_null($tvalue) && isset($_REQUEST[$tparam])) ? $this->__db->SafeSQL($_REQUEST[$tparam]) : $tvalue; $this->_afield[] = [
$this->__anomor[] = $bnomor; 'field' => $param,
'value' => (is_null($value) && !empty($req)) ? $req : $value,
'numbe' => $nomor,
];
} }
public function add_param_date($tparam = "", $tvalue = null) { public function add_param_date(string $param = "", string|null $value = null): void {
$this->__afield[] = $tparam; $req = Param::Get($param);
$this->__avalue[] = tgl_sql2str((is_null($tvalue) && isset($_REQUEST[$tparam])) ? $this->__db->SafeSQL($_REQUEST[$tparam]) : $tvalue); $this->_afield[] = [
$this->__anomor[] = false; 'field' => $param,
'value' => tgl_sql2str((is_null($value) && !empty($req)) ? $req : $value),
'numbe' => false,
];
} }
public function add_param_stamp($tparam = "DateStamp") { public function add_param_stamp(string $param = "DateStamp"): void {
$this->__afield[] = $tparam; $this->_afield[] = [
$this->__avalue[] = "NOW()"; 'field' => $param,
$this->__anomor[] = true; 'value' => 'NOW()',
'numbe' => true,
];
} }
public function add_param_unix() { public function add_param_unix(): void {
$this->__afield[] = "Unix"; $this->_afield[] = [
$this->__avalue[] = user_unix(); 'field' => 'Unix',
$this->__anomor[] = false; 'value' => $this->webuser['UNIX'],
'numbe' => false,
];
} }
public function add_param_userid($tparam = "UserID") { public function add_param_userid(string $param = "UserID"): void {
$this->__afield[] = $tparam; $this->_afield[] = [
$this->__avalue[] = user_id(); 'field' => $param,
$this->__anomor[] = false; 'value' => $this->webuser['UserID'],
'numbe' => false,
];
} }
public function add_where_unix() { public function add_where_unix(): void {
$this->__twhere .= (($this->__twhere=="") ? " WHERE " : " AND ") . "(Unix='".user_unix()."')"; $this->_awhere[] = [
'field' => 'Unix',
'value' => $this->webuser['UNIX'],
'numbe' => false,
];
} }
public function add_where_date($tfield = "", $tvalue = null) { public function add_where_date(string $field = "", string|null $value = null): void {
$tvalue = ($tvalue == null) ? "0000-00-00" : tgl_sql2str($tvalue); $this->_awhere[] = [
$this->add_where($tfield, $tvalue); 'field' => $field,
'value' => (is_null($value)) ? '0000-00-00' : tgl_sql2str($value),
'numbe' => false,
];
} }
public function add_where($tfield = "", $tvalue = null) { public function add_where(string $field = "", string|int|null $value = null, bool $nomor = false): void {
$__tvalue = (is_null($tvalue) && isset($_REQUEST[$tfield])) ? $this->__db->SafeSQL($_REQUEST[$tfield]) : $tvalue; $req = Param::Get($param);
$this->__twhere .= (($this->__twhere=="") ? " WHERE " : " AND ") . "(".$tfield."='".$__tvalue."')"; $this->_awhere[] = [
'field' => $field,
'value' => (is_null($value) && !empty($req)) ? $req : $value,
'numbe' => $nomor,
];
} }
public function clear_param() { public function clear_param(): void {
$this->__afield = array(); $this->_afield = [];
$this->__avalue = array();
$this->__anomor = array();
} }
public function clear_where() { public function clear_where(): void {
$this->__twhere = ""; $this->_awhere = [];
} }
public function InsertDB() { public function InsertDB(): void {
$tsql = "INSERT INTO ".$this->__ttable." ("; $__afield = [];
$tfield = ""; $__aplace = [];
$tvalue = ""; $__aexec = [];
for ($i=0; $i<count($this->__afield); $i++) { foreach ($this->_afield as $col) {
$tfield .= ",".$this->__afield[$i]; $__afield[] = '`'.$col['field'].'`';
$tvalue .= ",".(($this->__anomor[$i])?"":"'").$this->__avalue[$i].(($this->__anomor[$i])?"":"'"); if ($col['numbe'] === true) {
$__aplace[] = $col['value'];
} else {
$__aplace[] = '?';
$__aexec[] = $col['value'];
} }
$tsql .= substr($tfield,1); }
$tsql .= ") VALUES ("; $tsql = 'INSERT INTO '.$this->_ttable.' ('. implode(',', $__afield) .') VALUES ('. implode(',', $__aplace) .')';
$tsql .= substr($tvalue,1); $this->db->runQuery($tsql, $__aexec);
$tsql .= ")";
$this->__db->Query($tsql);
} }
public function UpdateDB() { public function UpdateDB(): void {
$tsql = "UPDATE ".$this->__ttable." SET "; $__aplace = [];
$tfield = ""; $__awhere = [];
for ($i=0; $i<count($this->__afield); $i++) { $__aexec = [];
$tfield .= ",".$this->__afield[$i]."=".(($this->__anomor[$i])?"":"'").$this->__avalue[$i].(($this->__anomor[$i])?"":"'"); foreach ($this->_afield as $col) {
if ($col['numbe'] === true) {
$__aplace[] = '`'.$col['field'].'`='. $col['value'];
} else {
$__aplace[] = '`'.$col['field'].'`=?';
$__aexec[] = $col['value'];
} }
$tsql .= substr($tfield,1); }
$tsql .= ($this->__twhere=="") ? "" : $this->__twhere; foreach ($this->_awhere as $col) {
$this->__db->Query($tsql); if ($col['numbe'] === true) {
$__awhere[] = '`'.$col['field'].'`='. $col['value'];
} else {
$__awhere[] = '`'.$col['field'].'`=?';
$__aexec[] = $col['value'];
}
}
$tsql = 'UPDATE '.$this->_ttable.' SET '. implode(',', $__aplace) .' WHERE '. implode(' AND ', $__awhere);
$this->db->runQuery($tsql, $__aexec);
} }
public function DeleteDB() { public function DeleteDB(): void {
$tsql = "DELETE FROM ".$this->__ttable; $__awhere = [];
$tsql .= ($this->__twhere=="") ? "" : $this->__twhere; $__aexec = [];
$this->__db->Query($tsql); foreach ($this->_awhere as $col) {
if ($col['numbe'] === true) {
$__awhere[] = '`'.$col['field'].'`='. $col['value'];
} else {
$__awhere[] = '`'.$col['field'].'`=?';
$__aexec[] = $col['value'];
}
}
$tsql = 'DELETE FROM '.$this->_ttable.' WHERE '. implode(' AND ', $__awhere);
$this->db->runQuery($tsql, $__aexec);
} }
public function LastInsertID() { public function LastInsertID(): int {
return $this->__db->LastInsertID(); return $this->db->lastInsertId();
} }
} }
+18 -8
View File
@@ -3,31 +3,41 @@
/******************************************************************* /*******************************************************************
Module : /Data/CSV.php Module : /Data/CSV.php
Desc. : Class pembuatan file CSV
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 2rd, 2011. 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); declare(strict_types=1);
namespace siaupheng\webapp\Data; namespace Webapp\Data;
define( DELI_CSV, ";" ); define( DELI_CSV, ";" );
define( CRLF_CSV, "\r\n" ); 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 { final class CSV {
private $__avalue = []; private $__avalue = [];
private $__atabel = []; private $__atabel = [];
public function add_field($tnama="", $ffunc="") { public function add_field(string $nama, string $func=""): void {
$this->__atabel[] = [$tnama, $ffunc]; $this->__atabel[] = [ $nama, $func ];
} }
public function add_value() { public function add_value(): void {
$tmp_arr = func_get_args(); $tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0]; if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = ""; $tmp_out = "";
@@ -44,7 +54,7 @@ final class CSV {
$this->__avalue[] = $tmp_out; $this->__avalue[] = $tmp_out;
} }
public function download($nama_file="export.csv") { public function download(string $nama_file="export.csv"): void {
$out = ""; $tmp_out = ""; $out = ""; $tmp_out = "";
// add header // add header
for ($i=0; $i<count($this->__atabel); $i++) { for ($i=0; $i<count($this->__atabel); $i++) {
+125 -102
View File
@@ -3,133 +3,142 @@
/******************************************************************* /*******************************************************************
Module : /Data/Cache.php Module : /Data/Cache.php
Desc. : Class cache aplikasi
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : March 16th, 2008. Created Date : March 16th, 2008.
Last Modified : July 25th, 2026. Last Modified : August 21st, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Data; namespace Webapp\Data;
use MatthiasMullie\Minify; 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 { final class Cache {
private $__cachedays = 0;
private $__cachedir = ""; private $__cachedir = "";
private $__cssdir = ""; private $__cssdir = "";
private $__localedir = ""; private $__localedir = "";
private $__jsdir = ""; private $__jsdir = "";
private $__jsapp = ""; private $__jsapp = "";
private $__realpath = ""; private $__rootdir = "";
private $__ini = []; private $__ini = [];
protected $__db = null; protected Engine $app;
protected Session $session;
protected array $__asset = [];
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__db = $db; } * @param Engine $app
else $this->__db = new \siaupheng\webapp\DB\MySQL(); */
$rootdir = $_SESSION['__WEB_APP']['REAL_PATH']; public function __construct(Engine $app) {
$this->__cachedir = $rootdir . 'chunks/'; $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/Scripts/locale/';
$this->__jsapp = $rootdir . '/app/Scripts/';
$this->__cssdir = __DIR__ . '/../../assets/css/'; $this->__cssdir = __DIR__ . '/../../assets/css/';
$this->__localedir = $rootdir . 'assets/locale/';
$this->__jsdir = __DIR__ . '/../../assets/js/'; $this->__jsdir = __DIR__ . '/../../assets/js/';
$this->__jsapp = $rootdir . 'apps/js/'; $this->__rootdir = $rootdir . '/';
$this->__realpath = $rootdir;
if (!is_dir($this->__cachedir)) mkdir($this->__cachedir, 0755, true); if (!is_dir($this->__cachedir)) mkdir($this->__cachedir, 0755, true);
if (!file_exists($this->__cachedir . "cache.ini")) { if (!file_exists($this->__cachedir . "cache.ini")) {
$this->__ini = [ $this->__ini = [
'css' => ['login_stamp'=>"0",'login_file'=>"",'index_stamp'=>"0",'index_file'=>"",'display_stamp'=>"0",'display_file'=>""], 'login' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
'js' => ['login_stamp'=>"0",'login_file'=>"",'index_stamp'=>"0",'index_file'=>"",'display_stamp'=>"0",'display_file'=>""] 'index' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
'display' => [ 'stamp' => 0, 'css' => "", 'js' => "", 'app' => "", ],
]; ];
$this->save_ini(); $this->save_ini();
} } else $this->__ini = parse_ini_file($this->__cachedir . "cache.ini", true);
$this->__ini = parse_ini_file($this->__cachedir . "cache.ini", true);
} }
private function gen_file($type="css", $mode="index") { public function set_asset(array $asset = []): void {
$this->__asset = $asset;
}
private function gen_file(string $mode = "index", string $type = "css"): array {
$itime = 0;
$afile = []; $afile = [];
if ($type == "css") { if ($type == "css") {
$_afile = array_unique($GLOBALS['A_CSS']); $_afile = array_unique($this->__asset['css'][$mode] ?? []);
foreach ($_afile as $__key => $val) { foreach ($_afile as $__key => $val) {
$afile[] = $this->__cssdir .$val; if (!file_exists($this->__cssdir . $val)) continue;
$_file = new SplFileInfo($this->__cssdir . $val);
$afile[] = $_file->getRealPath();
$itime += $_file->getMTime();
} }
if (file_exists($this->__realpath . 'assets/css/')) { if (is_dir($this->__rootdir . 'app/Styles/')) {
if ($handle = opendir($this->__realpath . 'assets/css/')) { $iterator = new FilesystemIterator($this->__rootdir . 'app/Styles/', FilesystemIterator::SKIP_DOTS);
while (false !== ($file = readdir($handle))) { foreach ($iterator as $_file) {
if ($file == '.' || $file == '..' || is_dir($this->__realpath . 'assets/css/'.$file)) continue; if ($_file->isFile()) {
$afile[] = $this->__realpath . 'assets/css/' . $file; $afile[] = $_file->getRealPath();
$itime += $_file->getMTime();
} }
closedir($handle);
} }
} }
} else if ($type == "js") { } else if ($type == "js") {
$_afile = array_unique($GLOBALS['A_JS']); $_afile = array_unique($this->__asset['js'][$mode] ?? []);
foreach ($_afile as $__key => $val) { foreach ($_afile as $__key => $val) {
$afile[] = $this->__jsdir .$val; if (!file_exists($this->__jsdir . $val)) continue;
} $_file = new SplFileInfo($this->__jsdir . $val);
if (file_exists($this->__realpath . 'assets/js/')) { $afile[] = $_file->getRealPath();
if ($handle = opendir($this->__realpath . 'assets/js/')) { $itime += $_file->getMTime();
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..' || is_dir($this->__realpath . 'assets/js/'.$file)) continue;
$afile[] = $this->__realpath . 'assets/js/' . $file;
}
closedir($handle);
}
} }
// add locale file // add locale file
$ljs = (isset($_SESSION['__WEB_USER']['LOCALE'])?$_SESSION['__WEB_USER']['LOCALE']:$_SESSION['__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)) { if (is_dir($this->__localedir)) {
if ($handle = opendir($this->__localedir)) { $iterator = new \FilesystemIterator($this->__localedir, \FilesystemIterator::SKIP_DOTS);
while (false !== ($file = readdir($handle))) { foreach ($iterator as $_file) {
$file = $this->__localedir . $file; if ($_file->isFile() && str_ends_with($_file->getFilename(), $ljs)) {
if (substr($file, -5) == $ljs) $afile[] = $this->__localedir .basename(str_replace("\\", "/", $file)); $afile[] = $_file->getRealPath();
} $itime += $_file->getMTime();
closedir($handle); }
} }
} }
$afile[] = $this->__jsapp . $mode . ".js";
} else if ($type == "app") { } else if ($type == "app") {
$afile[] = $this->__jsapp ."sys/profile.js"; if ($mode === 'index') {
$afile[] = $this->__jsapp ."sys/chpasswd.js"; if (is_dir($this->__jsapp)) {
$amenu = explode(",", $_SESSION['__WEB_USER']['Menu_Grup'] .",". $_SESSION['__WEB_USER']['Menu']); $dirIterator = new \RecursiveDirectoryIterator($this->__jsapp, \RecursiveDirectoryIterator::SKIP_DOTS);
$tmenu = implode("','", array_unique($amenu)); $dirFilter = new \RecursiveCallbackFilterIterator($dirIterator, fn($curr, $key, $iter) => !($curr->isDir() && in_array($curr->getFilename(), ['locale'])));
$this->__db->Query("SELECT * FROM app_menu WHERE Link<>'' AND Kode IN ('".$tmenu."') ORDER BY Level, Urut"); $iterator = new \RecursiveIteratorIterator($dirFilter);
while ($this->__db->Next()) { foreach ($iterator as $_file) {
$afile[] = $this->__jsapp . str_replace("php", "js", $this->__db->Row("Link")); if ($_file->isFile() && !in_array($_file->getFilename(), ['login.js','display.js'])) {
$afile[] = $_file->getRealPath();
$itime += $_file->getMTime();
} }
} }
return $afile; }
} else {
if (file_exists($this->__jsapp . $mode . '.js')) {
$_file = new SplFileInfo($this->__jsapp . $mode . '.js');
$afile[] = $_file->getRealPath();
$itime += $_file->getMTime();
}
}
}
return [ $afile, $itime ];
} }
private function check_file($afile) { private function create_cache(string $type = "css", array $afile = [], string $cachefile = ""): void {
$lastmod = 0;
foreach ($afile as $nfile) {
if (file_exists($nfile)) {
$lastmod += filemtime($nfile);
}
}
if ($this->__cachedays > 0) {
if ($handle = opendir($this->__cachedir)) {
while (false !== ($file = readdir($handle))) {
if ($file == '.' || $file == '..' || is_dir($this->__cachedir.$file)) continue;
if ((time()-filemtime($this->__cachedir.$file)) > (86400*$this->__cachedays)) {
unlink($this->__cachedir . $file);
}
}
closedir($handle);
}
}
return $lastmod;
}
private function create_cache($type="css", $mode="index", $afile=[], $lastmod=0) {
$contents = ''; $smini = null; $contents = ''; $smini = null;
$bpublic = ($_SERVER['SERVER_ADDR'] == "127.0.0.1") ? false : true; $bpublic = ($this->app->request()->ip === '127.0.0.1') ? false : true;
if ($bpublic == true) { if ($bpublic == true) {
if ($type=="css") { if ($type=="css") {
$smini = new Minify\CSS; $smini = new Minify\CSS;
@@ -147,15 +156,10 @@ final class Cache {
} }
} }
if ($bpublic) $contents = $smini->minify(); if ($bpublic) $contents = $smini->minify();
$cachefile = md5($mode . $lastmod) . ($type=="app"?".app":"") . ($type=="css" ? ".css" : ".js");
file_put_contents($this->__cachedir . $cachefile, $contents); file_put_contents($this->__cachedir . $cachefile, $contents);
if ($type == "app") return;
$this->__ini[$type][$mode.'_stamp'] = $lastmod;
$this->__ini[$type][$mode.'_file'] = $cachefile;
$this->save_ini();
} }
private function save_ini(){ private function save_ini(): void {
$content = ""; $content = "";
foreach ($this->__ini as $key => $elem) { foreach ($this->__ini as $key => $elem) {
$content .= ($content==""?"":"\n"). "[".$key."]\n"; $content .= ($content==""?"":"\n"). "[".$key."]\n";
@@ -167,27 +171,46 @@ final class Cache {
file_put_contents($this->__cachedir . "cache.ini", $content); file_put_contents($this->__cachedir . "cache.ini", $content);
} }
public function Main($type="css", $mode="") { public function Cache(string $mode = "index"): array {
if ($mode == "") $mode = "login"; $is_modif = false;
if (($_SESSION['__WEB_USER']['UserID'] ?? 0) > 0) $mode = "index"; foreach (['css','js','app'] as $type) {
$afile = $this->gen_file($type, $mode); [ $afile, $lastmod ] = $this->gen_file($mode, $type);
$lastmod = $this->check_file($afile); $cachefile = md5($mode . $type . $lastmod) . ($type=='css'?'.css':'.js');
if ($lastmod <> intval($this->__ini[$type][$mode.'_stamp']) || !file_exists($this->__cachedir . $this->__ini[$type][$mode.'_file'])) { if (!file_exists($this->__cachedir . $cachefile) || ((time()-(int)$this->__ini[$mode]['stamp']) > (86400*14))) {
$this->create_cache($type, $mode, $afile, $lastmod); $this->create_cache($type, $afile, $cachefile);
$this->__ini[$mode][$type] = $cachefile;
$this->__ini[$mode]['stamp'] = time();
$is_modif = true;
}
}
if ($is_modif === true) $this->save_ini();
$acache = [ 'CSS' => [], 'JS' => [], 'JSX' => [] ];
foreach ($this->__ini[$mode] as $_type => $_file) {
if ($_type == 'stamp') continue;
if (file_exists($this->__cachedir . $_file)) {
if ($_type === 'css') {
$acache['CSS'][] = 'chunks/' . $_file;
} else $acache['JS'][] = 'chunks/' . $_file;
} }
return $_SESSION['__WEB_APP']['WEB_PATH'] ."chunks/". $this->__ini[$type][$mode.'_file'];
} }
public function Apps() { $aoption = $this->session->get('__WEB_APP');
$id_user = (isset($_SESSION['__WEB_USER']) && is_array($_SESSION['__WEB_USER'])) ? $_SESSION['__WEB_USER']['UserID'] : 0; $auser = $this->session->get('__WEB_USER');
$afile = $this->gen_file("app", $id_user); $nonce = $this->app->get('csp_nonce');
$lastmod = $this->check_file($afile); $islog = user_logged($this->session);
$appfile = md5($id_user . $lastmod) . ".app.js"; $_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);
if (!file_exists($this->__cachedir . $appfile)) { $_suser = ($islog) ? $auser['Username'] .";". $auser['UserID'] .";". $auser['Grup_MenuID'] .";". $auser['Level'] : "nobody;999;999;9";
$this->create_cache("app", $id_user, $afile, $lastmod);
} $acache['JSX'][] = '<script nonce="'.$nonce.'" type="text/javascript">';
return $_SESSION['__WEB_APP']['WEB_PATH'] ."chunks/". $appfile; $acache['JSX'][] = 'FoniaJS.setConfig("'.base64_encode($_secret).'", "'.base64_encode($_suser).'");';
$acache['JSX'][] = '$(document).ready(function(){';
if ($islog) $acache['JSX'][] = 'FoniaJS.loadMenu();';
$acache['JSX'][] = '});';
$acache['JSX'][] = '</script>';
return $acache;
} }
} }
?> ?>
+54 -35
View File
@@ -3,35 +3,54 @@
/******************************************************************* /*******************************************************************
Module : /Data/PDF.php Module : /Data/PDF.php
Desc. : Class pembuatan file PDF
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 18th, 2015. 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); 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 { final class PDF {
private $__avalue = []; private $__avalue = [];
private $__atabel = []; private $__atabel = [];
private $__theader = ""; private $__theader = "";
private $__tcolname = ""; 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) { public function add_field(string $nama, string|int $lebar=0, string $align="L", string $func="", int $kol=1): void {
$this->__atabel[] = array($tnama, $nlebar.'%', $ffunc, $talign, $nkol); $this->__atabel[] = [ $nama, (string)$lebar.'%', $func, $align, $kol ];
} }
public function show_fields() { public function show_fields(): void {
$tmp_out = "<thead><tr>"; $tmp_out = "<thead><tr>";
for ($i=0; $i<count($this->__atabel); $i++) { for ($i=0; $i<count($this->__atabel); $i++) {
if ($this->__atabel[$i][4]==0) continue; if ($this->__atabel[$i][4]==0) continue;
@@ -41,21 +60,21 @@ final class PDF {
$this->__tcolname = $tmp_out; $this->__tcolname = $tmp_out;
} }
public function clear() { public function clear(): void {
$this->__avalue = []; $this->__avalue = [];
$this->__theader = ""; $this->__theader = "";
$this->__tcolname = ""; $this->__tcolname = "";
} }
public function set_header($tlapor="", $tperiod="") { public function set_header(string $lapor, string $period): void {
$thasil = '<div style="text-align:center;font-size:12pt;"><b>'.strtoupper($_SESSION['__WEB_APP']['REG_NAME']); $thasil = '<div style="text-align:center;font-size:12pt;"><b>'.strtoupper($this->webapp['REG_NAME']);
$thasil .= (($tlapor=="") ? "" : '<br>'.$tlapor) . '</b>'; $thasil .= (($lapor=="") ? "" : '<br>'.$lapor) . '</b>';
$thasil .= ($tperiod=="") ? "" : '<br><span style="font-size:11pt;">'.$tperiod.'</span>'; $thasil .= ($period=="") ? "" : '<br><span style="font-size:11pt;">'.$period.'</span>';
$thasil .= '</div><br>'; $thasil .= '</div><br>';
$this->__theader = $thasil; $this->__theader = $thasil;
} }
public function add_value() { public function add_value(): void {
$tmp_arr = func_get_args(); $tmp_arr = func_get_args();
if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0]; if (is_array($tmp_arr[0])) $tmp_arr = $tmp_arr[0];
$tmp_out = "<tr>"; $tmp_out = "<tr>";
@@ -73,7 +92,7 @@ final class PDF {
$this->__avalue[] = $tmp_out; $this->__avalue[] = $tmp_out;
} }
public function add_span() { public function add_span(): void {
$tmp_arr = func_get_args(); $tmp_arr = func_get_args();
$tmp_out = "<tr>"; $tmp_out = "<tr>";
for ($i=0; $i<count($tmp_arr); $i++) { for ($i=0; $i<count($tmp_arr); $i++) {
@@ -88,19 +107,19 @@ final class PDF {
$this->__avalue[] = $tmp_out; $this->__avalue[] = $tmp_out;
} }
public function add_empty() { public function add_empty(): void {
$this->__avalue[] = $this->set_align("&nbsp;", 0, "L,NB", true); $this->__avalue[] = $this->set_align("&nbsp;", 0, "L,NB", true);
} }
public function add_stamp($ctk_ke=1, $bnama=false) { public function add_stamp(int $ctk_ke=1, bool $tampil_nama=false): void {
$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); $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) { public function get_stamp(int $ctk_ke=1, bool $tampil_nama=false): string {
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):""); 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 = ' $html = '
<style> <style>
#pdf_area { #pdf_area {
@@ -148,33 +167,33 @@ final class PDF {
$html .= $this->__avalue[$i]; $html .= $this->__avalue[$i];
} }
$html .= '</tbody></table></div></div></body>'; $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->useSubstitutions = false;
$mpdf->WriteHTML($html); $mpdf->WriteHTML($html);
$mpdf->Output($nama_file.".pdf", "I"); $mpdf->Output($nama_file.".pdf", "I");
} }
public function set_align($ttext, $nlen, $tdir="L", $bline=false, $bhead=false, $ncol=1) { 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($tdir); $tstyle = $this->create_style($dir);
if (strpos(strtolower($ttext), "<tr>")===false) { //jika tidak ada <tr> up 2011-04-14 if (strpos(strtolower($text), "<tr>")===false) {
if ($bline===true) { if ($line===true) {
return '<tr><td colspan="'.count($this->__atabel).'" class="'.$tstyle.'">'.$ttext."</td></tr>"; return '<tr><td colspan="'.count($this->__atabel).'" class="'.$tstyle.'">'.$text."</td></tr>";
} else { } 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 { } 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"]; $apad = ["L"=>"left", "R"=>"right", "C"=>"center", "NB"=>"nb", "NL"=>"noleft", "NR"=>"noright", "B"=>"bold", "I"=>"italic"];
$_astyle = explode(",", $tstyle); $_astyle = explode(",", $style);
$thasil = ""; $ahasil = [];
foreach ($_astyle as $_key => $_val) { 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. Created Date : November 18th, 2012.
Last Modified : September 30th, 2025. 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); declare(strict_types=1);
namespace siaupheng\webapp\Data; namespace Webapp\Data;
final class SimpleXLS { final class SimpleXLS {
private $__wbook = null; private $__wbook = null;
+3 -2
View File
@@ -8,13 +8,14 @@
Created Date : November 18th, 2012. Created Date : November 18th, 2012.
Last Modified : October 26th, 2023. 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); declare(strict_types=1);
namespace siaupheng\webapp\Data; namespace Webapp\Data;
use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\IOFactory;
-75
View File
@@ -1,75 +0,0 @@
<?php
/*******************************************************************
Module : /Display.php
Desc. : HTML5 Page Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 10th, 2008.
Last Modified : July 25th, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
namespace siaupheng\webapp;
final class Display {
public $version = "1.1.0";
private $apps = [];
private $cache = null;
protected $__db = null;
public function __construct($db = null){
if (is_resource($db)) { $this->__db = $db; }
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); }
$this->apps = $_SESSION['__WEB_APP'];
if (($this->apps['TEMPLATE'] ?? "") == "") $this->apps['TEMPLATE'] = "display.php";
$this->cache = new \siaupheng\webapp\Data\Cache($this->__db);
}
public function TampilDisplay() {
// loading template file {{}}
$buffer = "";
if (file_exists($this->apps['REAL_PATH']."assets/templates/".$this->apps['TEMPLATE'])) {
$buffer = file_get_contents($this->apps['REAL_PATH']."assets/templates/".$this->apps['TEMPLATE']);
$buffer = preg_replace("/(?:(?:\\/\\*(?:[^*]|(?:\\*+[^*\\/]))*\\*+\\/)|(?:(?<!\\:)\\/\\/. *))/", "", $buffer);
}
$aoption = [...$this->apps, 'CSS_JS' => ""];
// penambahan file css + js + app-js
$aoption['CSS_JS'] = '<link rel="stylesheet" type="text/css" href="'.$this->cache->Main("css", "display").'">'."\n";
$aoption['CSS_JS'] .= '<script type="text/javascript" src="'.$this->cache->Main("js", "display").'"></script>'."\n";
$_secret = $aoption['APP_DISPLAY'] .";". $aoption['APP_SID'] .";". $_SERVER['HTTP_HOST'] .";". $aoption['WEB_PATH'] .";". "http://".$_SERVER['HTTP_HOST'].$aoption['WEB_PATH'] .";". isMobile() .";". ($aoption['AUTH_LEVEL']?$aoption['AUTH_LEVEL']:0) .";". $this->version;
$_suser = "nobody;999;999;9";
$aoption['CSS_JS'] .= '<script type="text/javascript" language="javascript">'."\n";
$aoption['CSS_JS'] .= 'FoniaJS.setConfig("'.base64_encode($_secret).'", "'.base64_encode($_suser).'");';
$aoption['CSS_JS'] .= '</script>'."\n";
// informasi tahun aplikasi dan pembuatan menu
if (strpos($buffer, '{{CREATOR_YEAR}}')===false) {
$aoption['REG_YEAR'] = ($aoption['REG_YEAR']!=date('Y')) ? $aoption['REG_YEAR']." - ".date('Y') : $aoption['REG_YEAR'];
} else {
$aoption['CREATOR_YEAR'] = ($aoption['CREATOR_YEAR']!=date('Y')) ? $aoption['CREATOR_YEAR']." - ".date('Y') : $aoption['CREATOR_YEAR'];
}
// perubahan variabel dari data konfigurasi
$aoption['APP_NAME_VER'] = $aoption['APP_NAME']." v".$aoption['APP_VER'];
$aoption['APP_NAMES_VER'] = $aoption['APP_NAMES']." v".$aoption['APP_VER'];
$aoption['APP_NAMES_UP'] = strtoupper($aoption['APP_NAMES'] ?? "");
$aoption['REG_NAME_UP'] = strtoupper($aoption['REG_NAME'] ?? "");
$aoption['REG_CITY_UP'] = strtoupper($aoption['REG_CITY'] ?? "");
$output = preg_replace_callback('/\{\{([a-zA-Z0-9_]+)\}\}/', fn($matches) => isset($aoption[$matches[1]]) ? $aoption[$matches[1]] : "", $buffer);
echo $output;
}
}
?>
+19 -19
View File
@@ -8,56 +8,56 @@
Created Date : January 27th, 2008. Created Date : January 27th, 2008.
Last Modified : January 21st, 2024. Last Modified : January 21st, 2024.
(c) 2008 - 2024, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
use \flight\Session;
if (!function_exists('user_level')) { if (!function_exists('user_level')) {
function user_level($level = 9) { function user_level(Session $session, int $level = 9): bool {
if ($_SESSION['__WEB_USER']['Level'] <= $level) return true; if ($session->get('__WEB_USER', ['Level'=>9])['Level'] <= $level) return true;
return false; return false;
} }
} }
if (!function_exists('user_level_not')) { if (!function_exists('user_level_not')) {
function user_level_not($level = 9) { function user_level_not(Session $session, int $level = 9): bool {
if ($_SESSION['__WEB_USER']['Level'] !== $level) return true; if ($session->get('__WEB_USER', ['Level'=>9])['Level'] !== $level) return true;
return false; return false;
} }
} }
if (!function_exists('user_logged')) { if (!function_exists('user_logged')) {
function user_logged() { function user_logged(Session $session): bool {
if (isset($_SESSION['__WEB_USER'])) return true; return !empty($session->get('__WEB_USER'));
return false;
} }
} }
if (!function_exists('user_id')) { if (!function_exists('user_id')) {
function user_id($idigit = 0) { function user_id(Session $session, int $digit = 0): string|int {
if ($idigit > 0) return isi_nol($_SESSION['__WEB_USER']['UserID'], $idigit); $id_user = (int)$session->get('__WEB_USER', ['UserID'=>0])['UserID'];
return $_SESSION['__WEB_USER']['UserID']; if ($digit > 0) return isi_nol($id_user, $digit);
return $id_user;
} }
} }
if (!function_exists('user_user')) { if (!function_exists('user_user')) {
function user_user() { function user_user(Session $session): string {
return $_SESSION['__WEB_USER']['Username']; return (string)$session->get('__WEB_USER', ['Username'=>''])['Username'];
} }
} }
if (!function_exists('user_unix')) { if (!function_exists('user_unix')) {
function user_unix() { function user_unix(Session $session): string {
return $_SESSION['__WEB_USER']['UNIX']; return (string)$session->get('__WEB_USER', ['UNIX'=>'0'])['UNIX'];
} }
} }
if (!function_exists('user_nama')) { if (!function_exists('user_nama')) {
function user_nama() { function user_nama(Session $session): string {
return $_SESSION['__WEB_USER']['Nama']; return (string)$session->get('__WEB_USER', ['Nama'=>''])['Nama'];
} }
} }
?>
-35
View File
@@ -1,35 +0,0 @@
<?php
/*******************************************************************
Module : /Function/JSON.php
Desc. : Fungsi Custom JSON
Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : April 14th, 2012.
Last Modified : April 29th, 2022.
(c) 2012 - 2022, 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/
declare(strict_types=1);
if (!function_exists('is_json')) {
function is_json($string) {
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
}
if (!function_exists('send_json')) {
function send_json($ajson = array(), $bempty = false) {
if (count($ajson) > 0 || $bempty == true) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
echo json_encode($ajson);
}
}
}
?>
+96 -85
View File
@@ -6,9 +6,9 @@
Desc. : Fungsi Custom Lain Lain Desc. : Fungsi Custom Lain Lain
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 27th, 2008. 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.
*******************************************************************/ *******************************************************************/
@@ -17,97 +17,99 @@ declare(strict_types=1);
/*************************** FORMAT ANGKA / CURRENCY *****************************/ /*************************** FORMAT ANGKA / CURRENCY *****************************/
if (!function_exists('rupiah')) { if (!function_exists('rupiah')) {
function rupiah($angka = 0, $desi = 0) { function rupiah(mixed $angka = 0, int $desi = 0): string {
return number_format(doubleval($angka), intval($desi), ",", "."); return number_format((float) $angka, $desi, ",", ".");
} }
} }
if (!function_exists('rupiah2')) { if (!function_exists('rupiah2')) {
function rupiah2($angka = 0) { function rupiah2(mixed $angka = 0): string {
return rupiah($angka, 2); return rupiah($angka, 2);
} }
} }
/* todo: deprecated
if (!function_exists('rupiah30')) { if (!function_exists('rupiah30')) {
function rupiah30($angka = 0) { function rupiah30($angka = 0): string {
$nilai = explode(".", $angka); $nilai = explode(".", $angka);
$hasil = (intval($nilai[1])==0) ? rupiah($angka, 0) : rupiah($angka, 3); $hasil = (intval($nilai[1])==0) ? rupiah($angka, 0) : rupiah($angka, 3);
return $hasil; return $hasil;
} }
} }*/
if (!function_exists('kurung_rup')) { if (!function_exists('kurung_rup')) {
function kurung_rup($angka = 0, $desi = 0) { function kurung_rup(mixed $angka = 0, int $desi = 0): string {
$thasil = rupiah(abs($angka), $desi); $thasil = rupiah(abs((float) $angka), $desi);
if ($angka<0) return "(".$thasil.")"; if ((float) $angka < 0) return "(".$thasil.")";
return $thasil." "; return $thasil." ";
} }
} }
if (!function_exists('kurung')) { if (!function_exists('kurung')) {
function kurung($angka = 0, $desi = 0) { function kurung(mixed $angka = 0, int $desi = 0): string {
$thasil = uang(abs($angka), $desi); $thasil = uang(abs((float) $angka), $desi);
if ($angka<0) return "(".$thasil.")"; if ((float) $angka < 0) return "(".$thasil.")";
return $thasil." "; return $thasil." ";
} }
} }
if (!function_exists('kurung2')) { if (!function_exists('kurung2')) {
function kurung2($angka = 0) { function kurung2(mixed $angka = 0): string {
return kurung($angka, 2); return kurung($angka, 2);
} }
} }
if (!function_exists('uang')) { if (!function_exists('uang')) {
function uang($angka = 0, $desi = 0) { function uang(mixed $angka = 0, int $desi = 0): string {
$angka = str_replace(",","",$angka); $angka = str_replace(",", "", (string) $angka);
return number_format(doubleval($angka), intval($desi)); return number_format((float) $angka, $desi);
} }
} }
if (!function_exists('uang2')) { if (!function_exists('uang2')) {
function uang2($angka = 0) { function uang2(mixed $angka = 0): string {
return uang($angka, 2); return uang($angka, 2);
} }
} }
/* todo: deprecated
if (!function_exists('koma30')) { if (!function_exists('koma30')) {
function koma30($angka = 0) { function koma30($angka = 0) {
$nilai = explode(".", $angka); $nilai = explode(".", $angka);
$hasil = (intval($nilai[1])==0) ? uang($angka, 0) : uang($angka, 3); $hasil = (intval($nilai[1])==0) ? uang($angka, 0) : uang($angka, 3);
return $hasil; return $hasil;
} }
} }*/
if (!function_exists('items')) { if (!function_exists('items')) {
function items($item = 0) { function items(mixed $item = 0): string {
return rupiah($item)." Items"; return rupiah($item)." Items";
} }
} }
if (!function_exists('records')) { if (!function_exists('records')) {
function records($item = 0) { function records(mixed $item = 0): string {
return rupiah($item)." Records"; return rupiah($item)." Records";
} }
} }
if (!function_exists('baris')) { if (!function_exists('baris')) {
function baris($item = 0) { function baris(mixed $item = 0): string {
return rupiah($item)." Baris"; return rupiah($item)." Baris";
} }
} }
if (!function_exists('npwp')) { 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); 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')) { if (!function_exists('romawi')) {
function romawi($n) { function romawi(int $n): string {
$hasil = ""; $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)) { if (array_key_exists($n, $iromawi)) {
$hasil = $iromawi[$n]; $hasil = $iromawi[$n];
} else if ($n >= 11 && $n <= 99) { } else if ($n >= 11 && $n <= 99) {
$i = $n % 10; $i = $n % 10;
@@ -124,7 +126,7 @@ if (!function_exists('romawi')) {
} }
if (!function_exists('abjad')) { if (!function_exists('abjad')) {
function abjad($n) { function abjad(int $n): string {
$_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
return substr($_str, ($n-1), 1); return substr($_str, ($n-1), 1);
} }
@@ -133,8 +135,8 @@ if (!function_exists('abjad')) {
/*************************** FORM CONTROL *****************************/ /*************************** FORM CONTROL *****************************/
if (!function_exists('checkbox')) { if (!function_exists('checkbox')) {
function checkbox($nilai = 0) { function checkbox(mixed $nilai): string {
$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"; $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>'; return '<i class="fs-6 bi-'.$thasil.'"></i>';
} }
} }
@@ -142,34 +144,34 @@ if (!function_exists('checkbox')) {
/*************************** FORMAT TANGGAL / KALENDER *****************************/ /*************************** FORMAT TANGGAL / KALENDER *****************************/
if (!function_exists('sqltgl')) { if (!function_exists('sqltgl')) {
function sqltgl($waktu = "0") { function sqltgl(string $waktu): string {
return tgl_sql2str($waktu); return tgl_sql2str($waktu);
} }
} }
if (!function_exists('sqltgls')) { if (!function_exists('sqltgls')) {
function sqltgls($waktu = "0") { function sqltgls(string $waktu): string {
return tgl_sql2str($waktu, false, true); return tgl_sql2str($waktu, false, true);
} }
} }
if (!function_exists('sqljam')) { if (!function_exists('sqljam')) {
function sqljam($waktu = "0") { function sqljam(string $waktu): string {
return tgl_sql2str($waktu, true); return tgl_sql2str($waktu, true);
} }
} }
if (!function_exists('sqljams')) { if (!function_exists('sqljams')) {
function sqljams($waktu = "0") { function sqljams(string $waktu): string {
return tgl_sql2str($waktu, true, true); return tgl_sql2str($waktu, true, true);
} }
} }
if (!function_exists('tgl_sql2str')) { if (!function_exists('tgl_sql2str')) {
function tgl_sql2str($waktu = "0", $jam = false, $short = false) { function tgl_sql2str(string $waktu, bool $jam = false, bool $short = false): string {
if ($waktu=="0" || $waktu=="") return; if (empty($waktu)) return '';
$atgl = explode(" ", $waktu); $atgl = explode(" ", $waktu);
$sjam = ($jam) ? ((empty($atgl[1]))?date("H:i:s"):$atgl[1]) : ""; $sjam = ($jam) ? ((empty($atgl[1])) ? date("H:i:s") : $atgl[1]) : "";
$atgl = explode("-", $atgl[0]); $atgl = explode("-", $atgl[0]);
$stgl = $atgl[2]."-".$atgl[1]."-".$atgl[0]; $stgl = $atgl[2]."-".$atgl[1]."-".$atgl[0];
if ($short) $stgl = $atgl[2].".".$atgl[1].".".substr($atgl[0],2); if ($short) $stgl = $atgl[2].".".$atgl[1].".".substr($atgl[0],2);
@@ -178,66 +180,66 @@ if (!function_exists('tgl_sql2str')) {
} }
if (!function_exists('tgl_ymd')) { 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")); return (($jam) ? date("Y-m-d H:i:s") : date("Y-m-d"));
} }
} }
if (!function_exists('tgl_dmy')) { 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")); return (($jam) ? date("d-m-Y H:i:s") : date("d-m-Y"));
} }
} }
if (!function_exists('tgl_operasi')) { if (!function_exists('tgl_operasi')) {
function tgl_operasi($dtgl = "", $nhari = 0, $nbln = 0, $nthn = 0) { function tgl_operasi(string $tgl, int $hari = 0, int $bln = 0, int $thn = 0): string {
$atgl = explode("-", $dtgl); $atgl = explode("-", $tgl);
return date("d-m-Y", mktime(0,0,0, $atgl[1]+$nbln, $atgl[0]+$nhari, $atgl[2]+$nthn)); 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')) { if (!function_exists('tgl_range_hari')) {
function tgl_range_hari($dftgl="", $dttgl="", $bhitung_awal=false) { function tgl_range_hari(string $tgl_from, string $tgl_to, bool $hitung_awal = false): float {
$_start = strtotime(tgl_sql2str($dftgl)); if (empty($tgl_to) or empty($tgl_from)) return 0;
$_end = strtotime(tgl_sql2str($dttgl)); $_start = strtotime(tgl_sql2str($tgl_from));
return ceil(abs($_end - $_start) / 86400) + (($bhitung_awal==true)?1:0); $_end = strtotime(tgl_sql2str($tgl_to));
return ceil(abs($_end - $_start) / 86400) + (($hitung_awal)?1:0);
} }
} }
if (!function_exists('tgl_akhbln')) { if (!function_exists('tgl_akhbln')) {
function tgl_akhbln($tgl) { function tgl_akhbln(string $tgl): string {
if (empty($tgl)) return '';
$atgl = explode("-", $tgl); $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 // jika tahun masehi dan bulan 2
if ( (round($atgl[2]/4)==($atgl[2]/4)) && intval($atgl[1])==2 ) return "29-02-".$atgl[2]; if ((round((int) $atgl[2]/4) === ((int) $atgl[2]/4)) && (int) $atgl[1] === 2) return "29-02-".$atgl[2];
return $ablna[(intval($atgl[1])-1)]."-".isi_nol($atgl[1],2)."-".$atgl[2]; return $ablna[(int) $atgl[1]-1]."-".isi_nol($atgl[1],2)."-".$atgl[2];
} }
} }
if (!function_exists('tgl_panjang')) { if (!function_exists('tgl_panjang')) {
function tgl_panjang($dtgl = "") { function tgl_panjang(string $tgl): string {
if (trim($dtgl)=="") $dtgl = tgl_dmy(); if (empty($tgl)) $tgl = tgl_dmy();
$atgl = explode("-", $dtgl); $atgl = explode("-", $tgl);
$abulan = bulan_array(); $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')) { if (!function_exists('tgl_hari')) {
function tgl_hari($dtgl = "") { function tgl_hari(string $tgl): string {
$nhari = date("w"); $nhari = date("w");
if (trim($dtgl)!="") { if (!empty($tgl)) {
//$atgl = getdate($dtgl); $nhari = date("w", strtotime(tgl_sql2str($tgl)));
//$nhari = $atgl[wday];
$nhari = date("w", strtotime(tgl_sql2str($dtgl)));
} }
$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]; return $ahari[$nhari];
} }
} }
if (!function_exists('tgl_triwulan')) { if (!function_exists('tgl_triwulan')) {
function tgl_triwulan($dtgl = "") { function tgl_triwulan(string $tgl): int {
if ($dtgl == "") { if (empty($tgl)) {
$dtgl = date("m"); $dtgl = date("m");
} else { } else {
$atgl = explode("-", $tgl); $atgl = explode("-", $tgl);
@@ -253,13 +255,13 @@ if (!function_exists('tgl_triwulan')) {
} }
if (!function_exists('bulan_array')) { if (!function_exists('bulan_array')) {
function bulan_array() { function bulan_array(): 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"); 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')) { 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"]; 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 *****************************/ /*************************** FORMAT TAMPILAN & ERROR *****************************/
if (!function_exists('subjudul')) { if (!function_exists('subjudul')) {
function subjudul($tjudul) { 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;">'.$tjudul.'</span>&nbsp;&nbsp;</td><td width="50%"><hr /></td></tr></table>'; 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')) { if (!function_exists('showerror')) {
function showerror($terror) { function showerror(string $error): void {
echo '<input type="hidden" id="_Error" class="error" value="'.$terror.'!" />'; echo '<input type="hidden" id="_Error" class="error" value="'.$error.'!" />';
} }
} }*/
if (!function_exists('br2nl')) { if (!function_exists('br2nl')) {
function br2nl($string) { function br2nl(string $string): string {
return preg_replace('/\<br(\s*)?\/?\>/i', "\n\r", $string); return preg_replace('/\<br(\s*)?\/?\>/i', "\n\r", $string);
} }
} }
if (!function_exists('isi_nol')) { if (!function_exists('isi_nol')) {
function isi_nol($nilai = "0", $panjang = 1) { function isi_nol(string|int $nilai = 0, int $panjang = 1): string {
$nilai = strval($nilai); $nilai = (string)$nilai;
return ($panjang>strlen($nilai) ? str_repeat("0", $panjang-strlen($nilai)):'').$nilai; return ($panjang>strlen($nilai) ? str_repeat("0", $panjang-strlen($nilai)):'').$nilai;
} }
} }
if (!function_exists('isMobile')) { if (!function_exists('isMobile')) {
function isMobile() { function isMobile(): bool {
$agen = $_SERVER['HTTP_USER_AGENT']; $agen = $_SERVER['HTTP_USER_AGENT'];
$amobile = ['Android', 'webOS', 'iPhone', 'iPad', 'iPod', 'BlackBerry', 'Windows Phone', 'Mobile']; $amobile = ['Android', 'webOS', 'iPhone', 'iPad', 'iPod', 'BlackBerry', 'Windows Phone', 'Mobile'];
foreach ($amobile as $keyword) { foreach ($amobile as $keyword) {
@@ -303,46 +306,47 @@ if (!function_exists('isMobile')) {
} }
if (!function_exists('isLinux')) { if (!function_exists('isLinux')) {
function isLinux() { function isLinux(): bool {
$agen = $_SERVER['HTTP_USER_AGENT']; $agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen,'linux') !== false) return true; if (stripos($agen, 'linux') !== false) return true;
return false; return false;
} }
} }
if (!function_exists('isIE')) { if (!function_exists('isIE')) {
function isIE() { function isIE(): bool {
$agen = $_SERVER['HTTP_USER_AGENT']; $agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen,'msie') !== false) return true; if (stripos($agen, 'msie') !== false) return true;
return false; return false;
} }
} }
if (!function_exists('isChrome')) { if (!function_exists('isChrome')) {
function isChrome() { function isChrome(): bool {
$agen = $_SERVER['HTTP_USER_AGENT']; $agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen,'chrome') !== false) return true; if (stripos($agen, 'chrome') !== false) return true;
return false; return false;
} }
} }
if (!function_exists('isFirefox')) { if (!function_exists('isFirefox')) {
function isFirefox() { function isFirefox(): bool {
$agen = $_SERVER['HTTP_USER_AGENT']; $agen = $_SERVER['HTTP_USER_AGENT'];
if (stripos($agen,'firefox') !== false) return true; if (stripos($agen, 'firefox') !== false) return true;
return false; return false;
} }
} }
/* todo: deprecated
if (!function_exists('potong')) { if (!function_exists('potong')) {
function potong($nilai) {//utk rkpd function potong($nilai) {//utk rkpd
return substr($nilai, 0, 60); return substr($nilai, 0, 60);
} }
} }*/
if (!function_exists('format_bytes')) { if (!function_exists('format_bytes')) {
function format_bytes($bytes) { function format_bytes(int $bytes): string {
if ($bytes < 1024) return $bytes.' B'; if ($bytes < 1024) return (string) $bytes.' B';
elseif ($bytes < 1048576) return uang2($bytes / 1024).' KB'; elseif ($bytes < 1048576) return uang2($bytes / 1024).' KB';
elseif ($bytes < 1073741824) return uang2($bytes / 1048576).' MB'; elseif ($bytes < 1073741824) return uang2($bytes / 1048576).' MB';
elseif ($bytes < 1099511627776) return uang2($bytes / 1073741824).' GB'; elseif ($bytes < 1099511627776) return uang2($bytes / 1073741824).' GB';
@@ -350,4 +354,11 @@ if (!function_exists('format_bytes')) {
} }
} }
?> if (!function_exists('random_color')) {
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 Module : /Printer/PrintHTML.php
Desc. : Class cetak HTML
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008. 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); 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 { final class PrintHTML {
private $__avalue = []; private $__avalue = [];
private $__atabel = []; private $__atabel = [];
private $__css = "table"; private $__css = "table";
private $__tstamp = ""; 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 = "") { public function set_css(string $style): void {
if ($style=="") return; if (!empty($style)) $this->__css = $style;
$this->__css = $style;
} }
public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="", $nkol=1) {//up 2012-03-07 public function add_field(string $nama, int $lebar=0, string $align="L", string $func="", int $kol=1): void {
$this->__atabel[] = [$tnama, $nlebar, $ffunc, $talign, $nkol]; $this->__atabel[] = [ $nama, $lebar, $func, $align, $kol ];
} }
public function show_fields() {//todo: deleted public function clear(): void {
}
public function clear() {
$this->__avalue = []; $this->__avalue = [];
} }
public function add_value() { public function add_value(): void {
$tmp_arr = func_get_args(); $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>"; $tmp_out = "<tr>";
for ($i=0; $i<count($this->__atabel); $i++) { for ($i=0; $i<count($this->__atabel); $i++) {
$tmp_val = $tmp_arr[$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]; $tmp_val = $this->__atabel[$i][2][$tmp_val];
} else if (function_exists($this->__atabel[$i][2]) && trim("".$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 = 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 .= $tmp_val;
} }
$tmp_out .= "</tr>"; $tmp_out .= "</tr>";
$this->__avalue[] = $tmp_out; $this->__avalue[] = $tmp_out;
} }
public function add_span() { public function add_span(): void {
$tmp_arr = func_get_args(); $tmp_arr = func_get_args();
$tmp_out = "<tr>"; $tmp_out = "<tr>";
for ($i=0; $i<count($tmp_arr); $i++) { for ($i=0; $i<count($tmp_arr); $i++) {
@@ -79,15 +94,15 @@ final class PrintHTML {
$this->__avalue[] = $tmp_out; $this->__avalue[] = $tmp_out;
} }
public function add_stamp($ctk_ke=1, $bnama=false) {//up 2023-10-13 public function add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$this->__tstamp = $this->get_stamp($ctk_ke, $bnama); $this->__tstamp = $this->get_stamp($ctk_ke, $cetak_nama);
} }
public function get_stamp($ctk_ke=1, $bnama=false) {//up 2012-10-11 public function get_stamp(int $ctk_ke=1, bool $cetak_nama=false): string {
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):""); 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>"; $out = "<table class=\"".$this->__css."\"><thead>";
// header out // header out
@@ -111,27 +126,29 @@ final class PrintHTML {
for ($i=1; $i<=$jumlah_ctk; $i++) echo $out; 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 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($tdir); $tstyle = $this->create_style($dir);
if ($bline===true) { if ($line===true) {
return "<tr><td colspan=\"".count($this->__atabel)."\" class=\"".$tstyle." ".$textra."\">".$ttext."</td></tr>"; return "<tr><td colspan=\"".count($this->__atabel)."\" class=\"".$tstyle." ".$extra."\">".$text."</td></tr>";
} else { } 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 // 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"]; $apad = ["L"=>"l", "R"=>"r", "C"=>"c", "NB"=>"nb", "NL"=>"noleft", "NR"=>"noright", "B"=>"b", "I"=>"i"];
$_astyle = explode(",", $tstyle); $_astyle = explode(",", $style);
$thasil = ""; $ahasil = [];
foreach ($_astyle as $_key => $_val) { 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 Module : /Printer/PrintPOS.php
Desc. : Class cetak POS
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008. 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); declare(strict_types=1);
namespace siaupheng\webapp\Printer; namespace Webapp\Printer;
/* VERSI BARU DENGAN MULTI SHEET */ use \flight\Engine;
class PrintPOS {//up: 20251203
/**
* 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 $_header = [];
private $_avalue = []; private $_avalue = [];
private $_astyle = []; private $_astyle = [];
@@ -27,37 +38,44 @@ class PrintPOS {//up: 20251203
'fontsize' => 1, 'fontsize' => 1,
'opendraw' => false, 'opendraw' => false,
'cutpaper' => 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; $this->_config['opendraw'] = true;
} }
public function set_cutpaper() { public function set_cutpaper(): void {
$this->_config['cutpaper'] = true; $this->_config['cutpaper'] = true;
} }
public function set_maxchr($nmax = 0) {//up: 2015-03-22 public function set_maxchr(int $max = 0): void {
if ($nmax > 0) $this->_maxchr = $nmax; if ($max > 0) $this->_maxchr = $max;
} }
public function set_fontsize($nsize = 1) {//up: 2015-09-30 public function set_fontsize(int $size = 1): void {
if ($nsize > 0) $this->_config['fontsize'] = $nsize; if ($size > 0) $this->_config['fontsize'] = $size;
} }
public function set_printnv_logo() {}//delete public function set_header_logo(string $logo_file = ""): void {
if (!empty($logo_file) && file_exists(PROJECT_ROOT."assets/images/".$logo_file)) {
public function set_header_logo($logo_file = "") {//up: 2019-01-08 $this->_config['logo'] = PROJECT_BASE."assets/images/".$logo_file;
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 add_header() {//up: 2025-12-03 public function add_header(): void {
$extra = func_get_args(); $extra = func_get_args();
if (count($extra) > 0) { if (count($extra) > 0) {
foreach ($extra as $_val) { 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++; $this->_ncont++;
} }
public function add() {//up: 20180524 public function add(): void {
$val_arr = func_get_args(); $ttext = ""; $tstyle = "L"; $val_arr = func_get_args(); $ttext = ""; $tstyle = "L";
if (is_array($val_arr[0])) { if (is_array($val_arr[0])) {
foreach($val_arr as $aval) { foreach($val_arr as $aval) {
@@ -84,32 +102,32 @@ class PrintPOS {//up: 20251203
$this->_astyle[$this->_ncont][] = $tstyle; $this->_astyle[$this->_ncont][] = $tstyle;
} }
public function addl($ttext = "") { public function addl(string $text = ""): void {
$this->add($ttext); $this->add($text);
} }
public function addr($ttext = "") { public function addr(string $text = ""): void {
$this->add($ttext, "R"); $this->add($text, "R");
} }
public function addc($ttext = "") { public function addc(string $text = ""): void {
$this->add($ttext, "C"); $this->add($text, "C");
} }
public function add_line($tmp = "-") { public function add_line(string $line = "-"): void {
$this->add("__LINE ".$tmp); $this->add("__LINE ".$line);
} }
public function add_empty($nrep = 1) { public function add_empty(int $baris = 1): void {
for ($i=0;$i<$nrep;$i++) $this->add(""); for ($i=0; $i<$baris; $i++) $this->add("");
} }
public function add_stamp($ctk_ke=1, $bnama=false) { public function add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$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):"")); $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 public function show(int $jumlah_ctk=1): void {
$acontent = array(); $acontent = [];
$nmax = $this->_maxchr; $nmax = $this->_maxchr;
for ($s=0; $s<count($this->_avalue); $s++) { 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['config'] = $this->_config;
$aout['header'] = $this->_header; $aout['header'] = $this->_header;
$aout['content'] = $acontent; $aout['content'] = $acontent;
send_json($aout); $this->app->json($aout);
} }
public function show($jumlah_ctk=1) { public function set_align(string $text, int $len=0, string $dir="L"): string {
$this->_config['times'] = $jumlah_ctk; $apad = ["L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH];
$this->_json_out(); $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 //todo: deprecated
$apad = array("L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH); public function set_printnv_logo() {}//delete
$nlen = ($nlen==0) ? strlen($ttext) : $nlen;
$ttext = (strlen($ttext)>$nlen) ? substr($ttext, 0, $nlen) : $ttext;
return str_pad($ttext, $nlen, " ", $apad[$tdir]);
}
} }
?> ?>
+60 -47
View File
@@ -2,19 +2,31 @@
/******************************************************************* /*******************************************************************
Module : /Printing/PrintRAW.php Module : /Printer/PrintRAW.php
Desc. : Class cetak RAW
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 15th, 2008. Created Date : June 15th, 2008.
Last Modified : November 1st, 2023. Last Modified : November 1st, 2023.
(c) 2008 - 2023, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); 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 { class PrintRAW {
private $_header = []; private $_header = [];
@@ -27,54 +39,59 @@ class PrintRAW {
'fontsize' => "01", 'fontsize' => "01",
'nvlogo' => false, 'nvlogo' => false,
'opendraw' => 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['opendraw'] = true;
$this->_config['opendrawbegin'] = $bbegin;
} }
public function set_cutpaper() { public function set_cutpaper(): void {
$this->_config['cutpaper'] = true; $this->_config['cutpaper'] = true;
} }
public function set_maxchr($nmax = 0) {//up: 2015-03-22 public function set_maxchr(int $max = 0): void {
if ($nmax > 0) $this->_maxchr = $nmax; if ($max > 0) $this->_maxchr = $max;
} }
public function set_fontsize($nsize = 1) {//up: 2015-09-30 public function set_fontsize(int $size = 1): void {
if ($nsize > 0) $this->_config['fontsize'] = str_pad($nsize, 2, "0", STR_PAD_LEFT); 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; $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->_config['nvlogo'] = $nvlogo;
$this->_header[] = $_SESSION['__WEB_APP']['REG_NAME'];
if (count($extra) > 0) { if (count($extra) > 0) {
foreach ($extra as $_val) { foreach ($extra as $_val) {
$this->_header[] = $_val; $this->_header[] = $_val;
} }
} }
$this->_header[] = $_SESSION['__WEB_APP']['REG_CITY'];
} }
public function add_sheet() {//up: 20170321 public function add_sheet(): void {
$this->_ncont++; $this->_ncont++;
} }
public function add_field($tnama="", $nlebar=0, $talign="L", $ffunc="") { public function add_field(string $nama, int $lebar=0, string $align="L", string $func=""): void {
$this->_atabel[] = [$tnama, $nlebar, $ffunc, $talign]; $this->_atabel[] = [ $nama, $lebar, $func, $align ];
} }
public function show_fields() { public function show_fields(): void {
$tmp_out = "<b>"; $tmp_out = "<b>";
for ($i=0; $i<count($this->_atabel); $i++) { for ($i=0; $i<count($this->_atabel); $i++) {
$tmp_out .= $this->set_align($this->_atabel[$i][0], $this->_atabel[$i][1], "C"); $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 -"; $this->_avalue[$this->_ncont][] = "__LINE -";
} }
public function add_value() { public function add_value(): void {
$tmp_arr = func_get_args(); $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 = ""; $tmp_out = "";
for ($i=0; $i<count($this->_atabel); $i++) { for ($i=0; $i<count($this->_atabel); $i++) {
$tmp_val = $tmp_arr[$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]; $tmp_val = $this->_atabel[$i][2][$tmp_val];
} else if (function_exists($this->_atabel[$i][2]) && trim($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 = call_user_func($this->_atabel[$i][2], $tmp_val);
@@ -104,24 +121,24 @@ class PrintRAW {
$this->_avalue[$this->_ncont][] = $tmp_out; $this->_avalue[$this->_ncont][] = $tmp_out;
} }
public function add($ttext = "") { public function add(string $text): void {
$this->_avalue[$this->_ncont][] = $ttext; $this->_avalue[$this->_ncont][] = $text;
} }
public function add_line($tmp = "-") { public function add_line(string $line = "-"): void {
$this->add("__LINE ".$tmp); $this->add("__LINE ".$line);
} }
public function add_empty($nrep = 1) { public function add_empty(int $rep = 1): void {
for ($i=0;$i<$nrep;$i++) $this->add(""); for ($i=0;$i<$rep;$i++) $this->add("");
} }
public function add_stamp($ctk_ke=1, $bnama=false) { public function add_stamp(int $ctk_ke=1, bool $cetak_nama=false): void {
$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):"")); $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 public function show(int $jumlah_ctk=1): void {
$acontent = array(); $acontent = [];
$nmax = $this->_maxchr; $nmax = $this->_maxchr;
for ($s=0; $s<count($this->_avalue); $s++) { 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['config'] = $this->_config;
$aout['header'] = $this->_header; $aout['header'] = $this->_header;
$aout['content'] = $acontent; $aout['content'] = $acontent;
send_json($aout); $this->app->json($aout);
} }
public function show($jumlah_ctk=1) { public function set_align(string $text, int $len, string $dir="L"): string {
$this->_config['times'] = $jumlah_ctk; $apad = ["L"=>STR_PAD_RIGHT, "R"=>STR_PAD_LEFT, "C"=>STR_PAD_BOTH];
$this->_json_out(); $ttext = (strlen($text)>$len) ? substr($text, 0, $len) : $text;
} return str_pad($text, $len, " ", $apad[$dir]);
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]);
} }
} }
+79 -71
View File
@@ -3,135 +3,143 @@
/******************************************************************* /*******************************************************************
Module : /Web/Auth.php Module : /Web/Auth.php
Desc. : Fungsi login dan user checking
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : March 16th, 2008. 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.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Auth {
private $__id_reg = 0; private int $__id_reg = 0;
protected $__db = null; protected Engine $app;
protected SimplePdo $db;
protected Session $session;
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__db = $db; } * @param Engine $app
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); } */
$this->__id_reg = $_SESSION['__WEB_APP']['REG_ID']; 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 = $id; if ($id > 0) $this->__id_reg = (int)$id;
} }
public function user_check($user, $pass) { public function user_check(string $user, string $pass): bool {
$i_hasil = 0; $i_hasil = (int)$this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Password=MD5(?) AND Aktif=1', [$user, $pass]);
$this->__db->Query("SELECT COUNT(*) Ada FROM app_operator WHERE Username='".$this->__db->safeSQL($user)."' AND Password=MD5('".$this->__db->safeSQL($pass)."') AND Aktif=1");
if ($this->__db->Next()) $i_hasil = $this->__db->Row("Ada", 0);
return ($i_hasil > 0 ? true : false); return ($i_hasil > 0 ? true : false);
} }
public function user_data($user) { public function user_data(string $user): array {
$adata = []; $adata = $this->db->fetchRow('SELECT *,DECODE(Menu,?) Menu2 FROM app_operator WHERE Username=?', [$this->__id_reg, $user])->getData();
$this->__db->Query("SELECT *,DECODE(Menu,'".$this->__id_reg."') Menu2 FROM app_operator WHERE Username='".$this->__db->SafeSQL($user)."'");
if ($this->__db->Next()) {
$adata = $this->__db->AllRow();
$adata['Menu'] = $adata['Menu2']; $adata['Menu'] = $adata['Menu2'];
unset($adata['Menu2']); unset($adata['Menu2']);
}
if (!isset($_SESSION['APP_TOKEN'])) { if (empty($this->session->get('APP_TOKEN'))) {
$_token = $this->genToken(60); $_token = $this->genToken(60);
$_SESSION['APP_TOKEN'] = $_token; $this->session->set('APP_TOKEN', $_token);
$this->__db->Query("INSERT INTO app_token SET Token='".$_token."',UserID='".$adata['UserID']."',IP='".$_SERVER['REMOTE_ADDR']."'"); $this->db->insert('app_token', [ 'Token' => $_token, 'UserID' => $adata['UserID'], 'IP' => $this->app->request()->ip ]);
} }
if (intval($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['UNIX'] = time();
$adata['LOCALE'] = $_SESSION['__WEB_APP']['DEF_LOCALE']; $adata['LOCALE'] = $this->session->get('__WEB_APP', ['DEF_LOCALE'=>'id'])['DEF_LOCALE'];
$adata['MENU_MODUL'] = [];
return $adata; return $adata;
} }
public function gen_module_menu() { public function gen_module_menu(): void {
$amodul = []; $aallow = []; $amodul = []; $aallow = []; $tallow = '';
if ($_SESSION['__WEB_APP']['APP_MODULE']) { if ($this->session->get('__WEB_APP', ['APP_MODULE'=>0])['APP_MODULE']) {
$this->__db->Query("SELECT * FROM app_menu_grup WHERE Grup_MenuID='".$_SESSION['__WEB_USER']['Grup_MenuID']."' LIMIT 1"); $tallow = $this->db->fetchField('SELECT Modul_Akses FROM app_menu_grup WHERE Grup_MenuID=?', [$this->session->get('__WEB_USER', ['Grup_MenuID'=>0])['Grup_MenuID']]);
if ($this->__db->Next()) $aallow = ($this->__db->Row("Modul_Akses")=="") ? array() : explode(",", $this->__db->Row("Modul_Akses")); $aallow = explode(",", $tallow);
if (count($aallow) > 0) { if (count($aallow) > 0) {
$this->__db->Query("SELECT * FROM (SELECT APP_MODULE,APP_PATH FROM app_config) A LEFT JOIN (SELECT Modul,Urut,Judul,Icon FROM app_menu WHERE Level=0) B ON (A.APP_MODULE=B.Modul) ORDER BY B.Urut"); $stat = $this->db->runQuery('SELECT * FROM (SELECT APP_MODULE,APP_PATH FROM app_config) A LEFT JOIN (SELECT Modul,Urut,Judul,Icon FROM app_menu WHERE Level=0) B ON (A.APP_MODULE=B.Modul) ORDER BY B.Urut');
while ($this->__db->Next()) { while ($row = $stat->fetch()) {
if (!in_array($this->__db->Row("Modul"), $aallow) || $this->__db->Row("Modul")==$_SESSION['__WEB_APP']['APP_MODULE']) continue; if (!in_array($row['Modul'], $aallow) || $row['Modul']==$this->session->get('__WEB_APP')['APP_MODULE']) continue;
$amodul[] = $this->__db->AllRow(); $amodul[] = $row;
} }
} }
} }
$_SESSION['__WEB_USER']['MENU_MODUL'] = $amodul; $auser = $this->session->get('__WEB_USER', []);
$auser['MENU_MODUL'] = $amodul;
$this->session->set('__WEB_USER', $auser);
} }
public function user_allmenu($id_grup = 0) { public function user_allmenu(int $id_grup = 0): string {
$allmenu = ""; $allmenu = $this->db->fetchField('SELECT DECODE(Menu,?) MenuX FROM app_menu_grup WHERE Grup_MenuID=?', [$this->__id_reg, $id_grup]);
$this->__db->Query("SELECT DECODE(Menu,'".$this->__id_reg."') MenuX FROM app_menu_grup WHERE Grup_MenuID='".$id_grup."'");
if ($this->__db->Next()) $allmenu = $this->__db->Row("MenuX");
return $allmenu; return $allmenu;
} }
public function user_check_level($user, $level = 9) { public function user_check_level(string $user, int $level = 9): bool {
$i_hasil = 0; $i_hasil = (int)$this->db->fetchField('SELECT COUNT(*) FROM app_operator WHERE Username=? AND Level<=? AND Aktif=1', [$user, $level]);
$this->__db->Query("SELECT COUNT(*) Ada FROM app_operator WHERE Username='".$this->__db->safeSQL($user)."' AND Level<='".$this->__db->safeSQL($level)."' AND Aktif=1");
if ($this->__db->Next()) $i_hasil = $this->__db->Row("Ada", 0);
return ($i_hasil > 0 ? true : false); return ($i_hasil > 0 ? true : false);
} }
public function user_log() { public function user_log(): void {
if ($_SESSION['__WEB_APP']['USER_LOG'] == false) return; $_user_id = $this->session->get('__WEB_USER')['UserID'] ?? 0;
$a_hasil = array(); if ($_user_id === 0) return;
$this->__db->Query("SELECT * FROM app_logs WHERE UserID='".user_id()."' ORDER BY Last_Date DESC LIMIT 1"); $a_hasil = $this->db->fetchRow('SELECT * FROM app_logs WHERE UserID=? ORDER BY Last_Date DESC LIMIT 1', [$_user_id])->getData();
if ($this->__db->Next()) $a_hasil = $this->__db->AllRow();
if (count($a_hasil) > 0) { if (count($a_hasil) > 0) {
$this->__db->Query("UPDATE app_operator SET Last_IP='".$a_hasil['Last_IP']."',Last_Date='".$a_hasil['Last_Date']."' WHERE 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->Query("INSERT IGNORE INTO app_logs SELECT UserID,Token,IP,DateStamp FROM app_token WHERE Token='".$_SESSION['APP_TOKEN']."'"); $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->Query("DELETE FROM app_token WHERE Token='".$_SESSION['APP_TOKEN']."'"); $this->db->delete('app_token', 'Token=?', [$this->session->get('APP_TOKEN')]);
} }
public function token_check() { public function token_check(string $token): bool {
$hasil = false; $hasil = (bool)$this->db->fetchField('SELECT 1 FROM app_token WHERE Token=?', [$token ?? $this->session->get('APP_TOKEN')]);
$this->__db->Query("SELECT * FROM app_token WHERE Token='".$_SESSION['APP_TOKEN']."'"); if ($hasil === true) $this->db->update('app_token', ['DateStamp' => 'NOW()'], 'Token=?', [$token ?? $this->session->get('APP_TOKEN')]);
if ($this->__db->Next()) $hasil = true;
if ($hasil == true) $this->__db->Query("UPDATE app_token SET DateStamp=NOW() WHERE Token='".$_SESSION['APP_TOKEN']."'");
return $hasil; return $hasil;
} }
public function token_update() { public function token_update(): void {
$this->__db->Query("UPDATE app_token SET DateStamp=NOW() WHERE Token='".$_SESSION['APP_TOKEN']."'"); $this->db->update('app_token', ['DateStamp' => 'NOW()'], 'Token=?', [$this->session->get('APP_TOKEN')]);
} }
public function redirect($appUrl) { public function redirect(string $appUrl): string {
$source = parse_url($appUrl); $source = parse_url($appUrl);
$desti = ""; $desti = "";
$this->__db->Query("SELECT * FROM app_host WHERE Nama_Host='".$source['host']."'"); $hasil = (bool)$this->db->fetchField('SELECT 1 FROM app_host WHERE Nama_Host=?', [$source['host']]);
if ($this->__db->Next()) { if ($hasil) $desti = $source['scheme'].$source['host'].$source['path'].'?'.'auth='.$this->session->get('APP_TOKEN');
$desti = $source['scheme'].$source['host'].$source['path'].'?'.'auth='.$_SESSION['APP_TOKEN'];
}
return $desti; return $desti;
} }
private function genToken($length = 16) { private function genToken(int $length = 16): string {
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, 5)), 0, $length); return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
} }
public function getUserByToken($token) { public function getUserByToken(string $token): string {
$hasil = ""; $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')]);
$this->__db->Query("SELECT * FROM app_operator WHERE UserID IN (SELECT UserID FROM app_token WHERE Token='".$token."') LIMIT 1");
if ($this->__db->Next()) $hasil = $this->__db->Row("Username");
return $hasil; return $hasil;
} }
} }
+36 -25
View File
@@ -3,58 +3,69 @@
/******************************************************************* /*******************************************************************
Module : /Web/Button.php Module : /Web/Button.php
Desc. : Button Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 27th, 2008. 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); 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 { class Button {
private $__abutton =[]; private $__abutton =[];
public function __construct() {} public function __construct() {}
private function add($type="info", $id="", $label="", $bmiss=false) {
if ($id=="") $id = "random".rand(1000, 10000); private function add(string $type="info", string $id="", string $label="", bool $miss=false): void {
$this->__abutton[] = ['type'=>$type, 'id'=>$id, 'label'=>$label, 'bmiss'=>$bmiss]; 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"]; $this->__abutton[] = [ 'type' => "separator" ];
} }
public function primary($id="", $label="", $bmiss=false) { public function primary(string $id="", string $label="", bool $miss=false): void {
$this->add("primary", $id, $label, $bmiss); $this->add("primary", $id, $label, $miss);
} }
public function info($id="", $label="", $bmiss=false) { public function info(string $id="", string $label="", bool $miss=false): void {
$this->add("info", $id, $label, $bmiss); $this->add("info", $id, $label, $miss);
} }
public function danger($id="", $label="", $bmiss=false) { public function danger(string $id="", string $label="", bool $miss=false): void {
$this->add("danger", $id, $label, $bmiss); $this->add("danger", $id, $label, $miss);
} }
public function warning($id="", $label="", $bmiss=false) { public function warning(string $id="", string $label="", bool $miss=false): void {
$this->add("warning", $id, $label, $bmiss); $this->add("warning", $id, $label, $miss);
} }
public function success($id="", $label="", $bmiss=false) { public function success(string $id="", string $label="", bool $miss=false): void {
$this->add("success", $id, $label, $bmiss); $this->add("success", $id, $label, $miss);
} }
public function secondary($id="", $label="", $bmiss=false) { public function secondary(string $id="", string $label="", bool $miss=false): void {
$this->add("secondary", $id, $label, $bmiss); $this->add("secondary", $id, $label, $miss);
} }
public function Button($size=2) { public function Button(int $size=2): string {
if (0==count($this->__abutton)) return ""; 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'; $_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) { 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'; $_out .= '</div><div class="col-12 col-sm-6 my-0 mx-sm-0 text-center text-sm-end">'; $_ma = ' ms-sm-2';
} else { } 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>'; $_out .= '</div></div>';
+191 -236
View File
@@ -3,46 +3,66 @@
/******************************************************************* /*******************************************************************
Module : /Web/Form.php Module : /Web/Form.php
Desc. : Form Generator (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 27th, 2008. Created Date : February 27th, 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.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Form {
private $__aform = array(); private $__aform = [];
private $__ahide = array(); private $__ahide = [];
private $__button = null; protected Engine $app;
private $__nbtnsize = 2; protected SimplePdo $db;
protected $__db = null; protected Session $session;
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__db = $db; } * @param Engine $app
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); } */
$this->__button = new Button(); public function __construct(Engine $app){
$this->app = $app;
$this->db = $app->db();
$this->session = $app->session();
} }
public function option($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $aarr=array(), $thelp="", $tchange=null, $bmulti=false, $bgroup=false) { 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 {
$_enab = ($benable==true) ? "" : ' disabled=true'; $_opsi = '';
$_req = ($breq==true) ? " required=true" : ""; if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
$_change = ($tchange==null) ? '' : ' onchange="'.$tchange.'"'; if ($enable===false) $_opsi .= ' disabled=true';
$_multi = ($bmulti==true) ? ' multiple' : ''; if ($req===true) $_opsi .= ' required=true';
$tout = '<select class="form-select option-tags" id="'.$tfield.'" name="'.$tfield.'"'.$_enab.$_change.$_req.$_multi.' >'; if ($multi===true) $_opsi .= ' multiple';
if (count($aarr)>0) { $tout = '<select class="form-select option-tags" id="'.$field.'" name="'.$field.'"'.$_opsi.' >';
if (count($arr)>0) {
$n_group = 0; $n_group = 0;
foreach ($aarr as $key => $val) { $aval = [$value];
if ($multi===true) $aval = explode(",", ($value ?? "0"));
foreach ($arr as $key => $val) {
$_val2 = $val; $olabel = ""; $_val2 = $val; $olabel = "";
if (is_array($val)) { if (is_array($val)) {
$_val2 = $val[0]; $_val2 = $val[0];
if ($bgroup) { if ($group) {
if (1==$val[1]) { if (1 == $val[1]) {
if (0 < $n_group++) $tout .= '</optgroup>'; if (0 < $n_group++) $tout .= '</optgroup>';
$tout .= '<optgroup label="'.$_val2.'">'; $tout .= '<optgroup label="'.$_val2.'">';
continue; continue;
@@ -52,274 +72,209 @@ final class Form {
} }
} }
$tout .= '<option value="'.$key.'"'.$olabel; $tout .= '<option value="'.$key.'"'.$olabel;
$aval = array($tvalue);
if ($bmulti==true) $aval = explode(",", ($tvalue ?? "0"));
$tout .= (in_array($key, $aval)) ? ' selected="selected"' : ""; $tout .= (in_array($key, $aval)) ? ' selected="selected"' : "";
$tout .= '>'.$_val2.'</option>'; $tout .= '>'.$_val2.'</option>';
} }
if ($bgroup && $n_group>0) $tout .= '</optgroup>'; if ($group && $n_group>0) $tout .= '</optgroup>';
} }
$tout .= '</select>'; $tout .= '</select>';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout); $this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout ];
return $tout; return $tout;
} }
public function option_db($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $ttable=null, $afield=null, $twhere=null, $addarray=null, $thelp=null, $tchange=null, $bmulti=false) { 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 {
$afield = ($afield==null) ? array("ID", "Nama", "Label") : $afield; $_twhere = '';
$_twhere = ($twhere==null) ? "" : " WHERE ".$twhere; if (!is_array($afield)) $afield = ["ID", "Nama", "Label"];
$_twhere .= ($twhere===null || stripos($twhere,"ORDER BY")===false) ? " ORDER BY ".$afield[1] : ""; if (!empty($where)) {
$_twhere = ' WHERE '.$where;
$_twhere .= (stripos($where,"ORDER BY")===false) ? ' ORDER BY '.$afield[1] : '';
}
$ahasil = []; $ahasil = [];
if (is_array($addarray)) $ahasil[$addarray[0]] = (!isset($afield[2])) ? $addarray[1] : [$addarray[1], $addarray[2]]; if (is_array($aarray)) $ahasil[$aarray[0]] = (!isset($afield[2])) ? $aarray[1] : [$aarray[1], $aarray[2]];
if ($ttable<>null) { if (!empty($table)) {
$this->__db->Query("SELECT ".implode(",", $afield)." FROM ".$ttable.$_twhere); $aopsi = $this->db->fetchAll("SELECT ".implode(",", $afield)." FROM ".$table.$_twhere);
while ($this->__db->Next()) { foreach ($aopsi as $opsi) {
$ahasil[$this->__db->Row($afield[0])] = (!isset($afield[2])) ? $this->__db->Row($afield[1]) : [$this->__db->Row($afield[1]), $this->__db->Row($afield[2])]; $ahasil[$opsi[$afield[0]]] = (!isset($afield[2])) ? $opsi[$afield[1]] : [$opsi[$afield[1]], $opsi[$afield[2]]];
} }
} }
$tout = $this->option($tlabel, $tfield, $tvalue, $benable, $breq, $ahasil, $thelp, $tchange, $bmulti); return $this->option($label, $field, $value, $enable, $req, $ahasil, $help, $change, $multi);
}
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]];
if (!empty($query)) {
$stat = $this->db->runQuery($query);
while ($row = $stat->fetch()) {
$ahasil[$row[$afield[0]]] = (!isset($afield[2])) ? $row[$afield[1]] : [$row[$afield[1]], $row[$afield[2]]];
}
}
return $this->option($label, $field, $value, $enable, $req, $ahasil, $help, $change);
}
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 {
return $this->option($label, $field, $value, $enable, $req, $this->session->get('__WEB_APP')['USER_LEVEL'], $help, $change);
}
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 = '';
if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
if ($enable===false) $_opsi .= ' disabled=true';
if ($req===true) $_opsi .= ' required=true';
$tout = '<input type="hidden" id="'.$field.'" value="'.$value.'" />';
if (count($arr)>0) {
foreach ($arr as $key => $val) {
$tout .= '<div class="col-form-label form-check form-check-inline me-2"><input class="form-check-input" id="'.$field.$key.'" type="radio" value="'.$key.'" name="'.$field.'"'.$_opsi;
$tout .= ($key == $value) ? ' checked="checked"' : '';
$tout .= '><label class="form-check-label" for="'.$field.$key.'">'.$val.'</label></div>';
}
}
$this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout ];
return $tout; return $tout;
} }
public function option_que($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $tquery=null, $afield=null, $addarray=null, $thelp="", $tchange=null) { public function radio_jkl(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
$afield = ($afield==null) ? array("ID", "Nama", "Label") : $afield; return $this->radio($label, $field, $value, $enable, $req, ["L" => "Laki-Laki", "P" => "Perempuan"], $help, $change);
$ahasil = array();
if (is_array($addarray)) $ahasil[$addarray[0]] = (!isset($afield[2])) ? $addarray[1] : array($addarray[1], $addarray[2]);
if ($tquery<>null) {
$this->__db->Query($tquery);
while ($this->__db->Next()) {
$ahasil[$this->__db->Row($afield[0])] = (!isset($afield[2])) ? $this->__db->Row($afield[1]) : array($this->__db->Row($afield[1]), $this->__db->Row($afield[2]));
}
}
$tout = $this->option($tlabel, $tfield, $tvalue, $benable, $breq, $ahasil, $thelp, $tchange);
return $tout;
} }
public function option_jkl($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tchange=null) { public function radio_gd(string $label, string $field, ?string $value=null, bool $enable=true, bool $req=false, ?string $help=null, ?string $change=null): string {
$akel = array("L" => "Laki-Laki", "P" => "Perempuan"); if (!empty($value)) $value = 'X';
$tout = $this->option($tlabel, $tfield, $tvalue, $benable, $breq, $akel, $thelp, $tchange); return $this->radio($label, $field, $value, $enable, $req, ["A"=>"A", "B"=>"B", "AB"=>"AB", "O"=>"O", "X"=>"NONE"], $help, $change);
return $tout;
} }
public function option_ulevel($tlabel="", $tfield, $tvalue=9, $benable=true, $breq=false, $thelp="", $tchange=null) { 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 {
$tout = $this->option($tlabel, $tfield, $tvalue, $benable, $breq, $_SESSION['__WEB_APP']['USER_LEVEL'], $thelp, $tchange); $_val = array_values($arr);
return $tout; if (empty($value)) $value = $_val[1];
} $_opsi = ' odata="'.htmlspecialchars(json_encode($arr)).'"';
if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
public function radio($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $aarr=array(), $thelp="", $tchange=null) { if ($enable===false) $_opsi .= ' disabled=true';
if ($tvalue == null) { if ($req===true) $_opsi .= ' required=true';
$tmp_key = array_keys($aarr); $tout = '<div class="col-form-label form-check"><input type="checkbox" class="form-check-input" id="'.$field.'" name="'.$field.'" value="'.$value.'"'.$_opsi;
$tvalue = $tmp_key[0]; $tout .= ($_val[0] == $value) ? ' checked="checked"' : '';
}
$_enab = ($benable==true) ? "" : ' disabled=true';
$_req = ($breq==true) ? " required=true" : "";
$_change = ($tchange==null) ? "" : ' onchange="'.$tchange.'"';
$tout = '<input type="hidden" id="'.$tfield.'" value="'.$tvalue.'" />';
if (count($aarr)>0) {
foreach ($aarr as $key => $val) {
$tout .= '<div class="form-check form-check-inline me-2"><input class="form-check-input" id="'.$tfield.$key.'" type="radio" value="'.$key.'" name="'.$tfield.'"';
$tout .= ($key == $tvalue) ? ' checked="checked"' : '';
$tout .= ' onclick="if(this.checked)$(\'#'.$tfield.'\').val(this.value);"'.$_enab.$_change.$_req;
$tout .= '><label class="form-check-label" for="'.$tfield.$key.'">'.$val.'</label></div>';
}
}
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout);
return $tout;
}
public function radio_jkl($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tchange=null) {
$tout = $this->radio($tlabel, $tfield, $tvalue, $benable, $breq, array("L" => "Laki-Laki", "P" => "Perempuan"), $thelp, $tchange);
return $tout;
}
public function radio_gd($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tchange=null) {
$tvalue = ($tvalue=="") ? "X" : $tvalue;
$tout = $this->radio($tlabel, $tfield, $tvalue, $benable, $breq, array("A"=>"A", "B"=>"B", "AB"=>"AB", "O"=>"O", "X"=>"NONE"), $thelp, $tchange);
return $tout;
}
public function checkbox($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $avalue=array(), $thelp="", $tchange=null) {
$bhasil = ((is_string($tvalue) && in_array($tvalue,array("N","T","0"))) or (is_numeric($tvalue) && $tvalue==0) or (is_bool($tvalue) && $tvalue===false) or empty($tvalue)) ? true : false;
$_enab = ($benable==true) ? "" : ' disabled=true';
$_req = ($breq==true) ? " required=true" : "";
$_change = ' onchange="this.value=(this.checked)?\''.$avalue[0].'\':\''.$avalue[1].'\';'.($tchange==null?'':$tchange).'"';
$tout = '<input type="checkbox" class="form-check-input" id="'.$tfield.'" name="'.$tfield.'" value="'.($bhasil?$avalue[1]:$avalue[0]).'"'.$_enab.$_change.$_req;
$tout .= ($bhasil==false) ? ' checked="checked"' : '';
$tout .= '>';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout);
return $tout;
}
public function switch($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $aarr=array(), $thelp="", $tchange=null) {
$_val = array_values($aarr);
$_enab = ($benable==true) ? "" : ' disabled=true';
$_req = ($breq==true) ? " required=true" : "";
$_change = ($tchange==null) ? ' onchange="this.value=(this.checked)?\''.$_val[0].'\':\''.$_val[1].'\';"' : ' onchange="this.value=(this.checked)?\''.$_val[0].'\':\''.$_val[1].'\';'.$tchange.'"';
$tout = '<div class="form-check form-switch"><input class="form-check-input me-0" id="'.$tfield.'" name="'.$tfield.'" type="checkbox" role="switch" value="'.$tvalue.'"'.$_enab.$_change.$_req;
$tout .= ($_val[0] == $tvalue) ? ' checked="checked"' : '';
$tout .= '></div>'; $tout .= '></div>';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout); $this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout];
return $tout; return $tout;
} }
//todo: belum diupgrade !! 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 {
public function group_cbox($tfield, $tkey=null, $tclass=null, $ttable=null, $afield=null, $ncol=2) { $_val = array_values($arr);
if ($ttable==null) return; if (empty($value)) $value = $_val[1];
$avalue = explode(",", $tkey); $_opsi = ' odata="'.htmlspecialchars(json_encode($arr)).'"';
$afield = ($afield==null) ? array("ID", "Nama") : $afield; if (!empty($change)) $_opsi .= ' ochan="'.$change.'"';
$_twhere = ($twhere=="") ? " ORDER BY ".$afield[0] : " WHERE ".$twhere; if ($enable===false) $_opsi .= ' disabled=true';
$tout = "<input id=\"".$tfield."\" value=\"".$tkey."\" type='hidden' class='cgrpbox' /><table width='100%' style='margin:1px 0;padding:2px 2px;'><tr>"; if ($req===true) $_opsi .= ' required=true';
$tout = '<div class="col-form-label form-check form-switch"><input class="form-check-input" id="'.$field.'" name="'.$field.'" type="checkbox" role="switch" value="'.$value.'"'.$_opsi;
$nkol = 1; $tout .= ($_val[0] == $value) ? ' checked="checked"' : '';
$this->__db->Query("SELECT ".implode(",", $afield)." FROM ".$ttable.$_twhere); $tout .= '></div>';
while ($this->__db->Next()) { $this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout ];
$tout .= "<td width='".round(100/$ncol)."%'><label><input type='checkbox' id='".$tfield."_cgrpbox_".$this->__db->Row($afield[0])."' value='".$this->__db->Row($afield[0])."'";
for ($i=0; $i<count($avalue); $i++) {
if ($avalue[$i]==$this->__db->Row($afield[0])) {
$tout .= " checked=\"checked\"";
break;
}
}
$tout .= " class='text ".$tclass."' />&nbsp;".$this->__db->Row($afield[1])."</label></td>";
if ($nkol==$ncol) {
$tout .= "</tr><tr>";
$nkol = 0;
}
$nkol++;
}
$tout .= "</tr></table>";
$this->__aform[$tfield] = $tout;
return $tout; return $tout;
} }
public function textbox($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $ttype="text", $holdtxt=null, $nmaxsize=null, $thelp="", $tkeyup=null, $tblur=null) { 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 {
$_enab = ($benable==true) ? "" : ' readonly'; $_opsi = '';
$_req = ($breq==true) ? " required=true" : ""; if (!empty($keyup)) $_opsi .= ' okyup="'.$keyup.'"';
$_max = ($nmaxsize==null) ? "" : ' maxlength="'.$nmaxsize.'"'; if (!empty($blur)) $_opsi .= ' oblur="'.$blur.'"';
$_keyup = ($tkeyup==null) ? "" : ' onkeyup="'.$tkeyup.'"'; if (!empty($holdtxt)) $_opsi .= ' placeholder="'.$holdtxt.'"';
$_blur = ($tblur==null) ? "" : ' onblur="'.$tblur.'"'; if (!empty($maxsize)) $_opsi .= ' maxlength="'.$maxsize.'"';
$_holdtxt = ($holdtxt==null) ? "" : ' placeholder="'.$holdtxt.'"'; if ($enable===false) $_opsi .= ' readonly';
$_tclass = ""; if ($req===true) $_opsi .= ' required=true';
if (in_array($ttype,array("pickdate","picktime"))) { $_tclass = '';
$_tclass = ' '.$ttype; if (in_array($type, ['pickdate','picktime','integer','angka','double'])) {
$ttype = "text"; $_tclass = ' '.$type;
if ($type === 'double') $value = uang2($value);
$type = "text";
} }
if (in_array($ttype,array("double"))) { $tout = '<input type="'.$type.'" class="form-control'.$_tclass.'" id="'.$field.'" name="'.$field.'" value="'.(string)$value.'"'.$_opsi.' />';
$_tclass = ' '.$ttype; $this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout ];
$tvalue = uang2($tvalue);
}
$tout = '<input type="'.$ttype.'" class="form-control'.$_tclass.'" id="'.$tfield.'" name="'.$tfield.'" value="'.$tvalue.'"'.$_enab.$_max.$_keyup.$_blur.$_holdtxt.$_req.' />';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout);
return $tout; return $tout;
} }
public function textauto($tlabel="", $tfield, $avalue=['value'=>0,'text'=>""], $benable=true, $breq=false, $holdtxt=null, $nmaxsize=null, $thelp="") { 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 {
$_enab = ($benable==true) ? "" : ' disabled=true'; $_opsi = '';
$_req = ($breq==true) ? " required=true" : ""; if (!empty($holdtxt)) $_opsi .= ' placeholder="'.$holdtxt.'"';
$_max = ($nmaxsize==null) ? "" : ' maxlength="'.$nmaxsize.'"'; if (!empty($maxsize)) $_opsi .= ' maxlength="'.$maxsize.'"';
$_holdtxt = ($holdtxt==null) ? "" : ' placeholder="'.$holdtxt.'"'; if ($enable===false) $_opsi .= ' disabled=true';
$tout = '<input type="search" class="form-control" id="'.$tfield.'" name="'.$tfield.'" value="'.$avalue['text'].'"'.$_enab.$_max.$_holdtxt.$_req.' autocomplete="off" />'; if ($req===true) $_opsi .= ' required=true';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout); $tout = '<input type="search" class="form-control" id="'.$field.'" name="'.$field.'" value="'.$avalue['text'].'"'.$_opsi.' autocomplete="off" />';
$this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout];
return $tout; return $tout;
} }
public function datebox($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tkeyup=null, $tblur=null) { 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 ($tvalue<>null) $tvalue = tgl_sql2str($tvalue); if (!empty($value)) $value = tgl_sql2str($value);
$tout = '<div class="input-group">'; $tout = '<div class="input-group date">';
$tout .= $this->textbox($tlabel, $tfield, $tvalue, $benable, $breq, "pickdate", "dd-mm-yyyy", 12, $thelp, $tkeyup, $tblur); $tout .= $this->textbox($label, $field, $value, $enable, $req, "pickdate", "dd-mm-yyyy", null, $help, $keyup, $blur);
$tout .= '<span class="input-group-text"><i class="bi-calendar4"></i></span></div>'; $tout .= '<span class="input-group-text input-group-addon"><i class="bi-calendar4"></i></span></div>';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout); $this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout];
return $tout; return $tout;
} }
public function timebox($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tkeyup=null, $tblur=null) { 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 {
$tout = $this->textbox($tlabel, $tfield, $tvalue, $benable, $breq, "picktime", "hh:mm:ss", 10, $thelp, $tkeyup, $tblur); 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 {
$_opsi = '';
if (!empty($keyup)) $_opsi .= ' okyup="'.$keyup.'"';
if (!empty($blur)) $_opsi .= ' oblur="'.$blur.'"';
if (!empty($holdtxt)) $_opsi .= ' placeholder="'.$holdtxt.'"';
if ($enable===false) $_opsi .= ' disabled=true';
if ($req===true) $_opsi .= ' required=true';
$tout = '<textarea class="form-control" id="'.$field.'" name="'.$field.'" rows="'.$rows.'"'.$_opsi.' >'.$value.'</textarea>';
$this->__aform[$field] = [ 'label' => $label, 'help' => $help, 'form' => $tout];
return $tout; return $tout;
} }
public function textarea($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $nrows=1, $holdtxt=null, $thelp="", $tkeyup=null, $tblur=null) { public function plaintext(string $label, string $field, mixed $value=null): string {
$_enab = ($benable==true) ? "" : ' disabled=true'; $tout = '<input type="text" class="form-control-plaintext" id="'.$field.'" name="'.$field.'" value="'.$value.'" readonly />';
$_req = ($breq==true) ? " required=true" : ""; $this->__aform[$field] = ['label' => $label, 'help' => "", 'form' => $tout];
$_rows = ($nrows==null) ? "" : ' rows="'.$nrows.'"';
$_keyup = ($tkeyup==null) ? "" : ' onkeyup="'.$tkeyup.'"';
$_blur = ($tblur==null) ? "" : ' onblur="'.$tblur.'"';
$_holdtxt = ($holdtxt==null) ? "" : ' placeholder="'.$holdtxt.'"';
$tout = '<textarea class="form-control" id="'.$tfield.'" name="'.$tfield.'"'.$_enab.$_rows.$_keyup.$_blur.$_holdtxt.$_req.' >'.$tvalue.'</textarea>';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout);
return $tout; return $tout;
} }
public function plaintext($tlabel="", $tfield, $tvalue=null) { 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 {
$tout = '<input type="text" class="form-control-plaintext" id="'.$tfield.'" name="'.$tfield.'" value="'.$tvalue.'" readonly />'; return $this->textbox($label, $field, $value, $enable, $req, "password", $holdtxt, $maxsize, $help, $keyup, null);
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>"", 'form'=>$tout); }
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';
if ($req===true) $_opsi .= ' required=true';
$tout = '<input type="color" class="form-control form-control-color" id="'.$field.'" name="'.$field.'" value="'.$value.'"'.$_opsi.' />';
$this->__aform[$field] = ['label' => $label, 'help' => $help, 'form' => $tout];
return $tout; return $tout;
} }
public function password($tlabel="", $tfield, $tvalue="", $benable=true, $breq=false, $holdtxt=null, $nmaxsize=null, $thelp="", $tkeyup=null) { public function hidden(string $field, mixed $value=null, string $class="text"): string {
$tout = $this->textbox($tlabel, $tfield, $tvalue, $benable, $breq, "password", $holdtxt, $nmaxsize, $thelp, $tkeyup, $tblur); $tout = '<input type="hidden" id="'.$field.'" value="'.$value.'" class="'.$class.'" />';
$this->__ahide[$field] = $tout;
return $tout; return $tout;
} }
public function color($tlabel="", $tfield, $tvalue=null, $benable=true, $breq=false, $thelp="", $tchange=null) { public function clear(): void {
$_enab = ($benable==true) ? "" : ' disabled=true'; $this->__aform = [];
$_req = ($breq==true) ? " required=true" : "";
$_change = ($tchange==null) ? '' : ' onchange="'.$tchange.'"';
$tout = '<input type="color" class="form-control form-control-color" id="'.$tfield.'" name="'.$tfield.'" value="'.$tvalue.'"'.$_enab.$_change.$_req.' />';
$this->__aform[$tfield] = array('label'=>$tlabel, 'help'=>$thelp, 'form'=>$tout);
return $tout;
} }
public function hidden($tfield, $tvalue="", $tclass="text") { public function show(int $lebar_kolom = 4): string {
$tout = '<input type="hidden" id="'.$tfield.'" value="'.$tvalue.'" class="'.$tclass.'" />'; $col_left = 'col-sm-' . ($lebar_kolom+2) . ' col-lg-' . $lebar_kolom;
$this->__ahide[$tfield] = $tout; $col_right = 'col-sm-' . (10-$lebar_kolom) . ' col-lg-' . (12-$lebar_kolom);
return $tout; $tres = '';
}
public function clear() {
$this->__aform = array();
}
public function show($tstr) {
foreach ($this->__aform as $_key => $_val) { foreach ($this->__aform as $_key => $_val) {
$tval = '<div class="row mb-1"><label class="col-sm-5 col-lg-4 col-form-label" for="'.$_key.'">'.$_val['label'].'</label><div class="col-sm-7 col-lg-8">'.$_val['form'].($_val['help']==""?'':'<span class="help-block"><small>'.$_val['help'].'</small></span>').'</div></div>'; $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>'));
$tstr = str_replace("_".$_key."_", $tval, $tstr);
}
$txtbtn = $this->__button->Button($this->__nbtnsize);
if (""<>$txtbtn) {
$tstr .= '<div class="row mb-1"><div class="col"><hr class="my-2"></div></div>';
$tstr .= $txtbtn;
} }
foreach ($this->__ahide as $_key => $_val) { foreach ($this->__ahide as $_key => $_val) {
$tstr = str_replace("_".$_key."_", $_val, $tstr); $tres .= $_val;
} }
$tstr = str_replace("\n", "", $tstr); return $tres;
$tstr = str_replace("\t", "", $tstr);
echo $tstr;
} }
public function btn_separator() {
$this->__button->separator();
}
public function btn_primary($id="", $label="", $bmiss=false) {
$this->__button->primary($id, $label, $bmiss);
}
public function btn_info($id="", $label="", $bmiss=false) {
$this->__button->info($id, $label, $bmiss);
}
public function btn_danger($id="", $label="", $bmiss=false) {
$this->__button->danger($id, $label, $bmiss);
}
public function btn_warning($id="", $label="", $bmiss=false) {
$this->__button->warning($id, $label, $bmiss);
}
public function btn_success($id="", $label="", $bmiss=false) {
$this->__button->success($id, $label, $bmiss);
}
public function btn_secondary($id="", $label="", $bmiss=false) {
$this->__button->secondary($id, $label, $bmiss);
}
public function Button($size=2) {
$this->__nbtnsize = $size;
}
} }
?> ?>
+88 -51
View File
@@ -3,54 +3,68 @@
/******************************************************************* /*******************************************************************
Module : /Web/Menu.php Module : /Web/Menu.php
Desc. : Class menu
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 16th, 2008. 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.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Menu {
protected $__db = null; private array $webapp;
private array $webuser;
protected Engine $app;
protected SimplePdo $db;
protected Session $session;
public function __construct($db = null){ /**
$this->__db = $db ?? new \siaupheng\webapp\DB\MySQL(); * @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'=>[]]);
} }
private function Menu_Query($qry = "", $order = "Kode") { public function Sidebar(): string {
$twhere = ($qry!="") ? "WHERE ".$qry : ""; $a_modul = [];
$this->__db->Query("SELECT * FROM app_menu ".$twhere." ORDER BY ".$order." ASC"); $is_modul = ($this->webapp['APP_MODULE'] !== '') ? true : false;
$ahasil = array();
while ($this->__db->Next()) {
$ahasil[] = $this->__db->AllRow();
}
return $ahasil;
}
public function Menu_Sidebar() {//oke
$a_modul = array();
$is_modul = (($_SESSION['__WEB_APP']['APP_MODULE'] ?? "") <> "") ? true : false;
if ($is_modul == true) { if ($is_modul == true) {
$a_modul[] = $_SESSION['__WEB_APP']['APP_MODULE']; $a_modul[] = $this->webapp['APP_MODULE'];
} else { } else {
$atmp = $this->Menu_Query("Level=0 AND Aktif=1 AND Modul<>'IND'", "Urut"); $atmp = $this->db->fetchAll('SELECT * FROM app_menu WHERE Level=0 AND Aktif=1 AND Modul<>"IND" ORDER BY Urut');
for ($i=0; $i<count($atmp); $i++) { foreach ($atmp as $tmp) {
$a_modul[] = $atmp[$i]['Modul']; $a_modul[] = $tmp['Modul'];
} }
} }
$my_menu = array_unique(array_filter(explode(",", $_SESSION['__WEB_USER']['Menu_Grup'].",".$_SESSION['__WEB_USER']['Menu']))); $my_menu = array_unique(array_filter(explode(",", $this->webuser['Menu_Grup'].",".$this->webuser['Menu'])));
$tsql = " AND Modul IN ('".implode("','",$a_modul)."')"; $tsql = 'SELECT * FROM app_menu WHERE Aktif=1 AND Modul IN (?) AND Kode IN (?)';
$tsql .= ($is_modul == true) ? " AND Level>0" : ""; if ($is_modul == true) $tsql .= ' AND Level>0';
$tsql .= " AND Kode IN ('".implode("','",$my_menu)."')";
$amodul = $this->Menu_Query("Aktif=1".$tsql, "Kode"); $amodul = $this->db->fetchAll($tsql . ' ORDER BY Kode', [$a_modul, $my_menu]);
$thasil = ''; $thasil = '';
$last_level = 0; $last_level = 0;
@@ -72,26 +86,25 @@ final class Menu {
return $thasil; return $thasil;
} }
public function Menu_Header() {//oke public function Header(): string {
$a_modul = array(); $a_modul = [];
$is_modul = (($_SESSION['__WEB_APP']['APP_MODULE'] ?? "") <> "") ? true : false; $is_modul = ($this->webapp['APP_MODULE'] !== '') ? true : false;
$mulai_level = 0; $mulai_level = 0;
if ($is_modul == true) { if ($is_modul == true) {
$a_modul[] = $_SESSION['__WEB_APP']['APP_MODULE']; $a_modul[] = $this->webapp['APP_MODULE'];
$mulai_level = 1; $mulai_level = 1;
} else { } else {
$atmp = $this->Menu_Query("Level=0 AND Aktif=1 AND Modul<>'IND'", "Urut"); $atmp = $this->db->fetchAll('SELECT * FROM app_menu WHERE Level=0 AND Aktif=1 AND Modul<>"IND" ORDER BY Urut');
for ($i=0; $i<count($atmp); $i++) { foreach ($atmp as $tmp) {
$a_modul[] = $atmp[$i]['Modul']; $a_modul[] = $tmp['Modul'];
} }
} }
$my_menu = array_unique(array_filter(explode(",", $_SESSION['__WEB_USER']['Menu_Grup'].",".$_SESSION['__WEB_USER']['Menu']))); $my_menu = array_unique(array_filter(explode(",", $this->webuser['Menu_Grup'].",".$this->webuser['Menu'])));
$tsql = " AND Modul IN ('".implode("','",$a_modul)."')"; $tsql = 'SELECT * FROM app_menu WHERE Aktif=1 AND Modul IN (?) AND Kode IN (?)';
$tsql .= ($is_modul == true) ? " AND Level>0" : ""; if ($is_modul == true) $tsql .= ' AND Level>0';
$tsql .= " AND Kode IN ('".implode("','",$my_menu)."')";
$amodul = $this->Menu_Query("Aktif=1".$tsql, "Kode"); $amodul = $this->db->fetchAll($tsql . ' ORDER BY Kode', [$a_modul, $my_menu]);
$thasil = ''; $thasil = '';
$last_level = 0; $last_level = 0;
@@ -119,34 +132,58 @@ final class Menu {
return $thasil; return $thasil;
} }
static function MenuJSON($db = null, $page = "", $tquery = "") {//oke public function Modul(): string {
$_mdb = $db ?? new \siaupheng\webapp\DB\MySQL(); $t_modul = '';
$_query = ($tquery=="") ? "" : ",'".$tquery."'"; 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]; $ajson = ['login' => true];
$apage = ['Link' => ""]; $apage = ['Link' => ""];
$acus_page = [ $acus_page = [
'SYSP' => ['Kode'=>"SYSP", 'Judul'=>"Profil Pengguna", 'Link'=>"sys/profile.php", 'JS'=>"SYSProfileJS", 'Width'=>600, 'Button'=>'[{},{"i":"butBatal"},{"i":"butSave","v":"Simpan","c":"success"}]'], 'SYSP' => ['Kode'=>"SYSP", 'Judul'=>"Profil Pengguna", 'Link'=>"system/profile", 'JS'=>"SYSProfileJS", 'Width'=>600, 'Button'=>'[{},{"i":"butBatal"},{"i":"butSave","v":"Simpan","c":"success"}]'],
'SYSC' => ['Kode'=>"SYSC", 'Judul'=>"Ubah Password", 'Link'=>"sys/chpasswd.php", 'JS'=>"SYSChpasswdJS", 'Width'=>500, 'Button'=>'[{},{"i":"butBatal"},{"i":"butSave","v":"Simpan","c":"success"}]'] 'SYSC' => ['Kode'=>"SYSC", 'Judul'=>"Ubah Password", 'Link'=>"system/chpasswd", 'JS'=>"SYSChpasswdJS", 'Width'=>500, 'Button'=>'[{},{"i":"butBatal"},{"i":"butSave","v":"Simpan","c":"success"}]']
]; ];
if ($acus_page[$page] ?? false) { if ($acus_page[$page] ?? false) {
$apage = $acus_page[$page]; $apage = $acus_page[$page];
} else if ($page <> "") { } else if ($page <> "") {
$_mdb->Query("SELECT * FROM app_menu WHERE Kode='".$page."'"); $apage = $db->fetchRow('SELECT * FROM app_menu WHERE Kode=?', [$page]);
if ($_mdb->Next()) $apage = $_mdb->AllRow(); $apage['Width'] = (int)$apage['Width'];
$apage['Width'] = intval($apage['Width']);
} }
$ajson['iswindow'] = ($apage['Width'] > 0) ? true : false; $ajson['iswindow'] = ($apage['Width'] > 0) ? true : false;
$ajson['width'] = $apage['Width']; $ajson['width'] = $apage['Width'];
$ajson['title'] = $apage['Judul']; $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['php'] = $apage['Link'];
$ajson['func'] = $apage['JS']; $ajson['func'] = $apage['JS'];
$ajson['kode'] = $apage['Kode']; $ajson['kode'] = $apage['Kode'];
if (!file_exists($_SESSION['__WEB_APP']['REAL_PATH']."apps/php/".$apage['Link'])) $ajson['php'] = "";
return $ajson; return $ajson;
} }
} }
+31 -25
View File
@@ -3,18 +3,30 @@
/******************************************************************* /*******************************************************************
Module : /Web/Param.php Module : /Web/Param.php
Desc. : Class data parameter dari client side
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : November 14th, 2013. Created Date : November 14th, 2013.
Last Modified : May 8th, 2021. Last Modified : August 22nd, 2026.
(c) 2013 - 2021, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); 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 { final class Param {
private static $__ahasil = []; private static $__ahasil = [];
@@ -23,49 +35,43 @@ final class Param {
if (count(self::$__ahasil)==0) self::__data(); if (count(self::$__ahasil)==0) self::__data();
} }
private static function __data() { private static function __data(): void {
$_asumber = array_merge($_REQUEST, $_POST, $_GET); global $app;
if (empty($app)) $app = \Flight::app();
$_asumber = array_merge($app->request()->query->getData(), $app->request()->data->getData());
foreach ($_asumber as $__key => $__val) { 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","'",'"'); $_se = array("\\","\0","\n","\r","\x1a","'",'"');
$_re = array("\\\\","\\0","\\n","\\r","\Z","\'",'\"'); $_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 (count(self::$__ahasil)==0) self::__data();
if (isset(self::$__ahasil[$tkey]) && self::$__ahasil[$tkey]) return self::$__ahasil[$tkey]; if (isset(self::$__ahasil[$key]) && self::$__ahasil[$key]) return self::$__ahasil[$key];
return $tdef; 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(); 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("\\r", "", $_str);
$_str = str_replace("\\n", " ", $_str); $_str = str_replace("\\n", " ", $_str);
$_str = str_replace("\\t", " ", $_str); $_str = str_replace("\\t", " ", $_str);
return (trim($_str)); return (trim($_str));
} }
public static function Get_Array() { public static function Get_Array(): array {
if (count(self::$__ahasil)==0) self::__data(); if (count(self::$__ahasil)==0) self::__data();
return self::$__ahasil; return self::$__ahasil;
} }
public static function Get_ArrayCBOX() {//note: bisa tidak dipakai lagi public static function Get_ArrayCBOX() {//delete
if (count(self::$__ahasil)==0) self::__data(); return [];
$_ahasil = [];
foreach (self::$__ahasil as $__key => $__val) {
if (strpos($__key, "_cbox_")>0) {
$_tmpkey = substr($__key, strpos($__key, "_cbox_")+6);
$_ahasil[$_tmpkey] = $__val;
}
}
return $_ahasil;
} }
} }
+30 -19
View File
@@ -3,44 +3,55 @@
/******************************************************************* /*******************************************************************
Module : /Web/Register.php Module : /Web/Register.php
Desc. : Class Registrasi Aplikasi
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : November 23th, 2011. Created Date : November 23th, 2011.
Last Modified : May 6th, 2021. Last Modified : August 22nd, 2026.
(c) 2011 - 2021, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Register {
protected $__db = null; public function __construct(){
public function __construct($db = null){
if (is_resource($db)) { $this->__db = $db; }
else { $this->__db = new \siaupheng\webapp\DB\MySQL(); }
} }
static public function reg_id() { public static function reg_id(Session $session) {
$id = $_SESSION['__WEB_APP']['REG_ID'] ?? ""; $id = (string)$session->get('__WEB_APP', ['REG_ID'=>''])['REG_ID'];
return (substr($id,0,3).".".substr($id,3,3).".".substr($id,6)); return (substr($id,0,3).".".substr($id,3,3).".".substr($id,6));
} }
static public function reg_code() { public static function reg_code(Session $session) {
$id = $_SESSION['__WEB_APP']['REG_CODE']; $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)); 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 function reg_check() { public static function reg_check(Session $session) {
$isreg = false; $webapp = $session->get('__WEB_APP');
$this->__db->Query("SELECT UPPER(CONVERT(MD5(CONCAT(REG_YEAR,CONVERT(MD5(CONCAT(REG_ID,REG_NAME)) using latin1),REG_ID,REG_NAME)) using latin1)) KODE_REGISTER FROM app_config WHERE REG_ID='".$_SESSION['__WEB_APP']['APP_CODE']."' LIMIT 1"); return (bool)(isset($webapp['REG_STATUS']) && $webapp['REG_STATUS']) ?? false;
if ($this->__db->Next()) {
if ($this->__db->Row("KODE_REGISTER","")==$_SESSION['__WEB_APP']['REG_CODE']) $isreg = true;
} }
return $isreg;
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 ];
} }
} }
+160 -155
View File
@@ -3,217 +3,216 @@
/******************************************************************* /*******************************************************************
Module : /Web/Table.php Module : /Web/Table.php
Desc. : HTML Table (jQuery & Bootstrap)
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : January 16th, 2008. Created Date : January 16th, 2008.
Last Modified : January 26th, 2026. Last Modified : August 22nd, 2026.
(c) 2008 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Table {
private $__ttable = ""; private $__ttable = "";
private $__tfield = ""; private $__tfield = "";
private $__twhere = ""; private $__twhere = "";
private $__tquery = ""; private $__aparam = [];
private $__tquery_footer = ""; private $__tfooter = "";
private $__aheader = [];
private $__afield = []; private $__afield = [];
private $__astyle = [];
private $__aformat = [];
private $__afooter = [];
private $__aotype = [];
private $__arowcol = []; private $__arowcol = [];
private $__arow_func = []; private $__arow_func = [];
private $__tfunc_select = ""; private $__tfunc_select = "";
private $__tfunc_navi = ""; private $__bno_navi = false;
private $__btxtbutton = false; private $__btxtbutton = false;
private $__bnobutton = false; private $__bnobutton = false;
private $__bscrollbar = false; private $__bscrollbar = false;
private $__acontrol = ['field'=>false, 'value'=>""]; private $__acontrol = [ 'field' => false, 'value' => "" ];
private $__acbox = []; private $__acbox = [];
private $__aoption = []; private $__aoption = [];
private $__npage_rec = 10;
private $__nreclimit = 0;
private $__nscrollheight = 0; private $__nscrollheight = 0;
private $__ord_field = ""; private $__ord_field = "";
private $__ord_dir = "A"; private $__ord_dir = "A";
private $__tcss = ""; private $__tcss = "";
private $__livedata = false; private $__livedata = false;
protected $__cdb = null; protected Engine $app;
protected $__cpa = null; protected SimplePdo $db;
protected array $data;
public function __construct($db = null){ /**
if (is_resource($db)) { $this->__cdb = $db; } * @param Engine $app
else { $this->__cdb = new \siaupheng\webapp\DB\MySQL(); } */
$this->__cpa = new \siaupheng\webapp\Web\Param(); public function __construct(Engine $app) {
$this->app = $app;
$this->db = $app->db();
$this->data = $this->app->request()->data->getData();
} }
public function set_table($ttable = "", $tfield = "", $twhere = "") { public function set_table(string $table = "", string $field = "", string $where = "", array $params = []): void {
$this->__ttable = $ttable; $this->__ttable = $table;
if ($tfield != "") $this->__tfield = $tfield; $this->__aparam = $params;
if ($twhere != "") $this->__twhere = $twhere; if (!empty($field)) $this->__tfield = $field;
if (!empty($where)) $this->__twhere = $where;
} }
public function set_query($tquery = "") { public function set_footer(string $field = ""): void {
$this->__tquery = $tquery; $this->__tfooter = $field;
} }
public function set_query_footer($tquery = "") { public function set_css(string $css = ""): void {
$this->__tquery_footer = $tquery; $this->__tcss = $css;
} }
public function set_css($tcss = "") { public function set_field_order(string $field = "", string $order = "A"): void {
$this->__tcss = $tcss; $this->__ord_field = $field;
$this->__ord_dir = $order;
} }
public function set_limit($nlimit = 0) { public function set_textbtn(bool $istxt = true): void {
$this->__nreclimit = $nlimit; $this->__btxtbutton = $istxt;
} }
public function set_field_order($tfield = "", $torder = "A") { public function set_scrollbar(bool $isscroll = true, int $height = 200): void {
$this->__ord_field = $tfield; $this->__bscrollbar = $isscroll;
$this->__ord_dir = $torder; $this->__nscrollheight = $height;
} }
public function set_textbtn($bistxt = true) { public function set_row_color(string $field = "", string $val = "", string $css = ""): void {
$this->__btxtbutton = $bistxt; if (empty($field)) return;
$this->__arowcol[] = [ 'F' => $field, 'V' => $val, 'C' => $css ];
} }
public function set_scrollbar($bisscroll = true, $nheight = 200) { public function set_func_navi(string $func = ""): void {//compatible
$this->__bscrollbar = $bisscroll; $this->__bno_navi = ($func === '');
$this->__nscrollheight = $nheight;
} }
public function set_row_color($tfield = "", $tval = "", $tcss = "") { public function set_navi_off(): void {
if ($tfield=="") return; $this->__bno_navi = true;
$this->__arowcol[] = ['F'=>$tfield, 'V'=>$tval, 'C'=>$tcss];
} }
public function set_func_navi($tfunc = "") { public function set_func_select(string $func = ""): void {
$this->__tfunc_navi = $tfunc; $this->__tfunc_select = $func;
} }
public function set_func_select($tfunc = "") { public function set_func_btn(string $func = "", string $label = ""): void {
$this->__tfunc_select = $tfunc; $this->__arow_func[] = [ 'label' => $label, 'func' => $func ];
} }
public function set_func_btn($tfunc = "", $tlabel = "") { public function set_row_control(string $field = "", string $value = "Y"): void {
$this->__arow_func[] = ['label' => $tlabel, 'func' => $tfunc]; $this->__acontrol['field'] = $field;
$this->__acontrol['value'] = $value;
} }
public function set_row_control($tfield = "", $tvalue = "Y") { public function add_row_form(string $icon = "pencil", string $label = "", string $func = "", string $field = "", string $value = ""): void {
$this->__acontrol['field'] = $tfield; $this->__aoption[] = [ 'type' => "button-dt", 'func' => $func, 'icon' => $icon, 'label' => $label, 'field' => $field, 'value' => $value ];
$this->__acontrol['value'] = $tvalue;
} }
public function add_row_form($ticon = "pencil", $tlabel = "", $tfunc = "", $tfield = "", $tvalue = "") { public function add_row_btn(string $icon = "", string $label = "", string $func = "", string $field = "", string|int $value = "", string $field_css = "", array $avalue_css = []): void {
if ($tfunc == "") { $this->__aoption[] = [ 'type' => 'button', 'func' => $func, 'icon' => $icon, 'label' => $label, 'field' => $field, 'value' => (string)$value, 'field_css' => $field_css, 'avalue_css' => $avalue_css ];
$this->__aoption[] = ['type' => "button-dt", 'func' => $tlabel, 'icon' => "pencil", 'label' => $ticon];
} else {//todo: new format with icon, upgrade all later !
$this->__aoption[] = ['type' => "button-dt", 'func' => $tfunc, 'icon' => $ticon, 'label' => $tlabel, 'field' => $tfield, 'value' => $tvalue];
}
} }
public function add_row_btn($ticon = "", $tlabel = "", $tfunc = "", $tfield = "", $tvalue = "", $tfield_css = "", $avalue_css = []) { public function add_row_del(string $label = "", string $func = "", string $field = "Unix", string $value = ""): void {
$this->__aoption[] = ['type' => "button", 'func' => $tfunc, 'icon' => $ticon, 'label' => $tlabel, 'field' => $tfield, 'value' => $tvalue, 'field_css' => $tfield_css, 'avalue_css' => $avalue_css]; $this->__aoption[] = [ 'type' => 'button', 'func' => $func, 'icon' => 'x', 'label' => $label, 'field' => $field, 'value' => $value ];
} }
public function add_row_del($tlabel = "", $tfunc = "", $tfield = "Unix", $tvalue = "") { public function add_row_edit(string $label = "", string $func = ""): void {
$this->__aoption[] = ['type' => "button", 'func' => $tfunc, 'icon' => "x", 'label' => $tlabel, 'field' => $tfield, 'value' => $tvalue]; $this->add_row_btn('clipboard', $label, $func);
} }
public function add_row_edit($tlabel = "", $tfunc = "") { public function add_row_checkbox(string $field = "ID", string $control = "Edit", array $value = ['Y','N']): void {
$this->add_row_btn("note", $tlabel, $tfunc); $this->__acbox = [ 'field' => $field, 'control' => $control, 'avalue' => $value ];
$this->__aoption[] = ['type' => "checkbox", 'field' => $field, 'avalue' => $value];
} }
public function add_row_checkbox($tfield = "ID", $tcontrol = "Edit", $avalue = ["Y","N"]) { public function no_button(): void {
$this->__acbox['field'] = $tfield;
$this->__acbox['control'] = $tcontrol;
$this->__acbox['avalue'] = $avalue;
$this->__aoption[] = ['type' => "checkbox", 'field' => $tfield, 'avalue' => $avalue];
}
public function no_button() {
$this->__bnobutton = true; $this->__bnobutton = true;
} }
public function add_field($tfield = "", $theader = "", $tstyle = "l", $tformat = "", $tfooter = "", $totype = "") { public function add_field(string $field = "", string $header = "", string $style = "l", string $format = "", string $footer = "", string $otype = ""): void {
$this->__aheader[] = $theader; $this->__afield[] = [ 'a' => $field, 'h' => $header, 's' => $style, 'f' => $format, 't' => $footer, 'o' => $otype ];
$this->__afield[] = $tfield;
$this->__astyle[] = $tstyle;
$this->__aformat[] = $tformat;
$this->__afooter[] = $tfooter;
$this->__aotype[] = $totype;
} }
public function json_table($nama_tabel = "tabel_", $baris_tabel = 10) { public function json_table(string $nama_tabel = "tabel_", int $baris_tabel = 10): array {
$adata = []; $njml_kol = 0; $this->prepare_query();
$adata = [];
// adding header // adding header
for ($i=0; $i<count($this->__afield); $i++) { foreach ($this->__afield as $col) {
$adata['header'][] = ['f'=>$this->__astyle[$i], 'o'=>$this->__afield[$i], 'c'=>$this->__aheader[$i], 's'=>$this->__aotype[$i]]; $adata['header'][] = [ 'f' => $col['s'], 'o' => $col['a'], 'c' => $col['h'], 's' => $col['o'] ];
$njml_kol += ($this->__astyle[$i]=="hidden") ? 0 : 1;
} }
// adding footer // adding footer
if ($this->__tquery_footer) { if (!empty($this->__tfooter)) {
$this->__cdb->Query($this->__tquery_footer); $row = $this->db->fetchRow("SELECT ".$this->__tfooter." FROM ".$this->__ttable.$this->__twhere, $this->__aparam);
$this->__cdb->Next(); foreach ($this->__afield as $col) {
for ($i=0; $i<count($this->__afield); $i++) { $tval = $row[$col['a']] ?? '';
$tval = $this->__cdb->Row($this->__afield[$i], 0); if (is_set($col['t']) && !empty($col['t'])) {
if (is_array($this->__afooter[$i])) { if (is_array($col['t'])) {
$tval2 = $this->__afooter[$i][$tval]; $tval2 = $col['t'][$tval] ?? '';
} else if (!is_null($this->__afooter[$i]) && function_exists($this->__afooter[$i])) { } else if (function_exists($col['t'])) {
$tval2 = call_user_func($this->__afooter[$i], $tval); $tval2 = call_user_func($col['t'], $tval);
} else {
$tval2 = ($this->__afooter[$i]<>"") ? $this->__afooter[$i] : $tval;
} }
$adata['footer'][] = ['c'=>$tval2]; } else {
$tval2 = $tval;
}
$adata['footer'][] = [ 'c' => $tval2 ];
} }
} }
$acontent = []; $acontent = [];
if (!$this->__livedata) { if (!$this->__livedata) {
$this->__cdb->Query($this->__tquery); $stat = $this->db->runQuery("SELECT ".$this->__tfield." FROM ".$this->__ttable.$this->__twhere, $this->__aparam);
while ($this->__cdb->Next()) { while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
$abaris = []; $abaris = [];
$aoption = ['button'=>[]]; $aoption = ['button'=>[]];
if (count($this->__aoption)>0) { if (count($this->__aoption)>0) {
if ((($this->__acontrol['field']===false) || ($this->__cdb->Row($this->__acontrol['field'])==$this->__acontrol['value'])) && $this->__bnobutton===false) { if ((($this->__acontrol['field']===false) || ($row[$this->__acontrol['field']]===$this->__acontrol['value'])) && $this->__bnobutton===false) {
// adding all option // adding all option
for ($i=0; $i<count($this->__aoption); $i++) { foreach ($this->__aoption as $opsi) {
if (in_array($this->__aoption[$i]['type'], ["button","button-dt"])) { if (in_array($opsi['type'], ["button","button-dt"])) {
if (!isset($this->__aoption[$i]['field'])) continue; if (!isset($opsi['field'])) continue;
if (($this->__aoption[$i]['field']!="") && ($this->__cdb->Row($this->__aoption[$i]['field'])<>(trim("".$this->__aoption[$i]['value'])!="" ? $this->__aoption[$i]['value'] : $_SESSION['__WEB_USER']['UNIX']))) {} else { if (!empty($opsi['field']) && ($row[$opsi['field']] !== (!empty($opsi['value']) ? $opsi['value'] : (string)$this->app->session()->get('__WEB_USER')['UNIX']))) {} else {
$aoption['button'][] = [$this->__aoption[$i]['icon'], (empty($this->__aoption[$i]['field_css'])?'':$this->__aoption[$i]['avalue_css'][$this->__cdb->Row($this->__aoption[$i]['field_css'])]??'')]; $aoption['button'][] = [ $opsi['icon'], (empty($opsi['field_css'])?'':$opsi['avalue_css'][$row[$opsi['field_css']]]??'') ];
} }
} }
} }
// adding checkbox option // adding checkbox option
if (array_key_exists("field", $this->__acbox)) { if (array_key_exists('field', $this->__acbox)) {
$aoption['checkbox']['field'] = $this->__cdb->Row($this->__acbox['field']); $aoption['checkbox']['field'] = $row[$this->__acbox['field']];
$aoption['checkbox']['value'] = $this->__cdb->Row($this->__acbox['control']); $aoption['checkbox']['value'] = $row[$this->__acbox['control']];
} }
} }
} }
if (count($this->__arowcol)>0) {//up: 2014-06-13 if (count($this->__arowcol) > 0) {
for ($i=0; $i<count($this->__arowcol); $i++) { foreach ($this->__arowcol as $rcol) {
if ($this->__cdb->Row($this->__arowcol[$i]['F']) == $this->__arowcol[$i]['V']) $aoption['rowcss'] = $this->__arowcol[$i]['C']; if ($row[$rcol['F']] == $rcol['V']) $aoption['rowcss'] = $rcol['C'];
} }
} }
$abaris[] = $aoption; $abaris[] = $aoption;
for ($i=0; $i<count($this->__afield); $i++) { foreach ($this->__afield as $col) {
$tval = stripslashes($this->__cdb->Row($this->__afield[$i]));//up: 2015-01-05 $tval = $row[$col['a']];
if (is_array($this->__aformat[$i])) { if (is_array($col['f'])) {
$tval = $this->__aformat[$i][$tval]; $tval = $col['f'][$tval];
} else if (!is_null($this->__aformat[$i]) && function_exists($this->__aformat[$i])) { } else if (!is_null($col['f']) && function_exists($col['f'])) {
$tval = call_user_func($this->__aformat[$i], $tval); $tval = call_user_func($col['f'], $tval);
} else if (is_string($tval)) {
$tval = stripslashes($tval);
} }
$abaris[] = $tval; $abaris[] = $tval;
} }
@@ -222,80 +221,82 @@ final class Table {
} }
// navigator // navigator
$anavi = [ 'func_navi' => $this->__tfunc_navi, 'button' => $this->__arow_func ]; $anavi = [ 'no_navi' => $this->__bno_navi, 'button' => $this->__arow_func ];
$adata['type'] = "table"; $adata['type'] = "table";
$adata['id'] = $nama_tabel; $adata['id'] = $nama_tabel;
$adata['config'] = ['css' => $this->__tcss, 'row_count' => $baris_tabel, 'func_select' => $this->__tfunc_select, 'nobutton' => $this->__bnobutton, 'txtbutton' => $this->__btxtbutton, 'scrollbar' => $this->__bscrollbar, 'scroll_height' => $this->__nscrollheight, 'sort_col' => $this->__ord_field, 'sort_dir' => $this->__ord_dir, 'live' => $this->__livedata]; $adata['config'] = ['css' => $this->__tcss, 'row_count' => $baris_tabel, 'func_select' => $this->__tfunc_select, 'nobutton' => $this->__bnobutton, 'txtbutton' => $this->__btxtbutton, 'scrollbar' => $this->__bscrollbar, 'scroll_height' => $this->__nscrollheight, 'sort_col' => $this->__ord_field, 'sort_dir' => $this->__ord_dir, 'live' => $this->__livedata];
$adata['option'] = []; $adata['option'] = [];
foreach ($this->__aoption as $aval) { foreach ($this->__aoption as $aval) {
if ($aval['type']!=="checkbox") unset($aval['field']); unset($aval['value']); unset($aval['field_css']); unset($aval['value_css']); $adata['option'][] = $aval; if ($aval['type'] !== 'checkbox') unset($aval['field'], $aval['value'], $aval['field_css'], $aval['avalue_css']);
$adata['option'][] = $aval;
} }
$adata['navi'] = $anavi; $adata['navi'] = $anavi;
$adata['content'] = $acontent; $adata['content'] = $acontent;
return $adata; return $adata;
} }
public function db_table($nama_tabel = "tabel_", $baris_tabel = 10) { public function db_table(string $nama_tabel = "tabel_", int $baris_tabel = 10): array {
$adata = [];
$this->__livedata = true;
$this->prepare_query(); $this->prepare_query();
$id_draw = intval($this->__cpa->Get("draw", 0)); $this->__livedata = true;
$i_start = intval($this->__cpa->Get("start", 0)); $adata = [];
$i_length = intval($this->__cpa->Get("length", 0)); $id_draw = (int) ($this->data['draw'] ?? 0);
$i_order = $this->__cpa->Get("order", 0); $i_start = (int) ($this->data['start'] ?? 0);
$i_length = (int) ($this->data['length'] ?? 0);
$a_order = (array) ($this->data['order'] ?? []);
if ($id_draw > 0) { if ($id_draw > 0) {
$record = 0; $record = (int)$this->db->fetchField("SELECT COUNT(*) FROM ".$this->__ttable.$this->__twhere, $this->__aparam) ?? 0;
$this->__cdb->Query("SELECT COUNT(*) Item FROM ".$this->__ttable.$this->__twhere);
if ($this->__cdb->Next()) $record = intval($this->__cdb->Row("Item", 0));
$adata['type'] = "table-live"; $adata['type'] = "table-live";
$adata['id'] = $nama_tabel; $adata['id'] = $nama_tabel;
$adata['config'] = ['draw' => $id_draw, 'recordsTotal' => $record, 'recordsFiltered' => $record]; $adata['config'] = [ 'draw' => $id_draw, 'recordsTotal' => $record, 'recordsFiltered' => $record ];
$t_order = "ASC"; $t_order = "ASC";
if ($i_order <> 0) { if (count($a_order) > 0) {
$t_order = ($i_order[0]['dir']=="asc") ? "ASC" : "DESC"; $t_order = ($a_order[0]['dir']=="asc") ? "ASC" : "DESC";
$i_order = $i_order[0]['column']; $c_order = $a_order[0]['column'];
} }
if (($i_length > $record) || ($i_start >= $record) || ($record <= 10)) $i_length = -1; if (($i_length > $record) || ($i_start >= $record) || ($record <= 10)) $i_length = -1;
$sql_limit = ($i_start>=0 && $i_length != -1) ? " LIMIT ".$i_start.", ".$i_length : ""; $sql_limit = ($i_start>=0 && $i_length != -1) ? " LIMIT ".$i_start.", ".$i_length : "";
$sql_order = ($this->__afield[$i_order]) ? " ORDER BY ".$this->__afield[$i_order]." ".$t_order : ""; $sql_order = ($this->__afield[$c_order]) ? " ORDER BY ".$this->__afield[$c_order]['a']." ".$t_order : "";
$adata['data'] = []; $adata['data'] = [];
$this->__cdb->Query("SELECT ".$this->__tfield." FROM ".$this->__ttable.$this->__twhere.$sql_order.$sql_limit); $stat = $this->db->runQuery("SELECT ".$this->__tfield." FROM ".$this->__ttable.$this->__twhere.$sql_order.$sql_limit, $this->__aparam);
while ($this->__cdb->Next()) { while ($row = $stat->fetch(SimplePdo::FETCH_ASSOC)) {
$abaris = []; $abaris = [];
$aoption = ['button'=>[]]; $aoption = ['button'=>[]];
if (count($this->__aoption)>0) { if (count($this->__aoption)>0) {
if ((($this->__acontrol['field']===false) || ($this->__cdb->Row($this->__acontrol['field'])==$this->__acontrol['value'])) && $this->__bnobutton===false) { if ((($this->__acontrol['field']===false) || ($row[$this->__acontrol['field']]==$this->__acontrol['value'])) && $this->__bnobutton===false) {
// adding all option // adding all option
for ($i=0; $i<count($this->__aoption); $i++) { foreach ($this->__aoption as $opsi) {
if (in_array($this->__aoption[$i]['type'], ["button","button-dt"])) { if (in_array($opsi['type'], ["button","button-dt"])) {
if (($this->__aoption[$i]['field']!="") && ($this->__cdb->Row($this->__aoption[$i]['field'])<>(trim("".$this->__aoption[$i]['value'])!="" ? $this->__aoption[$i]['value'] : $_SESSION['__WEB_USER']['UNIX']))) {} else { if (!isset($opsi['field'])) continue;
$aoption['button'][] = [$this->__aoption[$i]['icon'], (empty($this->__aoption[$i]['field_css'])?'':$this->__aoption[$i]['avalue_css'][$this->__cdb->Row($this->__aoption[$i]['field_css'])]??'')]; if (!empty($opsi['field']) && ($row[$opsi['field']] !== (!empty($opsi['value']) ? $opsi['value'] : $this->app->session()->get('__WEB_USER')['UNIX']))) {} else {
$aoption['button'][] = [ $opsi['icon'], (empty($opsi['field_css'])?'':$opsi['avalue_css'][$row[$opsi['field_css']]]??'') ];
} }
} }
} }
// adding checkbox option // adding checkbox option
if (array_key_exists("field", $this->__acbox)) { if (array_key_exists('field', $this->__acbox)) {
$aoption['checkbox']['field'] = $this->__cdb->Row($this->__acbox['field']); $aoption['checkbox']['field'] = $row[$this->__acbox['field']];
$aoption['checkbox']['value'] = $this->__cdb->Row($this->__acbox['control']); $aoption['checkbox']['value'] = $row[$this->__acbox['control']];
} }
} }
} }
if (count($this->__arowcol)>0) {//up: 2014-06-13 if (count($this->__arowcol)>0) {
for ($i=0; $i<count($this->__arowcol); $i++) { foreach ($this->__arowcol as $rcol) {
if ($this->__cdb->Row($this->__arowcol[$i]['F']) == $this->__arowcol[$i]['V']) $aoption['rowcss'] = $this->__arowcol[$i]['C']; if ($row[$rcol['F']] == $rcol['V']) $aoption['rowcss'] = $rcol['C'];
} }
} }
$abaris[] = $aoption; $abaris[] = $aoption;
for ($i=0; $i<count($this->__afield); $i++) { foreach ($this->__afield as $col) {
$tval = stripslashes($this->__cdb->Row($this->__afield[$i]));//up: 2015-01-05 $tval = $row[$col['a']];
if (is_array($this->__aformat[$i])) { if (is_array($col['f'])) {
$tval = $this->__aformat[$i][$tval]; $tval = $col['f'][$tval];
} else if (!is_null($this->__aformat[$i]) && function_exists($this->__aformat[$i])) { } else if (!is_null($col['f']) && function_exists($col['f'])) {
$tval = call_user_func($this->__aformat[$i], $tval); $tval = call_user_func($col['f'], $tval);
} else if (is_string($tval)) {
$tval = stripslashes($tval);
} }
$abaris[] = $tval; $abaris[] = $tval;
} }
@@ -308,9 +309,13 @@ final class Table {
} }
private function prepare_query() { private function prepare_query() {
if ($this->__tfield == "") $this->__tfield = "`".implode('`,`', $this->__afield)."`"; if (empty($this->__tfield)) $this->__tfield = '`'. implode('`,`', array_column($this->__afield, 'a')) .'`';
if ($this->__twhere != "") $this->__twhere = " WHERE " . $this->__twhere; if (!empty($this->__twhere)) $this->__twhere = ' WHERE ' . $this->__twhere;
} }
//public function set_query($tquery = "") {}
//public function set_limit($nlimit = 0) {}
} }
?> ?>
+22 -12
View File
@@ -3,28 +3,38 @@
/******************************************************************* /*******************************************************************
Module : /Web/Terbilang.php Module : /Web/Terbilang.php
Desc. : Class Format Angka & Terbilang
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : February 12th, 2009. 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); 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 { 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 __construct() {}
public function Terbilang($nilai=0, $muang="Rupiah") { public function Terbilang(float $nilai=0, string $muang="Rupiah"): string {
$number = 0; $number = 0;
$hasil = ""; $hasil = "";
$int = trim($nilai); $int = (string)$nilai;
if (is_int(strpos($int,"-"))) { if (is_int(strpos($int,"-"))) {
$number = substr($int,strpos($int,"-")+1,strlen($int)); $number = substr($int,strpos($int,"-")+1,strlen($int));
$hasil = "Minus"; $hasil = "Minus";
@@ -36,11 +46,11 @@ final class Terbilang {
$xpos = strpos($number,"."); $xpos = strpos($number,".");
if (is_int($xpos)) { if (is_int($xpos)) {
# round : Untuk pembulatan angka desimal, strlen : untuk menghitung jumlah karakter # 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); $last = substr($number,0,$xpos);
} else { } else {
$pecahan = ""; $pecahan = "";
$last = $number; $last = (float)$number;
} }
if ($last==0 || $number==0) { if ($last==0 || $number==0) {
return $hasil."NOL ".$muang; return $hasil."NOL ".$muang;
@@ -71,12 +81,12 @@ final class Terbilang {
return $hasil . $kata; return $hasil . $kata;
} }
private function mod($a, $b) { private function mod(float $a, float $b): float {
return $a-$b*floor($a/$b); return $a-$b*floor($a/$b);
} }
private function tigadigit($amount, $suffix="") { private function tigadigit(float $amount, string $suffix=""): string {
$last = (int) $amount; $last = (int)$amount;
$kata = ""; $kata = "";
if ($last == 1 && $suffix=="Ribu") { if ($last == 1 && $suffix=="Ribu") {
$kata = " Seribu"; $kata = " Seribu";
+43 -25
View File
@@ -3,46 +3,61 @@
/******************************************************************* /*******************************************************************
Module : /Web/Update.php Module : /Web/Update.php
Desc. : Class Update Aplikasi Otomatis
Created By : Siau Pheng (siaupheng@3fonia.com). Created By : Siau Pheng (siaupheng@3fonia.com).
Created Date : June 14th, 2013. Created Date : June 14th, 2013.
Last Modified : March 3rd, 2026. Last Modified : August 22nd, 2026.
(c) 2013 - 2026, 3FONIA Software; WWW.3FONIA.COM. (c) 3FONIA Software; WWW.3FONIA.COM.
*******************************************************************/ *******************************************************************/
declare(strict_types=1); declare(strict_types=1);
namespace siaupheng\webapp\Web; namespace Webapp\Web;
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 { final class Update {
protected $__conf = []; private Array $__conf = [];
protected $is_git = false; private Bool $is_git = false;
protected Engine $app;
public function __construct(){ /**
$this->__conf = $_SESSION['__WEB_APP']; * @param Engine $app
$this->get_current(); */
public function __construct(Engine $app){
$this->app = $app;
$this->__conf = $app->session()->get('__WEB_APP');
$this->current();
} }
public function get_current() { public function current(): void {
$_target = $this->__conf['REAL_PATH']; if (defined('PROJECT_ROOT')) chdir(PROJECT_ROOT);
if (isset($_target)) chdir($_target);
try { try {
$output = shell_exec("git log -1 --pretty=format:\"%H||%s||%ci\" --abbrev-commit 2>&1"); $output = shell_exec("git log -1 --pretty=format:\"%H||%s||%ci\" --abbrev-commit 2>&1");
if ($output) { if ($output) {
$_ainfo = explode("||", $output); $_ainfo = explode("||", $output);
$this->__conf['GIT_SHA1'] = $_ainfo[0]; $this->__conf['GIT_SHA1'] = $_ainfo[0] ?? '';
$this->__conf['GIT_DATE'] = $_ainfo[2]; $this->__conf['GIT_DATE'] = $_ainfo[2] ?? '';
$this->is_git = true; $this->is_git = true;
} }
$output = shell_exec("git config --get remote.origin.url 2>&1"); $output = shell_exec("git config --get remote.origin.url 2>&1");
if ($output) { if ($output) {
$output = str_replace(["http://","https://",".git"], "", $output); $output = str_replace(["http://","https://",".git"], "", $output);
$_ainfo = explode("/", trim($output)); $_ainfo = explode("/", trim($output));
$this->__conf['GIT_OWNER'] = $_ainfo[1]; $this->__conf['GIT_OWNER'] = $_ainfo[1] ?? '';
$this->__conf['GIT_REPO'] = $_ainfo[2]; $this->__conf['GIT_REPO'] = $_ainfo[2] ?? '';
} }
$output = shell_exec("git branch --show-current 2>&1"); $output = shell_exec("git branch --show-current 2>&1");
if ($output) { if ($output) {
@@ -52,15 +67,19 @@ final class Update {
} }
} }
public function check_update() { public function check(): array {
$_ainfo['cur_version'] = $this->__conf['APP_BUILD']; $_ainfo['cur_version'] = $this->__conf['APP_BUILD'];
$_ainfo['cur_sha'] = substr($this->__conf['GIT_SHA1'], 0, 10); $_ainfo['cur_sha'] = substr($this->__conf['GIT_SHA1'], 0, 10);
$_ainfo['cur_sha1'] = $this->__conf['GIT_SHA1']; $_ainfo['cur_sha1'] = $this->__conf['GIT_SHA1'];
$_ainfo['cur_date'] = $this->__conf['GIT_DATE']; $_ainfo['cur_date'] = $this->__conf['GIT_DATE'];
$_ainfo['svr_status'] = 0; $_ainfo['svr_status'] = 0;
$_ainfo['svr_message'] = "Server Offline"; $_ainfo['svr_message'] = "Server Offline";
$_ainfo['new_sha'] = 'check git config';
$_ainfo['new_sha1'] = $this->__conf['GIT_SHA1'];
$_ainfo['new_date'] = '';
$_ainfo['new_message'] = 'check git config';
if (!$this->is_git) return $_ainfo; if (!$this->is_git || empty($this->__conf['GIT_OWNER']) || empty($this->__conf['GIT_REPO'])) return $_ainfo;
try { try {
$_url = "https://git.trifonia.cloud/api/v1/repos/".$this->__conf['GIT_OWNER']."/".$this->__conf['GIT_REPO']."/commits?limit=1"; $_url = "https://git.trifonia.cloud/api/v1/repos/".$this->__conf['GIT_OWNER']."/".$this->__conf['GIT_REPO']."/commits?limit=1";
@@ -80,17 +99,16 @@ final class Update {
return $_ainfo; return $_ainfo;
} }
public function go_update() { public function go(): array {
$_target = $this->__conf['REAL_PATH'];
$_branch = $this->__conf['GIT_BRANCH'] ?? "main"; $_branch = $this->__conf['GIT_BRANCH'] ?? "main";
if (isset($_target)) { if (defined('PROJECT_ROOT')) {
chdir($_target); chdir(PROJECT_ROOT);
$output = shell_exec("git reset --hard HEAD && git pull origin {$_branch} 2>&1"); $output = shell_exec("git reset --hard HEAD && git pull origin {$_branch} 2>&1");
return ['success'=>true,'message'=>$output]; return ['success'=>true,'message'=>$output];
} else return ['success'=>false,'message'=>"Tanpa REAL_PATH !"]; } else return ['success'=>false,'message'=>"Tanpa PROJECT_ROOT !"];
} }
public function update_mysql() { public function mysql() {
} }
} }