Filter manage-booking workers by service category

Guests modifying a booking saw every worker for the subpage, so an
eyelash booking exposed nail-only workers as switchable. Now the worker
list is scoped to the booking's service category, other-category
services are disabled in step 1, and the process handler rejects any
worker/service category mismatch to defend against crafted POSTs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ubuntu
2026-06-16 07:43:15 +00:00
co-authored by Claude Opus 4.7
parent 4a93b5efa0
commit f86952dc95
2 changed files with 31 additions and 2 deletions
+27
View File
@@ -753,8 +753,24 @@ class Pages extends CI_Controller {
}
$data['services'] = $this->Service_model->getAllServiceByServiceType($subpage, $lang);
// Filter workers to those qualified for the booking's service category,
// so the guest can't switch to a worker who doesn't perform these services.
$categorySlug = '';
if(isset($firstService) && $firstService){
$category = $this->Service_model->getServiceCategoryById($firstService->service_category_id);
if($category){
$categorySlug = $category->serv_cat_slug;
}
}
if($categorySlug !== ''){
$data['workers'] = $this->Service_model->getWorkersByCategorySlug($categorySlug);
} else {
$data['workers'] = $this->Service_model->getActiveWorkers($subpage);
}
$data['selectedServiceIds'] = is_array($serviceIds) ? $serviceIds : array();
$data['categorySlug'] = $categorySlug;
$data['worker'] = $this->Service_model->getWorkerById($booking->worker_id);
$this->load->view('pages/manage-booking', $data);
@@ -806,6 +822,17 @@ class Pages extends CI_Controller {
$lang = $_POST['lang'];
$subpage = $_POST['subpage'];
// Category match: worker must perform the selected services' category.
$submittedWorker = $this->Service_model->getWorkerById($newWorkerId);
if(!empty($selectedServiceArray) && $submittedWorker){
$firstSelectedService = $this->Service_model->getServiceById($selectedServiceArray[0]);
if($firstSelectedService && $firstSelectedService->service_category_id != $submittedWorker->service_category_id){
$this->output->set_status_header(403)->set_content_type('application/json')
->set_output(json_encode(['error' => 'Selected worker does not perform the chosen services.']));
return;
}
}
// Schedule check
$weekday = date('w', strtotime($newBookingDate));
$schedule = $this->Service_model->getWorkerScheduleByDay($newWorkerId, $weekday);
+3 -1
View File
@@ -338,6 +338,7 @@
<?php
foreach($groups[$label] as $serviceItem){
$isChecked = in_array($serviceItem->service_id, $selectedServiceIds);
$isOtherCategory = ($categorySlug !== '' && $serviceItem->serv_cat_slug !== $categorySlug);
?>
<div class="serviceRow">
<div class="serviceCol serviceNameCol" id="serviceName_<?php echo $serviceItem->service_id; ?>">
@@ -362,7 +363,8 @@
id="<?php echo $serviceItem->service_id; ?>"
name="service_<?php echo $serviceItem->service_id; ?>"
value="1"
<?php echo $isChecked ? 'checked' : ''; ?>/>
<?php echo $isChecked ? 'checked' : ''; ?>
<?php echo $isOtherCategory ? 'disabled' : ''; ?>/>
</div>
</div>
<?php