Skip to content

Add ICS calendar feed import with automatic blocking timeframes - #23

Open
datengraben wants to merge 1 commit into
masterfrom
claude/ics-sync-mvp-V42KT
Open

Add ICS calendar feed import with automatic blocking timeframes#23
datengraben wants to merge 1 commit into
masterfrom
claude/ics-sync-mvp-V42KT

Conversation

@datengraben

Copy link
Copy Markdown
Owner

Summary

This PR introduces a new ICS (iCalendar) feed synchronization system that allows administrators to configure external calendar feeds and automatically create blocking timeframes for items/locations during calendar events. This makes items unavailable in the booking system when they're marked as busy in external calendars.

Key Changes

  • New ICSImport Service (src/Service/ICSImport.php):

    • Fetches and parses ICS calendar feeds from external URLs
    • Extracts VEVENT blocks and handles various datetime formats (UTC, timezone-aware, floating, all-day events)
    • Creates HOLIDAYS_ID blocking timeframes for each event × item × location combination
    • Implements cleanup logic to remove timeframes when events are deleted from the feed
    • Supports RFC 5545 line folding and ICS text escape sequences
    • Handles timezone conversions to the WordPress site timezone
  • New ICSFeed Custom Post Type (src/Wordpress/CustomPostType/ICSFeed.php):

    • Manages ICS feed configuration posts with CMB2 metabox
    • Allows administrators to configure: feed URL, target items, target locations, and lookahead window
    • Provides "Sync now" action in both list view and edit screen for manual synchronization
    • Displays sync status (last sync time, error messages) in the admin interface
    • Stores metadata for tracking synced events and their source feeds
  • Scheduler Integration (src/Service/Scheduler.php):

    • Registers hourly cron job to automatically sync all published ICS feeds
    • Ensures feeds are kept in sync without manual intervention
  • Plugin Registration (src/Plugin.php):

    • Registers the new ICSFeed custom post type in the plugin initialization
  • Comprehensive Test Suite (tests/php/Service/ICSImportTest.php):

    • Unit tests for ICS parsing (VEVENT extraction, datetime parsing with various formats)
    • Integration tests for feed synchronization, cleanup, and deduplication
    • HTTP mocking for testing without external dependencies

Notable Implementation Details

  • Datetime Handling: Properly handles UTC (Z suffix), timezone-aware (TZID parameter), floating, and all-day events, converting all to WordPress site timezone
  • Event Deduplication: Uses composite UIDs (event-uid:item-id:location-id) to track synced events and prevent duplicates on re-sync
  • Cleanup Strategy: Removes timeframes for events no longer present in the feed while preserving manually-created timeframes
  • Full-Day Timeframes: Creates blocking timeframes as full-day events (midnight to 23:59) matching the existing timeframe convention
  • Error Handling: Stores sync errors in post metadata for admin visibility without blocking the sync process

https://claude.ai/code/session_01WxALKfRznRXqZRu6LQ2a23

Admins can now configure external ICS calendar URLs and link them to
specific items/locations. A cron job syncs the feed hourly and creates
HOLIDAYS_ID blocking timeframes for each calendar event, preventing
bookings during those periods.

- src/Service/ICSImport.php: fetch, parse (UTC/TZID/floating/all-day),
  and sync VEVENT blocks into cb_timeframe posts; UID-based delta sync
  avoids duplicates and cleans up removed events
- src/Wordpress/CustomPostType/ICSFeed.php: admin-only CPT for feed
  config (URL, item/location targets, lookahead window); includes
  "Sync now" row action and status display in metabox
- src/Plugin.php: register ICSFeed CPT; add it to body-class filter
- src/Service/Scheduler.php: add hourly ICS sync cron job
- tests/php/Service/ICSImportTest.php: unit + integration tests for
  parser (UTC, floating, TZID, all-day, line folding) and sync logic
  (create, update, cleanup, idempotency)

https://claude.ai/code/session_01WxALKfRznRXqZRu6LQ2a23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants