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 selectedCount = document.getElementById('selected-count');
|
||||||
const selectAllCheckbox = document.getElementById('select-all');
|
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.remove('hidden');
|
||||||
bulkActions.classList.add('flex');
|
bulkActions.classList.add('flex');
|
||||||
selectedCount.textContent = `${checkboxes.length} domain(s) selected`;
|
selectedCount.textContent = `${count} domain(s) selected`;
|
||||||
} else {
|
} else {
|
||||||
bulkActions.classList.add('hidden');
|
bulkActions.classList.add('hidden');
|
||||||
bulkActions.classList.remove('flex');
|
bulkActions.classList.remove('flex');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update select all checkbox state
|
// 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) {
|
if (selectAllCheckbox) {
|
||||||
selectAllCheckbox.checked = allCheckboxes.length > 0 && checkboxes.length === allCheckboxes.length;
|
selectAllCheckbox.checked = allCheckboxes.length > 0 && checkedDesktopBoxes.length === allCheckboxes.length;
|
||||||
selectAllCheckbox.indeterminate = checkboxes.length > 0 && checkboxes.length < allCheckboxes.length;
|
selectAllCheckbox.indeterminate = checkedDesktopBoxes.length > 0 && checkedDesktopBoxes.length < allCheckboxes.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +486,9 @@ function clearSelection() {
|
|||||||
|
|
||||||
function getSelectedIds() {
|
function getSelectedIds() {
|
||||||
const checkboxes = document.querySelectorAll('.domain-checkbox:checked, .domain-checkbox-mobile:checked');
|
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() {
|
function bulkRefresh() {
|
||||||
@@ -491,6 +499,13 @@ function bulkRefresh() {
|
|||||||
form.method = 'POST';
|
form.method = 'POST';
|
||||||
form.action = '/domains/bulk-refresh';
|
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 => {
|
ids.forEach(id => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'hidden';
|
input.type = 'hidden';
|
||||||
@@ -515,6 +530,13 @@ function bulkDelete() {
|
|||||||
form.method = 'POST';
|
form.method = 'POST';
|
||||||
form.action = '/domains/bulk-delete';
|
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 => {
|
ids.forEach(id => {
|
||||||
const input = document.createElement('input');
|
const input = document.createElement('input');
|
||||||
input.type = 'hidden';
|
input.type = 'hidden';
|
||||||
|
|||||||
@@ -26,8 +26,7 @@ if (!isset($appName)) {
|
|||||||
$appTimezone = $appSettings['app_timezone'];
|
$appTimezone = $appSettings['app_timezone'];
|
||||||
$appVersion = $appSettings['app_version'];
|
$appVersion = $appSettings['app_version'];
|
||||||
|
|
||||||
// Set PHP timezone
|
// Note: Timezone is now set early in public/index.php (before controllers run)
|
||||||
date_default_timezone_set($appTimezone);
|
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|||||||
@@ -58,6 +58,21 @@ if (!isset($_SESSION['user_id']) && isset($_COOKIE['remember_token']) && !$isIns
|
|||||||
$authController->checkRememberToken();
|
$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
|
// Initialize application
|
||||||
$app = new Application();
|
$app = new Application();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user