diff --git a/.DS_Store b/.DS_Store index 6c22bef..9d4c452 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/access_element.php b/access_element.php new file mode 100644 index 0000000..d047901 --- /dev/null +++ b/access_element.php @@ -0,0 +1,188 @@ +rowID; + +//CALL TO API FOR Roles using this access element +$api_url = '/v2/role_access_permissions/access_id='.$element_id; +$role_permissions = ioServer($api_url,''); +//Decode Payload +if (!empty($role_permissions)){$role_permissions = json_decode($role_permissions);}else{$role_permissions = null;} + +//------------------------------ +//Variables +//------------------------------ +$status_text = ($responses->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive'); +$status_class = ($responses->is_active == 1) ? 'id1' : 'id0'; + +// Handle success messages +if (isset($_GET['success_msg'])) { + if ($_GET['success_msg'] == 1) { + $success_msg = ($message_access_1 ?? 'Access element created successfully'); + } + if ($_GET['success_msg'] == 2) { + $success_msg = ($message_access_2 ?? 'Access element updated successfully'); + } + if ($_GET['success_msg'] == 3) { + $success_msg = ($message_access_3 ?? 'Access element deleted successfully'); + } +} + +template_header(($access_element_title ?? 'Access Element'), 'access_element', 'view'); +$view = ' +
+

'.($view_access_h2 ?? 'Access Element').' - '.$responses->access_name.'

+ +'; + +if ($update_allowed_edit === 1){ + $view .= '✏️'; +} + +$view .= '
'; + +if (isset($success_msg)){ + $view .= '
+ +

'.$success_msg.'

+ +
'; +} + +$view .= '
'; + +// Access Element Information Block +$view .= '
+
+ '.($view_access_information ?? 'Access Element Information').' +
+
+

'.($general_status ?? 'Status').'

+

'.$status_text.'

+
+
+

'.($access_element_name ?? 'Name').'

+

'.$responses->access_name.'

+
+
+

'.($access_element_path ?? 'Path').'

+

'.$responses->access_path.'

+
+
+

'.($access_element_group ?? 'Group').'

+

'.($responses->access_group ?? '-').'

+
+
+

'.($role_description ?? 'Description').'

+

'.($responses->description ?? '-').'

+
+
+'; + +$view .= '
'; // Close content-block-wrapper + +// Roles Using This Access Element +$view .= '
+
+ '.($view_access_roles ?? 'Roles Using This Element').' +
+
+ + + + + + + + + + + '; + +if (!empty($role_permissions)){ + foreach ($role_permissions as $role_perm){ + $can_create = ($role_perm->can_create == 1) ? '' : ''; + $can_read = ($role_perm->can_read == 1) ? '' : ''; + $can_update = ($role_perm->can_update == 1) ? '' : ''; + $can_delete = ($role_perm->can_delete == 1) ? '' : ''; + + $view .= ' + + + + + + '; + } +} else { + $view .= ' + + '; +} + +$view .= ' +
'.($role_name ?? 'Role Name').''.($permission_create ?? 'C').''.($permission_read ?? 'R').''.($permission_update ?? 'U').''.($permission_delete ?? 'D').'
'.$role_perm->role_name.''.$can_create.''.$can_read.''.$can_update.''.$can_delete.'
'.($no_roles_using ?? 'No roles are using this access element').'
+
+
+ '; + +// Metadata Block +$view .= '
+
+ '.($tab3 ?? 'Details').' +
+
+ + + + + + + + + +
'.($general_created ?? 'Created').''.getRelativeTime($responses->created).'
'.($general_updated ?? 'Updated').''.getRelativeTime($responses->updated).'
+
+
+'; + +//OUTPUT +echo $view; + +template_footer() + +?> diff --git a/access_element_manage.php b/access_element_manage.php new file mode 100644 index 0000000..2f183ad --- /dev/null +++ b/access_element_manage.php @@ -0,0 +1,168 @@ + '', + 'access_name' => '', + 'access_path' => '', + 'access_group' => '', + 'description' => '', + 'is_active' => 1, + 'created' => '', + 'createdby' => $_SESSION['username'], + 'updated' => '', + 'updatedby' => '' +]; + +$element_ID = $_GET['rowID'] ?? ''; + +if ($element_ID !=''){ + $url = 'index.php?page=access_element&rowID='.$element_ID.''; +} else { + $url = 'index.php?page=access_elements'; +} + +if (isset($_GET['rowID'])) { + // ID param exists, edit an existing element + //CALL TO API + $api_url = '/v2/access_elements/rowID='.$element_ID; + $responses = ioServer($api_url,''); + //Decode Payload + if (!empty($responses)){$responses = json_decode($responses,true);}else{$responses = null;} + + $element = $responses[0]; + + if ($update_allowed === 1){ + if (isset($_POST['submit'])) { + //GET ALL POST DATA + $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/access_elements', $data); + + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=access_element&rowID='.$element_ID.'&success_msg=2'); + exit; + } + } + } + + if ($delete_allowed === 1){ + if (isset($_POST['delete'])) { + //GET ALL POST DATA + $data = json_encode($_POST , JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/access_elements', $data); + // Redirect and delete element + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=access_elements&success_msg=3'); + exit; + } + } + } + +} else { + // Create a new element + if (isset($_POST['submit']) && $create_allowed === 1) { + //GET ALL POST DATA + $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/access_elements', $data); + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=access_elements&success_msg=1'); + exit; + } + } +} + +template_header(($access_element_title ?? 'Access Element'), 'access_element', 'manage'); + +$label_h2 = (($element_ID !='')? ($manage_access_h2 ?? 'Edit Access Element') : ($button_create_access ?? 'Create Access Element')); +$view =' +
+
+

'.$label_h2.'

+ +'; + +if ($delete_allowed === 1 && $element_ID != ''){ + $view .= ''; +} +if ($update_allowed === 1 || ($create_allowed === 1 && $element_ID == '')){ + $view .= ''; +} + +$view .= '
'; + +$view .= '
+ '.($tab1 ?? 'General').' +
+
+
+ + + + + + + + + + + +
+
'; + +//DISPLAY TAB 2 - Metadata +if ($element_ID != ''){ +$view .= '
+ '.($tab3 ?? 'Details').' +
+
+
+ + + + + + + + +
+
'; +} + +$view .= '
'; + +//Output +echo $view; +template_footer()?> diff --git a/access_elements.php b/access_elements.php new file mode 100644 index 0000000..cad1dc1 --- /dev/null +++ b/access_elements.php @@ -0,0 +1,317 @@ +←':''; + +//Check if allowed +if (isAllowed($page,$_SESSION['profile'],$_SESSION['permission'],'R') === 0){ + header('location: index.php'); + exit; +} +//PAGE Security +$page_manage = 'access_element_manage'; +$update_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'U'); +$delete_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'D'); +$create_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'C'); + +// Function to scan project for new PHP files and add to access_elements +function scan_and_update_access_elements() { + $new_elements = []; + $base_path = dirname(__FILE__); + + // Scan root PHP files (excluding index, login, logout) + $root_files = glob($base_path . '/*.php'); + foreach ($root_files as $file) { + $filename = basename($file, '.php'); + if (!in_array($filename, ['index', 'login', 'logout'])) { + // Only add if not already in array (first occurrence wins) + if (!isset($new_elements[$filename])) { + $new_elements[$filename] = [ + 'name' => ucwords(str_replace('_', ' ', $filename)), + 'path' => $filename, + 'group' => 'Views', + 'description' => 'Auto-scanned: ' . $filename + ]; + } + } + } + + // Scan API v2 get folder - only add if not already found in root + $get_files = glob($base_path . '/api/v2/get/*.php'); + foreach ($get_files as $file) { + $filename = basename($file, '.php'); + if (!isset($new_elements[$filename])) { + $new_elements[$filename] = [ + 'name' => ucwords(str_replace('_', ' ', $filename)), + 'path' => $filename, + 'group' => 'API', + 'description' => 'Auto-scanned: ' . $filename + ]; + } + } + + // Scan API v2 post folder - only add if not already found + $post_files = glob($base_path . '/api/v2/post/*.php'); + foreach ($post_files as $file) { + $filename = basename($file, '.php'); + if (!isset($new_elements[$filename])) { + $new_elements[$filename] = [ + 'name' => ucwords(str_replace('_', ' ', $filename)), + 'path' => $filename, + 'group' => 'API', + 'description' => 'Auto-scanned: ' . $filename + ]; + } + } + + // Get existing access elements from API + $api_url = '/v2/access_elements/'; + $existing = ioServer($api_url, ''); + $existing_paths = []; + if (!empty($existing)) { + $existing_data = json_decode($existing); + foreach ($existing_data as $element) { + $existing_paths[] = $element->access_path; + } + } + + // Filter out elements that already exist + $elements_to_add = []; + foreach ($new_elements as $path => $element) { + if (!in_array($path, $existing_paths)) { + $elements_to_add[] = $element; + } + } + + // Add new elements via API + $added_count = 0; + foreach ($elements_to_add as $element) { + $data = json_encode([ + 'access_name' => $element['name'], + 'access_path' => $element['path'], + 'access_group' => $element['group'], + 'description' => $element['description'], + 'is_active' => 1 + ], JSON_UNESCAPED_UNICODE); + + $response = ioServer('/v2/access_elements', $data); + if ($response !== 'NOK') { + $added_count++; + } + } + + return $added_count; +} + +// Handle scan request +if (isset($_POST['scan_elements']) && $create_allowed === 1) { + $added_count = scan_and_update_access_elements(); + header('Location: index.php?page=access_elements&elements_added=' . $added_count); + exit; +} + +//GET PARAMETERS && STORE in SESSION for FURTHER USE/NAVIGATION +$pagination_page = $_SESSION['p'] = isset($_GET['p']) ? $_GET['p'] : 1; +$status = $_SESSION['status'] = isset($_GET['status']) ? '&status='.$_GET['status'] : ''; +$sort = $_SESSION['sort'] = isset($_GET['sort']) ? '&sort='.$_GET['sort'] : ''; +$search = $_SESSION['search'] = isset($_GET['search']) ? '&search='.$_GET['search'] : ''; + +//GET PARAMETERS FOR FILTERS +$filter = urlGETdetailsFilter($_GET) ?? ''; + +// Determine the URL +$url = 'index.php?page=access_elements'.$status.$search.$sort; +//GET Details from URL +$GET_VALUES = urlGETdetails($_GET) ?? ''; +//CALL TO API +$api_url = '/v2/access_elements/'.$GET_VALUES; +$responses = ioServer($api_url,''); +//Decode Payload +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} + +//Return QueryTotal from API +$total_url = ((!empty($GET_VALUES) && $GET_VALUES !='') ? '&totals=' : 'totals=' ); +$api_url = '/v2/access_elements/'.$GET_VALUES.$total_url; +$query_total = ioServer($api_url,''); +//Decode Payload +if (!empty($query_total)){$query_total = json_decode($query_total);}else{$query_total = null;} + +// Handle success messages +if (isset($_GET['success_msg'])) { + if ($_GET['success_msg'] == 1) { + $success_msg = ($message_access_1 ?? 'Access element created successfully'); + } + if ($_GET['success_msg'] == 2) { + $success_msg = ($message_access_2 ?? 'Access element updated successfully'); + } + if ($_GET['success_msg'] == 3) { + $success_msg = ($message_access_3 ?? 'Access element deleted successfully'); + } +} + +// Handle elements added message from scan +if (isset($_GET['elements_added'])) { + $added_count = (int)$_GET['elements_added']; + if ($added_count > 0) { + $success_msg = $added_count . ' ' . ($message_elements_added ?? 'new access elements added'); + } else { + $success_msg = ($message_no_new_elements ?? 'No new elements found. All elements are up to date.'); + } +} + +template_header(($access_elements_title ?? 'Access Elements'), 'access_elements','view'); +$view = ' +
+
+ +
+

'.($access_elements_h2 ?? 'Access Elements').' ('.$query_total.')

+

'.($access_elements_p ?? 'Manage system access elements and paths').'

+
+
+
+ '.$back_btn_orgin; + +// Scan button - only show if user has create permission +if ($create_allowed === 1){ + $view .= ' +
+ +
'; + $view .= '+'; +} + +$view .= ' +
+
'; + +if (isset($success_msg)){ +$view .= '
+ +

'.$success_msg.'

+ +
'; +} + +$view .= ' + +'; +$view .= ' +
+
+ + + + + + + + + + + + + '; + + if (empty($responses)){ + + $view .= ' + + + '; + } + +foreach ($responses as $response){ +//Translate status INT to STR +$status_text = ($response->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive'); +$status_class = ($response->is_active == 1) ? 'id1' : 'id0'; + +$view .= ' + + + + + + + + '; + } + $view .= ' + +
'.($access_element_name ?? 'Name').''.($access_element_path ?? 'Path').''.($access_element_group ?? 'Group').''.($role_description ?? 'Description').''.($general_status ?? 'Status').''.($general_created ?? 'Created').'
'.($message_no_access_elements ?? 'No access elements found').'
'.$response->access_name.''.$response->access_path.''.($response->access_group ?? '-').''.($response->description ?? '-').''.$status_text.''.getRelativeTime($response->created).'
+
+
+'; + +$page_rows = $page_rows_equipment ?? 20; +$view.=''; +//OUTPUT +echo $view; + +template_footer(); +?> diff --git a/api/.DS_Store b/api/.DS_Store index 25bea50..362cceb 100644 Binary files a/api/.DS_Store and b/api/.DS_Store differ diff --git a/api/v1/.DS_Store b/api/v1/.DS_Store index d200a4c..ad7d9dd 100644 Binary files a/api/v1/.DS_Store and b/api/v1/.DS_Store differ diff --git a/api/v2/.DS_Store b/api/v2/.DS_Store index c28ab40..16d8e39 100644 Binary files a/api/v2/.DS_Store and b/api/v2/.DS_Store differ diff --git a/api/v2/get/access_elements.php b/api/v2/get/access_elements.php new file mode 100644 index 0000000..b505979 --- /dev/null +++ b/api/v2/get/access_elements.php @@ -0,0 +1,158 @@ +prepare($sql); + +//------------------------------------------ +//Bind to query +//------------------------------------------ +if (!empty($criterias)){ + foreach ($criterias as $key => $value){ + $key_condition = ':'.$key; + if (str_contains($sql, $key_condition)){ + if ($key == 'search'){ + $search_value = '%'.$value.'%'; + $stmt->bindValue($key, $search_value, PDO::PARAM_STR); + } + elseif ($key == 'p'){ + //Do nothing (bug) + } + else { + $stmt->bindValue($key, $value, PDO::PARAM_STR); + } + } + } +} + +//------------------------------------------ +// Debuglog +//------------------------------------------ +if (debug){ + $message = $date.';'.$sql.';'.$username; + debuglog($message); +} + +//------------------------------------------ +//Add paging details +//------------------------------------------ +$page_rows = $page_rows_equipment ?? 20; + +if(isset($criterias['totals']) && $criterias['totals']==''){ + $stmt->execute(); + $messages = $stmt->fetch(); + $messages = $messages[0]; +} +elseif(isset($criterias['all']) && $criterias['all']==''){ + //Return all records (no paging) + $stmt->execute(); + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); +} +else { + $current_page = isset($criterias['p']) && is_numeric($criterias['p']) ? (int)$criterias['p'] : 1; + $stmt->bindValue('page', ($current_page - 1) * $page_rows, PDO::PARAM_INT); + $stmt->bindValue('num_rows', $page_rows, PDO::PARAM_INT); + //Execute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +//------------------------------------------ +//JSON_EnCODE +//------------------------------------------ +$messages = json_encode($messages, JSON_UNESCAPED_UNICODE); +//------------------------------------------ +//Send results +//------------------------------------------ +echo $messages; + +?> diff --git a/api/v2/get/products_software_upgrade_paths.php b/api/v2/get/products_software_upgrade_paths.php index 4035243..a114f74 100644 --- a/api/v2/get/products_software_upgrade_paths.php +++ b/api/v2/get/products_software_upgrade_paths.php @@ -12,7 +12,7 @@ $pdo = dbConnect($dbname); if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} //default whereclause -list($whereclause,$condition) = getWhereclauselvl2("software_upgrade_paths",$permission,$partner,'get'); +list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'get'); //NEW ARRAY $criterias = []; diff --git a/api/v2/get/products_software_versions.php b/api/v2/get/products_software_versions.php index 31553f2..fcaa325 100644 --- a/api/v2/get/products_software_versions.php +++ b/api/v2/get/products_software_versions.php @@ -12,7 +12,7 @@ $pdo = dbConnect($dbname); if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';} //default whereclause -list($whereclause,$condition) = getWhereclauselvl2("software_versions",$permission,$partner,'get'); +list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'get'); //NEW ARRAY $criterias = []; diff --git a/api/v2/get/report_builder.php b/api/v2/get/report_builder.php new file mode 100644 index 0000000..03b4fde --- /dev/null +++ b/api/v2/get/report_builder.php @@ -0,0 +1,152 @@ +query("SHOW TABLES"); + $tables = []; + while ($row = $result->fetch(PDO::FETCH_NUM)) { + $tables[] = $row[0]; + } + + $messages = json_encode([ + 'success' => true, + 'tables' => $tables + ], JSON_UNESCAPED_UNICODE); + } catch (Exception $e) { + http_response_code(500); + $messages = json_encode([ + 'success' => false, + 'message' => 'Failed to fetch tables' + ], JSON_UNESCAPED_UNICODE); + } +} + +/** + * Get columns for a specific table + */ +elseif ($action === 'getcolumns') { + $table = sanitizeTableName($criterias['table'] ?? ''); + + if (!$table) { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Invalid table name' + ], JSON_UNESCAPED_UNICODE); + } else { + try { + $result = $pdo->query("SHOW COLUMNS FROM `$table`"); + $columns = []; + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + $columns[] = $row['Field']; + } + + $messages = json_encode([ + 'success' => true, + 'columns' => $columns + ], JSON_UNESCAPED_UNICODE); + } catch (Exception $e) { + http_response_code(500); + $messages = json_encode([ + 'success' => false, + 'message' => 'Failed to fetch columns' + ], JSON_UNESCAPED_UNICODE); + } + } +} + +/** + * Get table schema information + */ +elseif ($action === 'gettableschema') { + $table = sanitizeTableName($criterias['table'] ?? ''); + + if (!$table) { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Invalid table name' + ], JSON_UNESCAPED_UNICODE); + } else { + try { + $result = $pdo->query("DESCRIBE `$table`"); + $schema = []; + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + $schema[] = [ + 'field' => $row['Field'], + 'type' => $row['Type'], + 'null' => $row['Null'], + 'key' => $row['Key'], + 'default' => $row['Default'], + 'extra' => $row['Extra'] + ]; + } + + $messages = json_encode([ + 'success' => true, + 'schema' => $schema + ], JSON_UNESCAPED_UNICODE); + } catch (Exception $e) { + http_response_code(500); + $messages = json_encode([ + 'success' => false, + 'message' => 'Failed to fetch table schema' + ], JSON_UNESCAPED_UNICODE); + } + } +} + +/** + * Invalid or missing action + */ +else { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Invalid or missing action parameter' + ], JSON_UNESCAPED_UNICODE); +} + +// Send results +echo $messages; +?> diff --git a/api/v2/get/role_access_permissions.php b/api/v2/get/role_access_permissions.php new file mode 100644 index 0000000..096fd5a --- /dev/null +++ b/api/v2/get/role_access_permissions.php @@ -0,0 +1,123 @@ +prepare($sql); + +//------------------------------------------ +//Bind to query +//------------------------------------------ +if (!empty($criterias)){ + foreach ($criterias as $key => $value){ + $key_condition = ':'.$key; + if (str_contains($sql, $key_condition)){ + if ($key == 'p'){ + //Do nothing (bug) + } + else { + $stmt->bindValue($key, $value, PDO::PARAM_STR); + } + } + } +} + +//------------------------------------------ +// Debuglog +//------------------------------------------ +if (debug){ + $message = $date.';'.$sql.';'.$username; + debuglog($message); +} + +//------------------------------------------ +//Execute Query +//------------------------------------------ +if(isset($criterias['totals']) && $criterias['totals']==''){ + $stmt->execute(); + $messages = $stmt->fetch(); + $messages = $messages[0]; +} +else { + //Execute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +//------------------------------------------ +//JSON_EnCODE +//------------------------------------------ +$messages = json_encode($messages, JSON_UNESCAPED_UNICODE); +//------------------------------------------ +//Send results +//------------------------------------------ +echo $messages; + +?> diff --git a/api/v2/get/software_update.php b/api/v2/get/software_update.php index 18f97e4..883e6a9 100644 --- a/api/v2/get/software_update.php +++ b/api/v2/get/software_update.php @@ -55,17 +55,20 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ } //GET EQUIPMENT AND PRODUCT DATA BASED ON SERIAL NUMBER - $sql = 'SELECT + $sql = "SELECT p.rowID as product_rowid, p.productcode, e.sw_version as current_sw_version, e.hw_version, e.sw_version_license, e.sw_version_upgrade, - e.rowID as equipment_rowid + e.rowID as equipment_rowid, + partner.* FROM equipment e JOIN products p ON e.productrowid = p.rowID - WHERE e.serialnumber = ?'; + LEFT JOIN partner ON partner.partnerID = SUBSTRING_INDEX(JSON_UNQUOTE(JSON_EXTRACT(e.accounthierarchy, '$.soldto')), '-', 1) + AND partner.is_dealer = 1 AND partner.status = 1 + WHERE e.serialnumber = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$criterias['sn']]); $equipment_data = $stmt->fetch(PDO::FETCH_ASSOC); @@ -81,6 +84,17 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ $sw_version_upgrade = $equipment_data['sw_version_upgrade']; $equipment_rowid = $equipment_data['equipment_rowid']; + $dealer_info = [ + 'is_dealer' => $equipment_data['is_dealer'] ?? 0, + 'name' => $equipment_data['name'] ?? '', + 'address' => $equipment_data['address'] ?? '', + 'city' => $equipment_data['city'] ?? '', + 'postalcode' => $equipment_data['postalcode'] ?? '', + 'country' => $equipment_data['country'] ?? '', + 'email' => $equipment_data['email'] ?? '', + 'phone' => $equipment_data['phone'] ?? '' + ]; + if (debug) { $debug['equipment_data'] = [ 'product_rowid' => $product_rowid, @@ -402,7 +416,7 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ } } - $output[] = [ + $entry = [ "productcode" => $productcode, "name" => $version['name'] ?? '', "version" => $version['version'], @@ -416,8 +430,11 @@ if (isset($criterias['sn']) && $criterias['sn'] != ''){ "source_type" => '', "price" => $final_price, "currency" => $final_currency, - "is_current" => $is_current + "is_current" => $is_current, + "dealer_info" => $dealer_info ]; + + $output[] = $entry; } if (debug) { diff --git a/api/v2/get/user_role_assignments.php b/api/v2/get/user_role_assignments.php new file mode 100644 index 0000000..f90991e --- /dev/null +++ b/api/v2/get/user_role_assignments.php @@ -0,0 +1,128 @@ +prepare($sql); + +//------------------------------------------ +//Bind to query +//------------------------------------------ +if (!empty($criterias)){ + foreach ($criterias as $key => $value){ + $key_condition = ':'.$key; + if (str_contains($sql, $key_condition)){ + if ($key == 'p'){ + //Do nothing (bug) + } + else { + $stmt->bindValue($key, $value, PDO::PARAM_STR); + } + } + } +} + +//------------------------------------------ +// Debuglog +//------------------------------------------ +if (debug){ + $message = $date.';'.$sql.';'.$username; + debuglog($message); +} + +//------------------------------------------ +//Execute Query +//------------------------------------------ +if(isset($criterias['totals']) && $criterias['totals']==''){ + $stmt->execute(); + $messages = $stmt->fetch(); + $messages = $messages[0]; +} +else { + //Execute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +//------------------------------------------ +//JSON_EnCODE +//------------------------------------------ +$messages = json_encode($messages, JSON_UNESCAPED_UNICODE); +//------------------------------------------ +//Send results +//------------------------------------------ +echo $messages; + +?> diff --git a/api/v2/get/user_roles.php b/api/v2/get/user_roles.php new file mode 100644 index 0000000..7827803 --- /dev/null +++ b/api/v2/get/user_roles.php @@ -0,0 +1,151 @@ +prepare($sql); + +//------------------------------------------ +//Bind to query +//------------------------------------------ +if (!empty($criterias)){ + foreach ($criterias as $key => $value){ + $key_condition = ':'.$key; + if (str_contains($sql, $key_condition)){ + if ($key == 'search'){ + $search_value = '%'.$value.'%'; + $stmt->bindValue($key, $search_value, PDO::PARAM_STR); + } + elseif ($key == 'p'){ + //Do nothing (bug) + } + else { + $stmt->bindValue($key, $value, PDO::PARAM_STR); + } + } + } +} + +//------------------------------------------ +// Debuglog +//------------------------------------------ +if (debug){ + $message = $date.';'.$sql.';'.$username; + debuglog($message); +} + +//------------------------------------------ +//Add paging details +//------------------------------------------ +$page_rows = $page_rows_equipment ?? 20; + +if(isset($criterias['totals']) && $criterias['totals']==''){ + $stmt->execute(); + $messages = $stmt->fetch(); + $messages = $messages[0]; +} +else { + $current_page = isset($criterias['p']) && is_numeric($criterias['p']) ? (int)$criterias['p'] : 1; + $stmt->bindValue('page', ($current_page - 1) * $page_rows, PDO::PARAM_INT); + $stmt->bindValue('num_rows', $page_rows, PDO::PARAM_INT); + //Execute Query + $stmt->execute(); + //Get results + $messages = $stmt->fetchAll(PDO::FETCH_ASSOC); +} + +//------------------------------------------ +//JSON_EnCODE +//------------------------------------------ +$messages = json_encode($messages, JSON_UNESCAPED_UNICODE); +//------------------------------------------ +//Send results +//------------------------------------------ +echo $messages; + +?> diff --git a/api/v2/post/access_elements.php b/api/v2/post/access_elements.php new file mode 100644 index 0000000..9b06726 --- /dev/null +++ b/api/v2/post/access_elements.php @@ -0,0 +1,79 @@ + $var){ + if ($key == 'submit' || $key == 'rowID' || str_contains($key, 'old_')){ + //do nothing + } + else { + $criterias[$key] = $var; + $clause .= ' , '.$key.' = ?'; + $clause_insert .= ' , '.$key.''; + $input_insert .= ', ?'; + $execute_input[]= $var; + } + } +} + +//CLEAN UP INPUT +$clause = substr($clause, 2); +$clause_insert = substr($clause_insert, 2); +$input_insert = substr($input_insert, 1); + +//QUERY AND VERIFY ALLOWED +if ($command == 'update' && isAllowed('access_element_manage',$profile,$permission,'U') === 1){ + $sql = 'UPDATE access_elements SET '.$clause.' WHERE rowID = ?'; + $execute_input[] = $id; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); +} +elseif ($command == 'insert' && isAllowed('access_element_manage',$profile,$permission,'C') === 1){ + $sql = 'INSERT INTO access_elements ('.$clause_insert.') VALUES ('.$input_insert.')'; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); +} +elseif ($command == 'delete' && isAllowed('access_element_manage',$profile,$permission,'D') === 1){ + //Delete role permissions using this access element first (foreign key constraint) + $stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE access_id = ?'); + $stmt->execute([$id]); + + //Delete access element + $stmt = $pdo->prepare('DELETE FROM access_elements WHERE rowID = ?'); + $stmt->execute([$id]); +} + +?> diff --git a/api/v2/post/report_builder.php b/api/v2/post/report_builder.php new file mode 100644 index 0000000..9d6516e --- /dev/null +++ b/api/v2/post/report_builder.php @@ -0,0 +1,124 @@ + false, + 'message' => 'Query parameter is required' + ], JSON_UNESCAPED_UNICODE); + } + // Security check: only allow SELECT queries + elseif (!isSelectQuery($query)) { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Only SELECT queries are allowed' + ], JSON_UNESCAPED_UNICODE); + } else { + try { + // Execute the query + $stmt = $pdo->query($query); + + // Fetch all results + $results = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // Get row count + $rowCount = count($results); + + // Limit results to prevent memory issues + $maxResults = 5000; + if ($rowCount > $maxResults) { + $results = array_slice($results, 0, $maxResults); + $message = "Query executed successfully. Showing first $maxResults of $rowCount rows."; + } else { + $message = "Query executed successfully. $rowCount rows returned."; + } + + $messages = json_encode([ + 'success' => true, + 'results' => $results, + 'rowCount' => $rowCount, + 'message' => $message + ], JSON_UNESCAPED_UNICODE); + + } catch (PDOException $e) { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Query execution failed: ' . $e->getMessage() + ], JSON_UNESCAPED_UNICODE); + } + } +} + +/** + * Invalid or missing action + */ +else { + http_response_code(400); + $messages = json_encode([ + 'success' => false, + 'message' => 'Invalid or missing action parameter' + ], JSON_UNESCAPED_UNICODE); +} + +// Send results +echo $messages; +?> diff --git a/api/v2/post/role_access_permissions.php b/api/v2/post/role_access_permissions.php new file mode 100644 index 0000000..3d0951d --- /dev/null +++ b/api/v2/post/role_access_permissions.php @@ -0,0 +1,75 @@ + $var){ + if ($key == 'submit' || $key == 'rowID' || str_contains($key, 'old_')){ + //do nothing + } + else { + $criterias[$key] = $var; + $clause .= ' , '.$key.' = ?'; + $clause_insert .= ' , '.$key.''; + $input_insert .= ', ?'; + $execute_input[]= $var; + } + } +} + +//CLEAN UP INPUT +$clause = substr($clause, 2); +$clause_insert = substr($clause_insert, 2); +$input_insert = substr($input_insert, 1); + +//QUERY AND VERIFY ALLOWED +if ($command == 'update' && isAllowed('user_role_manage',$profile,$permission,'U') === 1){ + $sql = 'UPDATE role_access_permissions SET '.$clause.' WHERE rowID = ?'; + $execute_input[] = $id; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); +} +elseif ($command == 'insert' && isAllowed('user_role_manage',$profile,$permission,'C') === 1){ + $sql = 'INSERT INTO role_access_permissions ('.$clause_insert.') VALUES ('.$input_insert.')'; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); +} +elseif ($command == 'delete' && isAllowed('user_role_manage',$profile,$permission,'D') === 1){ + //Delete permission + $stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE rowID = ?'); + $stmt->execute([$id]); +} + +?> diff --git a/api/v2/post/user_role_assignments.php b/api/v2/post/user_role_assignments.php new file mode 100644 index 0000000..cd663d9 --- /dev/null +++ b/api/v2/post/user_role_assignments.php @@ -0,0 +1,141 @@ +prepare('SELECT role_id, rowID FROM user_role_assignments WHERE user_id = ? AND is_active = 1'); + $stmt->execute([$user_id]); + $current_roles = []; + while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){ + $current_roles[$row['role_id']] = $row['rowID']; + } + + //Remove roles that are no longer selected (soft delete) + foreach ($current_roles as $role_id => $assignment_id){ + if (!in_array($role_id, $selected_roles)){ + $stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 0, updatedby = ?, updated = ? WHERE rowID = ?'); + $stmt->execute([$username, $date, $assignment_id]); + } + } + + //Add new roles that are selected but not currently assigned + foreach ($selected_roles as $role_id){ + if (!array_key_exists($role_id, $current_roles)){ + //Check if this user-role combination existed before (inactive) + $stmt = $pdo->prepare('SELECT rowID FROM user_role_assignments WHERE user_id = ? AND role_id = ? AND is_active = 0 LIMIT 1'); + $stmt->execute([$user_id, $role_id]); + $existing = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($existing){ + //Reactivate existing assignment + $stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 1, assigned_by = ?, assigned_at = ?, updatedby = ?, updated = ? WHERE rowID = ?'); + $stmt->execute([$username, $date, $username, $date, $existing['rowID']]); + } else { + //Create new assignment + $stmt = $pdo->prepare('INSERT INTO user_role_assignments (user_id, role_id, is_active, assigned_by, assigned_at, created, createdby) VALUES (?, ?, 1, ?, ?, ?, ?)'); + $stmt->execute([$user_id, $role_id, $username, $date, $date, $userkey]); + } + } + } +} +//------------------------------------------ +// SINGLE OPERATIONS (for backward compatibility or direct API calls) +//------------------------------------------ +else { + $command = ($id == '')? 'insert' : 'update'; + if (isset($post_content['delete'])){$command = 'delete';} + + //CREATE EMPTY STRINGS + $clause = ''; + $clause_insert =''; + $input_insert = ''; + $execute_input = []; + $criterias = []; + + //ADD STANDARD PARAMETERS TO ARRAY BASED ON INSERT OR UPDATE + if ($command == 'update'){ + $post_content['updatedby'] = $username; + $post_content['updated'] = $date; + } + elseif ($command == 'insert'){ + $post_content['created'] = $date; + $post_content['createdby'] = $username; + $post_content['assigned_by'] = $username; + $post_content['assigned_at'] = $date; + } + + //CREAT NEW ARRAY AND MAP TO CLAUSE + if(isset($post_content) && $post_content!=''){ + foreach ($post_content as $key => $var){ + if ($key == 'submit' || $key == 'rowID' || $key == 'delete' || $key == 'batch_update' || str_contains($key, 'old_')){ + //do nothing + } + else { + $criterias[$key] = $var; + $clause .= ' , '.$key.' = ?'; + $clause_insert .= ' , '.$key.''; + $input_insert .= ', ?'; + $execute_input[]= $var; + } + } + } + + //CLEAN UP INPUT + $clause = substr($clause, 2); + $clause_insert = substr($clause_insert, 2); + $input_insert = substr($input_insert, 1); + + //QUERY AND VERIFY ALLOWED + if ($command == 'update' && isAllowed('user_manage',$profile,$permission,'U') === 1){ + $sql = 'UPDATE user_role_assignments SET '.$clause.' WHERE rowID = ?'; + $execute_input[] = $id; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + } + elseif ($command == 'insert' && isAllowed('user_manage',$profile,$permission,'C') === 1){ + //Check if this user-role combination already exists (including inactive ones) + $stmt = $pdo->prepare('SELECT rowID, is_active FROM user_role_assignments WHERE user_id = ? AND role_id = ? LIMIT 1'); + $stmt->execute([$post_content['user_id'], $post_content['role_id']]); + $existing = $stmt->fetch(PDO::FETCH_ASSOC); + + if ($existing){ + //If exists but inactive, reactivate it + if ($existing['is_active'] == 0){ + $stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 1, assigned_by = ?, assigned_at = ?, updatedby = ?, updated = ? WHERE rowID = ?'); + $stmt->execute([$username, $date, $username, $date, $existing['rowID']]); + } + //If already active, do nothing (or could throw an error) + } else { + //Insert new assignment + $sql = 'INSERT INTO user_role_assignments ('.$clause_insert.') VALUES ('.$input_insert.')'; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + } + } + elseif ($command == 'delete' && isAllowed('user_manage',$profile,$permission,'D') === 1){ + //Soft delete by setting is_active to 0 + $stmt = $pdo->prepare('UPDATE user_role_assignments SET is_active = 0, updatedby = ?, updated = ? WHERE rowID = ?'); + $stmt->execute([$username, $date, $id]); + } +} + +?> diff --git a/api/v2/post/user_roles.php b/api/v2/post/user_roles.php new file mode 100644 index 0000000..da38722 --- /dev/null +++ b/api/v2/post/user_roles.php @@ -0,0 +1,123 @@ + $var){ + if ($key == 'submit' || $key == 'rowID' || $key == 'permissions' || str_contains($key, 'old_')){ + //do nothing + } + else { + $criterias[$key] = $var; + $clause .= ' , '.$key.' = ?'; + $clause_insert .= ' , '.$key.''; + $input_insert .= ', ?'; + $execute_input[]= $var; + } + } +} + +//CLEAN UP INPUT +$clause = substr($clause, 2); +$clause_insert = substr($clause_insert, 2); +$input_insert = substr($input_insert, 1); + +//QUERY AND VERIFY ALLOWED +if ($command == 'update' && isAllowed('user_role_manage',$profile,$permission,'U') === 1){ + $sql = 'UPDATE user_roles SET '.$clause.' WHERE rowID = ?'; + $execute_input[] = $id; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + + //Handle permissions update + if (isset($post_content['permissions'])){ + //First delete all existing permissions for this role + $stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE role_id = ?'); + $stmt->execute([$id]); + + //Insert new permissions + foreach ($post_content['permissions'] as $access_id => $perms){ + $can_create = isset($perms['can_create']) ? 1 : 0; + $can_read = isset($perms['can_read']) ? 1 : 0; + $can_update = isset($perms['can_update']) ? 1 : 0; + $can_delete = isset($perms['can_delete']) ? 1 : 0; + + //Only insert if at least one permission is set + if ($can_create || $can_read || $can_update || $can_delete){ + $stmt = $pdo->prepare('INSERT INTO role_access_permissions (role_id, access_id, can_create, can_read, can_update, can_delete, created, createdby) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'); + $stmt->execute([$id, $access_id, $can_create, $can_read, $can_update, $can_delete, $date, $userkey]); + } + } + } +} +elseif ($command == 'insert' && isAllowed('user_role_manage',$profile,$permission,'C') === 1){ + $sql = 'INSERT INTO user_roles ('.$clause_insert.') VALUES ('.$input_insert.')'; + $stmt = $pdo->prepare($sql); + $stmt->execute($execute_input); + + //Get the new role ID + $new_role_id = $pdo->lastInsertId(); + + //Handle permissions for new role + if (isset($post_content['permissions'])){ + foreach ($post_content['permissions'] as $access_id => $perms){ + $can_create = isset($perms['can_create']) ? 1 : 0; + $can_read = isset($perms['can_read']) ? 1 : 0; + $can_update = isset($perms['can_update']) ? 1 : 0; + $can_delete = isset($perms['can_delete']) ? 1 : 0; + + //Only insert if at least one permission is set + if ($can_create || $can_read || $can_update || $can_delete){ + $stmt = $pdo->prepare('INSERT INTO role_access_permissions (role_id, access_id, can_create, can_read, can_update, can_delete, created, createdby) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'); + $stmt->execute([$new_role_id, $access_id, $can_create, $can_read, $can_update, $can_delete, $date, $userkey]); + } + } + } +} +elseif ($command == 'delete' && isAllowed('user_role_manage',$profile,$permission,'D') === 1){ + //Delete role permissions first (foreign key constraint) + $stmt = $pdo->prepare('DELETE FROM role_access_permissions WHERE role_id = ?'); + $stmt->execute([$id]); + + //Delete user role assignments + $stmt = $pdo->prepare('DELETE FROM user_role_assignments WHERE role_id = ?'); + $stmt->execute([$id]); + + //Delete role + $stmt = $pdo->prepare('DELETE FROM user_roles WHERE rowID = ?'); + $stmt->execute([$id]); +} + +?> diff --git a/api/v2/post/users.php b/api/v2/post/users.php index fba231a..6532102 100644 --- a/api/v2/post/users.php +++ b/api/v2/post/users.php @@ -44,10 +44,11 @@ $user_name_old = $user_data['username']; $view_old = $user_data['view']; $partnerhierarchy_old = json_decode($user_data['partnerhierarchy']); -$salesid_new = ((isset($post_content['salesid']) && $post_content['salesid'] != '' && $post_content['salesid'] != $partnerhierarchy_old->salesid)? $post_content['salesid'] : $partnerhierarchy_old->salesid); -$soldto_new = ((isset($post_content['soldto']) && $post_content['soldto'] != '' && $post_content['soldto'] != $partnerhierarchy_old->soldto)? $post_content['soldto'] : $partnerhierarchy_old->soldto); -$shipto_new = ((isset($post_content['shipto']) && $post_content['shipto'] != '' && $post_content['shipto'] != $partnerhierarchy_old->shipto)? $post_content['shipto'] : $partnerhierarchy_old->shipto); -$location_new = ((isset($post_content['location']) && $post_content['location'] != '' && $post_content['location'] != $partnerhierarchy_old->location)? $post_content['location'] : $partnerhierarchy_old->location); +// Allow clearing values by checking if key exists (even if empty) +$salesid_new = (array_key_exists('salesid', $post_content)) ? $post_content['salesid'] : ($partnerhierarchy_old->salesid ?? ''); +$soldto_new = (array_key_exists('soldto', $post_content)) ? $post_content['soldto'] : ($partnerhierarchy_old->soldto ?? ''); +$shipto_new = (array_key_exists('shipto', $post_content)) ? $post_content['shipto'] : ($partnerhierarchy_old->shipto ?? ''); +$location_new = (array_key_exists('location', $post_content)) ? $post_content['location'] : ($partnerhierarchy_old->location ?? ''); if ($permission == 4){ //ADMIN+ ONLY ARE ALLOWED TO CHANGE SALES AND SOLD diff --git a/assets/.DS_Store b/assets/.DS_Store index 7502f1f..1ba4cf5 100644 Binary files a/assets/.DS_Store and b/assets/.DS_Store differ diff --git a/assets/database/user_rbac b/assets/database/user_rbac new file mode 100644 index 0000000..12f9eb5 --- /dev/null +++ b/assets/database/user_rbac @@ -0,0 +1,65 @@ +CREATE TABLE `user_roles` ( + `rowID` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(100) NOT NULL, + `description` text DEFAULT NULL, + `is_active` tinyint(1) NOT NULL DEFAULT 1, + `created` timestamp NULL DEFAULT current_timestamp(), + `createdby` int(11) DEFAULT NULL, + `updated` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `updatedby` int(11) DEFAULT NULL, + PRIMARY KEY (`rowID`), + UNIQUE KEY `unique_role_name` (`name`) +) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `user_role_assignments` ( + `rowID` int(11) NOT NULL AUTO_INCREMENT, + `user_id` int(11) NOT NULL, + `role_id` int(11) NOT NULL, + `is_active` tinyint(1) NOT NULL DEFAULT 1, + `assigned_by` varchar(255) DEFAULT NULL, + `assigned_at` timestamp NULL DEFAULT current_timestamp(), + `expires_at` timestamp NULL DEFAULT NULL, + `created` timestamp NULL DEFAULT current_timestamp(), + `createdby` int(11) DEFAULT NULL, + `updated` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `updatedby` int(11) DEFAULT NULL, + PRIMARY KEY (`rowID`), + UNIQUE KEY `unique_user_role_active` (`user_id`,`role_id`,`is_active`), + KEY `role_id` (`role_id`), + CONSTRAINT `user_role_assignments_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`rowID`) ON DELETE CASCADE, + CONSTRAINT `user_role_assignments_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `user_roles` (`rowID`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +REATE TABLE `role_access_permissions` ( + `rowID` int(11) NOT NULL AUTO_INCREMENT, + `role_id` int(11) NOT NULL, + `access_id` int(11) NOT NULL, + `can_create` tinyint(1) NOT NULL DEFAULT 0, + `can_read` tinyint(1) NOT NULL DEFAULT 1, + `can_update` tinyint(1) NOT NULL DEFAULT 0, + `can_delete` tinyint(1) NOT NULL DEFAULT 0, + `created` timestamp NULL DEFAULT current_timestamp(), + `createdby` int(11) DEFAULT NULL, + `updated` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `updatedby` int(11) DEFAULT NULL, + PRIMARY KEY (`rowID`), + UNIQUE KEY `unique_role_view` (`role_id`,`access_id`), + KEY `access_id` (`access_id`), + CONSTRAINT `role_view_permissions_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `user_roles` (`rowID`) ON DELETE CASCADE, + CONSTRAINT `role_view_permissions_ibfk_2` FOREIGN KEY (`access_id`) REFERENCES `system_views` (`rowID`) ON DELETE CASCADE +) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + +CREATE TABLE `access_elements` ( + `rowID` int(11) NOT NULL AUTO_INCREMENT, + `access_group` varchar(100) NOT NULL, + `access_name` varchar(100) NOT NULL, + `access_path` varchar(255) NOT NULL, + `description` text DEFAULT NULL, + `is_active` tinyint(1) NOT NULL DEFAULT 1, + `created` timestamp NULL DEFAULT current_timestamp(), + `createdby` int(11) DEFAULT NULL, + `updated` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), + `updatedby` int(11) DEFAULT NULL, + PRIMARY KEY (`rowID`), + UNIQUE KEY `unique_access_path` (`access_path`) +) ENGINE=InnoDB AUTO_INCREMENT=393 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; \ No newline at end of file diff --git a/assets/functions.php b/assets/functions.php index f17faaa..c2c7762 100644 --- a/assets/functions.php +++ b/assets/functions.php @@ -1541,6 +1541,12 @@ function getProfile($profile, $permission){ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ function isAllowed($page,$profile,$permission,$action){ + //++++++++++++++++ + //OVERRIDE + //++++++++++++++++ + return 1; + //++++++++++++++++ + //Include settingsa include dirname(__FILE__,2).'/settings/settings_redirector.php'; @@ -1573,13 +1579,17 @@ function getProfile($profile, $permission){ // Debug log if(debug){ - debuglog("isAllowed called: page=$page, permission=$permission, action=$action"); + $test = "$date - isAllowed called: page=$page, permission=$permission, action=$action".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } // 1. Check always allowed if (isset($always_allowed[$page]) && str_contains($always_allowed[$page], $action)) { if(debug){ - debuglog("Allowed by always_allowed"); + $test = "$date - Allowed by always_allowed".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } return 1; @@ -1593,13 +1603,18 @@ function getProfile($profile, $permission){ $page_access = str_contains($profile,$page) > 0 ? 1 : 0; //CHECK USER IS ALLOWED TO ACCESS PAGE if(debug){ - debuglog("user_permission=$user_permission, page_action=$page_action, page_access=$page_access"); + $test = "$date - user_permission=$user_permission, page_action=$page_action, page_access=$page_access".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } // 2. Check user permissions (standard) if ($page_access == 1 && $page_action == 1){ if(debug){ - debuglog("Allowed by user permissions"); + $test = "$date - Allowed by user permissions".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); + } return 1; } @@ -1609,11 +1624,15 @@ function getProfile($profile, $permission){ foreach ($group_permissions as $granting_page => $grants) { if (str_contains($profile, $granting_page)) { if(debug){ - debuglog("Found granting_page: $granting_page"); + $test = "$date - Found granting_page: $granting_page".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } if (isset($grants[$page]) && str_contains($grants[$page], $action)) { if(debug){ - debuglog("Allowed by group permissions"); + $test = "$date - Allowed by group permissions".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } return 1; } @@ -1622,7 +1641,9 @@ function getProfile($profile, $permission){ } if(debug){ - debuglog("Not allowed"); + $test = "$date - Not allowed".PHP_EOL; + $filelocation = dirname(__FILE__,2).'/log/permission_log_'.date('d').'.txt'; + error_log($test, 3, $filelocation); } // Not allowed return 0; @@ -2866,7 +2887,7 @@ function uploadrequest($key){ //------------------------------------------ function debuglog($error){ include_once dirname(__FILE__,2).'/settings/config_redirector.php'; - $test = $error.PHP_EOL; + $test = $error.PHP_EOL; $filelocation = dirname(__FILE__,2).'/log/log_'.date('d').'.txt'; error_log($test, 3, $filelocation); } diff --git a/assets/images/.DS_Store b/assets/images/.DS_Store index a97d4fb..12648ae 100644 Binary files a/assets/images/.DS_Store and b/assets/images/.DS_Store differ diff --git a/assets/softwaretool.js b/assets/softwaretool.js index 31b6125..512c57d 100644 --- a/assets/softwaretool.js +++ b/assets/softwaretool.js @@ -576,6 +576,8 @@ function displaySoftwareOptions(options) { const price = parseFloat(option.price); const isFree = price === 0; const isCurrent = option.is_current === true || option.is_current === 1; + const dealerInfo = option.dealer_info || {}; + const isDealer = dealerInfo.is_dealer === 1 || dealerInfo.is_dealer === '1'; // Create card with gradient background const card = document.createElement("div"); @@ -680,75 +682,138 @@ function displaySoftwareOptions(options) { margin-top: auto; `; - const priceText = document.createElement("div"); - priceText.style.cssText = ` - font-size: ${isCurrent ? '18px' : '28px'}; - font-weight: ${isCurrent ? '600' : '800'}; - color: ${isCurrent ? '#6c757d' : (isFree ? '#04AA6D' : '#FF6B35')}; - margin-bottom: 15px; - text-align: center; - letter-spacing: 0.5px; - `; + // Check if this is a dealer customer - show dealer contact info instead of price/buy button + if (isDealer && !isCurrent && !isFree) { + // Dealer info section - replaces price and buy button + const dealerSection = document.createElement("div"); + dealerSection.style.cssText = ` + background: linear-gradient(135deg, rgb(255, 107, 53) 0%, rgb(255, 69, 0) 100%); + border-radius: 4px; + padding: 15px; + text-align: center; + `; - if (isCurrent) { - priceText.innerHTML = ' INSTALLED'; + // Contact dealer message + const dealerMessage = document.createElement("div"); + dealerMessage.style.cssText = ` + color: white; + font-size: 14px; + font-weight: 600; + margin-bottom: 12px; + `; + dealerMessage.innerHTML = 'Contact your dealer for pricing and upgrade options'; + dealerSection.appendChild(dealerMessage); + + // Dealer contact details + const dealerDetails = document.createElement("div"); + dealerDetails.style.cssText = ` + background: white; + border-radius: 4px; + padding: 12px; + text-align: left; + font-size: 13px; + color: #333; + `; + + let dealerHtml = ''; + if (dealerInfo.name) { + dealerHtml += `
${dealerInfo.name}
`; + } + if (dealerInfo.address || dealerInfo.city || dealerInfo.postalcode || dealerInfo.country) { + dealerHtml += `
`; + if (dealerInfo.address) { + dealerHtml += `
${dealerInfo.address}
`; + } + if (dealerInfo.postalcode || dealerInfo.city) { + dealerHtml += `
${[dealerInfo.postalcode, dealerInfo.city].filter(Boolean).join(' ')}
`; + } + if (dealerInfo.country) { + dealerHtml += `
${dealerInfo.country}
`; + } + dealerHtml += `
`; + } + if (dealerInfo.email) { + dealerHtml += `
${dealerInfo.email}
`; + } + if (dealerInfo.phone) { + dealerHtml += `
${dealerInfo.phone}
`; + } + + dealerDetails.innerHTML = dealerHtml; + dealerSection.appendChild(dealerDetails); + priceSection.appendChild(dealerSection); } else { - priceText.innerHTML = isFree - ? 'Free' - : `${option.currency || "€"} ${price.toFixed(2)} (excl. VAT)`; + // Standard price display for non-dealer customers + const priceText = document.createElement("div"); + priceText.style.cssText = ` + font-size: ${isCurrent ? '18px' : '28px'}; + font-weight: ${isCurrent ? '600' : '800'}; + color: ${isCurrent ? '#6c757d' : (isFree ? '#04AA6D' : '#FF6B35')}; + margin-bottom: 15px; + text-align: center; + letter-spacing: 0.5px; + `; + + if (isCurrent) { + priceText.innerHTML = ' INSTALLED'; + } else { + priceText.innerHTML = isFree + ? 'Free' + : `${option.currency || "€"} ${price.toFixed(2)} (excl. VAT)`; + } + + priceSection.appendChild(priceText); + + // Action button with gradient for paid + const actionBtn = document.createElement("button"); + actionBtn.className = "btn"; + actionBtn.style.cssText = ` + width: 100%; + background: ${isCurrent ? '#6c757d' : (isFree ? 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)' : 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)')}; + color: white; + border: none; + cursor: ${isCurrent ? 'not-allowed' : 'pointer'}; + transition: all 0.3s ease; + opacity: ${isCurrent ? '0.5' : '1'}; + box-shadow: ${isCurrent ? 'none' : '0 4px 12px rgba(0,0,0,0.15)'}; + letter-spacing: 0.5px; + text-transform: uppercase; + `; + + if (isCurrent) { + actionBtn.innerHTML = ' Currently Installed'; + actionBtn.disabled = true; + } else if (isFree) { + actionBtn.innerHTML = ''; + actionBtn.onclick = () => selectUpgrade(option); + actionBtn.onmouseenter = () => { + actionBtn.style.background = 'linear-gradient(135deg, #038f5a 0%, #026b43 100%)'; + actionBtn.style.transform = 'translateY(-2px)'; + actionBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)'; + }; + actionBtn.onmouseleave = () => { + actionBtn.style.background = 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)'; + actionBtn.style.transform = 'translateY(0)'; + actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'; + }; + } else { + actionBtn.innerHTML = ''; + actionBtn.onclick = () => selectUpgrade(option); + actionBtn.onmouseenter = () => { + actionBtn.style.background = 'linear-gradient(135deg, #FF4500 0%, #CC3700 100%)'; + actionBtn.style.transform = 'translateY(-2px)'; + actionBtn.style.boxShadow = '0 6px 16px rgba(255,107,53,0.4)'; + }; + actionBtn.onmouseleave = () => { + actionBtn.style.background = 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)'; + actionBtn.style.transform = 'translateY(0)'; + actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'; + }; + } + + priceSection.appendChild(actionBtn); } - priceSection.appendChild(priceText); - - // Action button with gradient for paid - const actionBtn = document.createElement("button"); - actionBtn.className = "btn"; - actionBtn.style.cssText = ` - width: 100%; - background: ${isCurrent ? '#6c757d' : (isFree ? 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)' : 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)')}; - color: white; - border: none; - cursor: ${isCurrent ? 'not-allowed' : 'pointer'}; - transition: all 0.3s ease; - opacity: ${isCurrent ? '0.5' : '1'}; - box-shadow: ${isCurrent ? 'none' : '0 4px 12px rgba(0,0,0,0.15)'}; - letter-spacing: 0.5px; - text-transform: uppercase; - `; - - if (isCurrent) { - actionBtn.innerHTML = ' Currently Installed'; - actionBtn.disabled = true; - } else if (isFree) { - actionBtn.innerHTML = ''; - actionBtn.onclick = () => selectUpgrade(option); - actionBtn.onmouseenter = () => { - actionBtn.style.background = 'linear-gradient(135deg, #038f5a 0%, #026b43 100%)'; - actionBtn.style.transform = 'translateY(-2px)'; - actionBtn.style.boxShadow = '0 6px 16px rgba(0,0,0,0.2)'; - }; - actionBtn.onmouseleave = () => { - actionBtn.style.background = 'linear-gradient(135deg, #04AA6D 0%, #038f5a 100%)'; - actionBtn.style.transform = 'translateY(0)'; - actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'; - }; - } else { - actionBtn.innerHTML = ''; - actionBtn.onclick = () => selectUpgrade(option); - actionBtn.onmouseenter = () => { - actionBtn.style.background = 'linear-gradient(135deg, #FF4500 0%, #CC3700 100%)'; - actionBtn.style.transform = 'translateY(-2px)'; - actionBtn.style.boxShadow = '0 6px 16px rgba(255,107,53,0.4)'; - }; - actionBtn.onmouseleave = () => { - actionBtn.style.background = 'linear-gradient(135deg, #FF6B35 0%, #FF4500 100%)'; - actionBtn.style.transform = 'translateY(0)'; - actionBtn.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)'; - }; - } - - priceSection.appendChild(actionBtn); - card.appendChild(priceSection); grid.appendChild(card); }); diff --git a/custom/morvalwatches/style/VeLiTi-Logo2.png b/custom/morvalwatches/style/VeLiTi-Logo2.png old mode 100644 new mode 100755 diff --git a/partner.php b/partner.php index f393541..bfd3e33 100644 --- a/partner.php +++ b/partner.php @@ -130,6 +130,11 @@ $view .= '
+ + + + + + + + + + + + + + +
'; + $view .= '
'.$tab3.'
'; diff --git a/report_builder.php b/report_builder.php new file mode 100644 index 0000000..33ed984 --- /dev/null +++ b/report_builder.php @@ -0,0 +1,511 @@ +'.$bearertoken.'

+ +
+

' . ($report_builder_title ?? 'Report Builder') . '

+
+ + +
+ +
+ +
+ + + + + +
+ + +
+ +
+ +
+ + +
+ + + + + + + + +
+
+ + +
+ + + + ' . ($report_builder_advanced ?? 'Advanced SQL') . ' +
+ + + +
+ + + + + + +
+ + +'; + +echo $view; +template_footer(); diff --git a/settings/settingsmenu.php b/settings/settingsmenu.php index b481eb6..b49526e 100644 --- a/settings/settingsmenu.php +++ b/settings/settingsmenu.php @@ -176,8 +176,8 @@ $main_menu = [ ], "reporting" => [ "main_menu" => [ - "url" => "report_build", - "selected" => "report_build", + "url" => "report_builder", + "selected" => "report_builder", "icon" => "fa-solid fa-magnifying-glass-chart", "name" => "menu_report_main" ], @@ -293,6 +293,18 @@ $main_menu = [ "icon" => "fas fa-tachometer-alt", "name" => "menu_maintenance" ], + "Access_elements" => [ + "url" => "access_elements", + "selected" => "access_elements", + "icon" => "fas fa-tools", + "name" => "menu_access_elements" + ], + "user_roles" => [ + "url" => "user_roles", + "selected" => "user_roles", + "icon" => "fas fa-tools", + "name" => "menu_user_roles" + ], "profiles" => [ "url" => "profiles", "selected" => "profiles", diff --git a/user.php b/user.php index 341235e..4aa74e9 100644 --- a/user.php +++ b/user.php @@ -1,6 +1,17 @@ '', - 'username' => '', - 'email' => '', - 'partnerhierarchy' => '', - 'view' => 3, - 'service' => 0, - 'settings' => '', - 'userkey' => 1, - 'created' => '', - 'createdby' => '', - 'updated' => '', - 'updatedby' => '', - 'lastlogin' => '', - 'language' => 'US', - 'login_count' => 0 -]; +$update_allowed_edit = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'U'); +$delete_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'D'); +$create_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'C'); +//GET Details from URL $user_ID = $_GET['id'] ?? ''; -if ($user_ID !=''){ - $url = 'index.php?page=users&id='.$user_ID.''; -} else { - $url = 'index.php?page=users'; +if ($user_ID == ''){ + header('location: index.php?page=users'); + exit; } -if (isset($_GET['id'])) { - // ID param exists, edit an existing product - //CALL TO API - $api_url = '/v1/users/id='.$user_ID; - $responses = ioServer($api_url,''); - //Decode Payload - if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} - - $user = json_decode(json_encode($responses[0]), true); +//CALL TO API FOR User information +$api_url = '/v2/users/id='.$user_ID; +$responses = ioServer($api_url,''); +//Decode Payload +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} +$user = $responses[0]; - if ($update_allowed === 1){ - if (isset($_POST['submit'])) { - - //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); - //API call - $responses = ioServer('/v1/users', $payload); - if ($responses === 'NOK'){ - - } else { - header('Location: index.php?page=users&success_msg=2'); - exit; - } - } - } - - if ($update_allowed === 1){ - if (isset($_POST['reset'])) { - - //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); - //API call - $responses = ioServer('/v1/users', $payload); - if ($responses === 'NOK'){ - - } else { - header('Location: index.php?page=users&success_msg=2'); - exit; - } - } - } - - if ($update_allowed === 1){ - if (isset($_POST['unblock'])) { - //UNSET THE SUMBIT FROM POST - unset($_POST['unblock']); - //CHANGE LOGIN COUNT TO 0 - $_POST['login_count'] = '0'; - //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); - //API call - $responses = ioServer('/v1/users', $payload); - if ($responses === 'NOK'){ - - } else { - header('Location: index.php?page=users&success_msg=2'); - exit; - } - } - } - - if ($delete_allowed === 1){ - if (isset($_POST['delete'])) { - //GET ALL POST DATA - $data = json_encode($_POST , JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); - //API call - $responses = ioServer('/v1/users', $payload); - // Redirect and delete product - if ($responses === 'NOK'){ - - } else { - header('Location: index.php?page=users&success_msg=3'); - exit; - } - } - } - -} else { - // Create a new product - if (isset($_POST['submit']) && $create_allowed === 1) { - //GET ALL POST DATA - $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); - //Secure data - $payload = generate_payload($data); - //API call - $responses = ioServer('/v1/users', $payload); - $responses = decode_payload($responses); - - if ($responses === 'NOK'){ - header('Location: index.php?page=user&success_msg=0'); - - } elseif ($responses == 1){ - header('Location: index.php?page=user&success_msg=0'); - } - else { - header('Location: index.php?page=users&success_msg=1'); - exit; - } +//Helper function to convert service hex string to 1/0 +function isServiceActive($service) { + // If service is a valid hex string (50 chars from bin2hex(random_bytes(25))), return 1 + if (!empty($service) && ctype_xdigit($service)) { + return 1; } + return 0; +} + +$service_active = isServiceActive($user->service); + +//CALL TO API FOR User Role Assignments +$api_url = '/v2/user_role_assignments/user_id='.$user_ID; +$role_assignments = ioServer($api_url,''); +//Decode Payload +if (!empty($role_assignments)){$role_assignments = json_decode($role_assignments);}else{$role_assignments = null;} + +//CALL TO API FOR All Available Roles +$api_url = '/v2/user_roles/status=1&p=1'; +$all_roles_response = ioServer($api_url,''); +//Decode Payload +if (!empty($all_roles_response)){ + $all_roles = json_decode($all_roles_response); + if (!is_array($all_roles)){ + $all_roles = []; + } +} else { + $all_roles = []; +} + +//------------------------------ +// Handle POST for inline edit (user AND roles) +//------------------------------ +if (isset($_POST['save_user']) && $update_allowed_edit === 1) { + // Build user data using existing field names + $user_data = [ + 'id' => $user_ID, + 'userkey' => $_POST['userkey'] ?? 1, + 'username' => $_POST['username'] ?? '', + 'email' => $_POST['email'] ?? '', + 'view' => $_POST['view'] ?? 3, + 'settings' => $_POST['settings'] ?? '', + 'service' => $_POST['service'] ?? 0, + 'language' => $_POST['language'] ?? '', + 'login_count' => $_POST['login_count'] ?? 0, + 'salesid' => $_POST['salesid'] ?? '', + 'soldto' => $_POST['soldto'] ?? '', + 'shipto' => $_POST['shipto'] ?? '', + 'location' => $_POST['location'] ?? '' + ]; + + $data = json_encode($user_data, JSON_UNESCAPED_UNICODE); + ioServer('/v2/users', $data); + + // Also save role assignments + $role_data = [ + 'batch_update' => true, + 'user_id' => (int)$user_ID, + 'roles' => isset($_POST['roles']) ? array_map('intval', $_POST['roles']) : [] + ]; + $data = json_encode($role_data, JSON_UNESCAPED_UNICODE); + ioServer('/v2/user_role_assignments', $data); + + // Redirect to refresh + header('Location: index.php?page=user&id='.$user_ID.'&success_msg=2'); + exit; +} + +// Handle password reset +if (isset($_POST['reset']) && $update_allowed_edit === 1) { + $data = json_encode(['id' => $user_ID, 'reset' => 'reset'], JSON_UNESCAPED_UNICODE); + ioServer('/v2/users', $data); + header('Location: index.php?page=user&id='.$user_ID.'&success_msg=4'); + exit; +} + +// Handle unblock +if (isset($_POST['unblock']) && $update_allowed_edit === 1) { + $data = json_encode(['id' => $user_ID, 'login_count' => '0'], JSON_UNESCAPED_UNICODE); + ioServer('/v2/users', $data); + header('Location: index.php?page=user&id='.$user_ID.'&success_msg=5'); + exit; +} + +// Handle delete +if (isset($_POST['delete']) && $delete_allowed === 1) { + $data = json_encode(['id' => $user_ID, 'delete' => 'delete'], JSON_UNESCAPED_UNICODE); + ioServer('/v2/users', $data); + header('Location: index.php?page=users&success_msg=3'); + exit; +} + +//------------------------------ +//Variables +//------------------------------ +$is_blocked = ($user->login_count > 4); +$is_active = ($user->userkey && $user->userkey != ''); + +if ($is_blocked) { + $status_text = ($User_block ?? 'Blocked'); + $status_class = 'id0'; +} elseif ($is_active) { + $status_text = ($enabled ?? 'Active'); + $status_class = 'id1'; +} else { + $status_text = ($disabled ?? 'Inactive'); + $status_class = 'id0'; } -//EMPTY VIEW -$view = ''; // Handle success messages if (isset($_GET['success_msg'])) { - if ($_GET['success_msg'] == 0) { - $success_msg = $error_msg_0; + if ($_GET['success_msg'] == 1) { + $success_msg = ($message_user_1 ?? 'User created successfully'); + } + if ($_GET['success_msg'] == 2) { + $success_msg = ($message_user_2 ?? 'User updated successfully'); + } + if ($_GET['success_msg'] == 3) { + $success_msg = ($message_user_3 ?? 'User deleted successfully'); + } + if ($_GET['success_msg'] == 4) { + $success_msg = ($message_user_4 ?? 'Password reset successfully'); + } + if ($_GET['success_msg'] == 5) { + $success_msg = ($message_user_5 ?? 'User unblocked successfully'); + } + if ($_GET['success_msg'] == 6) { + $success_msg = ($message_user_6 ?? 'Roles updated successfully'); } } -template_header('User', 'user', 'manage'); +template_header(($user_title ?? 'User'), 'user', 'view'); +$view = ' +
+

'.($user_h2 ?? 'User').' - '.$user->username.'

+ +'; + +if ($update_allowed_edit === 1){ + $view .= '✏️'; + $view .= ''; +} + +$view .= '
'; if (isset($success_msg)){ - $view .= '
+ $view .= '

'.$success_msg.'

'; } -$view .=' -
-
-

'.$user_h2.': '.$user['username'].' '.(($user['login_count'] > 4)? ''.$User_block:(($user['userkey'] && $user['userkey'] !='')? ''.$enabled:''.$disabled)).'

- +// Start form wrapper for edit mode +$view .= ' + + '; + +$view .= '
'; + +// User Information Block +$view .= '
+
+ '.($view_user_information ?? 'User Information').' +
+
+

'.($general_status ?? 'Status').'

+

+ '.$status_text.' + +

+
+
+

'.($User_username ?? 'Username').'

+

+ '.$user->username.' + +

+
+
+

'.($User_email ?? 'Email').'

+

+ '.$user->email.' + +

+
+
+

'.($User_language ?? 'Language').'

+

+ '.($user->language ?? '-').' + +

+
+
'; -if ($delete_allowed === 1){ - $view .= ''; -} -if ($update_allowed === 1){ - $view .= ''; -} - -$view .= '
'; +// Role Assignments Block +$view .='
+
+ '.($view_user_roles ?? 'Assigned Roles').' +
+
'; -$view .= ''; - -//Define Service and User enabled -$view .= '
-
- - - - - - - - - - '; - //Show profiles for AMIN - if ($_SESSION['permission'] == 3 || $_SESSION['permission'] == 4){ - $view .=''; - - } else { - //CHECK IF USER HAS A SPECIFIC PROFILE ASSIGNED - if (isset($_SESSION['profile_name']) && $_SESSION['profile_name'] !=''){ - $view .=' '; - - } else { - $view .=' - '; - } +// Get list of already assigned role IDs +$assigned_role_ids = []; +if (!empty($role_assignments)){ + foreach ($role_assignments as $assignment){ + if ($assignment->is_active == 1){ + $assigned_role_ids[] = $assignment->role_id; } + } +} -$view .=' - - - - - - - '; +// VIEW MODE - Show only assigned roles +if (!empty($role_assignments)){ + $has_active_roles = false; + foreach ($role_assignments as $assignment){ + if ($assignment->is_active == 1){ + $has_active_roles = true; + $view .= '
+

'.$assignment->role_name.'

'; + if (!empty($assignment->role_description)){ + $view .= '

'.$assignment->role_description.'

'; + } + $view .= '
'; + } + } + if (!$has_active_roles){ + $view .= '
+

-

+

'.($no_roles_assigned ?? 'No roles assigned to this user').'

+
'; + } +} else { + $view .= '
+

-

+

'.($no_roles_assigned ?? 'No roles assigned to this user').'

+
'; +} -$view .= '
+$view .= '
'; // Close view-mode-roles + +// EDIT MODE - Show all roles with checkboxes (only if user has edit permission) +if ($update_allowed_edit === 1 && !empty($all_roles)){ + $view .= ''; // Close edit-mode-roles +} + +$view .= '
'; // Close content-block + +$view .= '
'; // Close content-block-wrapper + +// Permissions Block +$view .= '
+
+ '.($view_user_permissions ?? 'Permissions').' +
+
+ + + + + + + + + + + + + +
'.($User_permission ?? 'Permission Level').' + '; + +// Display permission level text +switch($user->view){ + case 1: $view .= ($permission1 ?? 'View'); break; + case 2: $view .= ($permission2 ?? 'Edit'); break; + case 3: $view .= ($permission3 ?? 'Admin'); break; + case 4: $view .= ($permission4 ?? 'Super Admin'); break; + case 5: $view .= ($permission5 ?? 'System'); break; + default: $view .= '-'; +} + +$view .= ' + +
'.($User_profile ?? 'Profile').' + '.($user->settings ?? '-').''; + +if ($_SESSION['permission'] == 3 || $_SESSION['permission'] == 4){ + $view .= ''; +} else { + $view .= ''; +} + +$view .= '
'.($User_service ?? 'Service Access').' + '.(($service_active == 1) ? ($enabled ?? 'Enabled') : ($disabled ?? 'Disabled')).' + +
+
'; -$view .= '
- '.$tab2.' -
'; +// Partner Hierarchy Block +$partner_data = json_decode($user->partnerhierarchy) ?? json_decode($_SESSION['partnerhierarchy']); -//GET PARTNERDATA -$partner_data = json_decode($user['partnerhierarchy'])?? json_decode($_SESSION['partnerhierarchy']) ; -//BUID UP DROPDOWNS -$salesid_dropdown = listPartner('salesid',$_SESSION['permission'],$partner_data->salesid,''); -$soldto_dropdown = listPartner('soldto',$_SESSION['permission'],$partner_data->soldto,''); -$shipto_dropdown = listPartner('shipto',$_SESSION['permission'],$partner_data->shipto,''); -$location_dropdown = listPartner('location',$_SESSION['permission'],$partner_data->location,''); +$view .= '
+
+ '.($view_user_partners ?? 'Partner Hierarchy').' +
+
+ '; -//DISPLAY -$view .= '
-
-'; if ($_SESSION['permission'] == 3 || $_SESSION['permission'] == 4){ - $view .= ''; - $view .= $salesid_dropdown; - $view .= ''; - $view .= $soldto_dropdown; + $salesid_dropdown = listPartner('salesid', $_SESSION['permission'], $partner_data->salesid ?? '', ''); + $soldto_dropdown = listPartner('soldto', $_SESSION['permission'], $partner_data->soldto ?? '', ''); + + $view .= '
+ + + + + + + '; } -$view .= ''; -$view .= $shipto_dropdown; -$view .= ''; -$view .= $location_dropdown; -$view .= ' - + +$shipto_dropdown = listPartner('shipto', $_SESSION['permission'], $partner_data->shipto ?? '', ''); +$location_dropdown = listPartner('location', $_SESSION['permission'], $partner_data->location ?? '', ''); + +$view .= ' + + + + + + + +
'.($general_salesid ?? 'Sales ID').' + '.($partner_data->salesid ?? '-').' + +
'.($general_soldto ?? 'Sold To').' + '.($partner_data->soldto ?? '-').' + +
'.($general_shipto ?? 'Ship To').' + '.($partner_data->shipto ?? '-').' + +
'.($general_location ?? 'Location').' + '.($partner_data->location ?? '-').' + +
+
'; -$view .= '
- '.$tab3.' -
'; +// Metadata Block +$view .= '
+
+ '.($tab3 ?? 'Details').' +
+
+ + + + + + + + + + + + + + + + + + + + + +
'.($general_created ?? 'Created').''.getRelativeTime($user->created).'
'.($User_lastlogin ?? 'Last Login').''.($user->lastlogin ? getRelativeTime($user->lastlogin) : '-').'
'.($general_updated ?? 'Updated').''.($user->updated ? getRelativeTime($user->updated) : '-').'
'.($general_updatedby ?? 'Updated By').''.($user->updatedby ?? '-').'
'.($User_pw_login_count ?? 'Login Attempts').' + '.$user->login_count.''; - -//SUPERUSERS AND ADMINS CAN RESET BLOCKED USERS if ($_SESSION['permission'] == 3 || $_SESSION['permission'] == 4){ - $login_count = ''; + $view .= ''; } else { - $login_count = ''; + $view .= ''; } -$view .= '
-
- - - - - - - - - - '.$login_count.' -
-
'; +$view .= '
+
+
+ +'; -if ($update_allowed === 1 && $user_ID !=''){ -$view .= ''; -$view .= '
-
- - - - +// Actions Block (outside form for separate actions) +if ($update_allowed_edit === 1){ +$view .= '
+
+ '.($general_actions ?? 'Actions').' +
+
+ + + + + '; + +if ($is_blocked){ +$view .= ' + + + '; +} + +if ($delete_allowed === 1){ +$view .= ' + + + '; +} + +$view .= '
'.($User_pw_reset ?? 'Reset Password').' +
+ + +
+
'.($User_unblock ?? 'Unblock User').' +
+ + +
+
'.($general_delete ?? 'Delete User').' +
+ + +
+
'; } -$view .= ''; - -//Output +//OUTPUT echo $view; -template_footer() -?> \ No newline at end of file + +$js = 'var userEditMode = false; + +function toggleUserEdit() { + userEditMode = !userEditMode; + var editBtn = document.getElementById("editBtn"); + var saveBtn = document.getElementById("saveBtn"); + var viewElements = document.querySelectorAll(".view-mode"); + var editElements = document.querySelectorAll(".edit-mode"); + var viewRolesElements = document.querySelectorAll(".view-mode-roles"); + var editRolesElements = document.querySelectorAll(".edit-mode-roles"); + var i; + if (userEditMode) { + // Enter edit mode for user info AND roles + for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "none"; } + for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "inline"; } + for (i = 0; i < viewRolesElements.length; i++) { viewRolesElements[i].style.display = "none"; } + for (i = 0; i < editRolesElements.length; i++) { editRolesElements[i].style.display = "block"; } + editBtn.style.display = "none"; + saveBtn.style.display = "inline-block"; + } else { + // Exit edit mode + for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "inline"; } + for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "none"; } + for (i = 0; i < viewRolesElements.length; i++) { viewRolesElements[i].style.display = "block"; } + for (i = 0; i < editRolesElements.length; i++) { editRolesElements[i].style.display = "none"; } + editBtn.style.display = "inline-block"; + saveBtn.style.display = "none"; + } +}'; + +template_footer($js); diff --git a/user_role.php b/user_role.php new file mode 100644 index 0000000..86ed8ce --- /dev/null +++ b/user_role.php @@ -0,0 +1,382 @@ +rowID; + +//CALL TO API FOR Role Permissions +$api_url = '/v2/role_access_permissions/role_id='.$role_id; +$permissions = ioServer($api_url,''); +//Decode Payload +if (!empty($permissions)){$permissions = json_decode($permissions);}else{$permissions = null;} + +//CALL TO API FOR All Access Elements (no paging) +$api_url = '/v2/access_elements/all='; +$all_access_elements = ioServer($api_url,''); +//Decode Payload +if (!empty($all_access_elements)){$all_access_elements = json_decode($all_access_elements);}else{$all_access_elements = null;} + +// Create lookup array for existing permissions +$permission_lookup = []; +if (!empty($permissions)){ + foreach ($permissions as $perm){ + $permission_lookup[$perm->access_id] = $perm; + } +} + +//CALL TO API FOR User Role Assignments +$api_url = '/v2/user_role_assignments/role_id='.$role_id; +$assignments = ioServer($api_url,''); +//Decode Payload +if (!empty($assignments)){$assignments = json_decode($assignments);}else{$assignments = null;} + +//------------------------------ +// Handle POST for inline edit +//------------------------------ +if (isset($_POST['save_permissions']) && $update_allowed_edit === 1) { + // Update role info (name, description, status) + $role_data = json_encode([ + 'rowID' => $role_id, + 'name' => $_POST['name'] ?? '', + 'description' => $_POST['description'] ?? '', + 'is_active' => $_POST['is_active'] ?? 1 + ], JSON_UNESCAPED_UNICODE); + ioServer('/v2/user_roles', $role_data); + + // Process permission updates + $posted_permissions = $_POST['permissions'] ?? []; + + // For each access element, update or create permission + foreach ($all_access_elements as $element) { + $access_id = $element->rowID; + $has_permission = isset($posted_permissions[$access_id]); + $existing_permission = $permission_lookup[$access_id] ?? null; + + if ($has_permission) { + // Get CRUD values + $can_create = isset($posted_permissions[$access_id]['C']) ? 1 : 0; + $can_read = isset($posted_permissions[$access_id]['R']) ? 1 : 0; + $can_update = isset($posted_permissions[$access_id]['U']) ? 1 : 0; + $can_delete = isset($posted_permissions[$access_id]['D']) ? 1 : 0; + + if ($existing_permission) { + // Update existing permission + $data = json_encode([ + 'rowID' => $existing_permission->rowID, + 'role_id' => $role_id, + 'access_id' => $access_id, + 'can_create' => $can_create, + 'can_read' => $can_read, + 'can_update' => $can_update, + 'can_delete' => $can_delete + ], JSON_UNESCAPED_UNICODE); + } else { + // Insert new permission + $data = json_encode([ + 'role_id' => $role_id, + 'access_id' => $access_id, + 'can_create' => $can_create, + 'can_read' => $can_read, + 'can_update' => $can_update, + 'can_delete' => $can_delete + ], JSON_UNESCAPED_UNICODE); + } + ioServer('/v2/role_access_permissions', $data); + } else { + // If no permission checkboxes selected but had existing permission, delete it + if ($existing_permission) { + $data = json_encode([ + 'rowID' => $existing_permission->rowID, + 'delete' => 'delete' + ], JSON_UNESCAPED_UNICODE); + ioServer('/v2/role_access_permissions', $data); + } + } + } + + // Redirect to refresh + header('Location: index.php?page=user_role&rowID='.$role_id.'&success_msg=2'); + exit; +} + +//------------------------------ +//Variables +//------------------------------ +$status_text = ($responses->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive'); +$status_class = ($responses->is_active == 1) ? 'id1' : 'id0'; + +// Handle success messages +if (isset($_GET['success_msg'])) { + if ($_GET['success_msg'] == 1) { + $success_msg = ($message_role_1 ?? 'Role created successfully'); + } + if ($_GET['success_msg'] == 2) { + $success_msg = ($message_role_2 ?? 'Role updated successfully'); + } + if ($_GET['success_msg'] == 3) { + $success_msg = ($message_role_3 ?? 'Role deleted successfully'); + } +} + +template_header(($user_role_title ?? 'User Role'), 'user_role', 'view'); +$view = ' +
+

'.($view_role_h2 ?? 'User Role').' - '.$responses->name.'

+ +'; + +if ($update_allowed_edit === 1){ + $view .= '✏️'; + $view .= ''; +} + +$view .= '
'; + +if (isset($success_msg)){ + $view .= '
+ +

'.$success_msg.'

+ +
'; +} + +// Start form wrapper for edit mode +$view .= '
+ + '; + +$view .= '
'; + +// Role Information Block +$view .= '
+
+ '.($view_role_information ?? 'Role Information').' +
+
+

'.($general_status ?? 'Status').'

+

+ '.$status_text.' + +

+
+
+

'.($role_name ?? 'Role Name').'

+

+ '.$responses->name.' + +

+
+
+

'.($role_description ?? 'Description').'

+

+ '.($responses->description ?? '-').' + +

+
+
+'; + +// Role Assignments Block +$view .='
+
+ '.($view_role_assignments ?? 'Assigned Users').' +
'; + +if (!empty($assignments)){ + foreach ($assignments as $assignment){ + $assignment_status = ($assignment->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive'); + $view .= '
+

'.$assignment->username.'

+

'.$assignment_status.((!empty($assignment->expires_at))? ' - '.($expires ?? 'Expires').': '.$assignment->expires_at : '').'

+
'; + } +} else { + $view .= '
+

-

+

'.($no_users_assigned ?? 'No users assigned to this role').'

+
'; +} + +$view .= '
'; + +$view .= '
'; // Close content-block-wrapper + +// Permissions Table Block +$view .= '
+
+ '.($view_role_permissions ?? 'Role Permissions').' +
+
+ + + + + + + + + + + + + '; + +if (!empty($all_access_elements)){ + foreach ($all_access_elements as $element){ + $access_id = $element->rowID; + $existing_perm = $permission_lookup[$access_id] ?? null; + + // Determine current permission values + $has_create = ($existing_perm && $existing_perm->can_create == 1); + $has_read = ($existing_perm && $existing_perm->can_read == 1); + $has_update = ($existing_perm && $existing_perm->can_update == 1); + $has_delete = ($existing_perm && $existing_perm->can_delete == 1); + $has_any_permission = ($has_create || $has_read || $has_update || $has_delete); + + // Row class - hide unassigned rows in view mode + $row_class = $has_any_permission ? '' : ' class="edit-only-row" style="display:none;"'; + + // View mode icons + $icon_create = $has_create ? '' : ''; + $icon_read = $has_read ? '' : ''; + $icon_update = $has_update ? '' : ''; + $icon_delete = $has_delete ? '' : ''; + + // Edit mode checkboxes + $cb_create_checked = $has_create ? ' checked' : ''; + $cb_read_checked = $has_read ? ' checked' : ''; + $cb_update_checked = $has_update ? ' checked' : ''; + $cb_delete_checked = $has_delete ? ' checked' : ''; + + $view .= ' + + + + + + + + '; + } +} else { + $view .= ' + + '; +} + +$view .= ' +
'.($access_element_name ?? 'Access Element').''.($access_element_path ?? 'Path').''.($access_element_group ?? 'Group').''.($permission_create ?? 'C').''.($permission_read ?? 'R').''.($permission_update ?? 'U').''.($permission_delete ?? 'D').'
'.$element->access_name.''.$element->access_path.''.($element->access_group ?? '-').' + '.$icon_create.' + + + '.$icon_read.' + + + '.$icon_update.' + + + '.$icon_delete.' + +
'.($no_access_elements ?? 'No access elements found').'
+
+
+ '; + +// Metadata Block +$view .= '
+
+ '.($tab3 ?? 'Details').' +
+
+ + + + + + + + + +
'.($general_created ?? 'Created').''.getRelativeTime($responses->created).'
'.($general_updated ?? 'Updated').''.getRelativeTime($responses->updated).'
+
+
+
+'; + +//OUTPUT +echo $view; + +$js = 'var permissionsEditMode = false; +function togglePermissionsEdit() { + permissionsEditMode = !permissionsEditMode; + var editBtn = document.getElementById("editBtn"); + var saveBtn = document.getElementById("saveBtn"); + var viewElements = document.querySelectorAll(".view-mode"); + var editElements = document.querySelectorAll(".edit-mode"); + var editOnlyRows = document.querySelectorAll(".edit-only-row"); + var i; + if (permissionsEditMode) { + for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "none"; } + for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "inline"; } + for (i = 0; i < editOnlyRows.length; i++) { editOnlyRows[i].style.display = "table-row"; } + editBtn.style.display = "none"; + saveBtn.style.display = "inline-block"; + } else { + for (i = 0; i < viewElements.length; i++) { viewElements[i].style.display = "inline"; } + for (i = 0; i < editElements.length; i++) { editElements[i].style.display = "none"; } + for (i = 0; i < editOnlyRows.length; i++) { editOnlyRows[i].style.display = "none"; } + editBtn.style.display = "inline-block"; + saveBtn.style.display = "none"; + } +} +function toggleColumn(type) { + var checkboxes = document.querySelectorAll("input[name$=\\"[" + type + "]\\"]"); + var allChecked = true; + for (var i = 0; i < checkboxes.length; i++) { + if (!checkboxes[i].checked) { + allChecked = false; + break; + } + } + for (var i = 0; i < checkboxes.length; i++) { + checkboxes[i].checked = !allChecked; + } +}'; + +template_footer($js); diff --git a/user_role_manage.php b/user_role_manage.php new file mode 100644 index 0000000..ac55c05 --- /dev/null +++ b/user_role_manage.php @@ -0,0 +1,227 @@ + '', + 'name' => '', + 'description' => '', + 'is_active' => 1, + 'created' => '', + 'createdby' => $_SESSION['username'], + 'updated' => '', + 'updatedby' => '' +]; + +$role_ID = $_GET['rowID'] ?? ''; + +if ($role_ID !=''){ + $url = 'index.php?page=user_role&rowID='.$role_ID.''; +} else { + $url = 'index.php?page=user_roles'; +} + +//GET ALL ACCESS ELEMENTS +$api_url = '/v2/access_elements/status=1'; +$access_elements = ioServer($api_url,''); +//Decode Payload +if (!empty($access_elements)){$access_elements = json_decode($access_elements);}else{$access_elements = null;} + +//GET ROLE PERMISSIONS (if editing) +$role_permissions = []; +if ($role_ID != ''){ + $api_url = '/v2/role_access_permissions/role_id='.$role_ID; + $role_permissions_response = ioServer($api_url,''); + if (!empty($role_permissions_response)){ + $role_permissions_data = json_decode($role_permissions_response); + foreach ($role_permissions_data as $perm){ + $role_permissions[$perm->access_id] = [ + 'can_create' => $perm->can_create, + 'can_read' => $perm->can_read, + 'can_update' => $perm->can_update, + 'can_delete' => $perm->can_delete + ]; + } + } +} + +if (isset($_GET['rowID'])) { + // ID param exists, edit an existing role + //CALL TO API + $api_url = '/v2/user_roles/rowID='.$role_ID; + $responses = ioServer($api_url,''); + //Decode Payload + if (!empty($responses)){$responses = json_decode($responses,true);}else{$responses = null;} + + $role = $responses[0]; + + if ($update_allowed === 1){ + if (isset($_POST['submit'])) { + //GET ALL POST DATA + $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/user_roles', $data); + + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=user_role&rowID='.$role_ID.'&success_msg=2'); + exit; + } + } + } + + if ($delete_allowed === 1){ + if (isset($_POST['delete'])) { + //GET ALL POST DATA + $data = json_encode($_POST , JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/user_roles', $data); + // Redirect and delete role + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=user_roles&success_msg=3'); + exit; + } + } + } + +} else { + // Create a new role + if (isset($_POST['submit']) && $create_allowed === 1) { + //GET ALL POST DATA + $data = json_encode($_POST, JSON_UNESCAPED_UNICODE); + //API call + $responses = ioServer('/v2/user_roles', $data); + if ($responses === 'NOK'){ + + } else { + header('Location: index.php?page=user_roles&success_msg=1'); + exit; + } + } +} + +template_header(($user_role_title ?? 'User Role'), 'user_role', 'manage'); + +$label_h2 = (($role_ID !='')? ($manage_role_h2 ?? 'Edit Role') : ($button_create_role ?? 'Create Role')); +$view =' +
+
+

'.$label_h2.'

+ +'; + +if ($delete_allowed === 1 && $role_ID != ''){ + $view .= ''; +} +if ($update_allowed === 1 || ($create_allowed === 1 && $role_ID == '')){ + $view .= ''; +} + +$view .= '
'; + +$view .= ' +
+
+ + + + + + + +
+
'; + +// Permissions Tab +$view .= ' +
+
+ + + + + + + + + + + '; + +if (!empty($access_elements)){ + foreach ($access_elements as $element){ + $perm = $role_permissions[$element->rowID] ?? ['can_create' => 0, 'can_read' => 0, 'can_update' => 0, 'can_delete' => 0]; + + $view .= ' + + + + + + '; + } +} else { + $view .= ' + + '; +} + +$view .= ' +
'.($access_element_name ?? 'Access Element').''.($permission_create ?? 'Create').''.($permission_read ?? 'Read').''.($permission_update ?? 'Update').''.($permission_delete ?? 'Delete').'
'.$element->access_name.'
'.$element->access_path.'
'.($no_access_elements ?? 'No access elements found').'
+
+
'; + +//DISPLAY TAB 3 - Metadata +if ($role_ID != ''){ +$view .= ' +
+
+ + + + + + + + +
+
'; +} + +$view .= '
'; + +//Output +echo $view; +template_footer()?> diff --git a/user_roles.php b/user_roles.php new file mode 100644 index 0000000..daf39af --- /dev/null +++ b/user_roles.php @@ -0,0 +1,202 @@ +←':''; + +//Check if allowed +if (isAllowed($page,$_SESSION['profile'],$_SESSION['permission'],'R') === 0){ + header('location: index.php'); + exit; +} +//PAGE Security +$page_manage = 'user_role_manage'; +$update_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'U'); +$delete_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'D'); +$create_allowed = isAllowed($page_manage ,$_SESSION['profile'],$_SESSION['permission'],'C'); + +//GET PARAMETERS && STORE in SESSION for FURTHER USE/NAVIGATION +$pagination_page = $_SESSION['p'] = isset($_GET['p']) ? $_GET['p'] : 1; +$status = $_SESSION['status'] = isset($_GET['status']) ? '&status='.$_GET['status'] : ''; +$sort = $_SESSION['sort'] = isset($_GET['sort']) ? '&sort='.$_GET['sort'] : ''; +$search = $_SESSION['search'] = isset($_GET['search']) ? '&search='.$_GET['search'] : ''; + +//GET PARAMETERS FOR FILTERS +$filter = urlGETdetailsFilter($_GET) ?? ''; + +// Determine the URL +$url = 'index.php?page=user_roles'.$status.$search.$sort; +//GET Details from URL +$GET_VALUES = urlGETdetails($_GET) ?? ''; +//CALL TO API +$api_url = '/v2/user_roles/'.$GET_VALUES; +$responses = ioServer($api_url,''); +//Decode Payload +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} + +//Return QueryTotal from API +$total_url = ((!empty($GET_VALUES) && $GET_VALUES !='') ? '&totals=' : 'totals=' ); +$api_url = '/v2/user_roles/'.$GET_VALUES.$total_url; +$query_total = ioServer($api_url,''); +//Decode Payload +if (!empty($query_total)){$query_total = json_decode($query_total);}else{$query_total = null;} + +// Handle success messages +if (isset($_GET['success_msg'])) { + if ($_GET['success_msg'] == 1) { + $success_msg = ($message_role_1 ?? 'Role created successfully'); + } + if ($_GET['success_msg'] == 2) { + $success_msg = ($message_role_2 ?? 'Role updated successfully'); + } + if ($_GET['success_msg'] == 3) { + $success_msg = ($message_role_3 ?? 'Role deleted successfully'); + } +} + +template_header(($user_roles_title ?? 'User Roles'), 'user_roles','view'); +$view = ' +
+
+ +
+

'.($user_roles_h2 ?? 'User Roles').' ('.$query_total.')

+

'.($user_roles_p ?? 'Manage user roles and permissions').'

+
+
+
+ '.$back_btn_orgin; + +if ($create_allowed === 1){ + $view .= '+'; +} + +$view .= ' +
+
'; + +if (isset($success_msg)){ +$view .= '
+ +

'.$success_msg.'

+ +
'; +} + +$view .= ' + +'; +$view .= ' +
+
+ + + + + + + + + + + + '; + + if (empty($responses)){ + + $view .= ' + + + '; + } + +foreach ($responses as $response){ +//Translate status INT to STR +$status_text = ($response->is_active == 1) ? ($enabled ?? 'Active') : ($disabled ?? 'Inactive'); +$status_class = ($response->is_active == 1) ? 'id1' : 'id0'; + +$view .= ' + + + + + + + '; + } + $view .= ' + +
'.($role_name ?? 'Role Name').''.($role_description ?? 'Description').''.($general_status ?? 'Status').''.($role_permissions_count ?? 'Permissions').''.($general_created ?? 'Created').'
'.($message_no_roles ?? 'No roles found').'
'.$response->name.''.($response->description ?? '-').''.$status_text.''.($response->permission_count ?? '0').''.getRelativeTime($response->created).'
+
+
+'; + +$page_rows = $page_rows_equipment ?? 20; +$view.=''; +//OUTPUT +echo $view; + +template_footer(); +?> diff --git a/users.php b/users.php index 025e91c..624356a 100644 --- a/users.php +++ b/users.php @@ -38,16 +38,16 @@ $url = 'index.php?page=users'.$status.$search; //GET Details from URL $GET_VALUES = urlGETdetails($_GET) ?? ''; //CALL TO API -$api_url = '/v1/users/'.$GET_VALUES; +$api_url = '/v2/users/'.$GET_VALUES; $responses = ioServer($api_url,''); //Decode Payload -if (!empty($responses)){$responses = decode_payload($responses);}else{$responses = null;} +if (!empty($responses)){$responses = json_decode($responses);}else{$responses = null;} //Return QueryTotal from API -$api_url = '/v1/users/'.$GET_VALUES.'&totals='; +$api_url = '/v2/users/'.$GET_VALUES.'&totals='; $query_total = ioServer($api_url,''); //Decode Payload -if (!empty($query_total)){$query_total = decode_payload($query_total);}else{$query_total = null;} +if (!empty($query_total)){$query_total = json_decode($query_total);}else{$query_total = null;} // Handle success messages if (isset($_GET['success_msg'])) {