FIX_BE_VALIDATION_FAQ&APP_CONTENT_MGMT
This commit is contained in:
parent
f1860e80e2
commit
0037133f8a
@ -62,32 +62,40 @@ class AppContentManagementController extends AdminController
|
||||
|
||||
$data = $this->request->getPost();
|
||||
$sanitized_post_data = sanitizeInputArrayAdvanced($data);
|
||||
$id = ((int) $sanitized_post_data['add_image_id']) ?? null;
|
||||
$id = (int)($sanitized_post_data['add_image_id'] ?? 0);
|
||||
|
||||
$rules = [
|
||||
'client_id' => [
|
||||
'rules' => 'required|integer',
|
||||
'add_image_id' => [
|
||||
'rules' => 'permit_empty|integer|is_natural',
|
||||
'errors' => [
|
||||
'required' => 'Client is required',
|
||||
'integer' => 'Invalid client selected'
|
||||
'integer' => 'Image ID must be a valid number',
|
||||
'is_natural' => 'Image ID must be a non-negative number'
|
||||
]
|
||||
],
|
||||
'client_id' => [
|
||||
'rules' => 'required|integer|is_natural_no_zero',
|
||||
'errors' => [
|
||||
'required' => 'Client is required',
|
||||
'integer' => 'Invalid client selected',
|
||||
'is_natural_no_zero' => 'Invalid client selected'
|
||||
]
|
||||
],
|
||||
'advertise_image' => [
|
||||
'rules' => ($id === 0 ? 'uploaded[advertise_image]|' : '')
|
||||
. 'is_image[advertise_image]'
|
||||
. '|mime_in[advertise_image,image/jpg,image/jpeg,image/png]'
|
||||
. '|max_size[advertise_image,200]'
|
||||
. '|min_dims[advertise_image,1640,664]'
|
||||
. '|max_dims[advertise_image,1640,664]',
|
||||
'errors' => [
|
||||
'uploaded' => 'Image is required',
|
||||
'is_image' => 'File must be an image',
|
||||
'mime_in' => 'Only JPG, JPEG, PNG allowed',
|
||||
'max_size' => 'Image size must not exceed 200 KB',
|
||||
'min_dims' => 'Image dimensions must be exactly 1640x664 pixels',
|
||||
'max_dims' => 'Image dimensions must be exactly 1640x664 pixels',
|
||||
]
|
||||
],
|
||||
];
|
||||
$rules['advertise_image'] = [
|
||||
'rules' => ($id === 0 ? 'uploaded[advertise_image]|' : '') // required only for ADD
|
||||
. 'is_image[advertise_image]'
|
||||
. '|mime_in[advertise_image,image/jpg,image/jpeg,image/png]'
|
||||
. '|max_size[advertise_image,200]'
|
||||
. '|min_dims[advertise_image,1640,664]'
|
||||
. '|max_dims[advertise_image,1640,664]',
|
||||
'errors' => [
|
||||
'uploaded' => 'Image is required',
|
||||
'is_image' => 'File must be an image',
|
||||
'mime_in' => 'Only JPG, JPEG, PNG allowed',
|
||||
'max_size' => 'Image size must not exceed 200 KB',
|
||||
'min_dims' => 'Image dimensions must be exactly 1640x664 pixels',
|
||||
'max_dims' => 'Image dimensions must be exactly 1640x664 pixels',
|
||||
]
|
||||
];
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
@ -100,7 +108,12 @@ class AppContentManagementController extends AdminController
|
||||
|
||||
|
||||
$file = $this->request->getFile('advertise_image');
|
||||
$client_id = $sanitized_post_data['client_id'] ?? null;
|
||||
$client_id = (int)($sanitized_post_data['client_id'] ?? 0);
|
||||
|
||||
$clientExists = $this->clientModel->where('id', $client_id)->where('is_active', 1)->first();
|
||||
if (!$clientExists) {
|
||||
return $this->respond(['status' => false, 'message' => 'Invalid client selected.'], 400);
|
||||
}
|
||||
|
||||
if (!$file || !$file->isValid()) {
|
||||
return $this->respond(['status' => false, 'message' => 'No file uploaded or invalid file.'], 400);
|
||||
@ -119,12 +132,15 @@ class AppContentManagementController extends AdminController
|
||||
|
||||
$file->move($uploadPath, $fileName);
|
||||
|
||||
$id = $sanitized_post_data['add_image_id'] ?? null;
|
||||
$details = ['name' => $fileName,'client_id'=>$client_id];
|
||||
|
||||
if ($id == 0) {
|
||||
if ($id === 0) {
|
||||
$this->addImgModel->insert($details);
|
||||
} else {
|
||||
$existingRecord = $this->addImgModel->find($id);
|
||||
if (!$existingRecord) {
|
||||
return $this->respond(['status' => false, 'message' => 'Record not found for update.'], 404);
|
||||
}
|
||||
$this->addImgModel->update($id, $details);
|
||||
}
|
||||
|
||||
@ -138,14 +154,34 @@ class AppContentManagementController extends AdminController
|
||||
public function remove_advertise_image()
|
||||
{
|
||||
try {
|
||||
$id = $this->request->getPost('add_image_id');
|
||||
$rules = [
|
||||
'add_image_id' => [
|
||||
'rules' => 'required|integer|is_natural_no_zero',
|
||||
'errors' => [
|
||||
'required' => 'Image ID is required',
|
||||
'integer' => 'Image ID must be a valid number',
|
||||
'is_natural_no_zero' => 'Image ID must be a positive number'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
if (!$id) {
|
||||
return $this->respond(['status' => false, 'message' => 'ID missing'], 400);
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => false,
|
||||
'message' => 'Input validation failed',
|
||||
'code' => 400,
|
||||
'errors' => $this->validator->getErrors()
|
||||
]);
|
||||
}
|
||||
|
||||
$data = ['is_active' => 0];
|
||||
$this->addImgModel->update($id, $data);
|
||||
$id = (int)$this->request->getPost('add_image_id');
|
||||
|
||||
$existing = $this->addImgModel->find($id);
|
||||
if (!$existing) {
|
||||
return $this->respond(['status' => false, 'message' => 'Record not found'], 404);
|
||||
}
|
||||
|
||||
$this->addImgModel->update($id, ['is_active' => 0]);
|
||||
|
||||
return $this->respond(['status' => true, 'message' => 'Deleted successfully']);
|
||||
|
||||
@ -158,19 +194,27 @@ class AppContentManagementController extends AdminController
|
||||
// Preview image Went Edit.
|
||||
public function showAdvertiseImage($filename)
|
||||
{
|
||||
// $path = WRITEPATH . 'uploads/advertiseImage/' . $filename;
|
||||
$path = ROOTPATH . 'public/uploads/add_image_upload/' . $filename;
|
||||
$filename = basename($filename);
|
||||
|
||||
if (!file_exists($path)) {
|
||||
if (!preg_match('/^[a-zA-Z0-9_\-]+\.(jpg|jpeg|png|gif|webp)$/i', $filename)) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
|
||||
// return $this->response->setStatusCode(404, 'File not found');
|
||||
}
|
||||
|
||||
$mime = mime_content_type($path);
|
||||
// header('Content-Type: ' . $mimeType);
|
||||
// readfile($path);
|
||||
// exit;
|
||||
return $this->response->setHeader('Content-Type', $mime)->setBody(file_get_contents($path));
|
||||
$path = ROOTPATH . 'public/uploads/add_image_upload/' . $filename;
|
||||
$realPath = realpath($path);
|
||||
$allowedDir = realpath(ROOTPATH . 'public/uploads/add_image_upload');
|
||||
|
||||
if (!$realPath || strpos($realPath, $allowedDir) !== 0 || !file_exists($realPath)) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
$mime = mime_content_type($realPath);
|
||||
$allowedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
||||
if (!in_array($mime, $allowedMimes, true)) {
|
||||
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
|
||||
}
|
||||
|
||||
return $this->response->setHeader('Content-Type', $mime)->setBody(file_get_contents($realPath));
|
||||
}
|
||||
|
||||
|
||||
@ -183,39 +227,51 @@ class AppContentManagementController extends AdminController
|
||||
if ($this->request->getMethod() === 'post') {
|
||||
|
||||
$rules = [
|
||||
'type' => [
|
||||
'rules' => 'required|max_length[255]',
|
||||
'fe_id' => [
|
||||
'rules' => 'permit_empty|integer|is_natural',
|
||||
'errors' => [
|
||||
'required' => 'Type is required',
|
||||
'max_length' => 'Type cannot exceed 255 characters'
|
||||
'integer' => 'ID must be a valid number',
|
||||
'is_natural' => 'ID must be a non-negative number'
|
||||
]
|
||||
],
|
||||
'type' => [
|
||||
'rules' => 'required|max_length[255]|regex_match[/^[a-zA-Z0-9_ \-]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Type is required',
|
||||
'max_length' => 'Type cannot exceed 255 characters',
|
||||
'regex_match' => 'Type contains invalid characters'
|
||||
]
|
||||
],
|
||||
'content_section' => [
|
||||
'rules' => 'required|max_length[255]',
|
||||
'rules' => 'required|max_length[255]|regex_match[/^[a-zA-Z0-9_ \-]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Content Section is required',
|
||||
'max_length' => 'Content Section cannot exceed 255 characters'
|
||||
'required' => 'Content Section is required',
|
||||
'max_length' => 'Content Section cannot exceed 255 characters',
|
||||
'regex_match' => 'Content Section contains invalid characters'
|
||||
]
|
||||
],
|
||||
'heading' => [
|
||||
'rules' => 'required|max_length[255]',
|
||||
'rules' => 'required|max_length[255]|regex_match[/^[a-zA-Z0-9 _\-.,;:!?()&\/]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Heading is required',
|
||||
'max_length' => 'Heading cannot exceed 255 characters'
|
||||
'required' => 'Heading is required',
|
||||
'max_length' => 'Heading cannot exceed 255 characters',
|
||||
'regex_match' => 'Heading contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed'
|
||||
]
|
||||
],
|
||||
'content' => [
|
||||
'rules' => 'required|max_length[5000]',
|
||||
'rules' => 'required|max_length[5000]|regex_match[/^[a-zA-Z0-9 _\-.,;:!?()&\/\r\n]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Content is required',
|
||||
'max_length' => 'Content cannot exceed 5000 characters'
|
||||
'required' => 'Content is required',
|
||||
'max_length' => 'Content cannot exceed 5000 characters',
|
||||
'regex_match' => 'Content contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed'
|
||||
]
|
||||
],
|
||||
'notes' => [
|
||||
'rules' => 'required|max_length[1500]',
|
||||
'rules' => 'required|max_length[1500]|regex_match[/^[a-zA-Z0-9 _\-.,;:!?()&\/\r\n]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Notes are required',
|
||||
'max_length' => 'Notes cannot exceed 1500 characters'
|
||||
'required' => 'Notes are required',
|
||||
'max_length' => 'Notes cannot exceed 1500 characters',
|
||||
'regex_match' => 'Notes contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed'
|
||||
]
|
||||
]
|
||||
];
|
||||
@ -230,8 +286,14 @@ class AppContentManagementController extends AdminController
|
||||
}
|
||||
$request_post_data = $this->request->getPost();
|
||||
$data = sanitizeInputArrayAdvanced($request_post_data);
|
||||
$id = $data['fe_id'];
|
||||
|
||||
$id = $data['fe_id'] ?? null;
|
||||
|
||||
if (!empty($id) && (!ctype_digit((string)$id) || (int)$id <= 0)) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => false, 'message' => 'Invalid ID format', 'code' => 400
|
||||
]);
|
||||
}
|
||||
$id = !empty($id) ? (int)$id : null;
|
||||
|
||||
unset($data['fe_id']);
|
||||
|
||||
@ -244,6 +306,12 @@ class AppContentManagementController extends AdminController
|
||||
$status = $this->feContentModel->insert($data);
|
||||
$text = "Created";
|
||||
} else {
|
||||
$existing = $this->feContentModel->find($id);
|
||||
if (!$existing) {
|
||||
return $this->response->setStatusCode(404)->setJSON([
|
||||
'status' => false, 'message' => 'Record not found', 'code' => 404
|
||||
]);
|
||||
}
|
||||
$status = $this->feContentModel->update($id, $data);
|
||||
$text = "Updated";
|
||||
}
|
||||
@ -260,6 +328,13 @@ class AppContentManagementController extends AdminController
|
||||
$id = $this->request->getGet('fe_id') ?? null;
|
||||
|
||||
if (!empty($id)) {
|
||||
|
||||
if (!ctype_digit((string)$id) || (int)$id <= 0) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => false, 'code' => 400, 'message' => 'Invalid ID format'
|
||||
]);
|
||||
}
|
||||
$id = (int)$id;
|
||||
|
||||
$data['fe_list'] = $this->feContentModel->where('id', $id)->orderBy('id', 'DESC')->findAll();
|
||||
|
||||
@ -276,16 +351,24 @@ class AppContentManagementController extends AdminController
|
||||
|
||||
} elseif ($method === 'delete') {
|
||||
|
||||
// $input = $this->request->getRawInput();
|
||||
$id = $this->request->getGet('fe_id'); // ✅ THIS
|
||||
$id = $id ?? null;
|
||||
$id = $this->request->getGet('fe_id') ?? null;
|
||||
|
||||
if (empty($id)) {
|
||||
if (empty($id) || !ctype_digit((string)$id) || (int)$id <= 0) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'code' => 400,
|
||||
'message' => 'Valid numeric ID is required for deletion'
|
||||
], 400);
|
||||
}
|
||||
$id = (int)$id;
|
||||
|
||||
$existing = $this->feContentModel->find($id);
|
||||
if (!$existing) {
|
||||
return $this->respond([
|
||||
'status' => false,
|
||||
'code' => 404,
|
||||
'message' => 'No ID provided for deletion'
|
||||
], 200);
|
||||
'message' => 'Record not found'
|
||||
], 404);
|
||||
}
|
||||
|
||||
$update_status = $this->feContentModel->where('id', $id)->set(['is_active' => 0])->update();
|
||||
@ -309,10 +392,15 @@ class AppContentManagementController extends AdminController
|
||||
}
|
||||
|
||||
|
||||
private const ALLOWED_RETURN_TYPES = ['api', 'web'];
|
||||
|
||||
public function FAQ()
|
||||
{
|
||||
$method = strtolower($this->request->getMethod());
|
||||
$returnType = strtolower($this->request->getGet('return_type') ?? 'api');
|
||||
if (!in_array($returnType, self::ALLOWED_RETURN_TYPES, true)) {
|
||||
$returnType = 'api';
|
||||
}
|
||||
$ref = ['timestamp' => date('Y-m-d H:i:s')];
|
||||
|
||||
try {
|
||||
@ -320,33 +408,64 @@ class AppContentManagementController extends AdminController
|
||||
if ($method === 'post') {
|
||||
$rules = [
|
||||
'category' => [
|
||||
'rules' => 'required',
|
||||
'rules' => 'required|max_length[100]|alpha_numeric_space',
|
||||
'errors' => [
|
||||
'required' => 'Category is required'
|
||||
'required' => 'Category is required',
|
||||
'max_length' => 'Category cannot exceed 100 characters',
|
||||
'alpha_numeric_space' => 'Category contains invalid characters'
|
||||
]
|
||||
],
|
||||
'question' => [
|
||||
'rules' => 'required',
|
||||
'rules' => 'required|max_length[1000]|regex_match[/^[a-zA-Z0-9 _\-.,;:!?()&\/\r\n]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Question is required'
|
||||
'required' => 'Question is required',
|
||||
'max_length' => 'Question cannot exceed 1000 characters',
|
||||
'regex_match' => 'Question contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed'
|
||||
]
|
||||
],
|
||||
'answer' => [
|
||||
'rules' => 'required',
|
||||
'rules' => 'required|max_length[5000]|regex_match[/^[a-zA-Z0-9 _\-.,;:!?()&\/\r\n]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Answer is required'
|
||||
'required' => 'Answer is required',
|
||||
'max_length' => 'Answer cannot exceed 5000 characters',
|
||||
'regex_match' => 'Answer contains invalid characters. Only letters, numbers, spaces and basic punctuation are allowed'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
if (!$this->validate($rules)) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => 'error',
|
||||
'message' => 'Input validation failed',
|
||||
'code' => 400,
|
||||
'errors' => $this->validator->getErrors(),
|
||||
'ref' => $ref
|
||||
]);
|
||||
}
|
||||
|
||||
$request_post_data = $this->request->getPost();
|
||||
$sanitized_post_data = sanitizeInputArrayAdvanced($request_post_data);
|
||||
$data = array_filter($sanitized_post_data, fn($v) => $v !== '' && $v !== null);
|
||||
$id = $data['faq_id'];
|
||||
$id = $data['faq_id'] ?? null;
|
||||
|
||||
if (!empty($id) && (!ctype_digit((string)$id) || (int)$id <= 0)) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => 'error', 'message' => 'Invalid FAQ ID format', 'code' => 400, 'ref' => $ref
|
||||
]);
|
||||
}
|
||||
$id = !empty($id) ? (int)$id : null;
|
||||
unset($data['faq_id']);
|
||||
|
||||
if (empty($id)) {
|
||||
$status = $this->faqModel->insert($data);
|
||||
$msg = "Created";
|
||||
} else {
|
||||
$existing = $this->faqModel->find($id);
|
||||
if (!$existing) {
|
||||
return $this->response->setStatusCode(404)->setJSON([
|
||||
'status' => 'error', 'message' => 'FAQ not found', 'code' => 404, 'ref' => $ref
|
||||
]);
|
||||
}
|
||||
$status = $this->faqModel->update($id, $data);
|
||||
$msg = "Updated";
|
||||
}
|
||||
@ -372,10 +491,17 @@ class AppContentManagementController extends AdminController
|
||||
$id = $this->request->getGet('faq_id');
|
||||
|
||||
if (!empty($id)) {
|
||||
if (!ctype_digit((string)$id) || (int)$id <= 0) {
|
||||
return $this->response->setStatusCode(400)->setJSON([
|
||||
'status' => 'error', 'message' => 'Invalid FAQ ID format', 'code' => 400, 'ref' => $ref
|
||||
]);
|
||||
}
|
||||
$id = (int)$id;
|
||||
|
||||
if($returnType === 'web'){
|
||||
$row = $this->faqModel->find((int)$id);
|
||||
$row = $this->faqModel->find($id);
|
||||
}else{
|
||||
$row = $this->faqModel->where('is_active', 1)->find((int)$id);
|
||||
$row = $this->faqModel->where('is_active', 1)->find($id);
|
||||
}
|
||||
|
||||
$data['faq_list'] = $row ? [$row] : [];
|
||||
@ -417,7 +543,15 @@ class AppContentManagementController extends AdminController
|
||||
// --- 3. DELETE: SOFT DELETE ---
|
||||
elseif ($method === 'delete') {
|
||||
$id = $this->request->getGet('faq_id');
|
||||
$status = (!empty($id)) ? $this->faqModel->update($id, ['is_active' => 0]) : false;
|
||||
|
||||
if (empty($id) || !ctype_digit((string)$id) || (int)$id <= 0) {
|
||||
return $this->response->setJSON([
|
||||
'status' => 'error', 'message' => 'Valid numeric FAQ ID is required', 'code' => 400, 'ref' => $ref
|
||||
])->setStatusCode(400);
|
||||
}
|
||||
$id = (int)$id;
|
||||
|
||||
$status = $this->faqModel->find($id) ? $this->faqModel->update($id, ['is_active' => 0]) : false;
|
||||
|
||||
return $this->response->setJSON([
|
||||
'status' => $status ? ($returnType === 'web' ? true : 'success') : ($returnType === 'web' ? false : 'error'),
|
||||
@ -429,12 +563,12 @@ class AppContentManagementController extends AdminController
|
||||
}
|
||||
|
||||
} catch (\Throwable $e) {
|
||||
$msg = $e->getMessage();
|
||||
log_message('error', 'FAQ error: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
|
||||
return $this->response->setJSON([
|
||||
'status' => $returnType === 'web' ? false : 'error',
|
||||
'code' => 500,
|
||||
'message' => $msg,
|
||||
'ref' => ['file' => $e->getFile(), 'line' => $e->getLine()]
|
||||
'message' => 'An internal error occurred. Please try again later.',
|
||||
'ref' => $ref
|
||||
])->setStatusCode(500);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user