PHPackages                             mobiscroll/connect-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. mobiscroll/connect-php

ActiveLibrary[API Development](/categories/api)

mobiscroll/connect-php
======================

PHP SDK for Mobiscroll Connect API

v1.1.1(1mo ago)00MITPHPPHP ^8.1

Since Apr 10Pushed 1mo agoCompare

[ Source](https://github.com/acidb/mobiscroll-connect-php)[ Packagist](https://packagist.org/packages/mobiscroll/connect-php)[ RSS](/packages/mobiscroll-connect-php/feed)WikiDiscussions main Synced 3w ago

READMEChangelogDependencies (10)Versions (5)Used By (0)

Mobiscroll Connect PHP SDK
==========================

[](#mobiscroll-connect-php-sdk)

A PHP client library for the Mobiscroll Connect API, enabling seamless calendar and event management across multiple providers (Google Calendar, Microsoft Outlook, Apple Calendar, CalDAV).

📖 **[Full documentation](https://mobiscroll.com/docs/connect/php-sdk)**

Features
--------

[](#features)

- **Multi-provider support**: Google Calendar, Microsoft Outlook, Apple Calendar, CalDAV
- **OAuth2 authentication**: Full authorization code flow with token exchange
- **Automatic token refresh**: Silently refreshes expired access tokens and retries the original request
- **Event management**: Create, read, update, and delete calendar events
- **Calendar operations**: List calendars from all connected providers
- **Connection management**: Check provider connection status and disconnect accounts
- **Typed exceptions**: Distinct error classes for authentication, validation, rate limiting, and more
- **Type-safe**: PHP 8.1+ with strict typing throughout

Requirements
------------

[](#requirements)

- PHP 8.1 or higher
- Composer

Installation
------------

[](#installation)

```
composer require mobiscroll/connect-php
```

Setup
-----

[](#setup)

Create a Mobiscroll Connect application at the [Mobiscroll Connect dashboard](https://app.mobiscroll.com/connect) to obtain your **Client ID**, **Client Secret**, and configure your **Redirect URI**.

Usage
-----

[](#usage)

### Initialize the Client

[](#initialize-the-client)

```
use Mobiscroll\Connect\MobiscrollConnectClient;

$client = new MobiscrollConnectClient(
    clientId: 'YOUR_CLIENT_ID',
    clientSecret: 'YOUR_CLIENT_SECRET',
    redirectUri: 'YOUR_REDIRECT_URI',
);
```

### Token Refresh

[](#token-refresh)

The SDK automatically refreshes expired access tokens. When a request returns `401 Unauthorized` and a refresh token is available, the SDK silently exchanges it for a new access token and retries the request.

Register a callback to persist the updated tokens — this is required so the new tokens survive future requests:

```
$client->onTokensRefreshed(function (\Mobiscroll\Connect\TokenResponse $updatedTokens): void {
    // Persist in your database or session store
    $_SESSION['access_token'] = $updatedTokens->access_token;
    $_SESSION['refresh_token'] = $updatedTokens->refresh_token;
    $_SESSION['expires_in'] = $updatedTokens->expires_in;
});
```

If the refresh token is invalid or revoked, the SDK throws `AuthenticationError` and the user must re-authorize.

### OAuth2 Flow

[](#oauth2-flow)

#### Step 1: Generate the authorization URL

[](#step-1-generate-the-authorization-url)

```
$authUrl = $client->auth()->generateAuthUrl(
    userId: 'your-app-user-id',
    // Optional:
    // scope: 'read-write',
    // state: 'csrf-protection-value',
    // providers: 'google,microsoft',
    // lng: 'es', // Connect page language ('en', 'es', 'fr', 'ar')
);

header('Location: ' . $authUrl);
```

#### Step 2: Handle the callback and exchange the code for tokens

[](#step-2-handle-the-callback-and-exchange-the-code-for-tokens)

```
$code = $_GET['code'] ?? null;

$tokenResponse = $client->auth()->getToken($code);

// Persist all token fields — you need the refresh_token for auto-refresh
$_SESSION['access_token'] = $tokenResponse->access_token;
$_SESSION['token_type'] = $tokenResponse->token_type;
$_SESSION['expires_in'] = $tokenResponse->expires_in;
$_SESSION['refresh_token'] = $tokenResponse->refresh_token;
```

#### Step 3: Restore credentials and make API calls

[](#step-3-restore-credentials-and-make-api-calls)

```
$client->auth()->setCredentials(new \Mobiscroll\Connect\TokenResponse(
    access_token: $_SESSION['access_token'],
    token_type: $_SESSION['token_type'] ?? 'Bearer',
    expires_in: $_SESSION['expires_in'] ?? null,
    refresh_token: $_SESSION['refresh_token'] ?? null,
));

// The client is now authenticated — make API calls
$calendars = $client->calendars()->list();
```

### Calendars

[](#calendars)

```
$calendars = $client->calendars()->list();

foreach ($calendars as $calendar) {
    echo "{$calendar['provider']}: {$calendar['title']} ({$calendar['id']})\n";
}
```

### Events

[](#events)

#### List events

[](#list-events)

```
$response = $client->events()->list([
    'start' => new DateTime('2024-01-01'),
    'end' => new DateTime('2024-01-31'),
    'calendarIds' => ['google' => ['primary']],
    'pageSize' => 50,
]);

foreach ($response['events'] as $event) {
    echo "{$event['title']}: {$event['start']} – {$event['end']}\n";
}

// Load the next page
if (!empty($response['nextPageToken'])) {
    $next = $client->events()->list([
        'pageSize' => 50,
        'nextPageToken' => $response['nextPageToken'],
    ]);
}
```

#### Create an event

[](#create-an-event)

```
$event = $client->events()->create([
    'provider' => 'google',
    'calendarId' => 'primary',
    'title' => 'Team Meeting',
    'start' => '2024-06-15T10:00:00Z',
    'end' => '2024-06-15T11:00:00Z',
    'description' => 'Quarterly review',
    'location' => 'Conference Room A',
]);

echo "Created: {$event->id}\n";
```

#### Update an event

[](#update-an-event)

```
$updated = $client->events()->update([
    'provider' => 'google',
    'calendarId' => 'primary',
    'eventId' => 'event-id-to-update',
    'title' => 'Team Meeting (Rescheduled)',
    'start' => '2024-06-15T14:00:00Z',
    'end' => '2024-06-15T15:00:00Z',
]);
```

#### Delete an event

[](#delete-an-event)

```
$client->events()->delete([
    'provider' => 'google',
    'calendarId' => 'primary',
    'eventId' => 'event-id-to-delete',
]);
```

#### Recurring events

[](#recurring-events)

```
// Update only this instance of a recurring event
$client->events()->update([
    'provider' => 'google',
    'calendarId' => 'primary',
    'eventId' => 'instance-id',
    'recurringEventId' => 'series-id',
    'updateMode' => 'this',
    'title' => 'One-off title change',
]);

// Delete this and all following instances
$client->events()->delete([
    'provider' => 'google',
    'calendarId' => 'primary',
    'eventId' => 'instance-id',
    'recurringEventId' => 'series-id',
    'deleteMode' => 'following',
]);
```

### Connection Management

[](#connection-management)

```
// Check which providers are connected
$status = $client->auth()->getConnectionStatus();

foreach ($status->connections as $provider => $accounts) {
    echo "{$provider}: " . count($accounts) . " account(s)\n";
}

if ($status->limitReached) {
    echo "Connection limit of {$status->limit} reached\n";
}

// Disconnect a provider
$result = $client->auth()->disconnect(provider: 'google');

if ($result->success) {
    echo "Disconnected successfully\n";
}
```

Error Handling
--------------

[](#error-handling)

All SDK methods throw exceptions that extend `MobiscrollConnectException`:

ExceptionHTTP StatusExtra method`AuthenticationError`401, 403—`ValidationError`400, 422`getDetails(): array``NotFoundError`404—`RateLimitError`429`getRetryAfter(): ?int``ServerError`5xx`getStatusCode(): int``NetworkError`——```
use Mobiscroll\Connect\Exceptions\{
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
    ServerError,
    NetworkError,
    MobiscrollConnectException,
};

try {
    $events = $client->events()->list();
} catch (AuthenticationError $e) {
    // Token expired and refresh failed — re-authorize the user
} catch (ValidationError $e) {
    $details = $e->getDetails(); // field-level errors
} catch (NotFoundError $e) {
    // Calendar or event not found
} catch (RateLimitError $e) {
    $retryAfter = $e->getRetryAfter(); // seconds
} catch (ServerError $e) {
    $status = $e->getStatusCode(); // 500, 502, 503, 504
} catch (NetworkError $e) {
    // Connection failed
} catch (MobiscrollConnectException $e) {
    // Catch-all
}
```

Testing
-------

[](#testing)

```
# Install dependencies
composer install

# Run all tests
composer run test

# Run a specific test file
vendor/bin/phpunit tests/Unit/AuthTest.php
```

Project Structure
-----------------

[](#project-structure)

```
src/
├── Exceptions/
│   ├── MobiscrollConnectException.php
│   ├── AuthenticationError.php
│   ├── ValidationError.php
│   ├── NotFoundError.php
│   ├── RateLimitError.php
│   ├── ServerError.php
│   └── NetworkError.php
├── Resources/
│   ├── Auth.php
│   ├── Calendars.php
│   └── Events.php
├── ApiClient.php
├── Config.php
├── MobiscrollConnectClient.php
├── TokenResponse.php
├── Calendar.php
├── CalendarEvent.php
├── EventsListResponse.php
├── ConnectionStatusResponse.php
└── DisconnectResponse.php
tests/
├── Unit/
│   ├── AuthTest.php
│   ├── CalendarsTest.php
│   ├── ConnectionStatusResponseTest.php
│   ├── EventsTest.php
│   └── ExceptionsTest.php
└── Smoke/
    └── MinimalAppSmokeTest.php

```

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 92.3% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~18 days

Total

4

Last Release

51d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/78792954?v=4)[Bence Kovács](/maintainers/bencekovacs01)[@bencekovacs01](https://github.com/bencekovacs01)

---

Top Contributors

[![bencekovacs01](https://avatars.githubusercontent.com/u/78792954?v=4)](https://github.com/bencekovacs01 "bencekovacs01 (12 commits)")[![dioslaska](https://avatars.githubusercontent.com/u/324318?v=4)](https://github.com/dioslaska "dioslaska (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mobiscroll-connect-php/health.svg)

```
[![Health](https://phpackages.com/badges/mobiscroll-connect-php/health.svg)](https://phpackages.com/packages/mobiscroll-connect-php)
```

###  Alternatives

[aws/aws-sdk-php

AWS SDK for PHP - Use Amazon Web Services in your PHP project

6.2k543.5M2.7k](/packages/aws-aws-sdk-php)[laravel/framework

The Laravel Framework.

34.8k543.8M20.5k](/packages/laravel-framework)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3661.3M47](/packages/tencentcloud-tencentcloud-sdk-php)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

293.1k](/packages/eslazarev-wildberries-sdk)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6942.5M425](/packages/drupal-core-recommended)[files.com/files-php-sdk

Files.com PHP SDK

2481.1k](/packages/filescom-files-php-sdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
