Search by

wts-calendar / server-php

PSR-7/PSR-15 REST API server for calendar events, scheduling, validation, ETags, and pluggable PHP storage.

Maintainers

Package info

github.com/wts-calendar/server-php

Homepage

Documentation

pkg:composer/wts-calendar/server-php

Transparency log

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-09-02 12:02 UTC

This package is not auto-updated.

Last update: 2026-09-03 10:40:16 UTC


README

Latest Stable Version PHP Requirement License

wts-calendar/server-php is the framework-neutral PHP REST API companion for @wts-calendar/core. It provides production-oriented PSR-7/PSR-15 HTTP handling, immutable event contracts, validation, strong ETags, optimistic concurrency, and a replaceable persistence boundary. It does not require a WTS-hosted backend.

Use it with Angular, React, Vue, React Native, or any client capable of calling JSON HTTP endpoints. Slim can mount the handler directly; Laravel and Symfony can use their standard PSR bridges.

Highlights

  • framework-neutral PSR-7, PSR-15, and PSR-17 integration;
  • visible-range loading and complete event CRUD routes;
  • strong ETag/If-Match protection against lost updates;
  • RFC 7807-compatible validation and conflict responses;
  • all-day, timed, custom-field, resource, and recurrence payload support;
  • pluggable persistence for PDO, Doctrine, Eloquent, document stores, or APIs;
  • bounded payload, query-window, page-size, and identifier validation;
  • no hosted backend, account, telemetry, or vendor-controlled database.

Compatibility

Component Supported
PHP 8.2, 8.3, 8.4 and later compatible 8.x releases
HTTP messages PSR-7 2.x
Request handler PSR-15 1.x
HTTP factories PSR-17 1.x
WTS browser client @wts-calendar/core REST data adapter

Install

composer require wts-calendar/server-php:^1.0

The package supports PHP 8.2 and newer and depends only on standard PSR interfaces at runtime. Your application supplies a PSR-17 response/stream factory; most PSR-compatible frameworks already provide one.

Configure

<?php

use WtsCalendar\Server\CalendarApiHandler;
use WtsCalendar\Server\CalendarApiOptions;
use WtsCalendar\Server\CalendarEventStoreInterface;

$handler = new CalendarApiHandler(
    $container->get(CalendarEventStoreInterface::class),
    $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
    $container->get(Psr\Http\Message\StreamFactoryInterface::class),
    new CalendarApiOptions(
        requireIfMatchForUpdate: true,
        requireIfMatchForDelete: true,
    ),
);

Route both the collection and item paths to this PSR-15 handler:

$app->map(
    ['GET', 'POST', 'PATCH', 'PUT', 'DELETE'],
    '/api/calendar/events[/{id}]',
    $handler,
);

That route syntax is directly usable with Slim 4. In Symfony or Laravel, expose the same handler through the framework's PSR-7/PSR-15 bridge. Authentication, authorization, CORS, and rate limiting remain normal host middleware.

Implement CalendarEventStoreInterface with PDO, Doctrine, Eloquent, a document database, or an existing service. InMemoryCalendarEventStore is included only for examples and tests; it is not durable and must not be used as production persistence.

Connect the browser package

import {
  CalendarDataClient,
  createRestCalendarDataAdapter,
} from '@wts-calendar/core/data-adapter-sdk';

const endpoint = 'https://api.example.com/api/calendar/events';

const adapter = createRestCalendarDataAdapter({
  url: endpoint,
  mutationUrl: ({ type, id }) =>
    type === 'create' ? endpoint : `${endpoint}/${encodeURIComponent(id ?? '')}`,
  headers: async () => ({
    authorization: `Bearer ${await accessToken()}`,
  }),
});

const events = new CalendarDataClient(adapter);

All-day values use yyyy-MM-dd. Timed values and query boundaries require ISO 8601 with Z or an explicit UTC offset. Mutation versions are sent as If-Match entity tags.

HTTP contract

Method Route Purpose
GET /api/calendar/events?start=...&end=...&timeZone=... Load a bounded visible range
GET /api/calendar/events/{id} Load one event and its ETag
POST /api/calendar/events Create; returns 201, Location, and ETag
PATCH or PUT /api/calendar/events/{id} Replace the event representation
DELETE /api/calendar/events/{id} Delete an event

The handler returns RFC 7807-compatible problem documents. Stale versions use 409 Conflict, matching the WTS REST adapter's conflict result.

Production responsibilities

The host application remains responsible for:

  • authentication and per-calendar/per-event authorization;
  • tenant isolation, durable storage, transactions, and migrations;
  • CORS origins, rate limits, server request-size limits, and observability;
  • provider secrets and Google/Microsoft/CalDAV token storage;
  • framework exception handling and conflict policy.

Configure a web-server/PHP request limit as well as maxPayloadBytes; the handler enforces its own bounded stream read, but rejecting oversized requests before PHP allocates them is more efficient.

Local verification

composer install
composer check
COMPOSER_ROOT_VERSION=1.0.0 composer archive --format=zip --dir=artifacts

The conformance script checks create, query, strict preconditions, stale-version conflicts, update, validation, delete, ETags, all-day serialization, and route isolation using a real PSR-7 implementation.

For a runnable month calendar with create, edit, and delete dialogs, see Suman201/calendar-server-php-example. It mounts this package's real handler and uses a host-provided JSON storage adapter.

Project links

License

MIT © Suman Mandal.