synara/sdk 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

synara/sdk

最新稳定版本:v1.0.0

Composer 安装命令:

composer require synara/sdk

包简介

PHP SDK for the Synara API

README 文档

README

A model-first PHP SDK for the Synara API. Build events with a fluent, immutable API and manage them through resource classes.

Installation

composer require synara/sdk

Quick Start

use Synara\Client;
use Synara\Api\Models\Event;
use DateTimeImmutable;
use DateInterval;

$client = new Client(
    apiKey: 'your-api-key-here'
);

$event = Event::make(
    uid: 'unique-event-id',
    title: 'Team Meeting',
    startsAt: new DateTimeImmutable('2024-01-15T10:00:00+00:00')
)->withDuration(new DateInterval('PT1H'));

$createdEvent = $client->events()->create($event);
printf("Event created: %s\n", $createdEvent->getUid());

Timezone requirement: the Synara API expects ISO 8601 timestamps with timezone offsets. Make sure your DateTimeImmutable values include an offset (e.g. 2024-01-15T10:00:00-08:00).

Resources & Requests

Client exposes typed resources. Each resource turns models into HTTP payloads for you, so you never have to hand-craft JSON.

  • $client->events()->create(Event $event): Event
  • $client->events()->find(string $uid): Event
  • $client->events()->update(string $uid, Event $event): Event

Every response is converted back into immutable model instances, ready for fluent reuse.

Creating Events

Build an event with Event::make() and then chain fluent modifiers. Every method returns a new immutable instance.

use Synara\Client;
use Synara\Api\Models\Event;
use DateTimeImmutable;
use DateInterval;

$client = new Client(apiKey: 'your-api-key');

$event = Event::make(
    uid: 'meeting-123',
    title: 'Team Standup',
    startsAt: new DateTimeImmutable('2024-01-15T10:00:00-08:00')
)
    ->withDuration(new DateInterval('PT30M'))
    ->withDescription('Daily team standup meeting')
    ->atLocation('Conference Room A');

$createdEvent = $client->events()->create($event);
printf("Created %s starting at %s\n", $createdEvent->getUid(), $createdEvent->getStartsAt()->format('c'));

The SDK automatically serializes this model into a JSCalendar jsevent payload when you call create() or update(). You work with PHP models; the SDK handles converting them to JSON that Synara understands.

Adding Attendees

Attendees are added using the fluent API:

use Synara\Api\Models\Attendee;

// Create an attendee
$attendee = Attendee::make(
    email: 'alice@example.com',
    name: 'Alice Smith'
);

// Optional attendee
$optionalAttendee = Attendee::make('bob@example.com', 'Bob Jones')
    ->asOptional();

// Attendee with RSVP status
$acceptedAttendee = Attendee::make('charlie@example.com', 'Charlie Brown')
    ->accepted();

$declinedAttendee = Attendee::make('dave@example.com', 'Dave Wilson')
    ->declined();

// Add attendees to event
$event = Event::make(
    uid: 'meeting-123',
    title: 'Team Meeting',
    startsAt: new DateTimeImmutable('2024-01-15T10:00:00Z')
)
    ->addAttendee($attendee)
    ->addAttendee($optionalAttendee)
    ->addAttendee($acceptedAttendee)
    ->addAttendee($declinedAttendee);

$createdEvent = $client->events()->create($event);

Updating Events

Because models are immutable, every modifier returns a new instance. Persist updates by sending the modified model back to the resource.

$event = $client->events()->find('meeting-123');

$updated = $event
    ->withDescription('Updated description')
    ->atLocation('New Location')
    ->addAttendee(Attendee::make('new@example.com', 'New Attendee'));

$saved = $client->events()->update($updated->getUid(), $updated);
printf("Updated %s to %s\n", $saved->getUid(), $saved->getLocation());

Finding Events

$event = $client->events()->find('meeting-123');

printf("Title: %s\n", $event->getTitle());
printf("Starts: %s\n", $event->getStartsAt()->format('c'));
printf("Location: %s\n", $event->getLocation() ?? 'n/a');

foreach ($event->getAttendees() as $attendee) {
    printf("Attendee: %s (%s)\n", $attendee->getEmail(), $attendee->getName() ?? 'no name');
}

Error Handling

The SDK throws specific exceptions for different error scenarios:

use Synara\Api\Exceptions\AuthenticationException;
use Synara\Api\Exceptions\ValidationException;
use Synara\Api\Exceptions\NetworkException;
use Synara\Api\Exceptions\ApiException;

try {
    $event = $client->events()->create($event);
} catch (AuthenticationException $e) {
    // 401 or 403 - Invalid API key or insufficient permissions
    echo "Authentication failed: {$e->getMessage()}\n";
} catch (ValidationException $e) {
    // 422 - Validation errors
    echo "Validation failed: {$e->getMessage()}\n";
    $errors = $e->getErrors();
    if ($errors) {
        print_r($errors);
    }
} catch (NetworkException $e) {
    // 500+ - Server errors or network issues
    echo "Network error: {$e->getMessage()}\n";
} catch (ApiException $e) {
    // Other API errors
    echo "API error: {$e->getMessage()}\n";
}

Custom HTTP Client

You can inject a custom PSR-18 HTTP client:

use Psr\Http\Client\ClientInterface;
use GuzzleHttp\Client as GuzzleClient;

$customClient = new GuzzleClient([
    'timeout' => 30,
    // ... other Guzzle options
]);

$client = new Client(
    apiKey: 'your-api-key',
    httpClient: $customClient
    // baseUri defaults to https://synara.events
);

Model Properties

Event

  • getUid(): string - Event unique identifier
  • getTitle(): string - Event title
  • getStartsAt(): DateTimeInterface - Event start time
  • getDuration(): ?DateInterval - Event duration (if set)
  • getDescription(): ?string - Event description (if set)
  • getLocation(): ?string - Event location (if set)
  • getAttendees(): array - Array of Attendee objects
  • getStatus(): string - Event status (default: 'confirmed')

Attendee

  • getEmail(): string - Attendee email address
  • getName(): ?string - Attendee name (if set)
  • getKind(): string - Attendee kind (default: 'individual')
  • getRole(): ?string - Attendee role (e.g., 'optional')
  • getRsvpStatus(): ?string - RSVP status, e.g. 'accepted', 'declined', 'needs-action' (or null if not set)

Serialization & Payloads

  • Event::toArray() returns a PHP associative array that matches the JSCalendar jsevent shape. The SDK JSON-encodes this structure whenever it calls the Synara API.
  • Attendee::toArray() returns the JSCalendar participant structure (email, optional name, role, RSVP status, etc.).

Example JSCalendar output:

$event = Event::make('uid-123', 'Test', new DateTimeImmutable('2024-01-01T10:00:00Z'));
$jsCalendar = $event->toArray();
{
    \"@type\": \"jsevent\",
    \"uid\": \"uid-123\",
    \"title\": \"Test\",
    \"start\": \"2024-01-01T10:00:00+00:00\"
}

Testing

Run the test suite:

composer install
vendor/bin/phpunit

The test suite includes:

  • EventModelTest - Tests for Event model immutability, fluent API, and serialization
  • AttendeeModelTest - Tests for Attendee model methods and serialization
  • EventsResourceTest - Tests for Events resource with mocked HTTP client

Immutability

All models are immutable. Methods like withDuration(), withDescription(), addAttendee(), etc., return new instances:

$event1 = Event::make('uid-123', 'Test', new DateTimeImmutable('2024-01-01T10:00:00Z'));
$event2 = $event1->withDescription('Description');

// $event1 is unchanged
assert($event1->getDescription() === null);
assert($event2->getDescription() === 'Description');
assert($event1 !== $event2); // Different instances

License

MIT

统计信息

  • 总下载量: 3
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-26