adding permissions
This commit is contained in:
parent
607b9d8838
commit
37abbe5d1e
@ -2,8 +2,8 @@
|
|||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
require_once __DIR__ . '/mail/MailService.php';
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
// Only admins can access this page
|
// Only users with settings view permission can access this page
|
||||||
if (!isAdmin()) {
|
if (!canView('settings')) {
|
||||||
redirect("index.php");
|
redirect("index.php");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,8 +12,12 @@ $error_msg = '';
|
|||||||
|
|
||||||
// Handle Re-enable SMTP
|
// Handle Re-enable SMTP
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['enable_smtp'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['enable_smtp'])) {
|
||||||
|
if (canEdit('settings')) {
|
||||||
db()->query("UPDATE smtp_settings SET is_enabled = 1, consecutive_failures = 0 WHERE id = 1");
|
db()->query("UPDATE smtp_settings SET is_enabled = 1, consecutive_failures = 0 WHERE id = 1");
|
||||||
$_SESSION['success'] = 'تم إعادة تفعيل SMTP وتصفير عداد الأخطاء';
|
$_SESSION['success'] = 'تم إعادة تفعيل SMTP وتصفير عداد الأخطاء';
|
||||||
|
} else {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لتعديل الإعدادات';
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +31,9 @@ $smtp = $stmt->fetch();
|
|||||||
|
|
||||||
// Handle Charity Settings Update
|
// Handle Charity Settings Update
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_charity'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_charity'])) {
|
||||||
|
if (!canEdit('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لتعديل الإعدادات';
|
||||||
|
} else {
|
||||||
$charity_name = $_POST['charity_name'];
|
$charity_name = $_POST['charity_name'];
|
||||||
$charity_email = $_POST['charity_email'];
|
$charity_email = $_POST['charity_email'];
|
||||||
$charity_phone = $_POST['charity_phone'];
|
$charity_phone = $_POST['charity_phone'];
|
||||||
@ -56,11 +63,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_charity'])) {
|
|||||||
$stmt = db()->prepare("UPDATE charity_settings SET charity_name = ?, charity_email = ?, charity_phone = ?, charity_address = ?, charity_logo = ?, charity_favicon = ? WHERE id = 1");
|
$stmt = db()->prepare("UPDATE charity_settings SET charity_name = ?, charity_email = ?, charity_phone = ?, charity_address = ?, charity_logo = ?, charity_favicon = ? WHERE id = 1");
|
||||||
$stmt->execute([$charity_name, $charity_email, $charity_phone, $charity_address, $charity_logo, $charity_favicon]);
|
$stmt->execute([$charity_name, $charity_email, $charity_phone, $charity_address, $charity_logo, $charity_favicon]);
|
||||||
$_SESSION['success'] = 'تم تحديث إعدادات النظام بنجاح';
|
$_SESSION['success'] = 'تم تحديث إعدادات النظام بنجاح';
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle SMTP Settings Update
|
// Handle SMTP Settings Update
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_smtp'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_smtp'])) {
|
||||||
|
if (!canEdit('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لتعديل الإعدادات';
|
||||||
|
} else {
|
||||||
$stmt = db()->prepare("UPDATE smtp_settings SET smtp_host = ?, smtp_port = ?, smtp_secure = ?, smtp_user = ?, smtp_pass = ?, from_email = ?, from_name = ?, reply_to = ?, max_failures = ? WHERE id = 1");
|
$stmt = db()->prepare("UPDATE smtp_settings SET smtp_host = ?, smtp_port = ?, smtp_secure = ?, smtp_user = ?, smtp_pass = ?, from_email = ?, from_name = ?, reply_to = ?, max_failures = ? WHERE id = 1");
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$_POST['smtp_host'],
|
$_POST['smtp_host'],
|
||||||
@ -74,11 +85,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_smtp'])) {
|
|||||||
(int)$_POST['max_failures']
|
(int)$_POST['max_failures']
|
||||||
]);
|
]);
|
||||||
$_SESSION['success'] = 'تم تحديث إعدادات البريد (SMTP) بنجاح';
|
$_SESSION['success'] = 'تم تحديث إعدادات البريد (SMTP) بنجاح';
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Test Email
|
// Handle Test Email
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_email_addr'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_email_addr'])) {
|
||||||
|
if (!canEdit('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء';
|
||||||
|
} else {
|
||||||
$to = $_POST['test_email_addr'];
|
$to = $_POST['test_email_addr'];
|
||||||
$res = MailService::sendMail($to, "رسالة تجريبية - Test Email", "<p>إذا كنت ترى هذه الرسالة، فإن إعدادات SMTP تعمل بشكل صحيح.</p>");
|
$res = MailService::sendMail($to, "رسالة تجريبية - Test Email", "<p>إذا كنت ترى هذه الرسالة، فإن إعدادات SMTP تعمل بشكل صحيح.</p>");
|
||||||
if ($res['success']) {
|
if ($res['success']) {
|
||||||
@ -86,11 +101,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_email_addr'])) {
|
|||||||
} else {
|
} else {
|
||||||
$_SESSION['error'] = "فشل إرسال الرسالة التجريبية: " . $res['error'];
|
$_SESSION['error'] = "فشل إرسال الرسالة التجريبية: " . $res['error'];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Status Operations
|
// Handle Status Operations
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_status'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_status'])) {
|
||||||
|
if (!canEdit('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لتعديل الإعدادات';
|
||||||
|
} else {
|
||||||
$name = $_POST['status_name'];
|
$name = $_POST['status_name'];
|
||||||
$color = $_POST['status_color'];
|
$color = $_POST['status_color'];
|
||||||
$is_default = isset($_POST['is_default']) ? 1 : 0;
|
$is_default = isset($_POST['is_default']) ? 1 : 0;
|
||||||
@ -98,10 +117,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_status'])) {
|
|||||||
$stmt = db()->prepare("INSERT INTO mailbox_statuses (name, color, is_default) VALUES (?, ?, ?)");
|
$stmt = db()->prepare("INSERT INTO mailbox_statuses (name, color, is_default) VALUES (?, ?, ?)");
|
||||||
$stmt->execute([$name, $color, $is_default]);
|
$stmt->execute([$name, $color, $is_default]);
|
||||||
$_SESSION['success'] = 'تم إضافة نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم إضافة نوع الحالة بنجاح';
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
||||||
|
if (!canEdit('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لتعديل الإعدادات';
|
||||||
|
} else {
|
||||||
$id = $_POST['status_id'];
|
$id = $_POST['status_id'];
|
||||||
$name = $_POST['status_name'];
|
$name = $_POST['status_name'];
|
||||||
$color = $_POST['status_color'];
|
$color = $_POST['status_color'];
|
||||||
@ -110,10 +133,14 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_status'])) {
|
|||||||
$stmt = db()->prepare("UPDATE mailbox_statuses SET name = ?, color = ?, is_default = ? WHERE id = ?");
|
$stmt = db()->prepare("UPDATE mailbox_statuses SET name = ?, color = ?, is_default = ? WHERE id = ?");
|
||||||
$stmt->execute([$name, $color, $is_default, $id]);
|
$stmt->execute([$name, $color, $is_default, $id]);
|
||||||
$_SESSION['success'] = 'تم تحديث نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم تحديث نوع الحالة بنجاح';
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
||||||
|
if (!canDelete('settings')) {
|
||||||
|
$_SESSION['error'] = 'عذراً، ليس لديك الصلاحية لحذف الإعدادات';
|
||||||
|
} else {
|
||||||
$id = $_POST['status_id'];
|
$id = $_POST['status_id'];
|
||||||
$count = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ?");
|
$count = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ?");
|
||||||
$count->execute([$id]);
|
$count->execute([$id]);
|
||||||
@ -123,6 +150,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_status'])) {
|
|||||||
db()->prepare("DELETE FROM mailbox_statuses WHERE id = ?")->execute([$id]);
|
db()->prepare("DELETE FROM mailbox_statuses WHERE id = ?")->execute([$id]);
|
||||||
$_SESSION['success'] = 'تم حذف نوع الحالة بنجاح';
|
$_SESSION['success'] = 'تم حذف نوع الحالة بنجاح';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
redirect('charity-settings.php');
|
redirect('charity-settings.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +256,9 @@ $post_max = ini_get('post_max_size');
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-end mt-4">
|
<div class="text-end mt-4">
|
||||||
|
<?php if (canEdit('settings')): ?>
|
||||||
<button type="submit" class="btn btn-dark px-4">حفظ جميع التغييرات</button>
|
<button type="submit" class="btn btn-dark px-4">حفظ جميع التغييرات</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -240,9 +270,11 @@ $post_max = ini_get('post_max_size');
|
|||||||
<?php if (!$smtp['is_enabled']): ?>
|
<?php if (!$smtp['is_enabled']): ?>
|
||||||
<div class="alert alert-danger py-2 px-3 mb-0 d-flex align-items-center">
|
<div class="alert alert-danger py-2 px-3 mb-0 d-flex align-items-center">
|
||||||
<small><i class="fas fa-exclamation-triangle me-2"></i> SMTP معطل حالياً</small>
|
<small><i class="fas fa-exclamation-triangle me-2"></i> SMTP معطل حالياً</small>
|
||||||
|
<?php if (canEdit('settings')): ?>
|
||||||
<form method="POST" class="ms-3">
|
<form method="POST" class="ms-3">
|
||||||
<button type="submit" name="enable_smtp" class="btn btn-sm btn-outline-danger">تفعيل الآن</button>
|
<button type="submit" name="enable_smtp" class="btn btn-sm btn-outline-danger">تفعيل الآن</button>
|
||||||
</form>
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<div class="badge bg-success p-2">
|
<div class="badge bg-success p-2">
|
||||||
@ -301,7 +333,9 @@ $post_max = ini_get('post_max_size');
|
|||||||
<input type="number" name="max_failures" class="form-control" value="<?= htmlspecialchars($smtp['max_failures'] ?? 5) ?>">
|
<input type="number" name="max_failures" class="form-control" value="<?= htmlspecialchars($smtp['max_failures'] ?? 5) ?>">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if (canEdit('settings')): ?>
|
||||||
<button type="submit" class="btn btn-primary">حفظ إعدادات البريد</button>
|
<button type="submit" class="btn btn-primary">حفظ إعدادات البريد</button>
|
||||||
|
<?php endif; ?>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div class="mt-5 p-4 bg-light rounded border">
|
<div class="mt-5 p-4 bg-light rounded border">
|
||||||
@ -310,7 +344,7 @@ $post_max = ini_get('post_max_size');
|
|||||||
<form method="POST">
|
<form method="POST">
|
||||||
<div class="input-group" style="max-width: 450px;">
|
<div class="input-group" style="max-width: 450px;">
|
||||||
<input type="email" name="test_email_addr" class="form-control" placeholder="بريد الوجهة (example@mail.com)" required>
|
<input type="email" name="test_email_addr" class="form-control" placeholder="بريد الوجهة (example@mail.com)" required>
|
||||||
<button class="btn btn-secondary" type="submit"><i class="fas fa-paper-plane me-2"></i> إرسال اختبار</button>
|
<button class="btn btn-secondary" type="submit" <?= !canEdit('settings') ? 'disabled' : '' ?>><i class="fas fa-paper-plane me-2"></i> إرسال اختبار</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -320,7 +354,9 @@ $post_max = ini_get('post_max_size');
|
|||||||
<div class="tab-pane fade" id="statuses" role="tabpanel">
|
<div class="tab-pane fade" id="statuses" role="tabpanel">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
<h5 class="fw-bold text-primary mb-0">أنواع حالات البريد</h5>
|
<h5 class="fw-bold text-primary mb-0">أنواع حالات البريد</h5>
|
||||||
|
<?php if (canAdd('settings')): ?>
|
||||||
<button class="btn btn-sm btn-primary" onclick="new bootstrap.Modal(document.getElementById('addStatusModal')).show()"><i class="fas fa-plus me-2"></i> إضافة حالة جديدة</button>
|
<button class="btn btn-sm btn-primary" onclick="new bootstrap.Modal(document.getElementById('addStatusModal')).show()"><i class="fas fa-plus me-2"></i> إضافة حالة جديدة</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
@ -345,8 +381,10 @@ $post_max = ini_get('post_max_size');
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
|
<?php if (canEdit('settings')): ?>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="editStatus(<?= $status['id'] ?>, '<?= htmlspecialchars($status['name'], ENT_QUOTES) ?>', '<?= $status['color'] ?>', <?= $status['is_default'] ?>)"><i class="fas fa-edit"></i></button>
|
<button type="button" class="btn btn-sm btn-outline-primary" onclick="editStatus(<?= $status['id'] ?>, '<?= htmlspecialchars($status['name'], ENT_QUOTES) ?>', '<?= $status['color'] ?>', <?= $status['is_default'] ?>)"><i class="fas fa-edit"></i></button>
|
||||||
<?php if (!$status['is_default']): ?>
|
<?php endif; ?>
|
||||||
|
<?php if (canDelete('settings') && !$status['is_default']): ?>
|
||||||
<form method="POST" onsubmit="return confirm('هل أنت متأكد من حذف هذه الحالة؟');" style="display:inline;">
|
<form method="POST" onsubmit="return confirm('هل أنت متأكد من حذف هذه الحالة؟');" style="display:inline;">
|
||||||
<input type="hidden" name="status_id" value="<?= $status['id'] ?>">
|
<input type="hidden" name="status_id" value="<?= $status['id'] ?>">
|
||||||
<input type="hidden" name="delete_status" value="1">
|
<input type="hidden" name="delete_status" value="1">
|
||||||
@ -429,7 +467,9 @@ $post_max = ini_get('post_max_size');
|
|||||||
<h6 class="fw-bold mb-2 text-warning-emphasis"><i class="fas fa-tools me-2"></i> أدوات الصيانة</h6>
|
<h6 class="fw-bold mb-2 text-warning-emphasis"><i class="fas fa-tools me-2"></i> أدوات الصيانة</h6>
|
||||||
<p class="small mb-3">هذه الأدوات مخصصة لمدير النظام فقط. يرجى توخي الحذر عند الاستخدام.</p>
|
<p class="small mb-3">هذه الأدوات مخصصة لمدير النظام فقط. يرجى توخي الحذر عند الاستخدام.</p>
|
||||||
<div class="d-flex gap-2">
|
<div class="d-flex gap-2">
|
||||||
|
<?php if (canEdit('settings')): ?>
|
||||||
<button class="btn btn-sm btn-outline-warning" onclick="alert('قريباً: نسخة احتياطية لقاعدة البيانات')"><i class="fas fa-database me-1"></i> نسخة احتياطية</button>
|
<button class="btn btn-sm btn-outline-warning" onclick="alert('قريباً: نسخة احتياطية لقاعدة البيانات')"><i class="fas fa-database me-1"></i> نسخة احتياطية</button>
|
||||||
|
<?php endif; ?>
|
||||||
<button class="btn btn-sm btn-outline-secondary" onclick="location.reload()"><i class="fas fa-sync-alt me-1"></i> تحديث الحالة</button>
|
<button class="btn btn-sm btn-outline-secondary" onclick="location.reload()"><i class="fas fa-sync-alt me-1"></i> تحديث الحالة</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
50
db/migrations/013_add_page_permissions.sql
Normal file
50
db/migrations/013_add_page_permissions.sql
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
-- Migration: Add per-page granular permissions
|
||||||
|
CREATE TABLE IF NOT EXISTS user_permissions (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
user_id INT NOT NULL,
|
||||||
|
page VARCHAR(50) NOT NULL,
|
||||||
|
can_view TINYINT(1) DEFAULT 0,
|
||||||
|
can_add TINYINT(1) DEFAULT 0,
|
||||||
|
can_edit TINYINT(1) DEFAULT 0,
|
||||||
|
can_delete TINYINT(1) DEFAULT 0,
|
||||||
|
UNIQUE KEY user_page (user_id, page),
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Seed permissions for existing users based on their roles
|
||||||
|
-- Inbound Mail
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'inbound', can_view, can_add, can_edit, can_delete FROM users;
|
||||||
|
|
||||||
|
-- Outbound Mail
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'outbound', can_view, can_add, can_edit, can_delete FROM users;
|
||||||
|
|
||||||
|
-- Internal Mail
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'internal', can_view, can_add, can_edit, can_delete FROM users;
|
||||||
|
|
||||||
|
-- Users (Only Admins)
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'users',
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0)
|
||||||
|
FROM users;
|
||||||
|
|
||||||
|
-- Settings (Only Admins)
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'settings',
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0),
|
||||||
|
IF(role = 'admin', 1, 0)
|
||||||
|
FROM users;
|
||||||
|
|
||||||
|
-- Reports
|
||||||
|
INSERT IGNORE INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete)
|
||||||
|
SELECT id, 'reports',
|
||||||
|
IF(role IN ('admin', 'clerk'), 1, 0),
|
||||||
|
0, 0, 0
|
||||||
|
FROM users;
|
||||||
16
inbound.php
16
inbound.php
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
require_once __DIR__ . '/mail/MailService.php';
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
// Check if user has view permission
|
// Check if user has view permission
|
||||||
if (!canView()) {
|
if (!canView('inbound')) {
|
||||||
redirect('index.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$action = $_POST['action'] ?? '';
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
// Permission checks for POST actions
|
// Permission checks for POST actions
|
||||||
if (($action === 'add' && !canAdd()) || ($action === 'edit' && !canEdit())) {
|
if (($action === 'add' && !canAdd('inbound')) || ($action === 'edit' && !canEdit('inbound'))) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء';
|
$error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء';
|
||||||
} else {
|
} else {
|
||||||
$type = 'inbound';
|
$type = 'inbound';
|
||||||
@ -134,7 +134,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
// Delete action
|
// Delete action
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
if (!canDelete()) {
|
if (!canDelete('inbound')) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لحذف السجلات';
|
$error = 'عذراً، ليس لديك الصلاحية لحذف السجلات';
|
||||||
} else {
|
} else {
|
||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
@ -206,7 +206,7 @@ $users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")-
|
|||||||
// Handle Deep Link for Edit
|
// Handle Deep Link for Edit
|
||||||
$deepLinkData = null;
|
$deepLinkData = null;
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
||||||
if (canEdit()) {
|
if (canEdit('inbound')) {
|
||||||
$stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'inbound'");
|
$stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'inbound'");
|
||||||
$stmt->execute([$_GET['id']]);
|
$stmt->execute([$_GET['id']]);
|
||||||
$deepLinkData = $stmt->fetch();
|
$deepLinkData = $stmt->fetch();
|
||||||
@ -229,7 +229,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
|
|
||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2">البريد الوارد</h1>
|
<h1 class="h2">البريد الوارد</h1>
|
||||||
<?php if (canAdd()): ?>
|
<?php if (canAdd('inbound')): ?>
|
||||||
<button type="button" class="btn btn-primary shadow-sm" onclick="openMailModal('add')">
|
<button type="button" class="btn btn-primary shadow-sm" onclick="openMailModal('add')">
|
||||||
<i class="fas fa-plus-circle me-1"></i> إضافة جديد
|
<i class="fas fa-plus-circle me-1"></i> إضافة جديد
|
||||||
</button>
|
</button>
|
||||||
@ -317,14 +317,14 @@ function getStatusBadgeInList($mail) {
|
|||||||
<td class="pe-4 text-center">
|
<td class="pe-4 text-center">
|
||||||
<a href="view_mail.php?id=<?= $mail['id'] ?>" class="btn btn-sm btn-outline-info" title="عرض التفاصيل"><i class="fas fa-eye"></i></a>
|
<a href="view_mail.php?id=<?= $mail['id'] ?>" class="btn btn-sm btn-outline-info" title="عرض التفاصيل"><i class="fas fa-eye"></i></a>
|
||||||
|
|
||||||
<?php if (canEdit()): ?>
|
<?php if (canEdit('inbound')): ?>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||||
onclick='openMailModal("edit", <?= json_encode($mail) ?>)' title="تعديل">
|
onclick='openMailModal("edit", <?= json_encode($mail) ?>)' title="تعديل">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (canDelete()): ?>
|
<?php if (canDelete('inbound')): ?>
|
||||||
<a href="javascript:void(0)" onclick="confirmDelete(<?= $mail['id'] ?>)" class="btn btn-sm btn-outline-danger" title="حذف"><i class="fas fa-trash"></i></a>
|
<a href="javascript:void(0)" onclick="confirmDelete(<?= $mail['id'] ?>)" class="btn btn-sm btn-outline-danger" title="حذف"><i class="fas fa-trash"></i></a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
@ -363,7 +363,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (canAdd() || canEdit()): ?>
|
<?php if (canAdd('inbound') || canEdit('inbound')): ?>
|
||||||
<!-- Mail Modal -->
|
<!-- Mail Modal -->
|
||||||
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
|
|||||||
@ -9,7 +9,6 @@ function isLoggedIn() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isAdmin() {
|
function isAdmin() {
|
||||||
// Check session first
|
|
||||||
if (isset($_SESSION['user_role']) && strtolower($_SESSION['user_role']) === 'admin') return true;
|
if (isset($_SESSION['user_role']) && strtolower($_SESSION['user_role']) === 'admin') return true;
|
||||||
if (isset($_SESSION['role']) && strtolower($_SESSION['role']) === 'admin') return true;
|
if (isset($_SESSION['role']) && strtolower($_SESSION['role']) === 'admin') return true;
|
||||||
return false;
|
return false;
|
||||||
@ -25,29 +24,40 @@ function redirect($path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Permission helpers
|
// Permission helpers
|
||||||
function canView() {
|
function canView($page = null) {
|
||||||
if (isAdmin()) return true;
|
if (isAdmin()) return true;
|
||||||
|
if ($page) {
|
||||||
|
return $_SESSION['permissions'][$page]['view'] ?? false;
|
||||||
|
}
|
||||||
return $_SESSION['can_view'] ?? false;
|
return $_SESSION['can_view'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canAdd() {
|
function canAdd($page = null) {
|
||||||
if (isAdmin()) return true;
|
if (isAdmin()) return true;
|
||||||
|
if ($page) {
|
||||||
|
return $_SESSION['permissions'][$page]['add'] ?? false;
|
||||||
|
}
|
||||||
return $_SESSION['can_add'] ?? false;
|
return $_SESSION['can_add'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canEdit() {
|
function canEdit($page = null) {
|
||||||
if (isAdmin()) return true;
|
if (isAdmin()) return true;
|
||||||
|
if ($page) {
|
||||||
|
return $_SESSION['permissions'][$page]['edit'] ?? false;
|
||||||
|
}
|
||||||
return $_SESSION['can_edit'] ?? false;
|
return $_SESSION['can_edit'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canViewInternal() {
|
function canDelete($page = null) {
|
||||||
if (isAdmin()) return true;
|
if (isAdmin()) return true;
|
||||||
return canView();
|
if ($page) {
|
||||||
|
return $_SESSION['permissions'][$page]['delete'] ?? false;
|
||||||
|
}
|
||||||
|
return $_SESSION['can_delete'] ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canDelete() {
|
function canViewInternal() {
|
||||||
if (isAdmin()) return true;
|
return canView('internal');
|
||||||
return $_SESSION['can_delete'] ?? false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch user info (theme and permissions)
|
// Fetch user info (theme and permissions)
|
||||||
@ -67,6 +77,22 @@ if (isLoggedIn()) {
|
|||||||
$_SESSION['name'] = $current_user['full_name'] ?: $current_user['username'];
|
$_SESSION['name'] = $current_user['full_name'] ?: $current_user['username'];
|
||||||
$_SESSION['user_role'] = strtolower($current_user['role']);
|
$_SESSION['user_role'] = strtolower($current_user['role']);
|
||||||
$_SESSION['role'] = strtolower($current_user['role']);
|
$_SESSION['role'] = strtolower($current_user['role']);
|
||||||
|
|
||||||
|
// Load granular permissions
|
||||||
|
if (!isset($_SESSION['permissions']) || empty($_SESSION['permissions'])) {
|
||||||
|
$perm_stmt = db()->prepare("SELECT * FROM user_permissions WHERE user_id = ?");
|
||||||
|
$perm_stmt->execute([$_SESSION['user_id']]);
|
||||||
|
$perms = $perm_stmt->fetchAll();
|
||||||
|
$_SESSION['permissions'] = [];
|
||||||
|
foreach ($perms as $p) {
|
||||||
|
$_SESSION['permissions'][$p['page']] = [
|
||||||
|
'view' => (bool)$p['can_view'],
|
||||||
|
'add' => (bool)$p['can_add'],
|
||||||
|
'edit' => (bool)$p['can_edit'],
|
||||||
|
'delete' => (bool)$p['can_delete']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,18 +261,27 @@ $charity_info = $charity_stmt->fetch();
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<?php if (canView('inbound') || canView('outbound')): ?>
|
||||||
<div class="sidebar-heading">البريد الخارجي</div>
|
<div class="sidebar-heading">البريد الخارجي</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('inbound')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'inbound.php' ? 'active' : '' ?>" href="inbound.php">
|
<a class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'inbound.php' && !isset($_GET['my_tasks'])) ? 'active' : '' ?>" href="inbound.php">
|
||||||
<i class="fas fa-download me-2"></i> البريد الوارد
|
<i class="fas fa-download me-2"></i> البريد الوارد
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('outbound')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'outbound.php' ? 'active' : '' ?>" href="outbound.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'outbound.php' ? 'active' : '' ?>" href="outbound.php">
|
||||||
<i class="fas fa-upload me-2"></i> البريد الصادر
|
<i class="fas fa-upload me-2"></i> البريد الصادر
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('internal')): ?>
|
||||||
<div class="sidebar-heading">البريد الداخلي</div>
|
<div class="sidebar-heading">البريد الداخلي</div>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'internal_inbox.php' ? 'active' : '' ?>" href="internal_inbox.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'internal_inbox.php' ? 'active' : '' ?>" href="internal_inbox.php">
|
||||||
@ -258,28 +293,38 @@ $charity_info = $charity_stmt->fetch();
|
|||||||
<i class="fas fa-paper-plane me-2"></i> الصادر الداخلي
|
<i class="fas fa-paper-plane me-2"></i> الصادر الداخلي
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="sidebar-heading">التقارير</div>
|
<div class="sidebar-heading">التقارير</div>
|
||||||
<?php if (isAdmin()): ?>
|
<?php if (canView('reports')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'overdue_report.php' ? 'active' : '' ?>" href="overdue_report.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'overdue_report.php' ? 'active' : '' ?>" href="overdue_report.php">
|
||||||
<i class="fas fa-clock me-2"></i> بريد متأخر
|
<i class="fas fa-clock me-2"></i> بريد متأخر
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('inbound')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'inbound.php' && isset($_GET['my_tasks'])) ? 'active' : '' ?>" href="inbound.php?my_tasks=1">
|
<a class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'inbound.php' && isset($_GET['my_tasks'])) ? 'active' : '' ?>" href="inbound.php?my_tasks=1">
|
||||||
<i class="fas fa-tasks me-2"></i> مهامي الحالية
|
<i class="fas fa-tasks me-2"></i> مهامي الحالية
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (isAdmin()): ?>
|
<?php if (canView('users') || canView('settings')): ?>
|
||||||
<div class="sidebar-heading">الإدارة</div>
|
<div class="sidebar-heading">الإدارة</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('users')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'users.php' ? 'active' : '' ?>" href="users.php">
|
<a class="nav-link <?= basename($_SERVER['PHP_SELF']) == 'users.php' ? 'active' : '' ?>" href="users.php">
|
||||||
<i class="fas fa-users me-2"></i> إدارة المستخدمين
|
<i class="fas fa-users me-2"></i> إدارة المستخدمين
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('settings')): ?>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'charity-settings.php' && !isset($_GET['tab'])) ? 'active' : '' ?>" href="charity-settings.php" onclick="localStorage.setItem('activeSettingsTab', '#general');">
|
<a class="nav-link <?= (basename($_SERVER['PHP_SELF']) == 'charity-settings.php' && !isset($_GET['tab'])) ? 'active' : '' ?>" href="charity-settings.php" onclick="localStorage.setItem('activeSettingsTab', '#general');">
|
||||||
<i class="fas fa-cog me-2"></i> الإعدادات
|
<i class="fas fa-cog me-2"></i> الإعدادات
|
||||||
|
|||||||
92
index.php
92
index.php
@ -10,8 +10,8 @@ $user_id = $_SESSION['user_id'];
|
|||||||
$is_admin = isAdmin();
|
$is_admin = isAdmin();
|
||||||
|
|
||||||
// Stats
|
// Stats
|
||||||
$total_inbound = db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'inbound'")->fetchColumn();
|
$total_inbound = canView('inbound') ? db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'inbound'")->fetchColumn() : 0;
|
||||||
$total_outbound = db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'outbound'")->fetchColumn();
|
$total_outbound = canView('outbound') ? db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'outbound'")->fetchColumn() : 0;
|
||||||
|
|
||||||
// Fetch statuses for badge and count
|
// Fetch statuses for badge and count
|
||||||
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
||||||
@ -26,35 +26,60 @@ foreach ($statuses_data as $id => $s) {
|
|||||||
}
|
}
|
||||||
$in_progress_count = 0;
|
$in_progress_count = 0;
|
||||||
if ($in_progress_id) {
|
if ($in_progress_id) {
|
||||||
$stmt = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ?");
|
$where_types = [];
|
||||||
|
if (canView('inbound')) $where_types[] = "'inbound'";
|
||||||
|
if (canView('outbound')) $where_types[] = "'outbound'";
|
||||||
|
|
||||||
|
if (!empty($where_types)) {
|
||||||
|
$types_sql = implode(',', $where_types);
|
||||||
|
$stmt = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE status_id = ? AND type IN ($types_sql)");
|
||||||
$stmt->execute([$in_progress_id]);
|
$stmt->execute([$in_progress_id]);
|
||||||
$in_progress_count = $stmt->fetchColumn();
|
$in_progress_count = $stmt->fetchColumn();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// My Assignments
|
// My Assignments
|
||||||
$my_assignments = db()->prepare("SELECT m.*, s.name as status_name, s.color as status_color
|
$my_assignments = [];
|
||||||
|
$assignment_types = [];
|
||||||
|
if (canView('inbound')) $assignment_types[] = "'inbound'";
|
||||||
|
if (canView('outbound')) $assignment_types[] = "'outbound'";
|
||||||
|
if (canView('internal')) $assignment_types[] = "'internal'";
|
||||||
|
|
||||||
|
if (!empty($assignment_types)) {
|
||||||
|
$types_sql = implode(',', $assignment_types);
|
||||||
|
$my_assignments = db()->prepare("SELECT m.*, s.name as status_name, s.color as status_color
|
||||||
FROM mailbox m
|
FROM mailbox m
|
||||||
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
WHERE m.assigned_to = ?
|
WHERE m.assigned_to = ? AND m.type IN ($types_sql)
|
||||||
ORDER BY m.created_at DESC LIMIT 5");
|
ORDER BY m.created_at DESC LIMIT 5");
|
||||||
$my_assignments->execute([$user_id]);
|
$my_assignments->execute([$user_id]);
|
||||||
$my_assignments = $my_assignments->fetchAll();
|
$my_assignments = $my_assignments->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
// Recent Mail (Global for Admin/Clerk, otherwise limited)
|
// Recent Mail (Global for Admin/Clerk, otherwise limited)
|
||||||
$recent_mail_query = "SELECT m.*, s.name as status_name, s.color as status_color, u.full_name as assigned_to_name
|
$recent_mail = [];
|
||||||
|
$recent_types = [];
|
||||||
|
if (canView('inbound')) $recent_types[] = "'inbound'";
|
||||||
|
if (canView('outbound')) $recent_types[] = "'outbound'";
|
||||||
|
|
||||||
|
if (!empty($recent_types)) {
|
||||||
|
$types_sql = implode(',', $recent_types);
|
||||||
|
$recent_mail_query = "SELECT m.*, s.name as status_name, s.color as status_color, u.full_name as assigned_to_name
|
||||||
FROM mailbox m
|
FROM mailbox m
|
||||||
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
LEFT JOIN users u ON m.assigned_to = u.id";
|
LEFT JOIN users u ON m.assigned_to = u.id
|
||||||
|
WHERE m.type IN ($types_sql)";
|
||||||
|
|
||||||
if (!$is_admin && ($_SESSION['user_role'] ?? '') !== 'clerk') {
|
if (!$is_admin && ($_SESSION['user_role'] ?? '') !== 'clerk') {
|
||||||
$recent_mail_query .= " WHERE m.assigned_to = ? OR m.created_by = ?";
|
$recent_mail_query .= " AND (m.assigned_to = ? OR m.created_by = ?)";
|
||||||
$recent_stmt = db()->prepare($recent_mail_query . " ORDER BY m.created_at DESC LIMIT 10");
|
$recent_stmt = db()->prepare($recent_mail_query . " ORDER BY m.created_at DESC LIMIT 10");
|
||||||
$recent_stmt->execute([$user_id, $user_id]);
|
$recent_stmt->execute([$user_id, $user_id]);
|
||||||
} else {
|
} else {
|
||||||
$recent_stmt = db()->prepare($recent_mail_query . " ORDER BY m.created_at DESC LIMIT 10");
|
$recent_stmt = db()->prepare($recent_mail_query . " ORDER BY m.created_at DESC LIMIT 10");
|
||||||
$recent_stmt->execute();
|
$recent_stmt->execute();
|
||||||
|
}
|
||||||
|
$recent_mail = $recent_stmt->fetchAll();
|
||||||
}
|
}
|
||||||
$recent_mail = $recent_stmt->fetchAll();
|
|
||||||
|
|
||||||
function getStatusBadge($mail) {
|
function getStatusBadge($mail) {
|
||||||
$status_name = $mail['status_name'] ?? 'غير معروف';
|
$status_name = $mail['status_name'] ?? 'غير معروف';
|
||||||
@ -74,19 +99,26 @@ function getStatusBadge($mail) {
|
|||||||
<h1 class="h2">لوحة التحكم الإدارية</h1>
|
<h1 class="h2">لوحة التحكم الإدارية</h1>
|
||||||
<div class="btn-toolbar mb-2 mb-md-0">
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
<div class="btn-group me-2">
|
<div class="btn-group me-2">
|
||||||
|
<?php if (canView('settings')): ?>
|
||||||
<a href="charity-settings.php" class="btn btn-sm btn-outline-dark"><i class="fas fa-cog me-1"></i> الإعدادات</a>
|
<a href="charity-settings.php" class="btn btn-sm btn-outline-dark"><i class="fas fa-cog me-1"></i> الإعدادات</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (canAdd('inbound')): ?>
|
||||||
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة بريد وارد</a>
|
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة بريد وارد</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (canAdd('outbound')): ?>
|
||||||
<a href="outbound.php" class="btn btn-sm btn-outline-secondary">إضافة بريد صادر</a>
|
<a href="outbound.php" class="btn btn-sm btn-outline-secondary">إضافة بريد صادر</a>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Overdue Alert -->
|
<!-- Overdue Alert -->
|
||||||
<?php
|
<?php
|
||||||
$overdue_count = db()->query("SELECT COUNT(*) FROM mailbox WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')")->fetchColumn();
|
if (canView('reports')):
|
||||||
if ($overdue_count > 0):
|
$overdue_count = db()->query("SELECT COUNT(*) FROM mailbox WHERE due_date < CURDATE() AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed') AND type != 'internal'")->fetchColumn();
|
||||||
?>
|
if ($overdue_count > 0):
|
||||||
<div class="row mb-4">
|
?>
|
||||||
|
<div class="row mb-4">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="alert alert-danger shadow-sm border-0 d-flex align-items-center justify-content-between mb-0">
|
<div class="alert alert-danger shadow-sm border-0 d-flex align-items-center justify-content-between mb-0">
|
||||||
<div>
|
<div>
|
||||||
@ -96,11 +128,15 @@ if ($overdue_count > 0):
|
|||||||
<a href="overdue_report.php" class="btn btn-danger btn-sm">عرض التقرير</a>
|
<a href="overdue_report.php" class="btn btn-danger btn-sm">عرض التقرير</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php
|
||||||
|
endif;
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
|
||||||
<!-- Stats Cards -->
|
<!-- Stats Cards -->
|
||||||
<div class="row g-4 mb-4">
|
<div class="row g-4 mb-4">
|
||||||
|
<?php if (canView('inbound')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-primary border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-primary border-4">
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
@ -114,6 +150,9 @@ if ($overdue_count > 0):
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('outbound')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
@ -127,6 +166,9 @@ if ($overdue_count > 0):
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('inbound') || canView('outbound')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
@ -140,6 +182,9 @@ if ($overdue_count > 0):
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (canView('users')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-warning border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-warning border-4">
|
||||||
<div class="d-flex align-items-center justify-content-between">
|
<div class="d-flex align-items-center justify-content-between">
|
||||||
@ -153,6 +198,7 @@ if ($overdue_count > 0):
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (!empty($my_assignments)): ?>
|
<?php if (!empty($my_assignments)): ?>
|
||||||
@ -204,6 +250,7 @@ if ($overdue_count > 0):
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<?php if (!empty($recent_mail)): ?>
|
||||||
<!-- Recent Mail -->
|
<!-- Recent Mail -->
|
||||||
<div class="card shadow-sm border-0 mb-4">
|
<div class="card shadow-sm border-0 mb-4">
|
||||||
<div class="card-header bg-white py-3">
|
<div class="card-header bg-white py-3">
|
||||||
@ -228,7 +275,6 @@ if ($overdue_count > 0):
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if ($recent_mail): ?>
|
|
||||||
<?php foreach ($recent_mail as $mail): ?>
|
<?php foreach ($recent_mail as $mail): ?>
|
||||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>'">
|
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>'">
|
||||||
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
||||||
@ -261,15 +307,11 @@ if ($overdue_count > 0):
|
|||||||
<td class="pe-4 text-center"><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
<td class="pe-4 text-center"><?= date('Y-m-d', strtotime($mail['date_registered'])) ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php else: ?>
|
|
||||||
<tr>
|
|
||||||
<td colspan="8" class="text-center py-4 text-muted">لا يوجد بريد مسجل حالياً</td>
|
|
||||||
</tr>
|
|
||||||
<?php endif; ?>
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
|
|
||||||
// Every logged-in user can access their own internal mail
|
// Every logged-in user can access their own internal mail if they have permission
|
||||||
if (!isLoggedIn()) {
|
if (!canView('internal')) {
|
||||||
redirect('login.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
@ -61,9 +61,11 @@ function getStatusBadgeInternal($mail) {
|
|||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2"><i class="fas fa-inbox me-2 text-primary"></i> بريد الموظفين - الوارد</h1>
|
<h1 class="h2"><i class="fas fa-inbox me-2 text-primary"></i> بريد الموظفين - الوارد</h1>
|
||||||
<div class="btn-toolbar mb-2 mb-md-0">
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
|
<?php if (canAdd('internal')): ?>
|
||||||
<a href="internal_outbox.php?action=compose" class="btn btn-primary shadow-sm">
|
<a href="internal_outbox.php?action=compose" class="btn btn-primary shadow-sm">
|
||||||
<i class="fas fa-paper-plane me-1"></i> إرسال رسالة جديدة
|
<i class="fas fa-paper-plane me-1"></i> إرسال رسالة جديدة
|
||||||
</a>
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
require_once __DIR__ . '/mail/MailService.php';
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
if (!isLoggedIn()) {
|
if (!canView('internal')) {
|
||||||
redirect('login.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
@ -12,6 +12,9 @@ $error = '';
|
|||||||
|
|
||||||
// Handle composing a new message
|
// Handle composing a new message
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'compose') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'compose') {
|
||||||
|
if (!canAdd('internal')) {
|
||||||
|
$error = 'عذراً، ليس لديك الصلاحية لإرسال رسائل';
|
||||||
|
} else {
|
||||||
$recipient_id = $_POST['recipient_id'] ?? null;
|
$recipient_id = $_POST['recipient_id'] ?? null;
|
||||||
$subject = $_POST['subject'] ?? '';
|
$subject = $_POST['subject'] ?? '';
|
||||||
$description = $_POST['description'] ?? '';
|
$description = $_POST['description'] ?? '';
|
||||||
@ -50,12 +53,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
|
|||||||
$recipient = $stmt_recp->fetch();
|
$recipient = $stmt_recp->fetch();
|
||||||
|
|
||||||
if ($recipient && !empty($recipient['email'])) {
|
if ($recipient && !empty($recipient['email'])) {
|
||||||
$email_subject = "رسالة داخلية جديدة من " . $_SESSION['username'];
|
$email_subject = "رسالة داخلية جديدة من " . $_SESSION['name'];
|
||||||
$htmlBody = "
|
$htmlBody = "
|
||||||
<div dir='rtl' style='font-family: Arial, sans-serif;'>
|
<div dir='rtl' style='font-family: Arial, sans-serif;'>
|
||||||
<h3>لديك رسالة داخلية جديدة</h3>
|
<h3>لديك رسالة داخلية جديدة</h3>
|
||||||
<p><strong>الموضوع:</strong> " . htmlspecialchars($subject) . "</p>
|
<p><strong>الموضوع:</strong> " . htmlspecialchars($subject) . "</p>
|
||||||
<p><strong>المرسل:</strong> " . htmlspecialchars($_SESSION['username']) . "</p>
|
<p><strong>المرسل:</strong> " . htmlspecialchars($_SESSION['name']) . "</p>
|
||||||
<hr>
|
<hr>
|
||||||
<div>" . $description . "</div>
|
<div>" . $description . "</div>
|
||||||
<br>
|
<br>
|
||||||
@ -75,6 +78,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['
|
|||||||
} else {
|
} else {
|
||||||
$error = 'يرجى اختيار المرسل إليه وكتابة الموضوع';
|
$error = 'يرجى اختيار المرسل إليه وكتابة الموضوع';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get session messages
|
// Get session messages
|
||||||
@ -143,9 +147,11 @@ function getStatusBadgeInternal($mail) {
|
|||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2"><i class="fas fa-paper-plane me-2 text-success"></i> بريد الموظفين - الصادر</h1>
|
<h1 class="h2"><i class="fas fa-paper-plane me-2 text-success"></i> بريد الموظفين - الصادر</h1>
|
||||||
<div class="btn-toolbar mb-2 mb-md-0">
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
|
<?php if (canAdd('internal')): ?>
|
||||||
<button type="button" class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#composeModal">
|
<button type="button" class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#composeModal">
|
||||||
<i class="fas fa-plus-circle me-1"></i> إنشاء رسالة جديدة
|
<i class="fas fa-plus-circle me-1"></i> إنشاء رسالة جديدة
|
||||||
</button>
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -296,6 +302,7 @@ function getStatusBadgeInternal($mail) {
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
if (typeof ClassicEditor !== 'undefined') {
|
||||||
ClassicEditor
|
ClassicEditor
|
||||||
.create(document.querySelector('#composeEditor'), {
|
.create(document.querySelector('#composeEditor'), {
|
||||||
language: 'ar',
|
language: 'ar',
|
||||||
@ -310,6 +317,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
<?php if (isset($_GET['action']) && $_GET['action'] === 'compose'): ?>
|
<?php if (isset($_GET['action']) && $_GET['action'] === 'compose'): ?>
|
||||||
var myModal = new bootstrap.Modal(document.getElementById('composeModal'));
|
var myModal = new bootstrap.Modal(document.getElementById('composeModal'));
|
||||||
|
|||||||
16
outbound.php
16
outbound.php
@ -3,7 +3,7 @@ require_once __DIR__ . '/includes/header.php';
|
|||||||
require_once __DIR__ . '/mail/MailService.php';
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
// Check if user has view permission
|
// Check if user has view permission
|
||||||
if (!canView()) {
|
if (!canView('outbound')) {
|
||||||
redirect('index.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$action = $_POST['action'] ?? '';
|
$action = $_POST['action'] ?? '';
|
||||||
|
|
||||||
// Permission checks for POST actions
|
// Permission checks for POST actions
|
||||||
if (($action === 'add' && !canAdd()) || ($action === 'edit' && !canEdit())) {
|
if (($action === 'add' && !canAdd('outbound')) || ($action === 'edit' && !canEdit('outbound'))) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء';
|
$error = 'عذراً، ليس لديك الصلاحية للقيام بهذا الإجراء';
|
||||||
} else {
|
} else {
|
||||||
$type = 'outbound';
|
$type = 'outbound';
|
||||||
@ -147,7 +147,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
|
|
||||||
// Delete action
|
// Delete action
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
if (!canDelete()) {
|
if (!canDelete('outbound')) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لحذف السجلات';
|
$error = 'عذراً، ليس لديك الصلاحية لحذف السجلات';
|
||||||
} else {
|
} else {
|
||||||
$id = $_GET['id'];
|
$id = $_GET['id'];
|
||||||
@ -219,7 +219,7 @@ $users_list = db()->query("SELECT id, full_name FROM users ORDER BY full_name")-
|
|||||||
// Handle Deep Link for Edit
|
// Handle Deep Link for Edit
|
||||||
$deepLinkData = null;
|
$deepLinkData = null;
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
||||||
if (canEdit()) {
|
if (canEdit('outbound')) {
|
||||||
$stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'outbound'");
|
$stmt = db()->prepare("SELECT * FROM mailbox WHERE id = ? AND type = 'outbound'");
|
||||||
$stmt->execute([$_GET['id']]);
|
$stmt->execute([$_GET['id']]);
|
||||||
$deepLinkData = $stmt->fetch();
|
$deepLinkData = $stmt->fetch();
|
||||||
@ -242,7 +242,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
|
|
||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2">البريد الصادر</h1>
|
<h1 class="h2">البريد الصادر</h1>
|
||||||
<?php if (canAdd()): ?>
|
<?php if (canAdd('outbound')): ?>
|
||||||
<button type="button" class="btn btn-primary shadow-sm" onclick="openMailModal('add')">
|
<button type="button" class="btn btn-primary shadow-sm" onclick="openMailModal('add')">
|
||||||
<i class="fas fa-plus-circle me-1"></i> إضافة جديد
|
<i class="fas fa-plus-circle me-1"></i> إضافة جديد
|
||||||
</button>
|
</button>
|
||||||
@ -330,14 +330,14 @@ function getStatusBadgeInList($mail) {
|
|||||||
<td class="pe-4 text-center">
|
<td class="pe-4 text-center">
|
||||||
<a href="view_mail.php?id=<?= $mail['id'] ?>" class="btn btn-sm btn-outline-info" title="عرض التفاصيل"><i class="fas fa-eye"></i></a>
|
<a href="view_mail.php?id=<?= $mail['id'] ?>" class="btn btn-sm btn-outline-info" title="عرض التفاصيل"><i class="fas fa-eye"></i></a>
|
||||||
|
|
||||||
<?php if (canEdit()): ?>
|
<?php if (canEdit('outbound')): ?>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||||
onclick='openMailModal("edit", <?= json_encode($mail) ?>)' title="تعديل">
|
onclick='openMailModal("edit", <?= json_encode($mail) ?>)' title="تعديل">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (canDelete()): ?>
|
<?php if (canDelete('outbound')): ?>
|
||||||
<a href="javascript:void(0)" onclick="confirmDelete(<?= $mail['id'] ?>)" class="btn btn-sm btn-outline-danger" title="حذف"><i class="fas fa-trash"></i></a>
|
<a href="javascript:void(0)" onclick="confirmDelete(<?= $mail['id'] ?>)" class="btn btn-sm btn-outline-danger" title="حذف"><i class="fas fa-trash"></i></a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
@ -376,7 +376,7 @@ function getStatusBadgeInList($mail) {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if (canAdd() || canEdit()): ?>
|
<?php if (canAdd('outbound') || canEdit('outbound')): ?>
|
||||||
<!-- Mail Modal -->
|
<!-- Mail Modal -->
|
||||||
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
<div class="modal fade" id="mailModal" tabindex="-1" aria-labelledby="mailModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once 'includes/header.php';
|
require_once 'includes/header.php';
|
||||||
|
|
||||||
if (!isAdmin()) {
|
if (!canView('reports')) {
|
||||||
redirect('index.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
|
|
||||||
// Check if user has view permission
|
// Check if user has view permission
|
||||||
if (!canView()) {
|
if (!isLoggedIn()) {
|
||||||
// If they can't even view, they shouldn't be here, but header.php already handles basic login.
|
redirect('login.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$user_id = $_SESSION['user_id'];
|
$user_id = $_SESSION['user_id'];
|
||||||
@ -16,42 +16,61 @@ $stmt = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE assigned_to = ?");
|
|||||||
$stmt->execute([$user_id]);
|
$stmt->execute([$user_id]);
|
||||||
$my_total_assignments = $stmt->fetchColumn();
|
$my_total_assignments = $stmt->fetchColumn();
|
||||||
|
|
||||||
$stmt = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE assigned_to = ? AND status != 'closed'");
|
$stmt = db()->prepare("SELECT COUNT(*) FROM mailbox WHERE assigned_to = ? AND status_id IN (SELECT id FROM mailbox_statuses WHERE name != 'closed')");
|
||||||
$stmt->execute([$user_id]);
|
$stmt->execute([$user_id]);
|
||||||
$my_pending_tasks = $stmt->fetchColumn();
|
$my_pending_tasks = $stmt->fetchColumn();
|
||||||
|
|
||||||
// Global Stats (for Clerks or if we want to show them)
|
// Global Stats (for Clerks or if we want to show them)
|
||||||
$total_inbound = db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'inbound'")->fetchColumn();
|
$total_inbound = canView('inbound') ? db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'inbound'")->fetchColumn() : 0;
|
||||||
$total_outbound = db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'outbound'")->fetchColumn();
|
$total_outbound = canView('outbound') ? db()->query("SELECT COUNT(*) FROM mailbox WHERE type = 'outbound'")->fetchColumn() : 0;
|
||||||
|
|
||||||
// Fetch statuses for badge and count
|
// Fetch statuses for badge and count
|
||||||
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
$statuses_data = db()->query("SELECT * FROM mailbox_statuses")->fetchAll(PDO::FETCH_UNIQUE);
|
||||||
|
|
||||||
// My Assignments
|
// My Assignments
|
||||||
$my_assignments = db()->prepare("SELECT m.*, s.name as status_name, s.color as status_color
|
$my_assignments = [];
|
||||||
|
$assignment_types = [];
|
||||||
|
if (canView('inbound')) $assignment_types[] = "'inbound'";
|
||||||
|
if (canView('outbound')) $assignment_types[] = "'outbound'";
|
||||||
|
if (canView('internal')) $assignment_types[] = "'internal'";
|
||||||
|
|
||||||
|
if (!empty($assignment_types)) {
|
||||||
|
$types_sql = implode(',', $assignment_types);
|
||||||
|
$my_assignments = db()->prepare("SELECT m.*, s.name as status_name, s.color as status_color
|
||||||
FROM mailbox m
|
FROM mailbox m
|
||||||
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
WHERE m.assigned_to = ?
|
WHERE m.assigned_to = ? AND m.type IN ($types_sql)
|
||||||
ORDER BY m.created_at DESC LIMIT 10");
|
ORDER BY m.created_at DESC LIMIT 10");
|
||||||
$my_assignments->execute([$user_id]);
|
$my_assignments->execute([$user_id]);
|
||||||
$my_assignments = $my_assignments->fetchAll();
|
$my_assignments = $my_assignments->fetchAll();
|
||||||
|
}
|
||||||
|
|
||||||
// Recent Activity
|
// Recent Activity
|
||||||
$recent_query = "SELECT m.*, s.name as status_name, s.color as status_color, u.full_name as assigned_to_name
|
$recent_activity = [];
|
||||||
|
$recent_types = [];
|
||||||
|
if (canView('inbound')) $recent_types[] = "'inbound'";
|
||||||
|
if (canView('outbound')) $recent_types[] = "'outbound'";
|
||||||
|
if (canView('internal')) $recent_types[] = "'internal'";
|
||||||
|
|
||||||
|
if (!empty($recent_types)) {
|
||||||
|
$types_sql = implode(',', $recent_types);
|
||||||
|
$recent_query = "SELECT m.*, s.name as status_name, s.color as status_color, u.full_name as assigned_to_name
|
||||||
FROM mailbox m
|
FROM mailbox m
|
||||||
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
LEFT JOIN mailbox_statuses s ON m.status_id = s.id
|
||||||
LEFT JOIN users u ON m.assigned_to = u.id";
|
LEFT JOIN users u ON m.assigned_to = u.id
|
||||||
|
WHERE m.type IN ($types_sql)";
|
||||||
|
|
||||||
if ($is_admin || $is_clerk) {
|
if ($is_admin || $is_clerk) {
|
||||||
// Admins and Clerks see all recent activity EXCEPT internal mail they are not part of
|
// Admins and Clerks see all recent activity EXCEPT internal mail they are not part of
|
||||||
$recent_stmt = db()->prepare($recent_query . " WHERE m.type != 'internal' OR m.assigned_to = ? OR m.created_by = ? ORDER BY m.updated_at DESC LIMIT 10");
|
$recent_stmt = db()->prepare($recent_query . " AND (m.type != 'internal' OR m.assigned_to = ? OR m.created_by = ?) ORDER BY m.updated_at DESC LIMIT 10");
|
||||||
$recent_stmt->execute([$user_id, $user_id]);
|
$recent_stmt->execute([$user_id, $user_id]);
|
||||||
} else {
|
} else {
|
||||||
// Staff see only theirs
|
// Staff see only theirs
|
||||||
$recent_stmt = db()->prepare($recent_query . " WHERE m.assigned_to = ? OR m.created_by = ? ORDER BY m.updated_at DESC LIMIT 10");
|
$recent_stmt = db()->prepare($recent_query . " AND (m.assigned_to = ? OR m.created_by = ?) ORDER BY m.updated_at DESC LIMIT 10");
|
||||||
$recent_stmt->execute([$user_id, $user_id]);
|
$recent_stmt->execute([$user_id, $user_id]);
|
||||||
|
}
|
||||||
|
$recent_activity = $recent_stmt->fetchAll();
|
||||||
}
|
}
|
||||||
$recent_activity = $recent_stmt->fetchAll();
|
|
||||||
|
|
||||||
function getStatusBadge($mail) {
|
function getStatusBadge($mail) {
|
||||||
$status_name = $mail['status_name'] ?? 'غير معروف';
|
$status_name = $mail['status_name'] ?? 'غير معروف';
|
||||||
@ -74,7 +93,7 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="d-flex justify-content-between align-items-center position-relative">
|
<div class="d-flex justify-content-between align-items-center position-relative">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="fw-bold mb-1">مرحباً، <?= htmlspecialchars($current_user['full_name'] ?? $_SESSION['username']) ?>!</h2>
|
<h2 class="fw-bold mb-1">مرحباً، <?= htmlspecialchars($current_user['full_name'] ?? $_SESSION['name']) ?>!</h2>
|
||||||
<p class="mb-0 opacity-75">
|
<p class="mb-0 opacity-75">
|
||||||
أنت مسجل كـ <strong>
|
أنت مسجل كـ <strong>
|
||||||
<?php
|
<?php
|
||||||
@ -135,6 +154,7 @@ function getStatusBadge($mail) {
|
|||||||
|
|
||||||
<?php if ($is_admin || $is_clerk): ?>
|
<?php if ($is_admin || $is_clerk): ?>
|
||||||
<!-- Admin/Clerk specific stats -->
|
<!-- Admin/Clerk specific stats -->
|
||||||
|
<?php if (canView('inbound')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-info border-4">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -148,6 +168,8 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (canView('outbound')): ?>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
<div class="card h-100 p-3 shadow-sm border-0 border-start border-success border-4">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
@ -161,6 +183,7 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<!-- Staff specific stats -->
|
<!-- Staff specific stats -->
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
@ -198,6 +221,7 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -208,8 +232,10 @@ function getStatusBadge($mail) {
|
|||||||
<div class="card-header bg-white py-3 border-bottom d-flex justify-content-between align-items-center">
|
<div class="card-header bg-white py-3 border-bottom d-flex justify-content-between align-items-center">
|
||||||
<h5 class="mb-0 fw-bold"><i class="fas fa-clipboard-list me-2 text-primary"></i> مهامي المسندة</h5>
|
<h5 class="mb-0 fw-bold"><i class="fas fa-clipboard-list me-2 text-primary"></i> مهامي المسندة</h5>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<?php if (canAdd()): ?>
|
<?php if (canAdd('inbound')): ?>
|
||||||
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة وارد</a>
|
<a href="inbound.php?action=add" class="btn btn-sm btn-outline-primary">إضافة وارد</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (canAdd('outbound')): ?>
|
||||||
<a href="outbound.php" class="btn btn-sm btn-outline-success">إضافة صادر</a>
|
<a href="outbound.php" class="btn btn-sm btn-outline-success">إضافة صادر</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
@ -227,7 +253,7 @@ function getStatusBadge($mail) {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if ($my_assignments): ?>
|
<?php if (!empty($my_assignments)): ?>
|
||||||
<?php foreach ($my_assignments as $mail): ?>
|
<?php foreach ($my_assignments as $mail): ?>
|
||||||
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>'">
|
<tr style="cursor: pointer;" onclick="window.location='view_mail.php?id=<?= $mail['id'] ?>'">
|
||||||
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
<td class="ps-4 fw-bold text-primary"><?= $mail['ref_no'] ?></td>
|
||||||
@ -270,7 +296,7 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0" style="max-height: 500px; overflow-y: auto;">
|
<div class="card-body p-0" style="max-height: 500px; overflow-y: auto;">
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<?php if ($recent_activity): ?>
|
<?php if (!empty($recent_activity)): ?>
|
||||||
<?php foreach ($recent_activity as $act): ?>
|
<?php foreach ($recent_activity as $act): ?>
|
||||||
<a href="view_mail.php?id=<?= $act['id'] ?>" class="list-group-item list-group-item-action p-3 border-0 border-bottom">
|
<a href="view_mail.php?id=<?= $act['id'] ?>" class="list-group-item list-group-item-action p-3 border-0 border-bottom">
|
||||||
<div class="d-flex w-100 justify-content-between mb-1">
|
<div class="d-flex w-100 justify-content-between mb-1">
|
||||||
@ -294,7 +320,9 @@ function getStatusBadge($mail) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer bg-light text-center py-2">
|
<div class="card-footer bg-light text-center py-2">
|
||||||
|
<?php if (canView('inbound')): ?>
|
||||||
<a href="inbound.php" class="small text-decoration-none">عرض كافة المراسلات <i class="fas fa-chevron-left ms-1"></i></a>
|
<a href="inbound.php" class="small text-decoration-none">عرض كافة المراسلات <i class="fas fa-chevron-left ms-1"></i></a>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
244
users.php
244
users.php
@ -1,13 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
|
|
||||||
if (!isAdmin()) {
|
if (!canView('users')) {
|
||||||
redirect('index.php');
|
redirect('index.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
$error = '';
|
$error = '';
|
||||||
$success = '';
|
$success = '';
|
||||||
|
|
||||||
|
$modules = [
|
||||||
|
'inbound' => 'البريد الوارد',
|
||||||
|
'outbound' => 'البريد الصادر',
|
||||||
|
'internal' => 'البريد الداخلي',
|
||||||
|
'users' => 'إدارة المستخدمين',
|
||||||
|
'settings' => 'الإعدادات',
|
||||||
|
'reports' => 'التقارير'
|
||||||
|
];
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$action = $_POST['action'] ?? '';
|
$action = $_POST['action'] ?? '';
|
||||||
$username = $_POST['username'] ?? '';
|
$username = $_POST['username'] ?? '';
|
||||||
@ -16,21 +25,39 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$password = $_POST['password'] ?? '';
|
$password = $_POST['password'] ?? '';
|
||||||
$id = $_POST['id'] ?? 0;
|
$id = $_POST['id'] ?? 0;
|
||||||
|
|
||||||
// Permissions
|
// Global permissions (legacy/fallback)
|
||||||
$can_view = isset($_POST['can_view']) ? 1 : 0;
|
$can_view = isset($_POST['can_view_global']) ? 1 : 0;
|
||||||
$can_add = isset($_POST['can_add']) ? 1 : 0;
|
$can_add = isset($_POST['can_add_global']) ? 1 : 0;
|
||||||
$can_edit = isset($_POST['can_edit']) ? 1 : 0;
|
$can_edit = isset($_POST['can_edit_global']) ? 1 : 0;
|
||||||
$can_delete = isset($_POST['can_delete']) ? 1 : 0;
|
$can_delete = isset($_POST['can_delete_global']) ? 1 : 0;
|
||||||
|
|
||||||
if ($action === 'add') {
|
if ($action === 'add') {
|
||||||
|
if (!canAdd('users')) redirect('users.php');
|
||||||
if ($username && $password && $full_name) {
|
if ($username && $password && $full_name) {
|
||||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
try {
|
try {
|
||||||
$stmt = db()->prepare("INSERT INTO users (username, password, full_name, role, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
$pdo = db();
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO users (username, password, full_name, role, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
$stmt->execute([$username, $hashed_password, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete]);
|
$stmt->execute([$username, $hashed_password, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete]);
|
||||||
|
$user_id = $pdo->lastInsertId();
|
||||||
|
|
||||||
|
// Save page permissions
|
||||||
|
$perm_stmt = $pdo->prepare("INSERT INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?)");
|
||||||
|
foreach ($modules as $module => $label) {
|
||||||
|
$m_view = isset($_POST["perm_{$module}_view"]) ? 1 : 0;
|
||||||
|
$m_add = isset($_POST["perm_{$module}_add"]) ? 1 : 0;
|
||||||
|
$m_edit = isset($_POST["perm_{$module}_edit"]) ? 1 : 0;
|
||||||
|
$m_delete = isset($_POST["perm_{$module}_delete"]) ? 1 : 0;
|
||||||
|
$perm_stmt->execute([$user_id, $module, $m_view, $m_add, $m_edit, $m_delete]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
$_SESSION['success'] = 'تم إضافة المستخدم بنجاح';
|
$_SESSION['success'] = 'تم إضافة المستخدم بنجاح';
|
||||||
redirect('users.php');
|
redirect('users.php');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
if (isset($pdo)) $pdo->rollBack();
|
||||||
if ($e->getCode() == 23000) {
|
if ($e->getCode() == 23000) {
|
||||||
$error = 'اسم المستخدم موجود مسبقاً';
|
$error = 'اسم المستخدم موجود مسبقاً';
|
||||||
} else {
|
} else {
|
||||||
@ -41,19 +68,43 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
$error = 'يرجى ملء جميع الحقول المطلوبة';
|
$error = 'يرجى ملء جميع الحقول المطلوبة';
|
||||||
}
|
}
|
||||||
} elseif ($action === 'edit') {
|
} elseif ($action === 'edit') {
|
||||||
|
if (!canEdit('users')) redirect('users.php');
|
||||||
if ($username && $full_name && $id) {
|
if ($username && $full_name && $id) {
|
||||||
try {
|
try {
|
||||||
|
$pdo = db();
|
||||||
|
$pdo->beginTransaction();
|
||||||
|
|
||||||
if ($password) {
|
if ($password) {
|
||||||
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
||||||
$stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, password = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, password = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
||||||
$stmt->execute([$username, $full_name, $role, $hashed_password, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
$stmt->execute([$username, $full_name, $role, $hashed_password, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
||||||
} else {
|
} else {
|
||||||
$stmt = db()->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
$stmt = $pdo->prepare("UPDATE users SET username = ?, full_name = ?, role = ?, can_view = ?, can_add = ?, can_edit = ?, can_delete = ? WHERE id = ?");
|
||||||
$stmt->execute([$username, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
$stmt->execute([$username, $full_name, $role, $can_view, $can_add, $can_edit, $can_delete, $id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update page permissions
|
||||||
|
$pdo->prepare("DELETE FROM user_permissions WHERE user_id = ?")->execute([$id]);
|
||||||
|
$perm_stmt = $pdo->prepare("INSERT INTO user_permissions (user_id, page, can_view, can_add, can_edit, can_delete) VALUES (?, ?, ?, ?, ?, ?)");
|
||||||
|
foreach ($modules as $module => $label) {
|
||||||
|
$m_view = isset($_POST["perm_{$module}_view"]) ? 1 : 0;
|
||||||
|
$m_add = isset($_POST["perm_{$module}_add"]) ? 1 : 0;
|
||||||
|
$m_edit = isset($_POST["perm_{$module}_edit"]) ? 1 : 0;
|
||||||
|
$m_delete = isset($_POST["perm_{$module}_delete"]) ? 1 : 0;
|
||||||
|
$perm_stmt->execute([$id, $module, $m_view, $m_add, $m_edit, $m_delete]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo->commit();
|
||||||
|
|
||||||
|
// Refresh own session if editing self
|
||||||
|
if ($id == $_SESSION['user_id']) {
|
||||||
|
unset($_SESSION['permissions']);
|
||||||
|
}
|
||||||
|
|
||||||
$_SESSION['success'] = 'تم تحديث بيانات المستخدم بنجاح';
|
$_SESSION['success'] = 'تم تحديث بيانات المستخدم بنجاح';
|
||||||
redirect('users.php');
|
redirect('users.php');
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
|
if (isset($pdo)) $pdo->rollBack();
|
||||||
$error = 'حدث خطأ: ' . $e->getMessage();
|
$error = 'حدث خطأ: ' . $e->getMessage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -63,6 +114,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['id'])) {
|
||||||
|
if (!canDelete('users')) redirect('users.php');
|
||||||
if ($_GET['id'] != $_SESSION['user_id']) {
|
if ($_GET['id'] != $_SESSION['user_id']) {
|
||||||
$stmt = db()->prepare("DELETE FROM users WHERE id = ?");
|
$stmt = db()->prepare("DELETE FROM users WHERE id = ?");
|
||||||
$stmt->execute([$_GET['id']]);
|
$stmt->execute([$_GET['id']]);
|
||||||
@ -86,20 +138,32 @@ if (isset($_SESSION['error'])) {
|
|||||||
$stmt = db()->query("SELECT * FROM users ORDER BY created_at DESC");
|
$stmt = db()->query("SELECT * FROM users ORDER BY created_at DESC");
|
||||||
$users = $stmt->fetchAll();
|
$users = $stmt->fetchAll();
|
||||||
|
|
||||||
|
// Fetch permissions for all users
|
||||||
|
$user_perms = [];
|
||||||
|
$perm_stmt = db()->query("SELECT * FROM user_permissions");
|
||||||
|
while ($row = $perm_stmt->fetch()) {
|
||||||
|
$user_perms[$row['user_id']][$row['page']] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle Deep Link for Edit
|
// Handle Deep Link for Edit
|
||||||
$deepLinkData = null;
|
$deepLinkData = null;
|
||||||
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id'])) {
|
||||||
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
$stmt = db()->prepare("SELECT * FROM users WHERE id = ?");
|
||||||
$stmt->execute([$_GET['id']]);
|
$stmt->execute([$_GET['id']]);
|
||||||
$deepLinkData = $stmt->fetch();
|
$deepLinkData = $stmt->fetch();
|
||||||
|
if ($deepLinkData) {
|
||||||
|
$deepLinkData['page_permissions'] = $user_perms[$deepLinkData['id']] ?? [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||||
<h1 class="h2">إدارة المستخدمين والصلاحيات</h1>
|
<h1 class="h2">إدارة المستخدمين والصلاحيات</h1>
|
||||||
|
<?php if (canAdd('users')): ?>
|
||||||
<button type="button" class="btn btn-primary shadow-sm" onclick="openUserModal('add')">
|
<button type="button" class="btn btn-primary shadow-sm" onclick="openUserModal('add')">
|
||||||
<i class="fas fa-user-plus me-1"></i> إضافة مستخدم جديد
|
<i class="fas fa-user-plus me-1"></i> إضافة مستخدم جديد
|
||||||
</button>
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ($success): ?>
|
<?php if ($success): ?>
|
||||||
@ -125,7 +189,6 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
<th class="ps-4">الاسم الكامل</th>
|
<th class="ps-4">الاسم الكامل</th>
|
||||||
<th>اسم المستخدم</th>
|
<th>اسم المستخدم</th>
|
||||||
<th>الدور</th>
|
<th>الدور</th>
|
||||||
<th>الصلاحيات</th>
|
|
||||||
<th>تاريخ الإنشاء</th>
|
<th>تاريخ الإنشاء</th>
|
||||||
<th class="pe-4 text-center">الإجراءات</th>
|
<th class="pe-4 text-center">الإجراءات</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -144,21 +207,15 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
<span class="badge bg-secondary">موظف</span>
|
<span class="badge bg-secondary">موظف</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
|
||||||
<div class="d-flex gap-1">
|
|
||||||
<span class="badge <?= $user['can_view'] ? 'bg-success' : 'bg-light text-muted' ?>" title="عرض">ع</span>
|
|
||||||
<span class="badge <?= $user['can_add'] ? 'bg-success' : 'bg-light text-muted' ?>" title="إضافة">إ</span>
|
|
||||||
<span class="badge <?= $user['can_edit'] ? 'bg-success' : 'bg-light text-muted' ?>" title="تعديل">ت</span>
|
|
||||||
<span class="badge <?= $user['can_delete'] ? 'bg-success' : 'bg-light text-muted' ?>" title="حذف">ح</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td><?= $user['created_at'] ?></td>
|
<td><?= $user['created_at'] ?></td>
|
||||||
<td class="pe-4 text-center">
|
<td class="pe-4 text-center">
|
||||||
|
<?php if (canEdit('users')): ?>
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||||
onclick="openUserModal('edit', <?= htmlspecialchars(json_encode($user), ENT_QUOTES, 'UTF-8') ?>)">
|
onclick="openUserModal('edit', <?= htmlspecialchars(json_encode(array_merge($user, ['page_permissions' => $user_perms[$user['id']] ?? []])), ENT_QUOTES, 'UTF-8') ?>)">
|
||||||
<i class="fas fa-edit"></i> تعديل
|
<i class="fas fa-edit"></i> تعديل الصلاحيات
|
||||||
</button>
|
</button>
|
||||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
<?php endif; ?>
|
||||||
|
<?php if (canDelete('users') && $user['id'] != $_SESSION['user_id']): ?>
|
||||||
<a href="javascript:void(0)" onclick="confirmDelete(<?= $user['id'] ?>)" class="btn btn-sm btn-outline-danger">
|
<a href="javascript:void(0)" onclick="confirmDelete(<?= $user['id'] ?>)" class="btn btn-sm btn-outline-danger">
|
||||||
<i class="fas fa-trash"></i> حذف
|
<i class="fas fa-trash"></i> حذف
|
||||||
</a>
|
</a>
|
||||||
@ -174,7 +231,7 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
|
|
||||||
<!-- User Modal -->
|
<!-- User Modal -->
|
||||||
<div class="modal fade" id="userModal" tabindex="-1" aria-labelledby="userModalLabel" aria-hidden="true">
|
<div class="modal fade" id="userModal" tabindex="-1" aria-labelledby="userModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content border-0 shadow">
|
<div class="modal-content border-0 shadow">
|
||||||
<div class="modal-header bg-primary text-white">
|
<div class="modal-header bg-primary text-white">
|
||||||
<h5 class="modal-title fw-bold" id="userModalLabel">إضافة مستخدم جديد</h5>
|
<h5 class="modal-title fw-bold" id="userModalLabel">إضافة مستخدم جديد</h5>
|
||||||
@ -185,19 +242,23 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
<input type="hidden" name="action" id="modalAction" value="add">
|
<input type="hidden" name="action" id="modalAction" value="add">
|
||||||
<input type="hidden" name="id" id="modalId" value="0">
|
<input type="hidden" name="id" id="modalId" value="0">
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
<label class="form-label fw-bold">الاسم الكامل</label>
|
<label class="form-label fw-bold">الاسم الكامل</label>
|
||||||
<input type="text" name="full_name" id="modalFullName" class="form-control" required>
|
<input type="text" name="full_name" id="modalFullName" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label class="form-label fw-bold">اسم المستخدم</label>
|
<label class="form-label fw-bold">اسم المستخدم</label>
|
||||||
<input type="text" name="username" id="modalUsername" class="form-control" required>
|
<input type="text" name="username" id="modalUsername" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
<label class="form-label fw-bold">كلمة المرور <span id="pwdHint" class="text-muted small"></span></label>
|
<label class="form-label fw-bold">كلمة المرور <span id="pwdHint" class="text-muted small"></span></label>
|
||||||
<input type="password" name="password" id="modalPassword" class="form-control">
|
<input type="password" name="password" id="modalPassword" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="col-md-6 mb-3">
|
||||||
<label class="form-label fw-bold">الدور</label>
|
<label class="form-label fw-bold">الدور</label>
|
||||||
<select name="role" id="modalRole" class="form-select" onchange="applyRolePresets(this.value)">
|
<select name="role" id="modalRole" class="form-select" onchange="applyRolePresets(this.value)">
|
||||||
<option value="staff">موظف</option>
|
<option value="staff">موظف</option>
|
||||||
@ -205,36 +266,50 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
<option value="admin">مدير</option>
|
<option value="admin">مدير</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<hr>
|
||||||
<label class="form-label fw-bold d-block">الصلاحيات</label>
|
|
||||||
<div class="row g-2 bg-light p-3 rounded">
|
<h6 class="fw-bold mb-3"><i class="fas fa-lock me-2 text-primary"></i> صلاحيات الوصول لكل صفحة</h6>
|
||||||
<div class="col-6">
|
|
||||||
<div class="form-check">
|
<div class="table-responsive">
|
||||||
<input class="form-check-input" type="checkbox" name="can_view" id="permView" value="1">
|
<table class="table table-bordered table-sm align-middle">
|
||||||
<label class="form-check-label" for="permView">عرض البيانات</label>
|
<thead class="bg-light">
|
||||||
</div>
|
<tr class="text-center">
|
||||||
</div>
|
<th class="text-start ps-3">الصفحة / الموديول</th>
|
||||||
<div class="col-6">
|
<th>عرض</th>
|
||||||
<div class="form-check">
|
<th>إضافة</th>
|
||||||
<input class="form-check-input" type="checkbox" name="can_add" id="permAdd" value="1">
|
<th>تعديل</th>
|
||||||
<label class="form-check-label" for="permAdd">إضافة سجلات</label>
|
<th>حذف</th>
|
||||||
</div>
|
</tr>
|
||||||
</div>
|
</thead>
|
||||||
<div class="col-6">
|
<tbody>
|
||||||
<div class="form-check">
|
<?php foreach ($modules as $key => $label): ?>
|
||||||
<input class="form-check-input" type="checkbox" name="can_edit" id="permEdit" value="1">
|
<tr class="text-center">
|
||||||
<label class="form-check-label" for="permEdit">تعديل سجلات</label>
|
<td class="text-start ps-3 fw-bold"><?= $label ?></td>
|
||||||
</div>
|
<td>
|
||||||
</div>
|
<input class="form-check-input" type="checkbox" name="perm_<?= $key ?>_view" id="perm_<?= $key ?>_view" value="1">
|
||||||
<div class="col-6">
|
</td>
|
||||||
<div class="form-check">
|
<td>
|
||||||
<input class="form-check-input" type="checkbox" name="can_delete" id="permDelete" value="1">
|
<input class="form-check-input" type="checkbox" name="perm_<?= $key ?>_add" id="perm_<?= $key ?>_add" value="1">
|
||||||
<label class="form-check-label" for="permDelete">حذف سجلات</label>
|
</td>
|
||||||
</div>
|
<td>
|
||||||
</div>
|
<input class="form-check-input" type="checkbox" name="perm_<?= $key ?>_edit" id="perm_<?= $key ?>_edit" value="1">
|
||||||
</div>
|
</td>
|
||||||
|
<td>
|
||||||
|
<input class="form-check-input" type="checkbox" name="perm_<?= $key ?>_delete" id="perm_<?= $key ?>_delete" value="1">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Hidden legacy fields for backward compatibility if needed -->
|
||||||
|
<input type="hidden" name="can_view_global" id="permViewGlobal" value="1">
|
||||||
|
<input type="hidden" name="can_add_global" id="permAddGlobal" value="0">
|
||||||
|
<input type="hidden" name="can_edit_global" id="permEditGlobal" value="0">
|
||||||
|
<input type="hidden" name="can_delete_global" id="permDeleteGlobal" value="0">
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer bg-light">
|
<div class="modal-footer bg-light">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">إلغاء</button>
|
||||||
@ -247,22 +322,34 @@ if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['id']))
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
let userModal;
|
let userModal;
|
||||||
|
const modules = <?= json_encode(array_keys($modules)) ?>;
|
||||||
|
|
||||||
function applyRolePresets(role) {
|
function applyRolePresets(role) {
|
||||||
const view = document.getElementById('permView');
|
modules.forEach(m => {
|
||||||
const add = document.getElementById('permAdd');
|
const view = document.getElementById(`perm_${m}_view`);
|
||||||
const edit = document.getElementById('permEdit');
|
const add = document.getElementById(`perm_${m}_add`);
|
||||||
const del = document.getElementById('permDelete');
|
const edit = document.getElementById(`perm_${m}_edit`);
|
||||||
|
const del = document.getElementById(`perm_${m}_delete`);
|
||||||
|
|
||||||
if (role === 'admin') {
|
if (role === 'admin') {
|
||||||
view.checked = add.checked = edit.checked = del.checked = true;
|
view.checked = add.checked = edit.checked = del.checked = true;
|
||||||
} else if (role === 'clerk') {
|
} else if (role === 'clerk') {
|
||||||
view.checked = add.checked = edit.checked = true;
|
if (m === 'users' || m === 'settings') {
|
||||||
del.checked = false;
|
view.checked = add.checked = edit.checked = del.checked = false;
|
||||||
} else {
|
} else {
|
||||||
view.checked = true;
|
view.checked = add.checked = edit.checked = true;
|
||||||
add.checked = edit.checked = del.checked = false;
|
del.checked = (m === 'reports' ? false : false);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (m === 'inbound' || m === 'outbound' || m === 'internal') {
|
||||||
|
view.checked = true;
|
||||||
|
add.checked = (m === 'internal'); // Staff can send internal mail
|
||||||
|
edit.checked = del.checked = false;
|
||||||
|
} else {
|
||||||
|
view.checked = add.checked = edit.checked = del.checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openUserModal(action, data = null) {
|
function openUserModal(action, data = null) {
|
||||||
@ -288,13 +375,6 @@ function openUserModal(action, data = null) {
|
|||||||
role: document.getElementById('modalRole')
|
role: document.getElementById('modalRole')
|
||||||
};
|
};
|
||||||
|
|
||||||
const perms = {
|
|
||||||
can_view: document.getElementById('permView'),
|
|
||||||
can_add: document.getElementById('permAdd'),
|
|
||||||
can_edit: document.getElementById('permEdit'),
|
|
||||||
can_delete: document.getElementById('permDelete')
|
|
||||||
};
|
|
||||||
|
|
||||||
modalAction.value = action;
|
modalAction.value = action;
|
||||||
|
|
||||||
if (action === 'add') {
|
if (action === 'add') {
|
||||||
@ -313,10 +393,13 @@ function openUserModal(action, data = null) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Set permissions checkboxes
|
// Set permissions checkboxes
|
||||||
perms.can_view.checked = data.can_view == 1;
|
modules.forEach(m => {
|
||||||
perms.can_add.checked = data.can_add == 1;
|
const p = data.page_permissions && data.page_permissions[m] ? data.page_permissions[m] : {};
|
||||||
perms.can_edit.checked = data.can_edit == 1;
|
document.getElementById(`perm_${m}_view`).checked = p.can_view == 1;
|
||||||
perms.can_delete.checked = data.can_delete == 1;
|
document.getElementById(`perm_${m}_add`).checked = p.can_add == 1;
|
||||||
|
document.getElementById(`perm_${m}_edit`).checked = p.can_edit == 1;
|
||||||
|
document.getElementById(`perm_${m}_delete`).checked = p.can_delete == 1;
|
||||||
|
});
|
||||||
|
|
||||||
modalPassword.required = false;
|
modalPassword.required = false;
|
||||||
pwdHint.textContent = '(اتركه فارغاً للحفاظ على كلمة المرور الحالية)';
|
pwdHint.textContent = '(اتركه فارغاً للحفاظ على كلمة المرور الحالية)';
|
||||||
@ -328,18 +411,6 @@ function openUserModal(action, data = null) {
|
|||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
<?php if ($deepLinkData): ?>
|
<?php if ($deepLinkData): ?>
|
||||||
openUserModal('edit', <?= json_encode($deepLinkData) ?>);
|
openUserModal('edit', <?= json_encode($deepLinkData) ?>);
|
||||||
<?php elseif ($error && isset($_POST['action'])): ?>
|
|
||||||
const errorData = <?= json_encode([
|
|
||||||
'id' => $_POST['id'] ?? 0,
|
|
||||||
'username' => $_POST['username'] ?? '',
|
|
||||||
'full_name' => $_POST['full_name'] ?? '',
|
|
||||||
'role' => $_POST['role'] ?? 'staff',
|
|
||||||
'can_view' => $_POST['can_view'] ?? 0,
|
|
||||||
'can_add' => $_POST['can_add'] ?? 0,
|
|
||||||
'can_edit' => $_POST['can_edit'] ?? 0,
|
|
||||||
'can_delete' => $_POST['can_delete'] ?? 0
|
|
||||||
]) ?>;
|
|
||||||
openUserModal('<?= $_POST['action'] ?>', errorData);
|
|
||||||
<?php elseif (isset($_GET['action']) && $_GET['action'] === 'add'): ?>
|
<?php elseif (isset($_GET['action']) && $_GET['action'] === 'add'): ?>
|
||||||
openUserModal('add');
|
openUserModal('add');
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -381,6 +452,9 @@ function confirmDelete(id) {
|
|||||||
background-color: #198754;
|
background-color: #198754;
|
||||||
border-color: #198754;
|
border-color: #198754;
|
||||||
}
|
}
|
||||||
|
.table-sm th, .table-sm td {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
<?php require_once __DIR__ . '/includes/footer.php'; ?>
|
||||||
@ -2,11 +2,6 @@
|
|||||||
require_once __DIR__ . '/includes/header.php';
|
require_once __DIR__ . '/includes/header.php';
|
||||||
require_once __DIR__ . '/mail/MailService.php';
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
|
||||||
// Check if user has view permission
|
|
||||||
if (!canView()) {
|
|
||||||
redirect('index.php');
|
|
||||||
}
|
|
||||||
|
|
||||||
$id = $_GET['id'] ?? 0;
|
$id = $_GET['id'] ?? 0;
|
||||||
if (!$id) redirect('index.php');
|
if (!$id) redirect('index.php');
|
||||||
|
|
||||||
@ -22,6 +17,11 @@ $mail = $stmt->fetch();
|
|||||||
|
|
||||||
if (!$mail) redirect('index.php');
|
if (!$mail) redirect('index.php');
|
||||||
|
|
||||||
|
// Check if user has view permission for this mail type
|
||||||
|
if (!canView($mail['type'])) {
|
||||||
|
redirect('index.php');
|
||||||
|
}
|
||||||
|
|
||||||
// Security check for internal mail: only sender or recipient can view
|
// Security check for internal mail: only sender or recipient can view
|
||||||
// Even admins should only see their own internal mail for privacy
|
// Even admins should only see their own internal mail for privacy
|
||||||
if ($mail['type'] === 'internal') {
|
if ($mail['type'] === 'internal') {
|
||||||
@ -35,7 +35,8 @@ $error = '';
|
|||||||
|
|
||||||
// Handle Comment submission
|
// Handle Comment submission
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
||||||
if (!canEdit() && $mail['type'] !== 'internal') {
|
// For internal mail, users can always comment if involved. For others, check edit permission.
|
||||||
|
if ($mail['type'] !== 'internal' && !canEdit($mail['type'])) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لإضافة تعليقات';
|
$error = 'عذراً، ليس لديك الصلاحية لإضافة تعليقات';
|
||||||
} else {
|
} else {
|
||||||
$comment = $_POST['comment'] ?? '';
|
$comment = $_POST['comment'] ?? '';
|
||||||
@ -52,11 +53,12 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
|||||||
$referred_user = $stmt_u->fetch();
|
$referred_user = $stmt_u->fetch();
|
||||||
|
|
||||||
if ($referred_user && !empty($referred_user['email'])) {
|
if ($referred_user && !empty($referred_user['email'])) {
|
||||||
$sender_name = $_SESSION['full_name'] ?? 'زميلك';
|
$sender_name = $_SESSION['name'] ?? 'زميلك';
|
||||||
$mail_subject = "إحالة بريد: " . $mail['subject'];
|
$mail_subject = "إحالة بريد: " . $mail['subject'];
|
||||||
$mail_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]" . dirname($_SERVER['PHP_SELF']) . "/view_mail.php?id=" . $id;
|
$mail_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]" . dirname($_SERVER['PHP_SELF']) . "/view_mail.php?id=" . $id;
|
||||||
|
|
||||||
$html = "
|
$html = "
|
||||||
|
<div dir='rtl'>
|
||||||
<h3>مرحباً " . htmlspecialchars($referred_user['full_name']) . "</h3>
|
<h3>مرحباً " . htmlspecialchars($referred_user['full_name']) . "</h3>
|
||||||
<p>قام <strong>" . htmlspecialchars($sender_name) . "</strong> بإحالة بريد إليك مع التعليق التالي:</p>
|
<p>قام <strong>" . htmlspecialchars($sender_name) . "</strong> بإحالة بريد إليك مع التعليق التالي:</p>
|
||||||
<blockquote style='background: #f9f9f9; padding: 10px; border-left: 5px solid #ccc;'>
|
<blockquote style='background: #f9f9f9; padding: 10px; border-left: 5px solid #ccc;'>
|
||||||
@ -68,6 +70,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
|||||||
<li><strong>الموضوع:</strong> " . htmlspecialchars($mail['subject']) . "</li>
|
<li><strong>الموضوع:</strong> " . htmlspecialchars($mail['subject']) . "</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p><a href='{$mail_link}' style='display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px;'>عرض البريد</a></p>
|
<p><a href='{$mail_link}' style='display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 5px;'>عرض البريد</a></p>
|
||||||
|
</div>
|
||||||
";
|
";
|
||||||
|
|
||||||
$txt = "قام {$sender_name} بإحالة بريد إليك: {$mail['subject']}\n\nالتعليق: {$comment}\n\nعرض البريد: {$mail_link}";
|
$txt = "قام {$sender_name} بإحالة بريد إليك: {$mail['subject']}\n\nالتعليق: {$comment}\n\nعرض البريد: {$mail_link}";
|
||||||
@ -84,7 +87,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) {
|
|||||||
|
|
||||||
// Handle Attachment upload
|
// Handle Attachment upload
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
||||||
if (!canEdit() && $mail['type'] !== 'internal') {
|
if ($mail['type'] !== 'internal' && !canEdit($mail['type'])) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لرفع مرفقات';
|
$error = 'عذراً، ليس لديك الصلاحية لرفع مرفقات';
|
||||||
} else {
|
} else {
|
||||||
$file = $_FILES['attachment'];
|
$file = $_FILES['attachment'];
|
||||||
@ -110,7 +113,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['attachment'])) {
|
|||||||
|
|
||||||
// Handle Attachment deletion
|
// Handle Attachment deletion
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_attachment'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_attachment'])) {
|
||||||
if (!canDelete() && $mail['type'] !== 'internal') {
|
if ($mail['type'] !== 'internal' && !canDelete($mail['type'])) {
|
||||||
$error = 'عذراً، ليس لديك الصلاحية لحذف المرفقات';
|
$error = 'عذراً، ليس لديك الصلاحية لحذف المرفقات';
|
||||||
} else {
|
} else {
|
||||||
$attachment_id = $_POST['attachment_id'] ?? 0;
|
$attachment_id = $_POST['attachment_id'] ?? 0;
|
||||||
@ -182,7 +185,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
<h1 class="h2">تفاصيل <?= $type_label ?></h1>
|
<h1 class="h2">تفاصيل <?= $type_label ?></h1>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<a href="<?= $back_link ?>" class="btn btn-outline-secondary">عودة للقائمة</a>
|
<a href="<?= $back_link ?>" class="btn btn-outline-secondary">عودة للقائمة</a>
|
||||||
<?php if (canEdit() && $mail['type'] !== 'internal'): ?>
|
<?php if ($mail['type'] !== 'internal' && canEdit($mail['type'])): ?>
|
||||||
<a href="<?= $mail['type'] ?>.php?action=edit&id=<?= $mail['id'] ?>" class="btn btn-outline-primary">تعديل البيانات</a>
|
<a href="<?= $mail['type'] ?>.php?action=edit&id=<?= $mail['id'] ?>" class="btn btn-outline-primary">تعديل البيانات</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
@ -315,6 +318,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
<h5 class="mb-0 fw-bold">الردود والمتابعة</h5>
|
<h5 class="mb-0 fw-bold">الردود والمتابعة</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<?php if ($mail['type'] === 'internal' || canEdit($mail['type'])): ?>
|
||||||
<form method="POST" class="mb-4 bg-light p-3 rounded border">
|
<form method="POST" class="mb-4 bg-light p-3 rounded border">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-label small fw-bold">إضافة <?= $mail['type'] == 'internal' ? 'رد' : 'تعليق' ?></label>
|
<label class="form-label small fw-bold">إضافة <?= $mail['type'] == 'internal' ? 'رد' : 'تعليق' ?></label>
|
||||||
@ -334,6 +338,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<button type="submit" name="add_comment" class="btn btn-sm btn-primary">إرسال <?= $mail['type'] == 'internal' ? 'الرد' : 'التعليق' ?></button>
|
<button type="submit" name="add_comment" class="btn btn-sm btn-primary">إرسال <?= $mail['type'] == 'internal' ? 'الرد' : 'التعليق' ?></button>
|
||||||
</form>
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="comment-list">
|
<div class="comment-list">
|
||||||
<?php if ($mail_comments): foreach ($mail_comments as $c): ?>
|
<?php if ($mail_comments): foreach ($mail_comments as $c): ?>
|
||||||
@ -366,6 +371,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
<h5 class="mb-0 fw-bold">المرفقات</h5>
|
<h5 class="mb-0 fw-bold">المرفقات</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
<?php if ($mail['type'] === 'internal' || canEdit($mail['type'])): ?>
|
||||||
<form method="POST" enctype="multipart/form-data" class="mb-4">
|
<form method="POST" enctype="multipart/form-data" class="mb-4">
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
<label class="form-label small mb-1">اسم المرفق (يظهر في القائمة)</label>
|
<label class="form-label small mb-1">اسم المرفق (يظهر في القائمة)</label>
|
||||||
@ -375,6 +381,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-sm btn-secondary w-100">رفع ملف</button>
|
<button type="submit" class="btn btn-sm btn-secondary w-100">رفع ملف</button>
|
||||||
</form>
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
<?php if ($mail_attachments): foreach ($mail_attachments as $a): ?>
|
<?php if ($mail_attachments): foreach ($mail_attachments as $a): ?>
|
||||||
@ -397,7 +404,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php if (canDelete() || $mail['type'] == 'internal'): ?>
|
<?php if ($mail['type'] == 'internal' || canDelete($mail['type'])): ?>
|
||||||
<form method="POST" class="d-inline delete-attachment-form">
|
<form method="POST" class="d-inline delete-attachment-form">
|
||||||
<input type="hidden" name="attachment_id" value="<?= $a['id'] ?>">
|
<input type="hidden" name="attachment_id" value="<?= $a['id'] ?>">
|
||||||
<input type="hidden" name="delete_attachment" value="1">
|
<input type="hidden" name="delete_attachment" value="1">
|
||||||
@ -479,6 +486,7 @@ if ($mail['type'] == 'internal') {
|
|||||||
document.querySelectorAll('.delete-btn').forEach(btn => {
|
document.querySelectorAll('.delete-btn').forEach(btn => {
|
||||||
btn.addEventListener('click', function() {
|
btn.addEventListener('click', function() {
|
||||||
const form = this.closest('form');
|
const form = this.closest('form');
|
||||||
|
if (typeof Swal !== 'undefined') {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: 'هل أنت متأكد؟',
|
title: 'هل أنت متأكد؟',
|
||||||
text: "سيتم حذف المرفق نهائياً!",
|
text: "سيتم حذف المرفق نهائياً!",
|
||||||
@ -493,6 +501,11 @@ if ($mail['type'] == 'internal') {
|
|||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (confirm('هل أنت متأكد من الحذف؟')) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user