| Server IP : 172.67.201.108 / Your IP : 216.73.216.11 Web Server : Apache/2.4.68 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-69-123.ec2.internal 6.1.176-223.369.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Jul 24 13:34:27 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/hotel-dev/public_html/classes/ |
Upload File : |
<?php
class lcs_db_grid {
public $html = '';
private $columns = array();
private $column_ctr = 0;
private $sub_column_ctr = 1;
private $width = 0;
private $scrollbar_width = 0;
private $spacer_width = 0;
private $uid = 0;
private $old_uid = 0;
private $sort_col = 1;
private $sort_order = 0;
private $search_str = '';
private $filter_cols = [];
private $filter = false;
private $div = '';
private $call = '';
private $func = '';
private $ix_form = '';
private $parm1 = '';
private $parm2 = '';
private $parm3 = '';
private $block_html = '';
private $block_count = 0;
private $block_row = 0;
private $block_limit = 200;
private $appear_trigger = 190;
private $load_method = 'lazy3'; /* lazy1 - background renedering, lazy2 - lazy rendering, lazy3 - lazy loading and rendering */
private $ar_blocks = [];
private $roles = '';
private $multi_filter = [];
public function __construct() {
$this->uid = str_replace(' ', '', microtime());
$this->uid = str_replace('.', '', $this->uid);
$this->scrollbar_width = intval($_GET['scrollbar_width']);
$this->spacer_width = intval($_GET['spacer_width']);
if (!empty($_GET['load_method'])) :
$this->load_method = intval($_GET['load_method']);
endif;
if (!empty($_GET['old_uid'])) :
$this->old_uid = intval($_GET['old_uid']);
endif;
if (!empty($_GET['sort_col'])) :
$this->sort_col = intval($_GET['sort_col']);
endif;
if (!empty($_GET['sort_order'])) :
$this->sort_order = intval($_GET['sort_order']);
endif;
if (!empty($_GET['search_str'])) :
$this->search_str = trim($_GET['search_str']);
endif;
if (!empty($_GET['filter_cols'])) :
$this->filter_cols = explode(',',trim($_GET['filter_cols']));
endif;
if (!empty($_GET['div'])) :
$this->div = trim($_GET['div']);
endif;
if (!empty($_GET['call'])) :
$this->call = trim($_GET['call']);
endif;
if (!empty($_GET['func'])) :
$this->func = trim($_GET['func']);
endif;
if (!empty($_GET['ix_form'])) :
$this->ix_form = trim($_GET['ix_form']);
endif;
if (!empty($_GET['parm1'])) :
$this->parm1 = trim($_GET['parm1']);
$_GET['parm1'] = xls_sql_decrypt($_GET['parm1']);
endif;
if (!empty($_GET['parm2'])) :
$this->parm2 = trim($_GET['parm2']);
$_GET['parm2'] = xls_sql_decrypt($_GET['parm2']);
endif;
if (!empty($_GET['parm3'])) :
$this->parm3 = trim($_GET['parm3']);
$_GET['parm3'] = xls_sql_decrypt($_GET['parm3']);
endif;
if (!empty($_GET['multi_filter'])) :
$this->multi_filter = json_decode(urldecode($_GET['multi_filter']));
endif;
/*
if (!empty($this->ix_form)) :
$ar_url = explode('&', $_GET['ix_form']);
foreach($ar_url as &$value) :
if (substr($value, 0, 4) == 'ref=') :
$value .= urlencode('&search_'.$this->div.'='.$this->search_str.'&scol_'.$this->div.'='.$this->sort_col.'&sorder_'.$this->div.'='.$this->sort_order);
endif;
endforeach;
$_GET['ix_form'] = implode('&', $ar_url);
endif;
*/
$this->roles = get_roles();
}
public function start_header_section() {
$this->html .= '<table class="lcs_dbg_header_section" id="lcs_dbg_header_'.$this->uid.'">';
}
public function end_header_section() {
$this->width += $this->spacer_width * ($this->column_ctr + 1);
$this->html .= '</table>';
}
public function start_data_section() {
$this->html .= '<div class="lcs_dbg_data_section" id="lcs_dbg_data_wrapper_'.$this->uid.'" ><table class="lcs_dbg_data" id="lcs_dbg_data_'.$this->uid.'" onscroll="lcs_db_scroll(\''.$this->uid.'\', \''.$this->div.'\');" >';
}
public function end_data_section() {
$this->block_count++;
$this->ar_blocks[$this->block_count] = $this->block_html;
$this->html .= '</table></div>';
}
public function start_header() {
$this->column_ctr = 0;
$this->html .= '<tr class="lcs_dbg_header">';
}
public function end_header() {
$this->html .= '</tr>';
if ($this->filter) :
$this->html .= '<tr class="lcs_dbg_header_filter">';
foreach ($this->columns as $key => $value) :
//$this->html .= '<td class="lcs_dbg_filter_cell" style="width:'.$value['width'].'; max-width:'.$value['width'].';" >';
if ($value['hidden']) :
continue;
endif;
$this->html .= '<td class="lcs_dbg_filter_cell" >';
if ($value['filter']) :
$filter_action = 'onclick="lcs_db_toggle_filter(\''.$this->div.'\', \''.$this->call.'\', \''.$this->func.'\', \''.$this->ix_form.'\', '.$this->sort_col.', '.$this->sort_order.', \''.$this->search_str.'\', \''.$this->parm1.'\', \''.$this->parm2.'\', \''.$this->parm3.'\', \''.implode(',', $this->filter_cols).'\', '.$this->div.'_multi_filter, '.$key.');"';
$filter_class = '';
if ($this->filter_cols[$key - 1] == 1) :
$filter_class = ' class="filtered" ';
endif;
$this->html .= '<img src="img/filter_icon.png" '.$filter_class.' '.$filter_action.' />';
endif;
if (count($value['multi_filter']) > 1) :
$popup_div_id = 'lcs_dbg_multi_filter_'.$this->div.'_'.$key;
$filter_action = 'onclick="lcs_db_multi_filter_open(\''.$popup_div_id.'\');"';
$this->html .= '<div class="popup" id="'.$popup_div_id.'">';
$this->html .= '<div style="float:right; cursor:pointer" onclick="lcs_db_multi_filter_close(\''.$popup_div_id.'\')">X</div>';
$this->html .= '<b><i>'.$value['label'].'</i></b><br>';
$this->html .= 'Select filters and click Apply<br>';
$this->html .= '<input type="button" class="mini" value="Clear" onclick="lcs_db_multi_filter_clear(\''.$popup_div_id.'\')" /> ';
$this->html .= '<input type="button" class="mini" value="Apply" onclick="lcs_db_multi_filter_apply('.$key.', \''.$popup_div_id.'\', \''.$this->div.'\', \''.$this->call.'\', \''.$this->func.'\', \''.$this->ix_form.'\', '.$this->sort_col.', '.$this->sort_order.', \''.$this->search_str.'\', \''.$this->parm1.'\', \''.$this->parm2.'\', \''.$this->parm3.'\', \''.implode(',', $this->filter_cols).'\','.$key.');" /><br><hr>';
$this->html .= '<div class="popup_scrollable">';
$filter_class = '';
foreach($value['multi_filter'] as $filter_key => $filter_value) :
$checked = '';
if (!empty($this->multi_filter[$key]) && is_array($this->multi_filter[$key]) && in_array($filter_key, $this->multi_filter[$key])) :
$checked = ' checked ';
$filter_class = ' class="filtered" ';
endif;
$this->html .= '<label><input type="checkbox" value="'.$filter_key.'" '.$checked.' > '.$filter_value.'</label><br>';
endforeach;
$this->html .= '</div>';
$this->html .= '</div>';
$this->html .= '<img src="img/filter_icon.png" '.$filter_class.' '.$filter_action.' />';
endif;
$this->html .= '</td>';
endforeach;
$this->html .= '</tr>';
endif;
}
public function start_sub_header() {
$this->sub_column_ctr = 1;
$this->html .= '<tr class="lcs_dbg_header_filter">';
}
public function end_sub_header() {
for ($i = $this->sub_column_ctr; $i <= $this->column_ctr; $i++) :
//$this->html .= '<td class="lcs_dbg_filter_cell" style="width:'.$this->columns[$i]['width'].';" >';
$this->html .= '<td class="lcs_dbg_filter_cell" >';
$this->html .= '</td>';
endfor;
$this->html .= '</tr>';
}
public function add_sub_column($args) {
$defaults = array(
'start' => 1,
'cols' => 1,
'align' => 'center', /** left, center, right **/
'label' => '',
);
$args = array_merge($defaults, array_intersect_key($args, $defaults));
for ($i = $this->sub_column_ctr; $i < $args['start']; $i++) :
if (!$this->columns[$i]['hidden']) :
//$this->html .= '<td class="lcs_dbg_filter_cell"><div style="width:'.$this->columns[$i]['width'].';" >';
$this->html .= '<td class="lcs_dbg_filter_cell"><div >';
$this->html .= '</div></td>';
endif;
endfor;
$width = 0;
for ($i = $args['start']; $i < $args['start'] + $args['cols']; $i++) :
$width += intval($this->columns[$i]['width']);
endfor;
$width += ($args['cols'] - 1) * $this->spacer_width;
$this->html .= '<td colspan="'.$args['cols'].'" class="lcs_dbg_sub_header_cell"><div style="text-align:'.$args['align'].'; max-width:none;" >';
$this->html .= $args['label'];
$this->html .= '</div></td>';
$this->sub_column_ctr = $args['start'] + $args['cols'];
}
public function start_row() {
$this->column_ctr = 0;
if ($this->block_row >= $this->block_limit) :
$this->block_count++;
$this->ar_blocks[$this->block_count] = $this->block_html;
$this->block_row = 0;
$this->block_html = '';
endif;
//$this->html .= '<div class="lcs_dbg_row" style="width:'.$this->width.'px">';
$appear_class = '';
if ($this->block_row == $this->appear_trigger) :
$appear_class = ' lcs_appear';
endif;
$this->block_row++;
$this->block_html .= '<tr class="lcs_dbg_row'.$appear_class.'">';
}
public function end_row() {
$this->block_html .= '</tr>';
}
public function add_column($args) {
global $ar_pagecontrol;
$defaults = [
'label' => '',
'dbcol' => '',
'datatype' => 'text', /** text, number, currency, date, time, datetime, checkbox, image **/
'align' => 'left', /** left, center, right **/
'width' => '',
'sortable' => true,
'searchable' => true,
'href' => '',
'filter' => false,
'multi_filter' => [],
'multi_filter_col' => '',
'multi_filter_type' => 'string',
'update' => false,
'hidden' => false,
'class' => '',
];
$args = array_merge($defaults, array_intersect_key($args, $defaults));
$this->column_ctr++;
$this->columns[$this->column_ctr] = $args;
if ($args['update'] && (!empty($ar_pagecontrol[$this->call]['update_roles']) && !role_match($ar_pagecontrol[$this->call]['update_roles'], $this->roles))) :
return;
endif;
if ($args['hidden']) :
return;
endif;
$this->width += intval($this->columns[$this->column_ctr]['width']);
$sort_class = '';
$sort_action = '';
if ($this->columns[$this->column_ctr]['sortable']) :
$sort_class .= ' lcs_dbg_sortable ';
$sort_direction = 0;
if ($this->column_ctr == $this->sort_col) :
if ($this->sort_order == 0) :
$sort_class .= 'lcs_dbg_sorting_asc';
$sort_direction = 1;
else :
$sort_class .= 'lcs_dbg_sorting_desc';
endif;
endif;
$sort_action .= 'onclick="lcs_db_load(\''.$this->div.'\', \''.$this->call.'\', \''.$this->func.'\', \''.$this->ix_form.'\', '.$this->column_ctr.', '.$sort_direction.', \''.$this->search_str.'\', \''.$this->parm1.'\', \''.$this->parm2.'\', \''.$this->parm3.'\', \''.implode(',', $this->filter_cols).'\', '.$this->div.'_multi_filter);"';
endif;
//$this->html .= '<td class="lcs_dbg_header_cell '.$sort_class.'"><div class="lcs_dbg_header_cell_label resizeable_'.$this->div.'_'.$this->column_ctr.'" style="width:'.$this->columns[$this->column_ctr]['width'].';" '.$sort_action.'>';
$this->html .= '<td class="lcs_dbg_header_cell '.$sort_class.' resizeable_'.$this->div.'_'.$this->column_ctr.'"><div class="lcs_dbg_header_cell_label resizeable_'.$this->div.'_'.$this->column_ctr.'" '.$sort_action.'>';
$this->html .= $args['label'];
$this->html .= '<div class="lcs_dbg_resizer" onmousedown="lcs_db_col_resize_start(\'resizeable_'.$this->div.'_'.$this->column_ctr.'\', $(this), \''.$this->div.'\');" onmouseup="lcs_db_col_resize_stop();" onmousemove="lcs_db_col_resize_move();"></div>';
$this->html .= '</div></td>';
if ($args['filter']) :
$this->filter = true;
endif;
if (count($args['multi_filter']) > 0) :
$this->filter = true;
endif;
if (($this->filter_cols[$this->column_ctr - 1] ?? NULL) != '1') :
$this->filter_cols[$this->column_ctr - 1] = '0';
endif;
}
public function add_cell($str) {
global $ar_pagecontrol;
if ($str == '') :
$str = ' ';
endif;
$this->column_ctr++;
if ($this->columns[$this->column_ctr]['update'] && (!empty($ar_pagecontrol[$this->call]['update_roles']) && !role_match($ar_pagecontrol[$this->call]['update_roles'], $this->roles))) :
return;
endif;
if ($this->columns[$this->column_ctr]['hidden']) :
return;
endif;
//$this->block_html .= '<td class="lcs_dbg_data_cell"><div class="resizeable_'.$this->div.'_'.$this->column_ctr.'" style="width:'.$this->columns[$this->column_ctr]['width'].'; text-align:'.$this->columns[$this->column_ctr]['align'].';">';
$this->block_html .= '<td class="lcs_dbg_data_cell resizeable_'.$this->div.'_'.$this->column_ctr.'"><div class="resizeable_'.$this->div.'_'.$this->column_ctr.' '.$this->columns[$this->column_ctr]['class'].'" style="text-align:'.$this->columns[$this->column_ctr]['align'].';">';
$this->block_html .= $str;
$this->block_html .= '</div></td>';
}
public function sort_spec() {
if ($this->sort_order == 0) :
$sort_order = 'ASC';
else :
$sort_order = 'DESC';
endif;
$sort_spec = " ".$this->columns[$this->sort_col]['dbcol']." ".$sort_order." ";
return $sort_spec;
}
public function search_spec() {
$db = $GLOBALS['db'];
$ar_tokens = array();
$si = 0;
$search_spec = '';
$filter_spec = '';
$multi_filter_spec = '';
for ($i=1; $i<=$this->column_ctr; $i++) :
if ($this->columns[$i]['searchable']) :
$si++;
if ($this->columns[$i]['datatype'] == 'number' || $this->columns[$i]['datatype'] == 'currency') :
$search_token = " (".$this->columns[$i]['dbcol']." = ".floatval($this->search_str).") ";
else :
$search_token = " (".$this->columns[$i]['dbcol']." LIKE ".$db->quote('%'.htmlspecialchars_decode($this->search_str, ENT_QUOTES).'%').") ";
endif;
$ar_tokens[$si] = $search_token;
endif;
if ($this->columns[$i]['filter']) :
if ($this->filter_cols[$i - 1] == '1') :
$filter_spec .= " AND ".$this->columns[$i]['dbcol']." = 1 ";
endif;
endif;
$multi_filter = $this->multi_filter[$i] ?? [];
if (count($this->columns[$i]['multi_filter']) > 0 && is_array($multi_filter) && count($multi_filter) > 0) :
if ($this->columns[$i]['multi_filter_type'] == 'int') :
$multi_filter = array_map(function($value) {
return (int)$value;
}, $multi_filter);
$in_str = implode(',', $multi_filter);
else :
$multi_filter = array_map(function($value) {
$db = $GLOBALS['db'];
return $db->quote(trim($value));
}, $multi_filter);
$in_str = implode(',', $multi_filter);
endif;
if (!empty($this->columns[$i]['multi_filter_col'])) :
$multi_filter_spec .= " AND ".$this->columns[$i]['multi_filter_col']." IN ({$in_str}) ";
else :
$multi_filter_spec .= " AND ".$this->columns[$i]['dbcol']." IN ({$in_str}) ";
endif;
endif;
endfor;
if ($si > 0) :
$search_spec = " (".implode(' OR ', $ar_tokens).") ";
else :
$search_spec = ' (1=1) ';
endif;
return $search_spec.$filter_spec.$multi_filter_spec;
}
public function get_html() {
$this->width += $this->scrollbar_width;
$style = '';
foreach ($this->columns as $key => $value) :
$style .= 'div.resizeable_'.$this->div.'_'.$key.'{width:'.$value['width'].';}';
$style .= 'td.resizeable_'.$this->div.'_'.$key.'{width:'.$value['width'].';}';
endforeach;
$style = '<style id=\"lcs_dbg_style_'.$this->div.'\" type=\"text/css\">'.$style.'</style>';
//$this->html = '<div class="lcs_dbg_wrapper" style="width:'.$this->width.'px;">'.$this->html.'</div>';
$this->html = '<div class="lcs_dbg_wrapper" style="width:'.$this->width.'px;"><div id="lcs_db_loading"></div>'.$this->html.'</div>';
$this->html .= '<div id ="lcs_dbg_resizer_guide_'.$this->div.'" class="lcs_dbg_resizer_guide" ></div>';
$this->html .= '<script>';
$this->html .= 'if ($("#lcs_dbg_style_'.$this->div.'").length == 0) {';
$this->html .= '$("head").append("'.$style.'");';
$this->html .= '}';
$this->html .= 'var '.$this->div.'_sort_col = '.$this->sort_col.';';
$this->html .= 'var '.$this->div.'_sort_order = '.$this->sort_order.';';
$this->html .= 'var '.$this->div.'_search_str = "'.$this->search_str.'";';
$this->html .= 'var '.$this->div.'_filter_cols = "'.implode(',', $this->filter_cols).'";';
$this->html .= 'var '.$this->div.'_multi_filter = '.json_encode($this->multi_filter, JSON_HEX_QUOT).';';
$this->html .= 'var '.$this->div.'_parm1 = "'.$this->parm1.'";';
$this->html .= 'var '.$this->div.'_parm2 = "'.$this->parm2.'";';
$this->html .= 'var '.$this->div.'_parm3 = "'.$this->parm3.'";';
$this->html .= 'var '.$this->div.'_call = "'.$this->call.'";';
$this->html .= 'var '.$this->div.'_func = "'.$this->func.'";';
$this->html .= 'var '.$this->div.'_ix_form = "'.$this->ix_form.'";';
$this->html .= 'window["'.$this->div.'_block_count"] = '.$this->block_count.';';
$this->html .= 'window["'.$this->div.'_current_block"] = 1;';
$this->html .= 'window["'.$this->div.'_uid"] = "'.$this->uid.'";';
$this->html .= 'window["'.$this->div.'_load_method"] = "'.$this->load_method.'";';
$this->html .= 'window["'.$this->div.'_ar_blocks"] = [];';
$this->html .= 'if (typeof appstack_switch_param == "function") { ';
$this->html .= 'appstack_switch_param("search_'.$this->div.'", "'.$this->search_str.'");';
$this->html .= 'appstack_switch_param("scol_'.$this->div.'", "'.$this->sort_col.'");';
$this->html .= 'appstack_switch_param("sorder_'.$this->div.'", "'.$this->sort_order.'");';
$this->html .= 'appstack_switch_param("fcols_'.$this->div.'", "'.implode(',', $this->filter_cols).'");';
$this->html .= 'appstack_switch_param("multi_filter_'.$this->div.'", \''.json_encode($this->multi_filter, JSON_HEX_QUOT).'\');';
$this->html .= ' } ';
switch ($this->load_method):
case 'lazy1' :
for ($i=1; $i<=$this->block_count; $i++) :
$this->html .= 'window["'.$this->div.'_ar_blocks"]['.$i.'] = '.json_encode($this->ar_blocks[$i]).';';
endfor;
$this->html .= 'setTimeout(function() { lcs_db_lazy_load1(1, '.$this->block_count.', "'.$this->uid.'", "'.$this->div.'"); }, 50);';
break;
case 'lazy2' :
for ($i=1; $i<=$this->block_count; $i++) :
$this->html .= 'window["'.$this->div.'_ar_blocks"]['.$i.'] = '.json_encode($this->ar_blocks[$i]).';';
endfor;
break;
case 'lazy3' :
$_SESSION['lcs_db_grid_blocks_'.$this->old_uid] = NULL;
unset($_SESSION['lcs_db_grid_blocks_'.$this->old_uid]);
$_SESSION['lcs_db_grid_blocks_'.$this->uid] = array();
for ($i=1; $i<=$this->block_count; $i++) :
$_SESSION['lcs_db_grid_blocks_'.$this->uid][$i] = sys_compress($this->ar_blocks[$i]);
endfor;
if (!isset($_SESSION['lcs_db_grid_keep_alive']) || !is_array($_SESSION['lcs_db_grid_keep_alive'])) :
$_SESSION['lcs_db_grid_keep_alive'] = array();
endif;
foreach ($_SESSION['lcs_db_grid_keep_alive'] as $key=>$value) :
if (($value + 300) < time()) :
$_SESSION['lcs_db_grid_blocks_'.$key] = NULL;
unset($_SESSION['lcs_db_grid_blocks_'.$key]);
endif;
endforeach;
$_SESSION['lcs_db_grid_keep_alive'][$this->uid] = time();
$this->ar_blocks = NULL;
break;
endswitch;
$this->html .= '</script>';
return $this->html;
}
}
?>