# Calendar Plugin Changelog ## Version 7.5.2 (2026-04-05) Major release focused on DokuWiki farm compatibility, security hardening, and new features. ### New Features **Namespace Exclude Parameter** - `{{calendar namespace=* exclude=journal}}` β€” hide specific namespaces from wildcard views - `{{calendar namespace=* exclude="journal;drafts"}}` β€” exclude multiple (semicolon-separated) - Supports exact and prefix matching: `exclude=journal` also hides `journal:daily`, `journal:notes` - Works with `{{calendar}}`, `{{eventpanel}}`, and `{{eventlist}}` - Preserved across AJAX navigation and all-dates search **Default Search Scope Setting** - New admin setting (Themes tab) to default the search bar to "This Month" or "All Dates" - Users can still toggle per-session with the πŸ“…/🌐 button - Stored in `data/meta/calendar_search_default.txt` ### DokuWiki Farm Compatibility **Data Path Migration** - Replaced 77 hardcoded `DOKU_INC . 'data/meta/'` references with `$conf['metadir']` across 8 files - Cache paths now use `$conf['cachedir']` (EventCache, RateLimiter, clearCache) - All temp files (`.event_stats_cache`, `.sync_abort`) moved from shared plugin dir to per-animal data dir - Added `metaDir()` helper to syntax, action, and admin plugin classes **Per-Animal Sync Credentials** - `sync_config.php` now checked in `$conf['metadir']/calendar/` first (per-animal), falls back to `DOKU_PLUGIN` (shared) - Added `syncConfigPath()` helper with fallback logic - Google OAuth tokens already stored per-animal in `$conf['metadir']` **CLI Sync Safety** - `sync_outlook.php` bootstraps DokuWiki with `NOSESSION` for CLI safety - Defensive fallback for `$conf['metadir']` when not set - Cron jobs should run as `www-data`, not root, to avoid file ownership issues ### Security Hardening **ACL Enforcement on All AJAX Endpoints** - Read operations (`load_month`, `get_event`, `get_static_calendar`, `search_all`) verify `AUTH_READ` - Write operations (`save_event`, `delete_event`, `toggle_task`) verify `AUTH_EDIT` - Wildcard/multi-namespace views silently filter out namespaces the user cannot access - Applied to both server-side rendering (syntax.php) and AJAX paths (action.php) **CSRF Protection on Admin Panel** - Added `checkSecurityToken()` validation to the admin `handle()` method - Added `formSecurityToken()` to all 12 HTML forms - Added `JSINFO.sectok` hidden input to all 11 JavaScript-generated forms **Removed System Stats Endpoint** - Deleted `get_system_stats.php` β€” exposed CPU, memory, load averages, uptime, and top processes via `shell_exec('ps aux')` and `/proc/meminfo` through a directly-accessible PHP endpoint - Removed admin UI section, CSS, and save/load methods - System load inline JS remains but never executes (`getShowSystemLoad()` returns `false`) ### Bug Fixes **Weekly Recurring Events on Sunday Created 365 Daily Events** - PHP's string `'0'` is falsy β€” when Sunday (day index 0) was the only selected weekday, the `$weekDays` array was empty, and every day matched - Fixed: strict comparison `($weekDaysStr !== '')` instead of truthy check **Memory Exhaustion on Large Wikis (namespace=*)** - Replaced recursive `findSubNamespaces` (which scanned every directory in `data/meta/`) with `findCalendarNamespaces` using iterative `glob()` to locate `calendar/` directories directly - On a wiki with 5,000 pages: old approach scanned 5,000+ dirs; new approach runs ~10 glob calls **Page Load Crash: "Cannot read properties of null"** - ARIA live region creation ran before `document.body` existed (script loaded in ``) - Wrapped in deferred function that waits for `DOMContentLoaded` **JS Cache Busting** - `script.js` was using `Date.now()` as cache buster, forcing fresh HTTP requests on every page load - Changed to version-based `?v=7.2.1` ### Housekeeping - Updated `@version` docblocks across all PHP files - Added localized strings (EN/DE/CS) for exclude and search scope features - Template `style.ini` lookups now check `$conf['savedir']` for farm-specific overrides ### Migration Notes **From 7.0.x (non-farm):** No action needed β€” paths resolve to the same location. **Farm setups:** Calendar data stays in the master wiki's `data/meta/`. Move per-animal data manually: ```bash mv /path/to/master/data/meta/calendar/ /path/to/animal/data/meta/calendar/ mv /path/to/master/data/meta/calendar_*.txt /path/to/animal/data/meta/ ``` **Cleanup:** The file `calendar_show_system_load.txt` in your data directory can be safely deleted. --- ## Version 7.0.8 (2026-02-15) - TIMEZONE FIX ### Bug Fix: Date Shift in Non-UTC Timezones Fixed critical bug where events appeared shifted by one day in timezones ahead of UTC (e.g., Europe/Prague UTC+1). **Root Cause:** JavaScript's `toISOString()` converts dates to UTC, so local midnight (00:00) in Prague becomes 23:00 UTC of the *previous day*. When split to get YYYY-MM-DD, this returns the wrong date. **Fix:** Added `formatLocalDate(date)` helper function that formats dates using local time methods (`getFullYear()`, `getMonth()`, `getDate()`) instead of UTC conversion. **Affected Areas (now fixed):** - Multi-day event spanning (line 385) - Today string calculation in event list (line 566) - Past event detection in event items (line 1022) ### Files Modified - `calendar-main.js` - Added `formatLocalDate()` helper, replaced 3 `toISOString().split('T')[0]` calls --- ## Version 7.0.7 (2026-02-15) - GOOGLE CALENDAR SYNC ### Google Calendar Integration - Two-way sync with Google Calendar via OAuth 2.0 - Import events from Google Calendar to DokuWiki - Export events from DokuWiki to Google Calendar - Support for all-day and timed events - Multi-day event handling - Color mapping between Google and DokuWiki - Duplicate detection prevents re-importing same events - Select which Google calendar to sync with - Admin panel UI for configuration and sync controls ### Setup Requirements - Google Cloud Console project - Google Calendar API enabled - OAuth 2.0 Web Application credentials - Redirect URI configuration ### New Files - `classes/GoogleCalendarSync.php` - OAuth and Calendar API integration ### Files Modified - `action.php` - Added Google sync action handlers - `admin.php` - Added Google sync admin tab --- ## Version 7.0.6 (2026-02-15) - ACCESSIBILITY IMPROVEMENTS ### Screen Reader Support - Added ARIA live region for dynamic announcements - Announces "Event created", "Event updated", "Event deleted" on actions - Announces "Task marked complete/incomplete" on toggle - Screen readers receive feedback without visual alerts ### Debug Mode - Added `CALENDAR_DEBUG` flag for JavaScript console logging - `calendarLog()` and `calendarError()` helper functions - Debug output disabled by default ### Code Quality - Consistent error handling patterns - Better separation of concerns ### Files Modified - `calendar-main.js` - ARIA live region, debug helpers, announcements --- ## Version 7.0.5 (2026-02-15) - AUDIT LOGGING & ACCESSIBILITY ### Audit Logging - New `AuditLogger.php` class for compliance logging - Logs all event modifications: create, update, delete, move, task toggle - JSON-formatted log files with timestamps, user info, and IP addresses - Automatic log rotation (5MB max, 10 files retained) - Log entries include: namespace, date, event ID, title, and change details ### Keyboard Navigation (Accessibility) - Arrow keys navigate between calendar days - Enter/Space activates focused day (opens popup) - Arrow Up/Down navigates between events in popups - Enter on event opens edit dialog - Delete/Backspace on event triggers delete - Escape closes all dialogs, popups, and dropdowns - Added `tabindex` and `role` attributes for screen readers - Added `aria-label` descriptions for calendar days and events ### CSS Focus States - Visible focus indicators on calendar days - Focus styles on event items in popups - Focus styles on custom date/time pickers - Uses `focus-visible` for keyboard-only focus rings ### Files Added - `classes/AuditLogger.php` - Compliance audit logging ### Files Modified - `action.php` - Integrated audit logging for all event operations - `calendar-main.js` - Extended keyboard navigation - `syntax.php` - Added accessibility attributes to calendar cells - `style.css` - Added focus state styles --- ## Version 7.0.4 (2026-02-15) - CODE CLEANUP ### Code Cleanup - Removed unused `calendarDebounce()` and `calendarThrottle()` utility functions - Removed duplicate `updateEndTimeOptions()` function definition - Removed unused `_calendarSelectOpen` tracking variable - Removed orphaned `.input-date` and `.time-select` CSS (no longer using native inputs) - Consolidated legacy function calls ### Improvements - End date picker now opens to start date's month when no end date is selected - End time picker now scrolls to first available time after start time ### Files Modified - `calendar-main.js` - Removed ~40 lines of dead code - `style.css` - Removed ~25 lines of unused CSS --- ## Version 7.0.3 (2026-02-15) - CUSTOM DATE & TIME PICKERS ### Complete Replacement of Native Browser Controls Both date inputs and time selects have been replaced with custom, lightweight pickers to eliminate all browser-related performance issues. #### Custom Date Picker - **Mini calendar grid** - Clean monthly view with day selection - **Month navigation** - Previous/next buttons for quick browsing - **Visual indicators** - Today highlighted, selected date marked - **End date validation** - Cannot select end date before start date - **Clear button** - Easy removal of optional end date #### Custom Time Picker (from v7.0.2) - **Period groupings** - Morning, Afternoon, Evening, Night - **Lazy loading** - Options built only when dropdown opens - **Smart filtering** - End times after start time only #### Code Cleanup - Removed old `setupSelectTracking()` function (was causing conflicts) - Removed redundant event listener code - Unified dropdown close handling for all picker types - No native `` or `` element with 97 time options was causing browser freezes when opening. This version replaces them with lightweight custom dropdown pickers. #### New Custom Time Picker Features - **Instant opening** - No browser rendering delay - **Lazy-loaded options** - Dropdown HTML built only when clicked - **Period grouping** - Morning, Afternoon, Evening, Night sections - **Smart filtering** - End time options automatically hide times before start time - **Visual feedback** - Selected time highlighted, disabled times grayed out #### Technical Changes - Replaced `` stores actual value for form submission - Time data pre-computed once, reused for all pickers - Event delegation for option clicks - Automatic cleanup when clicking outside #### Removed - Native `