Skip to content

neonish/php-ics-transform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ics-transform

A lightweight PHP script that fetches an ICS calendar feed, applies rule-based transformations, and serves the result as a new ICS feed — no Composer, no framework, no cron job required.

Use case

Subscribe to a calendar (e.g. from Microsoft Exchange/Outlook) and transform it on the fly before it reaches your calendar app: rename events, set location or reminders, remove entries, or filter by day, time, date, title, busy status, or recurrence.

Requirements

  • PHP 8.1+
  • allow_url_fopen = On in php.ini
  • Spyc — place it as yaml.php in the same directory

Setup

  1. Copy ics.php, yaml.php, and .htaccess to your web server.
  2. Create a <calendarname>.yaml for each calendar you want to transform.
  3. Subscribe to the transformed feed in your calendar app.

The .htaccess blocks direct HTTP access to all files except ics.php and yaml.php.

URL parameters

https://yourserver.com/ics.php?cal=mycalendar&pw=yourpassword
Parameter Description
cal Calendar name — must match a <cal>.yaml file
pw Password defined in the YAML file
debug Returns a plain-text stats report with a per-event transformation log
text Returns the transformed ICS as plain text for inspection

Calendar YAML

Each calendar has its own .yaml file with the source URL, password, and rules.

password: yourpassword
source_ics: https://your-exchange-server/calendar.ics

rules:
    - filter:
          days:
              - wed
          time:
              - type: exact
                starts: "11:00"
      apply:
          name: "Weekly Meeting"
          reminder: 10

Filter

All keys are optional — omitting a key (or setting it to null) matches anything.

days

List of weekdays: mon tue wed thu fri sat sun

time

List of conditions (all must match). All-day events are treated as 00:00 for range/before/after comparisons.

type fields
allday — matches only all-day events
exact starts: "HH:MM"
range from: "HH:MM" · to: "HH:MM"
before at: "HH:MM"
after at: "HH:MM"

date

List of conditions (all must match). For recurring events only DTSTART is evaluated, not generated occurrences.

type fields
exact at: "YYYY-MM-DD"
range from: "YYYY-MM-DD" · to: "YYYY-MM-DD"
before at: "YYYY-MM-DD"
after at: "YYYY-MM-DD"

busy_status

Matches X-MICROSOFT-CDO-BUSYSTATUS: FREE · BUSY · TENTATIVE · OOF

name

List of conditions (all must match, case-insensitive).

type fields
exact text: "Full Title"
contains text: "partial"
startswith text: "Prefix"
endswith text: "Suffix"

recurrent

true (has RRULE or RECURRENCE-ID) · false

Apply

All keys are optional — omitting a key leaves that field unchanged.

key type description
name string Overwrite event title
busy_status string Overwrite busy status
location string Overwrite location
reminder int Set VALARM to X minutes before start
remove bool Set to true to drop the event entirely

Rule matching

  • First matching rule wins — subsequent rules are not evaluated
  • Unmatched events pass through unchanged
  • Multiple conditions within the same filter key are combined with AND

Security

  • The cal parameter is validated against [a-zA-Z0-9_-] to prevent path traversal
  • Password is checked before fetching or processing anything
  • Keep .yaml files out of version control if they contain sensitive calendar URLs

License

MIT

About

A rule-based php proxy for overwriting ICS calendar events

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages