Refactor global stats handling and user ID access
Moved global stats logic from LayoutHelper to Domain model and updated views/controllers to use the new stats structure. Replaced direct $_SESSION['user_id'] access with Core\Auth::id() for consistency. Cleaned up redundant code and improved isolation mode handling for statistics.
This commit is contained in:
@@ -27,13 +27,11 @@ class DashboardController extends Controller
|
|||||||
$settingModel = new \App\Models\Setting();
|
$settingModel = new \App\Models\Setting();
|
||||||
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
|
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
|
||||||
|
|
||||||
// Get statistics based on isolation mode
|
// Get data based on isolation mode (stats are now handled in base.php)
|
||||||
if ($isolationMode === 'isolated') {
|
if ($isolationMode === 'isolated') {
|
||||||
$stats = $this->domainModel->getStatistics($userId);
|
|
||||||
$recentDomains = $this->domainModel->getRecent(5, $userId);
|
$recentDomains = $this->domainModel->getRecent(5, $userId);
|
||||||
$groups = $this->groupModel->getAllWithChannelCount($userId);
|
$groups = $this->groupModel->getAllWithChannelCount($userId);
|
||||||
} else {
|
} else {
|
||||||
$stats = $this->domainModel->getStatistics();
|
|
||||||
$recentDomains = $this->domainModel->getRecent(5);
|
$recentDomains = $this->domainModel->getRecent(5);
|
||||||
$groups = $this->groupModel->getAllWithChannelCount();
|
$groups = $this->groupModel->getAllWithChannelCount();
|
||||||
}
|
}
|
||||||
@@ -59,12 +57,7 @@ class DashboardController extends Controller
|
|||||||
$formattedRecentDomains = \App\Helpers\DomainHelper::formatMultiple($recentDomains);
|
$formattedRecentDomains = \App\Helpers\DomainHelper::formatMultiple($recentDomains);
|
||||||
$formattedExpiringDomains = \App\Helpers\DomainHelper::formatMultiple($expiringThisMonth);
|
$formattedExpiringDomains = \App\Helpers\DomainHelper::formatMultiple($expiringThisMonth);
|
||||||
|
|
||||||
// Get global stats for dashboard cards
|
|
||||||
$globalStats = \App\Helpers\LayoutHelper::getGlobalStats($userId);
|
|
||||||
|
|
||||||
$this->view('dashboard/index', [
|
$this->view('dashboard/index', [
|
||||||
'stats' => $stats,
|
|
||||||
'globalStats' => $globalStats,
|
|
||||||
'recentDomains' => $formattedRecentDomains,
|
'recentDomains' => $formattedRecentDomains,
|
||||||
'expiringThisMonth' => $formattedExpiringDomains,
|
'expiringThisMonth' => $formattedExpiringDomains,
|
||||||
'expiringCount' => count($allExpiringDomains),
|
'expiringCount' => count($allExpiringDomains),
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class ErrorLogController extends Controller
|
|||||||
$notes = $_POST['notes'] ?? null;
|
$notes = $_POST['notes'] ?? null;
|
||||||
|
|
||||||
// Mark error as resolved using model
|
// Mark error as resolved using model
|
||||||
$this->errorLogModel->markErrorResolved($errorId, $_SESSION['user_id'], $notes);
|
$this->errorLogModel->markErrorResolved($errorId, \Core\Auth::id(), $notes);
|
||||||
|
|
||||||
$_SESSION['success'] = 'Error marked as resolved';
|
$_SESSION['success'] = 'Error marked as resolved';
|
||||||
header('Location: /errors/' . urlencode($errorId));
|
header('Location: /errors/' . urlencode($errorId));
|
||||||
|
|||||||
@@ -34,73 +34,6 @@ class LayoutHelper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get stats for sidebar (respects user isolation)
|
|
||||||
*/
|
|
||||||
public static function getGlobalStats(?int $userId = null): array
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$pdo = \Core\Database::getConnection();
|
|
||||||
|
|
||||||
// Check isolation mode
|
|
||||||
$settingModel = new Setting();
|
|
||||||
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
|
|
||||||
|
|
||||||
// Build WHERE clause based on isolation mode
|
|
||||||
$whereClause = '';
|
|
||||||
$params = [];
|
|
||||||
|
|
||||||
if ($isolationMode === 'isolated' && $userId) {
|
|
||||||
$whereClause = ' WHERE user_id = ?';
|
|
||||||
$params[] = $userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get total domains
|
|
||||||
$totalSql = "SELECT COUNT(*) as count FROM domains" . $whereClause;
|
|
||||||
$totalStmt = $pdo->prepare($totalSql);
|
|
||||||
$totalStmt->execute($params);
|
|
||||||
$total = $totalStmt->fetch(\PDO::FETCH_ASSOC)['count'] ?? 0;
|
|
||||||
|
|
||||||
// Get active domains
|
|
||||||
$activeSql = "SELECT COUNT(*) as count FROM domains WHERE is_active = 1" . $whereClause;
|
|
||||||
$activeStmt = $pdo->prepare($activeSql);
|
|
||||||
$activeStmt->execute($params);
|
|
||||||
$active = $activeStmt->fetch(\PDO::FETCH_ASSOC)['count'] ?? 0;
|
|
||||||
|
|
||||||
// Get expiring soon
|
|
||||||
$notificationDays = $settingModel->getNotificationDays();
|
|
||||||
$threshold = !empty($notificationDays) ? max($notificationDays) : 30;
|
|
||||||
|
|
||||||
$expiringSql = "SELECT COUNT(*) as count FROM domains
|
|
||||||
WHERE is_active = 1
|
|
||||||
AND expiration_date IS NOT NULL
|
|
||||||
AND expiration_date <= DATE_ADD(NOW(), INTERVAL ? DAY)
|
|
||||||
AND expiration_date >= NOW()" . $whereClause;
|
|
||||||
|
|
||||||
$expiringParams = [$threshold];
|
|
||||||
if ($isolationMode === 'isolated' && $userId) {
|
|
||||||
$expiringParams[] = $userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
$expiringSoonStmt = $pdo->prepare($expiringSql);
|
|
||||||
$expiringSoonStmt->execute($expiringParams);
|
|
||||||
$expiringSoon = $expiringSoonStmt->fetch(\PDO::FETCH_ASSOC)['count'] ?? 0;
|
|
||||||
|
|
||||||
return [
|
|
||||||
'total' => $total,
|
|
||||||
'active' => $active,
|
|
||||||
'expiring_soon' => $expiringSoon,
|
|
||||||
'expiring_threshold' => $threshold
|
|
||||||
];
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
return [
|
|
||||||
'total' => 0,
|
|
||||||
'active' => 0,
|
|
||||||
'expiring_soon' => 0,
|
|
||||||
'expiring_threshold' => 30
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert timestamp to "time ago" format
|
* Convert timestamp to "time ago" format
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ class Domain extends Model
|
|||||||
'expiring_soon' => 0,
|
'expiring_soon' => 0,
|
||||||
'expired' => 0,
|
'expired' => 0,
|
||||||
'inactive' => 0,
|
'inactive' => 0,
|
||||||
|
'expiring_threshold' => 30,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Build WHERE clause for user filtering
|
// Build WHERE clause for user filtering
|
||||||
@@ -204,6 +205,25 @@ class Domain extends Model
|
|||||||
// Add inactive count to total
|
// Add inactive count to total
|
||||||
$stats['total'] += $stats['inactive'];
|
$stats['total'] += $stats['inactive'];
|
||||||
|
|
||||||
|
// Get expiring soon count
|
||||||
|
$settingModel = new \App\Models\Setting();
|
||||||
|
$notificationDays = $settingModel->getNotificationDays();
|
||||||
|
$threshold = !empty($notificationDays) ? max($notificationDays) : 30;
|
||||||
|
$stats['expiring_threshold'] = $threshold;
|
||||||
|
|
||||||
|
$expiringWhereClause = "WHERE is_active = 1 AND expiration_date IS NOT NULL AND expiration_date <= DATE_ADD(NOW(), INTERVAL ? DAY) AND expiration_date >= NOW()";
|
||||||
|
$expiringParams = [$threshold];
|
||||||
|
|
||||||
|
if ($userId) {
|
||||||
|
$expiringWhereClause .= " AND user_id = ?";
|
||||||
|
$expiringParams[] = $userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
$expiringStmt = $this->db->prepare("SELECT COUNT(*) as count FROM domains $expiringWhereClause");
|
||||||
|
$expiringStmt->execute($expiringParams);
|
||||||
|
$expiringResult = $expiringStmt->fetch();
|
||||||
|
$stats['expiring_soon'] = $expiringResult['count'] ?? 0;
|
||||||
|
|
||||||
return $stats;
|
return $stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ ob_start();
|
|||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-xs font-medium text-gray-500 uppercase tracking-wide">Expiring Soon</p>
|
<p class="text-xs font-medium text-gray-500 uppercase tracking-wide">Expiring Soon</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900 mt-1"><?= $globalStats['expiring_soon'] ?? 0 ?></p>
|
<p class="text-2xl font-semibold text-gray-900 mt-1"><?= $stats['expiring_soon'] ?? 0 ?></p>
|
||||||
<p class="text-xs text-gray-400 mt-1">within <?= $globalStats['expiring_threshold'] ?? 30 ?> days</p>
|
<p class="text-xs text-gray-400 mt-1">within <?= $stats['expiring_threshold'] ?? 30 ?> days</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-12 h-12 bg-orange-50 rounded-lg flex items-center justify-center">
|
<div class="w-12 h-12 bg-orange-50 rounded-lg flex items-center justify-center">
|
||||||
<i class="fas fa-exclamation-triangle text-orange-600 text-lg"></i>
|
<i class="fas fa-exclamation-triangle text-orange-600 text-lg"></i>
|
||||||
@@ -255,7 +255,7 @@ ob_start();
|
|||||||
<div class="p-6 text-center">
|
<div class="p-6 text-center">
|
||||||
<i class="fas fa-check-circle text-green-500 text-3xl mb-2"></i>
|
<i class="fas fa-check-circle text-green-500 text-3xl mb-2"></i>
|
||||||
<p class="text-sm text-gray-600">No domains expiring soon</p>
|
<p class="text-sm text-gray-600">No domains expiring soon</p>
|
||||||
<p class="text-xs text-gray-400 mt-1">within <?= $globalStats['expiring_threshold'] ?? 30 ?> days</p>
|
<p class="text-xs text-gray-400 mt-1">within <?= $stats['expiring_threshold'] ?? 30 ?> days</p>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,9 +4,12 @@
|
|||||||
* Contains: HTML structure, meta tags, CSS/JS includes, global stats
|
* Contains: HTML structure, meta tags, CSS/JS includes, global stats
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Get current user ID (used for both notifications and stats)
|
||||||
|
$userId = \Core\Auth::id();
|
||||||
|
|
||||||
// Fetch notifications for top nav (available on all pages)
|
// Fetch notifications for top nav (available on all pages)
|
||||||
if (isset($_SESSION['user_id'])) {
|
if ($userId) {
|
||||||
$notificationData = \App\Helpers\LayoutHelper::getNotifications($_SESSION['user_id']);
|
$notificationData = \App\Helpers\LayoutHelper::getNotifications($userId);
|
||||||
$recentNotifications = $notificationData['items'];
|
$recentNotifications = $notificationData['items'];
|
||||||
$unreadNotifications = $notificationData['unread_count'];
|
$unreadNotifications = $notificationData['unread_count'];
|
||||||
} else {
|
} else {
|
||||||
@@ -14,10 +17,17 @@ if (isset($_SESSION['user_id'])) {
|
|||||||
$unreadNotifications = 0;
|
$unreadNotifications = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch global stats for sidebar (available on all pages)
|
// Get stats for sidebar (available on all pages)
|
||||||
if (!isset($globalStats)) {
|
if (!isset($stats)) {
|
||||||
$userId = \Core\Auth::id();
|
$domainModel = new \App\Models\Domain();
|
||||||
$globalStats = \App\Helpers\LayoutHelper::getGlobalStats($userId);
|
$settingModel = new \App\Models\Setting();
|
||||||
|
$isolationMode = $settingModel->getValue('user_isolation_mode', 'shared');
|
||||||
|
|
||||||
|
if ($isolationMode === 'isolated') {
|
||||||
|
$stats = $domainModel->getStatistics($userId);
|
||||||
|
} else {
|
||||||
|
$stats = $domainModel->getStatistics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get application settings from database
|
// Get application settings from database
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="text-gray-400 text-xs">Total</span>
|
<span class="text-gray-400 text-xs">Total</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-white font-semibold text-sm"><?= $globalStats['total'] ?? 0 ?></span>
|
<span class="text-white font-semibold text-sm"><?= $stats['total'] ?? 0 ?></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -94,9 +94,9 @@
|
|||||||
<div class="w-7 h-7 bg-orange-500/20 rounded flex items-center justify-center mr-2.5">
|
<div class="w-7 h-7 bg-orange-500/20 rounded flex items-center justify-center mr-2.5">
|
||||||
<i class="fas fa-exclamation-triangle text-orange-400 text-xs"></i>
|
<i class="fas fa-exclamation-triangle text-orange-400 text-xs"></i>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-gray-400 text-xs" title="Within <?= $globalStats['expiring_threshold'] ?? 30 ?> days">Expiring</span>
|
<span class="text-gray-400 text-xs" title="Within <?= $stats['expiring_threshold'] ?? 30 ?> days">Expiring</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-orange-400 font-semibold text-sm"><?= $globalStats['expiring_soon'] ?? 0 ?></span>
|
<span class="text-orange-400 font-semibold text-sm"><?= $stats['expiring_soon'] ?? 0 ?></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="text-gray-400 text-xs">Active</span>
|
<span class="text-gray-400 text-xs">Active</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-green-400 font-semibold text-sm"><?= $globalStats['active'] ?? 0 ?></span>
|
<span class="text-green-400 font-semibold text-sm"><?= $stats['active'] ?? 0 ?></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ $pagination = $pagination ?? [
|
|||||||
<?php foreach ($users as $user): ?>
|
<?php foreach ($users as $user): ?>
|
||||||
<tr class="hover:bg-gray-50 transition-colors duration-150">
|
<tr class="hover:bg-gray-50 transition-colors duration-150">
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
<?php if ($user['id'] != \Core\Auth::id()): ?>
|
||||||
<input type="checkbox" class="user-checkbox rounded border-gray-300 text-primary focus:ring-primary" value="<?= $user['id'] ?>" onchange="updateBulkActions()">
|
<input type="checkbox" class="user-checkbox rounded border-gray-300 text-primary focus:ring-primary" value="<?= $user['id'] ?>" onchange="updateBulkActions()">
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<span class="text-gray-300" title="Cannot select your own account">
|
<span class="text-gray-300" title="Cannot select your own account">
|
||||||
@@ -261,7 +261,7 @@ $pagination = $pagination ?? [
|
|||||||
<a href="/users/edit?id=<?= $user['id'] ?>" class="text-blue-600 hover:text-blue-800" title="Edit">
|
<a href="/users/edit?id=<?= $user['id'] ?>" class="text-blue-600 hover:text-blue-800" title="Edit">
|
||||||
<i class="fas fa-edit"></i>
|
<i class="fas fa-edit"></i>
|
||||||
</a>
|
</a>
|
||||||
<?php if ($user['id'] != $_SESSION['user_id']): ?>
|
<?php if ($user['id'] != \Core\Auth::id()): ?>
|
||||||
<a href="/users/toggle-status?id=<?= $user['id'] ?>"
|
<a href="/users/toggle-status?id=<?= $user['id'] ?>"
|
||||||
class="text-orange-600 hover:text-orange-800"
|
class="text-orange-600 hover:text-orange-800"
|
||||||
title="<?= $user['is_active'] ? 'Deactivate' : 'Activate' ?>">
|
title="<?= $user['is_active'] ? 'Deactivate' : 'Activate' ?>">
|
||||||
|
|||||||
Reference in New Issue
Block a user