File: /home/cafsindia/uds.cafsinfotech.in/smart_hrms_dev/application/controllers/Formm.php
<?php if ( ! defined('BASEPATH')) exit('No direct script is allowed');
require_once("Action_controller.php");
require('./application/libraries/dompdf/autoload.inc.php');
use Dompdf\Dompdf;
use DOMDocument;
class Formm extends Action_controller{
public function __construct(){
parent::__construct('formm');
if(!$this->Appconfig->isAppvalid()){
redirect('config');
}
$this->load->library('pdf');
}
// LOAD PAGE WITH TABLE DATA
public function index(){
$role_info = $this->db->query("CALL sp_a_run ('SELECT','select * from `cw_category` where trans_status = 1 and prime_category_id !=1')");
$role_result = $role_info->result();
$role_info->next_result();
$category_list[""] = "---- Select Category ----";
foreach($role_result as $for){
$role_id = $for->prime_category_id;
$category_name = $for->category_name;
$category_list[$role_id] = $category_name;
}
$category_list['0'] = "ALL";
$data['category_list'] = $category_list;
$from_query = 'select * from cw_form_setting where prime_module_id = "employees" and field_show = "1" and field_type in (1,4,5,7) ORDER BY input_for,field_sort asc';
$form_data = $this->db->query("CALL sp_a_run ('SELECT','$from_query')");
$form_result = $form_data->result();
$form_data->next_result();
$fliter_list = $this->get_filter_data($form_result);
$data['fliter_list'] = $fliter_list;
$group_query = 'select label_name,view_name from cw_form_setting where prime_module_id = "employees" and field_show = "1" and input_view_type !=3 and field_type in (5,7) ORDER BY input_for,field_sort asc';
$group_info = $this->db->query("CALL sp_a_run ('SELECT','$group_query')");
$group_result = $group_info->result();
$group_info->next_result();
$group_by[""] = "---- Select Group ----";
foreach($group_result as $rlst){
$col_name = "cw_employees.".$rlst->label_name;
$view_name = $rlst->view_name;
$group_by[$col_name] = $view_name;
}
$data['key'] = $this->generateKey();
$data['group_by'] = $group_by;
$this->load->view("$this->control_name/manage",$data);
}
//PROVIDE QUERY AND DROPDOWN VALUES
public function get_filter_data($form_result){
$filter = array();
foreach($form_result as $setting){
$prime_form_id = (int)$setting->prime_form_id;
$prime_module_id = $setting->prime_module_id;
$input_view_type = (int)$setting->input_view_type;
$input_for = (int)$setting->input_for;
$field_type = (int)$setting->field_type;
$label_id = $setting->label_name;
$label_name = ucwords($setting->view_name);
$field_length = $setting->field_length;
$field_decimals = $setting->field_decimals;
$pick_list_type = (int)$setting->pick_list_type;
$pick_list = $setting->pick_list;
$pick_table = $setting->pick_table;
$auto_prime_id = $setting->auto_prime_id;
$auto_dispaly_value = $setting->auto_dispaly_value;
$field_isdefault = (int)$setting->field_isdefault;
$file_type = (int)$setting->file_type;
$mandatory_field = (int)$setting->mandatory_field;
$unique_field = (int)$setting->unique_field;
$search_show = (int)$setting->search_show;
$array_list = array();
if($label_id != 'role' && $label_id != 'employee_code' && $label_id != 'emp_name'){
if(($field_type === 5) || ($field_type === 7)){
if($pick_list_type === 1){
$pick_list_val = explode(",",$pick_list);
$pick_list_val_1 = $pick_list_val[0];
$pick_list_val_2 = $pick_list_val[1];
if($pick_table == "cw_category"){
$qry = " and prime_category_id != 1";
}else{
$qry = "";
}
if($pick_table == "cw_payroll_formula"){
$pick_query = "select $pick_list from $pick_table where trans_status = 1";
$pick_data = $this->db->query("CALL sp_a_run ('SELECT','$pick_query')");
$pick_result = $pick_data->result();
$pick_data->next_result();
$array_list[""] = "---- $label_name ----";
foreach($pick_result as $pick){
$pick_key = $pick->$pick_list_val_1;
$pick_val = ucwords(str_replace("_"," ",$pick->$pick_list_val_2));
$array_list[$pick_key] = $pick_val;
}
}else{
if($label_id === "excemption_component"){
$pick_query = "select $pick_list from $pick_table where trans_status = 1 and tax_section = 1 $qry";
}else{
$pick_query = "select $pick_list from $pick_table where trans_status = 1 $qry";
}
$pick_data = $this->db->query("CALL sp_a_run ('SELECT','$pick_query')");
$pick_result = $pick_data->result();
$pick_data->next_result();
$array_list[""] = "---- $label_name ----";
foreach($pick_result as $pick){
$pick_key = $pick->$pick_list_val_1;
$pick_val = $pick->$pick_list_val_2;
$array_list[$pick_key] = $pick_val;
}
}
}else
if($pick_list_type === 2){
$pick_list_val_1 = $pick_table."_id";
$pick_list_val_2 = $pick_table."_value";
$pick_list_val_3 = $pick_table."_status";
$pick_query = "select $pick_list_val_1,$pick_list_val_2 from $pick_table where $pick_list_val_3 = 1";
$pick_data = $this->db->query("CALL sp_a_run ('SELECT','$pick_query')");
$pick_result = $pick_data->result();
$pick_data->next_result();
$array_list[""] = "---- $label_name ----";
foreach($pick_result as $pick){
$pick_key = $pick->$pick_list_val_1;
$pick_val = $pick->$pick_list_val_2;
$array_list[$pick_key] = $pick_val;
}
}
}
if(($input_view_type === 1) || ($input_view_type === 2)){
$filter[] = array('label_id'=> $label_id, 'field_isdefault'=> $field_isdefault, 'array_list'=> $array_list, 'field_type'=> $field_type);
}
}
}
return $filter;
}
// generate pdf
public function formm_generate_pdf(){
$encString = file_get_contents('php://input');
$_POST = $this->cryptoDecrypt($encString);
if(!$_POST){
echo json_encode(array('success' => false,'message' => 'Invalid Request..','table_data' => ""));
exit(0);
}
$process_month = $this->input->post('process_month');
$process_month = $this->input->post('process_month');
$sheets_per_page = $this->input->post('sheets_per_page');
$category = $this->input->post('category');
$fliter_label = $this->input->post('fliter_label');
$fliter_type = $this->input->post('fliter_type');
$filter_cond = $this->input->post('filter_cond');
$fliter_val = $this->input->post('fliter_val');
$input_field_type = $this->input->post('input_field_type');
$group_by = ltrim(implode(",",$this->input->post('group_by[]') ?? []),",");
$filter_count = count($fliter_label ?? []);
$fliter_query = "";
$search_count = 0;
for($i=0;$i<=(int)$filter_count;$i++){
$db_name = $fliter_label[$i];
$table_name = $fliter_type[$i];
$db_cond = $filter_cond[$i];
$db_value = $fliter_val[$i];
$field_type = $field_type[$i];
if(($db_cond) && ($db_value)){
$search_count++;
if((int)$field_type === 4){
$search_val = date("Y-m-d",strtotime($db_value));
}else{
$search_val = $db_value;
}
if($db_cond === "LIKE"){ $search_val = "$db_value%"; }
if((int)$table_name === 1){
$this->prime_table = "cw_employees";
$fliter_query .= ' and '. $this->prime_table .".". $db_name ." ". $db_cond .' "'.$search_val.'"';
}
}
}
if($group_by){
$group_by_qry = "group by $group_by";
}else{
$group_by_qry = "";
}
$category_info = $this->db->query("CALL sp_a_run ('SELECT','SELECT category_name FROM `cw_category` where trans_status = 1 and prime_category_id = $category')");
$category_result = $category_info->result();
$category_info->next_result();
if(!empty($category_result)){
$category_name = $category_result[0]->category_name;
$role_qry = " and role = $category";
}else{
$category_name = "ALL";
$role_qry = "";
}
$payroll_exist_qry = 'select count(*) as result_count from cw_transactions where trans_status = 1 and transactions_month = "'.$process_month.'"'.$role_qry;
$payroll_data = $this->db->query("CALL sp_a_run ('SELECT','$payroll_exist_qry')");
$payroll_result = $payroll_data->result();
$payroll_data->next_result();
$payroll_count = $payroll_result[0]->result_count;
if((int)$payroll_count === 0){
echo json_encode(array('success'=>False,'msg'=>"Please run payroll first for this month $process_month!!!"));
exit(0);
}
$process_month_val = "01-".$process_month;
$process_month_name = date('F-Y',strtotime($process_month_val));
//FORM M IS MAPPED OR NOT
$form_m_exit_design_qry = 'select * from cw_print_design inner join cw_print_info on cw_print_info.prime_print_info_id = cw_print_design.print_design_for where cw_print_design.trans_status = 1 and cw_print_info.trans_status = 1 and print_info_module_id ="'.$this->control_name.'"';
$form_m_exit_design_info = $this->db->query("CALL sp_a_run ('SELECT','$form_m_exit_design_qry')");
$form_m_exit_design_result = $form_m_exit_design_info->result();
$form_m_exit_design_info->next_result();
$print_id = $form_m_exit_design_result[0]->prime_print_info_id;
$block_qry = 'select * from cw_print_block where print_block_for = "'.$print_id.'" and trans_status = 1';
$block_data = $this->db->query("CALL sp_a_run ('SELECT','$block_qry')");
$check_block_count = $block_data->num_rows();
$block_result = $block_data->result();
$block_data->next_result();
$status = TRUE;
if((int)$check_block_count){
$prime_print_block_id = $block_result[0]->prime_print_block_id;
$table_qry = 'select * from cw_print_table where print_table_for_id = "'.$prime_print_block_id.'" and trans_status = 1';
$table_data = $this->db->query("CALL sp_a_run ('SELECT','$table_qry')");
$table_count = $table_data->num_rows();
$table_data->next_result();
if(!(int)$table_count > 0){
$status = False;
}
}
if($form_m_exit_design_result && (int)$check_block_count > 0 && $status){
if((int)$category !== 0){
$cat_qry = ' and role = "'.$category.'" ';
}else{
$cat_qry ="";
}
$emp_ids_query = 'SELECT GROUP_CONCAT(DISTINCT employee_code order by prime_employees_id) as employee_code from cw_employees where trans_status = 1 '.$cat_qry.' '.$fliter_query.' ';
$emp_ids_info = $this->db->query("CALL sp_a_run ('SELECT','$emp_ids_query')");
$emp_ids_result = $emp_ids_info->result();
$emp_ids_info->next_result();
$employee_code = $emp_ids_result[0]->employee_code;
$employee_code = explode(",",$employee_code);
$final_result = $this->load_formm_data($print_id,$employee_code,$process_month,$sheets_per_page);
//$final_result=str_ireplace('<p',"<p style='display:none;'",$final_result);
$final_result = preg_replace('/<\/tbody><\/table>(.*?)<tbody>/','',$final_result);//regex replace
//get company details
$company_info = $this->db->query("CALL sp_a_run ('SELECT','SELECT * FROM `cw_company_information` where cw_company_information.trans_status = 1')");
$company_result = $company_info->result();
$company_info->next_result();
$company_name = $company_result[0]->company_name;
$company_address = $company_result[0]->address;
$company_city = $company_result[0]->city;
$company_state = $company_result[0]->state;
$company_country = $company_result[0]->country;
$header_info = "<h5 style='text-align:center;'>$company_name<br/>$company_address<br/>$company_city<br/>$company_state<br/>$company_country<br/>Wage Register for the month of $process_month_name</h5>";
$pdf_path = $this->get_pdf_path($final_result,$process_month,$category_name);
echo json_encode(array('success'=>TRUE,'pdf_path'=>$pdf_path));
}else{
if((int)$check_block_count === 0){
echo json_encode(array('success'=>False,'msg'=>"Print Block Not Added In Print Setting"));
}else
if(!$status){
echo json_encode(array('success'=>False,'msg'=>"Map the tables in print setting"));
}else
{
echo json_encode(array('success'=>False,'msg'=>"Form M Not Designed"));
}
}
}
public function load_formm_data($print_doc_id,$emp_code_rslt,$process_month,$sheets_per_page){
$data['print_sts'] = false;
$design_qry = 'select * from cw_print_design where print_design_for = "'.$print_doc_id.'" and trans_status = 1';
$design_data = $this->db->query("CALL sp_a_run ('SELECT','$design_qry')");
$design_result = $design_data->result();
$design_data->next_result();
$print_design = $design_result[0]->print_design;
$print_design = str_replace('~','"',$print_design);
$block_qry = 'select * from cw_print_block where print_block_for = "'.$print_doc_id.'" and trans_status = 1';
$block_data = $this->db->query("CALL sp_a_run ('SELECT','$block_qry')");
$block_result = $block_data->result();
$block_data->next_result();
foreach($block_result as $block){
$prime_print_block_id = $block->prime_print_block_id;
$print_block_name = $block->print_block_name;
$print_block_type = (int)$block->print_block_type;
$print_block_table = $block->print_block_table;
$print_block_column = $block->print_block_column;
$cumulative_data = $block->cumulative_data;
}
$table_qry = 'select * from cw_print_table where print_table_for_id = "'.$prime_print_block_id.'" and trans_status = 1';
$table_data = $this->db->query("CALL sp_a_run ('SELECT','$table_qry')");
$table_result = $table_data->result();
$table_data->next_result();
$line_table_query = "";
$cutome_table_check = array('transactions'=>'cw_transactions');
$results = array_map(function($table){
$line_prime_table = $table->line_prime_table;
$line_prime_col = $table->line_prime_col;
$line_join_type = $table->line_join_type;
$line_join_table = $table->line_join_table;
$line_join_col = $table->line_join_col;
$line_sort = $table->line_sort;
$module_name = str_replace("cw_","",$line_prime_table);
$prime_id = "prime_".$module_name."_id";
$join_module_name = str_replace("cw_","",$line_join_table);
$join_prime_id = "prime_".$join_module_name."_id";
$join_cf_id = "prime_".$join_module_name."_cf_id";
$join_cf_table_name = $this->db->dbprefix($join_module_name."_cf");
if((int)$line_sort === 1){
if($cutome_table_check[$module_name]){
$line_prime_table = " $line_prime_table ";
}else{
$line_prime_table = " $line_prime_table ";
}
if($cutome_table_check[$join_module_name]){
$line_join_table = " $line_join_table on $line_join_col = $line_prime_col";
}else{
$line_join_table = " $line_join_table on $line_join_col = $line_prime_col ";
}
$line_table_query = " $line_prime_table $line_join_type join $line_join_table";
}else{
if($cutome_table_check[$join_module_name]){
$line_table_query = " $line_join_type join $line_join_table on $line_join_col = $line_prime_col ";
}else{
$line_table_query = " $line_join_type join $line_join_table on $line_join_col = $line_prime_col ";
}
}
return $line_table_query;
}, $table_result);
$line_table_query = implode('',$results ?? []);
if(!$line_table_query){
$module_name = str_replace("cw_","",$print_block_table);
$prime_id = "prime_".$module_name."_id";
$line_table_query = " $print_block_table ";
}
if(!$print_block_column){
$print_block_column = "*";
}else{
$select_query = "";
$pick_query = "";
$map_column = explode(",",$print_block_column);
$column_name = '';
$module_name = '';
$check_array = array();
foreach($map_column as $table_column){
$map_column = explode(".",$table_column);
$table_name = $map_column[0];
$column = $map_column[1];
$control_name = str_replace('cw_',"",$table_name);
if($control_name === "transactions"){
$check_array["employees"][] = $control_name;
$control_name = "employees";
}else{
$check_array[$control_name][] = $control_name;
}
$column_name .= "\"$column\",";
$module_name .= "\"$control_name\",";
}
$column_name = '('.rtrim($column_name,',').')';
$module_name = '('.rtrim($module_name,',').')';
$form_qry = "select cw_form_setting.prime_form_id,cw_form_setting.view_name,cw_form_setting.label_name,cw_form_setting.field_type,cw_form_setting.pick_list_type,cw_form_setting.pick_list,cw_form_setting.pick_table,cw_form_setting.auto_prime_id,cw_form_setting.auto_dispaly_value,cw_form_setting.prime_module_id from cw_form_setting where label_name IN $column_name and cw_form_setting.prime_module_id IN $module_name and trans_status = \"1\"";
$form_data = $this->db->query("CALL sp_a_run ('SELECT','$form_qry')");
$form_result = $form_data->result();
$form_data->next_result();
$k = 0;
foreach($form_result as $form){
$table_name = "cw_".$check_array[$form->prime_module_id][$k];
$k++;
$prime_form_id = (int)$form->prime_form_id;
$view_name = $form->view_name;
$label_name = $form->label_name;
$field_type = (int)$form->field_type;
$pick_list_type = (int)$form->pick_list_type;
$pick_list = $form->pick_list;
$pick_table = $form->pick_table;
$auto_prime_id = $form->auto_prime_id;
$auto_dispaly_value = $form->auto_dispaly_value;
if((int)$field_type === 4){
$select_query .= 'DATE_FORMAT('.$table_name.'.'.$label_name.', "%d-%m-%Y") as '.$label_name.' , ';
}else
if(($field_type === 5) || ($field_type === 7)){
if($pick_list_type === 1){
$pick_list_val = explode(",",$pick_list);
$pick_list_val_1 = $pick_list_val[0];
$pick_list_val_2 = $pick_list_val[1];
$pick_query_as = $pick_table."_".$prime_form_id;
$select_query .= "$pick_query_as.$pick_list_val_2 as $label_name , ";
$pick_query .= " left join $pick_table as $pick_query_as on $pick_query_as.$pick_list_val_1 = $table_name.$label_name ";
}else
if($pick_list_type === 2){
$pick_list_val_1 = $pick_table."_id";
$pick_list_val_2 = $pick_table."_value";
$pick_list_val_3 = $pick_table."_status";
$pick_query_as = $pick_table."_".$prime_form_id;
$select_query .= "$pick_query_as.$pick_list_val_2 as $label_name , ";
$pick_query .= " left join $pick_table as $pick_query_as on $pick_query_as.$pick_list_val_1 = $table_name.$label_name ";
}
}else
if($field_type === 9){
$pick_query_as = $pick_table."_".$prime_form_id;
$select_query .= "$pick_query_as.$auto_dispaly_value as $label_name,";
$pick_query .= " left join $pick_table as $pick_query_as on $pick_query_as.$auto_prime_id = $table_name.$label_name ";
}else
if(($field_type === 2) || ($field_type === 3)){
$label_ytd = $label_name."_ytd";
$select_ytd_query .= "sum($table_name.$label_name) as $label_ytd, ";
$select_query .= "$table_name.$label_name , ";
}else{
$select_query .= "$table_name.$label_name , ";
}
}
}
$where_trans = "";
$where_trans_info = explode(",",$print_block_table);
foreach($where_trans_info as $trans_info){
if($trans_info === "cw_transactions"){
$select_query .= "cw_transactions.transactions_month , ";
}
$where_trans .= "$trans_info.trans_status = 1 and ";
}
$where_trans = rtrim($where_trans,'and ');
$where_qry = 'select where_condition from cw_print_table_where where where_for_id = "'.$prime_print_block_id.'" and trans_status = 1';
$where_data = $this->db->query("CALL sp_a_run ('SELECT','$where_qry')");
$where_result = $where_data->row();
$where_data->next_result();
$where_condition = "";
$split_qry = 'select * from cw_print_split where trans_status = 1 and split_table_info ="'.$print_doc_id.'"';
$split_data = $this->db->query("CALL sp_a_run ('SELECT','$split_qry')");
$split_result = $split_data->result();
$split_data->next_result();
$split_array = array();
foreach($split_result as $split){
$split_info = $split->split_info;
$split_colum = $split->split_colum;
$split_array[$split_colum] = $split_info;
}
if(!$where_result){
$where_condition = str_replace('^','"',$where_result->where_condition);
$where_condition = str_replace('@logged_id@',$emp_id,$where_condition);
$where_condition = str_replace('@input_month@',$payslip_month,$where_condition);
$session_date_list = array("logged_DMY"=>"d-m-Y","logged_YMD"=>"Y-m-d","logged_MY"=>"m-Y","logged_YM"=>"Y-m","logged_Y"=>"Y");
$session_query = 'select session_value from cw_session_value where session_for = 1 and trans_status = "1"';
$session_data = $this->db->query("CALL sp_a_run ('SELECT','$session_query')");
$session_result = $session_data->result();
$session_data->next_result();
foreach($session_result as $rslt){
$session_value = $rslt->session_value;
if($session_value !== "access_data"){
$exist_val = "@".$session_value."@";
if($session_date_list[$session_value]){
$date_formate = $session_date_list[$session_value];
$saved_session_val = date($date_formate);
}else{
$saved_session_val = $this->session->userdata($session_value);
}
$where_condition = str_replace($exist_val,$saved_session_val,$where_condition);
}
}
}else{
$emp_codes = '';
foreach($emp_code_rslt as $emp_code){
$emp_codes .= "\"$emp_code\",";
}
$emp_codes = '('.rtrim($emp_codes,',').')';
$where_condition = " and cw_transactions.transactions_month=\"$payslip_month\" and cw_transactions.employee_code IN $emp_codes";
}
$select_query = rtrim($select_query,',');
$select_query = rtrim($select_query,' , ');
$final_qry = "select $select_query from $line_table_query $pick_query where $where_trans $where_condition";
$final_data = $this->db->query("CALL sp_a_run ('SELECT','$final_qry')");
$final_rslt = $final_data->result();
$final_data->next_result();
$results = array_map(function($rslt){
$return_data['employee_data'] = $rslt;
$return_data['employee_code'] = $rslt->employee_code;
return $return_data;
}, $final_rslt);
$final_rslt = array_column($results,'employee_data','employee_code');
$i = 1;
$final_html = '';
foreach ($emp_code_rslt as $emp_code){
$print_data = '';
$rslt = $final_rslt[$emp_code];
if($rslt){
$print_data = $print_design;
$data['print_sts'] = true;
$map_column = explode(",",$print_block_column);
$td_line = "";
foreach($map_column as $table_column){
$map_column = explode(".",$table_column);
$column = $map_column[1];
$value = $rslt->$column;
$replace_val = "@".$column."@";
if($column == 'net_pay'){
$value = $rslt->$column;
$print_data = str_replace($replace_val,$value,$print_data);
$net_pay_val = $value;
$net_pay_words = $this->numbertowords($net_pay_val);
$net_pay_words = strtoupper($net_pay_words);
$print_data = str_replace("@net_pay_words@",$net_pay_words,$print_data);
}
if($split_array[$replace_val]){
//Process split informtion
$process_function = $split_array[$replace_val];
if((int)$process_function === 1){
$transactions_month = $final_result[0]->transactions_month;
$employee_code = $final_result[0]->employee_code;
$loan_info = $this->get_loan_value($transactions_month,$employee_code);
$print_data = str_replace($replace_val,$loan_info,$print_data);
}
}else{
if($print_block_type === 1){
$print_data = str_replace($replace_val,$value,$print_data);
foreach($assign_date_formate_list as $key=>$formate){
$start = "@".$key."_";
$end = "_".$key."@";
$replace_val = $start.$column.$end;
$date_value = date_create($value);
$replace_value = date_format($date_value,$formate);
$print_data = str_replace($replace_val,$replace_value,$print_data);
}
}else
if($print_block_type === 2){
$td_line .= "<td style='text-align:center;'>$value</td>";
}
if($count === 1){
$head_name = ucwords(str_replace("_"," ",$column));
if(($value === "") || ($value === "0.00") || ($value === "0") || (!$value)){
$th_line = "";
}else{
$th_line .= "<th style='text-align:center;'>$head_name</th>";
}
}
}
}
if($print_block_type === 2){
if($count === 1){
if(($value === "") || ($value === "0.00") || ($value === "0") || (!$value)){
$th_line = "";
}else{
$th_line = "$th_line";
$tr_line .= "<tr>$td_line</tr>";
}
}
}
if($print_block_type === 2){
$table_list = "<table style='width:100%;'><thead>$th_line</thead><tbody>$tr_line</tbody></table>";
$replce_block = "@".strtolower(str_replace(" ","_",$print_block_name))."@";
$print_data = str_replace($replce_block,$table_list,$print_data);
}
}
$print_data = str_replace("<br>","",$print_data);
if($i !== 1){
//thead hide
$print_data =str_ireplace('<thead',"<thead style='display:none;'",$print_data);
}
$final_html .= $print_data;
if($i % $sheets_per_page === 0){
$final_html .= "<div style='page-break-before:always;'></div><br/><br/>";
}
$i++;
}
return $final_html;
}
public function get_pdf_path($final_result,$process_month,$category_name){
$folder = "./form_m/".$process_month;
$path_name = $this->common_generate_pdf($final_result,$folder,$category_name,'landscape','A4','','');
return $path_name;
}
}
?>