Fix bulk actions selection and set timezone earlier
Improves bulk actions in the domains view by ensuring unique domain IDs are counted and selected, preventing double-counting from desktop and mobile checkboxes. Adds CSRF token to bulk actions forms for security. Moves timezone initialization to public/index.php to ensure it is set before any date operations, and updates base layout to reflect this change.
This commit is contained in:
@@ -452,20 +452,26 @@ function updateBulkActions() {
|
||||
const selectedCount = document.getElementById('selected-count');
|
||||
const selectAllCheckbox = document.getElementById('select-all');
|
||||
|
||||
if (checkboxes.length > 0) {
|
||||
// Get unique domain IDs (avoid counting both desktop and mobile checkboxes)
|
||||
const uniqueIds = new Set(Array.from(checkboxes).map(cb => cb.value));
|
||||
const count = uniqueIds.size;
|
||||
|
||||
if (count > 0) {
|
||||
bulkActions.classList.remove('hidden');
|
||||
bulkActions.classList.add('flex');
|
||||
selectedCount.textContent = `${checkboxes.length} domain(s) selected`;
|
||||
selectedCount.textContent = `${count} domain(s) selected`;
|
||||
} else {
|
||||
bulkActions.classList.add('hidden');
|
||||
bulkActions.classList.remove('flex');
|
||||
}
|
||||
|
||||
// Update select all checkbox state
|
||||
const allCheckboxes = document.querySelectorAll('.domain-checkbox, .domain-checkbox-mobile');
|
||||
// Only count desktop checkboxes to avoid double counting
|
||||
const allCheckboxes = document.querySelectorAll('.domain-checkbox');
|
||||
const checkedDesktopBoxes = document.querySelectorAll('.domain-checkbox:checked');
|
||||
if (selectAllCheckbox) {
|
||||
selectAllCheckbox.checked = allCheckboxes.length > 0 && checkboxes.length === allCheckboxes.length;
|
||||
selectAllCheckbox.indeterminate = checkboxes.length > 0 && checkboxes.length < allCheckboxes.length;
|
||||
selectAllCheckbox.checked = allCheckboxes.length > 0 && checkedDesktopBoxes.length === allCheckboxes.length;
|
||||
selectAllCheckbox.indeterminate = checkedDesktopBoxes.length > 0 && checkedDesktopBoxes.length < allCheckboxes.length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +486,9 @@ function clearSelection() {
|
||||
|
||||
function getSelectedIds() {
|
||||
const checkboxes = document.querySelectorAll('.domain-checkbox:checked, .domain-checkbox-mobile:checked');
|
||||
return Array.from(checkboxes).map(cb => cb.value);
|
||||
// Return unique IDs only (avoid duplicates from desktop and mobile views)
|
||||
const ids = Array.from(checkboxes).map(cb => cb.value);
|
||||
return [...new Set(ids)];
|
||||
}
|
||||
|
||||
function bulkRefresh() {
|
||||
@@ -491,6 +499,13 @@ function bulkRefresh() {
|
||||
form.method = 'POST';
|
||||
form.action = '/domains/bulk-refresh';
|
||||
|
||||
// Add CSRF token
|
||||
const csrfInput = document.createElement('input');
|
||||
csrfInput.type = 'hidden';
|
||||
csrfInput.name = 'csrf_token';
|
||||
csrfInput.value = '<?= csrf_token() ?>';
|
||||
form.appendChild(csrfInput);
|
||||
|
||||
ids.forEach(id => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
@@ -515,6 +530,13 @@ function bulkDelete() {
|
||||
form.method = 'POST';
|
||||
form.action = '/domains/bulk-delete';
|
||||
|
||||
// Add CSRF token
|
||||
const csrfInput = document.createElement('input');
|
||||
csrfInput.type = 'hidden';
|
||||
csrfInput.name = 'csrf_token';
|
||||
csrfInput.value = '<?= csrf_token() ?>';
|
||||
form.appendChild(csrfInput);
|
||||
|
||||
ids.forEach(id => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'hidden';
|
||||
|
||||
@@ -26,8 +26,7 @@ if (!isset($appName)) {
|
||||
$appTimezone = $appSettings['app_timezone'];
|
||||
$appVersion = $appSettings['app_version'];
|
||||
|
||||
// Set PHP timezone
|
||||
date_default_timezone_set($appTimezone);
|
||||
// Note: Timezone is now set early in public/index.php (before controllers run)
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
|
||||
@@ -58,6 +58,21 @@ if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token']) && !$isIns
|
||||
$authController->checkRememberToken();
|
||||
}
|
||||
|
||||
// Set application timezone early (before any date operations)
|
||||
if (!$isInstallerPath && file_exists($installedFlagFile)) {
|
||||
try {
|
||||
$settingModel = new \App\Models\Setting();
|
||||
$timezone = $settingModel->getValue('app_timezone', 'UTC');
|
||||
date_default_timezone_set($timezone);
|
||||
} catch (\Exception $e) {
|
||||
// Database not available, use UTC as fallback
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
} else {
|
||||
// Default to UTC during installation
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
// Initialize application
|
||||
$app = new Application();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user