WebCalendar

About WebCalendar

WebCalendar is a PHP-based calendar application that can be configured as a single-user calendar, a multi-user calendar for groups of users, or as an event calendar viewable by visitors. MySQL/MariaDB, SQLite3, PostgreSQL, Oracle, DB2, Interbase, MS SQL Server, or ODBC is required. The version 1.9.X releases are still a little rough around the edges since these include an overhaul of the UI to use Bootstrap and jQuery and a complete rewrite of the web-based installer.

WebCalendar can be setup in a variety of ways, such as…

  • A schedule management system for a single person
  • A schedule management system for a group of people, allowing one or more assistants to manage the calendar of another user
  • An events schedule that anyone can view, allowing visitors to submit new events
  • A calendar server that can be viewed with iCalendar-compliant calendar applications like Mozilla Sunbird, Apple iCal or GNOME Evolution or RSS-enabled applications like Firefox, Thunderbird, RSSOwl, FeedDemon, or BlogExpress.

Overview of Features

  • Multi-user support
  • 30 supported languages: Basque, Bulgarian, Chinese-Big5, Chinese-GB2312, Czech, Danish, Dutch, English-US, Estonian, Finnish, French, Galician, German, Greek, Holo-Big5, Hungarian, Icelandic, Italian, Japanese, Korean, Norwegian, Polish, Portuguese_BR, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish, Welsh (see current list of translations here)
  • Web-based installer
  • Auto-detect user’s language preference from browser settings
  • View calendars by day, week, month or year
  • View another user’s calendar
  • View one or more users’ calendar via layers on top of your own calendar
  • Add/Edit/Delete users
  • Add/Edit/Delete events
  • Repeating events including support for overriding or deleting (exceptions)
  • Configurable custom event fields
  • User-configurable preferences for colors, 12/24 time format, Sun/Mon week start
  • Checks for scheduling conflicts
  • Email reminders for upcoming events
  • Email notifications for new/updated/deleted events
  • Export events to iCalendar
  • Import from iCalendar/ics format
  • Optional general access (no login required) to allow calendar to be viewed by people without a login (useful for event calendars)
  • Users can make their calendar available publicly to anyone with an iCalendar-compliant calendar program (such as Apple’s iCal, Mozilla Calendar or Sunbird)
  • Publishing of free/busy schedules (part of the iCalendar standard)
  • RSS support that puts a user’s calendar into RSS
  • Subscribe to “remote” calendars (hosted elsewhere on the net) in either iCalendar or hCalendar formats (WebCalendar 1.1+)
  • User authentication: Web-based, HTTP, LDAP or NIS

System Requirements

  • PHP 8 or later
  • PHP support and access to one of the following databases:
    • SQLite
    • MySQL/MariaDB
    • Oracle
    • Postgres
    • IBM DB2
  • Access to cron for Linux/Unix systems (to send out reminders)

Development Cost

The following metrics from Ohloh show how much it would have cost to commercially develop WebCalendar.

  • Codebase Size: 138,588 lines
  • Estimated Effort: 34 person-years
  • Estimated Cost: $1,884,469
  • (As of 11 August 2024)

Donations

If you’d like to help support the costs of developing, maintaining and supporting WebCalendar, please consider donating.

Developer Resources

License

WebCalendar is available under the GNU General Public License, version 2.

For more information on this license:

Documentation

Most Recent Changes

Below are the most recent source code commits to github on the master branch.

  • fix: custom template HTML save, Firefox select font, mobile minicals …
    by craigk5n on April 19, 2026 at 1:11 pm

    fix: custom template HTML save, Firefox select font, mobile minicals (#639) – edit_template.php: read $_POST[‘template’] directly instead of via getPostValue(), which invokes the banned-tag XSS filter and addslashes(). The custom header/stylesheet/trailer editor is admin-only and designed to accept raw HTML (<link>, <script>, etc.); CSRF is already enforced and dbi_execute() uses prepared statements, so manual escaping corrupted stored values with literal backslashes. – styles.css: re-assert font-family/size/line-height: inherit on button/input/optgroup/select/textarea so Firefox’s UA styles for native form widgets don’t override Bootstrap’s reboot (fixes oversized category selector in Firefox). – styles.css: drop float on #prevmonth/#nextmonth below 576px and switch to inline-block so the two mini-calendars stack cleanly on narrow Android/phone viewports instead of leaving a jagged gap.

  • fix: keep Month/Week/Year horizontal on iPad portrait (#639)
    by craigk5n on April 18, 2026 at 10:52 pm

    fix: keep Month/Week/Year horizontal on iPad portrait (#639) Regression introduced by the navbar-expand-md -> navbar-expand-lg change in 58eddb5a. Bootstrap’s .navbar-nav defaults to flex-direction: column; only the expand-breakpoint selector (.navbar-expand-lg .navbar-nav) flips it to row. Since the collapse breakpoint moved from 768px to 992px, the center date-selector stacked vertically at 768-991px (iPad portrait, iPad Pro portrait, phones). The center block is never inside navbar-collapse and should always render horizontally regardless of viewport. Added flex-row utility (flex-direction: row !important) to the ul. Three short items (Month/Week/Year, ~126px total) fit side-by-side at all widths down to 320px.

  • fix: navbar collapse breakpoint, dual-collapse toggle, dead w-* class…
    by craigk5n on April 18, 2026 at 10:47 pm

    fix: navbar collapse breakpoint, dual-collapse toggle, dead w-* classes (#639) Reported by @Dellenoy in #639: “Month – week – day” selector overlaps the top menu when the screen is too small. Reproduced at viewport widths 768-900px, where the 8 main-menu dropdowns physically collide with the centered Month/Week/Year block. – navbar-expand-md -> navbar-expand-lg: collapse to hamburger below 992px instead of 768px. Eliminates the overlap band entirely; tablets in portrait now get the mobile menu (the expanded nav was unusable at those widths anyway). – data-target: switched from #navbarNavDropdown to .dual-collapse2 so the hamburger toggles both the main-menu AND the Logout collapses. The Logout <div> has carried the dual-collapse2 class since the original template was copied in, but the toggle hookup was never completed — Logout has been unreachable in mobile mode. Added id=”navbarLogoutCollapse” and updated aria-controls with both ids per ARIA spec. – Removed dead w-30 and w-20 classes. Bootstrap 4 ships only w-25/50/75/100/auto; these two were silently no-ops. Middle and right blocks have always been content-sized. Pure cleanup, zero visual change. w-50 retained as it is defined and constraining.

  • fix: remove stray quote and PHP block from styles.css (#639)
    by craigk5n on April 18, 2026 at 8:32 pm

    fix: remove stray quote and PHP block from styles.css (#639) Reported by @Dellenoy in #639 after diagnosing Firefox vs Edge rendering divergence (Edge enforces CSS parsing more strictly). – Line 347: trailing ” broke the .tt font-family declaration. – Lines 1409-1412: a raw <?php … ?> block was being sent to the browser verbatim since this file is served as a plain .css asset. Replaced with an equivalent /* */ comment.

  • fix: bypass and clear stale query cache for WEBCAL_PROGRAM_VERSION (#…
    by craigk5n on April 17, 2026 at 11:46 am

    fix: bypass and clear stale query cache for WEBCAL_PROGRAM_VERSION (#639) Aad’s latest report in #639 pinned the bug: webcal_config actually contained WEBCAL_PROGRAM_VERSION = v1.9.16 (he verified directly in the DB), yet config.php kept reporting “Database upgrade required (version v1.3.0 -> v1.9.16)” and redirecting back to the wizard on every request. Root cause is dbi4php’s on-disk query cache. includes/config.php:367 and includes/classes/WebCalendar.php:669 both read the version stamp via dbi_get_cached_rows(), which persists SELECT results to {db_cachedir}/*.dat and returns them for all future callers. The cache invalidation that dbi_query() runs on non-SELECT statements only fires when the write goes through dbi_execute(); the wizard’s updateVersionInDb() uses native mysqli/pg/sqlite3 directly, so the .dat file written while the DB was still at v1.3.0 stayed valid forever and pinned that value in the bootstrap version check. Three-part fix: 1. includes/config.php: drop the cache on the bootstrap version read. The cost is a single extra SELECT per request; correctness here is worth far more than one tiny cached row. 2. includes/classes/WebCalendar.php: same treatment for the duplicate version check. Also repoint its “mismatch” redirect at wizard/index.php — the hardcoded install/index.php target was dead code left over from #608 and would have 404’d if anything reached it. 3. WizardDatabase::executeUpgrade(): after a successful upgrade, wipe {dbCacheDir}/*.dat via direct filesystem ops so any OTHER stale cached queries (PUBLIC_ACCESS, user prefs, etc.) get refreshed on the next request. No dbi4php dependency needed for the cleanup. Tests cover the cache-clear step (stale .dat file gets removed after executeUpgrade) and the noop-when-no-cachedir guard.

Download Metrics

  • Downloads via Github: 20136
  • Downloads via SourceForge:

Related Links

  • Standards
    • RFC 2445: Internet Calendaring and Scheduling Core Object Specification (iCalendar)
    • CalDAV: Calendaring and Scheduling Extensions to WebDAV (DRAFT) 
      [Note: WebCalendar does not yet support CalDAV.)
  • Calendar client applications – You can use the applications to view events stored in WebCalendar if you enable its publishing settings.
  • iCalendar/ics download sites – These sites contain calendars for holidays, sports teams schedules, music converts, etc. You can import these files into WebCalendar.