Update: 2026-05-08 04:58:23

This commit is contained in:
Hamza-Ayed
2026-05-08 04:58:23 +03:00
parent 4721ca83da
commit 6db8986fca
48 changed files with 2212 additions and 108 deletions

View File

@@ -38,3 +38,19 @@ if (!function_exists('dd')) {
die();
}
}
if (!function_exists('safe_error')) {
/**
* Log exception details securely and return a safe user-facing message.
* Full details go to error_log; users only see a generic Arabic message.
*
* @param \Throwable $e The caught exception
* @param string $context Short label for the endpoint (e.g. 'invoices/upload')
* @param string $userMsg Arabic message shown to the user
* @param int $code HTTP status code
*/
function safe_error(\Throwable $e, string $context, string $userMsg = 'حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى.', int $code = 500): void {
error_log("[{$context}] " . get_class($e) . ': ' . $e->getMessage() . ' | ' . $e->getFile() . ':' . $e->getLine());
json_error($userMsg, $code);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* Pagination Helper
*
* Usage:
* $pagination = paginate_params(); // extracts page, per_page from query string
* // Use $pagination['limit'] and $pagination['offset'] in SQL
* // Wrap results: json_paginated($items, $totalCount, $pagination);
*/
if (!function_exists('paginate_params')) {
/**
* Extract pagination parameters from the query string.
*
* @param int $defaultPerPage Default items per page
* @param int $maxPerPage Maximum allowed per page (prevents abuse)
* @return array ['page' => int, 'per_page' => int, 'limit' => int, 'offset' => int]
*/
function paginate_params(int $defaultPerPage = 25, int $maxPerPage = 100): array
{
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = min($maxPerPage, max(1, (int)($_GET['per_page'] ?? $defaultPerPage)));
$offset = ($page - 1) * $perPage;
return [
'page' => $page,
'per_page' => $perPage,
'limit' => $perPage,
'offset' => $offset,
];
}
}
if (!function_exists('json_paginated')) {
/**
* Return a paginated JSON response with metadata.
*
* @param array $items The current page of results
* @param int $total Total count of all matching records
* @param array $pagination Output from paginate_params()
* @param string $message Optional success message
*/
function json_paginated(array $items, int $total, array $pagination, string $message = 'Success'): void
{
$totalPages = (int)ceil($total / max(1, $pagination['per_page']));
json_success([
'items' => $items,
'pagination' => [
'page' => $pagination['page'],
'per_page' => $pagination['per_page'],
'total' => $total,
'total_pages' => $totalPages,
'has_next' => $pagination['page'] < $totalPages,
'has_prev' => $pagination['page'] > 1,
],
], $message);
}
}