PHPackages                             carshub/carshub-connector - 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. carshub/carshub-connector

ActiveLibrary[API Development](/categories/api)

carshub/carshub-connector
=========================

Connect your Laravel site to your CarsHub crew — syncs pages, events, members, and cars via the CarsHub API with a local JSON cache.

v0.5.0(3w ago)1130[2 issues](https://github.com/IriksIT/CarsHub-Composer-Connector/issues)MITPHPPHP ^8.2CI passing

Since Jun 12Pushed 1w agoCompare

[ Source](https://github.com/IriksIT/CarsHub-Composer-Connector)[ Packagist](https://packagist.org/packages/carshub/carshub-connector)[ RSS](/packages/carshub-carshub-connector/feed)WikiDiscussions production Synced 1w ago

READMEChangelog (8)Dependencies (8)Versions (10)Used By (0)

CarsHub Connector
=================

[](#carshub-connector)

A Laravel package that connects your crew's website to [CarsHub](https://carshub.nl). It pulls pages, events, members, and cars from the CarsHub API and keeps them in a local JSON cache so your site stays fast and responsive even when the CarsHub API is unavailable.

How it works
------------

[](#how-it-works)

- **Stale-while-revalidate** — every read returns immediately from cache. If the cache is fresh the request never touches the API. If the cache is stale, the stale data is returned while the scheduler refreshes it in the background.
- **First-run sync** — when no cache files exist the connector fetches all data on first boot and stores it, so your pages work from the first request.
- **Scheduled refresh** — register `php artisan schedule:run` as a cron job once and the connector handles the rest:
    - Pages and settings → refreshed **daily**
    - Events, members, cars, stats → refreshed **hourly**

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

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, 12, or 13

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

[](#installation)

```
composer require carshub/carshub-connector
```

Publish the config file:

```
php artisan vendor:publish --tag=carshub-config
```

Add your credentials to `.env`:

```
CARSHUB_API_KEY=your-api-key-from-crew-settings
CARSHUB_CREW_SLUG=your-crew-slug

# System-managed crews only — needed for event import (create/update/delete)
CARSHUB_EVENT_IMPORT_KEY=eik_...
```

You can find `CARSHUB_API_KEY` and `CARSHUB_CREW_SLUG` in **Crew Settings → Website Sync** on carshub.nl. The `CARSHUB_EVENT_IMPORT_KEY` is shown when the crew is created via the `crews:create-system` command.

Make sure Laravel's scheduler is running:

```
# Add to your server's crontab:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```

Usage
-----

[](#usage)

### Blade / controllers

[](#blade--controllers)

```
use CarsHub\Connector\Facades\CarsHub;

// All six page configurations in one call — use this in your layout/middleware
// to determine which pages are enabled and what their titles/settings are.
// Keys: home, about, crew_list, events, event_detail, contact
$allPages = CarsHub::pages();

// Or fetch a single page by key (useful for page-level controllers)
$home = CarsHub::page('home');

// Upcoming and past events (list — id, title, location, starts_at, ends_at, avatar_url, banner_url)
$upcoming = CarsHub::events('upcoming');
$past     = CarsHub::events('past');

// Full event detail including the attendee list (attending + maybe)
$detail = CarsHub::eventDetail(3);
// $detail['attendees']         — list of attendees; every entry includes:
//     'id', 'name', 'username', 'avatar_url', 'status' ('attending'|'maybe')
//     'is_passenger' => true/false  — attending as a passenger (no car brought)
//     'car'          => ['id','make','model','year','color'] | null — first car (backward-compat)
//     'cars'         => [['id','make','model','year','color'], ...]  — all cars (may be empty)
// $detail['attendees_count']   — total attending/maybe count
// $detail['is_multi_day']      — true when the event spans multiple calendar days
// $detail['event_days']        — ['2026-08-15', '2026-08-16', ...] (null for single-day events)
// $detail['attendees_by_day']  — map of date → attendee list for multi-day events (null for single-day)
//   Each entry in attendees_by_day has the same shape as attendees[] above (per-day cars/is_passenger)

// Crew member roster (id, name, username, avatar_url, role, staff_title, joined_at, social_links)
// social_links: {instagram, facebook, x, snapchat, website} — null when not set
$members = CarsHub::members();

// All active cars owned by crew members (includes social_links with owner fallback)
// social_links: car's own link, or the owner's link for that platform when the car has none
$cars = CarsHub::cars();

// Crew overview stats (members, cars, representatives, past_events, upcoming_events)
// Also includes crew info (name, description, avatar_url, banner_url)
$stats = CarsHub::stats();
```

### Event import (system-managed crews only)

[](#event-import-system-managed-crews-only)

If your crew is a system-managed crew with an `CARSHUB_EVENT_IMPORT_KEY` configured, you can write events directly from your application. All write methods throw `CarsHubApiException` on failure — wrap them in a try/catch.

```
use CarsHub\Connector\Facades\CarsHub;
use CarsHub\Connector\Exceptions\CarsHubApiException;

try {
    // Create a new event — returns the created event array
    $event = CarsHub::createEvent([
        'title'        => 'Silvia Cup Round 1',
        'description'  => 'First round of the Nissan Silvia one-make series.',
        'location'     => 'Circuit Zandvoort',
        'address'      => 'Burgemeester van Alphenstraat 108, Zandvoort',
        'starts_at'    => '2026-08-15T09:00:00Z',
        'ends_at'      => '2026-08-15T17:00:00Z',
        'members_only' => false,
        'invite_only'  => false,
    ]);
    $eventId = $event['id'];

    // Update an existing event (replaces all fields)
    $updated = CarsHub::updateEvent($eventId, [
        'title'     => 'Silvia Cup Round 1 — Updated',
        'starts_at' => '2026-08-15T09:00:00Z',
        'ends_at'   => '2026-08-15T18:00:00Z',
    ]);

    // Delete an event permanently
    CarsHub::deleteEvent($eventId);
} catch (CarsHubApiException $e) {
    // Log or surface the error as appropriate for your application
    logger()->error('CarsHub event import failed: ' . $e->getMessage());
}
```

After each write the local events cache (`events.upcoming`, `events.past`, and the event detail if cached) is invalidated automatically, so the next read will return fresh data.

### Artisan commands

[](#artisan-commands)

```
# Show cache freshness for all data types
php artisan carshub:status

# Sync all stale data right now
php artisan carshub:sync

# Force-refresh everything regardless of TTL
php artisan carshub:sync --force

# Sync only specific types
php artisan carshub:sync --type=events --type=members

# Clear the local cache (next read will re-fetch from the API)
php artisan carshub:cache:clear
```

Configuration
-------------

[](#configuration)

All options are in `config/carshub.php` after publishing.

KeyDefaultDescription`api_key``env('CARSHUB_API_KEY')`API key from Crew Settings → Website Sync`crew_slug``env('CARSHUB_CREW_SLUG')`Your crew's URL slug`api_base_url``https://carshub.nl/api`CarsHub API base URL`event_import_key``env('CARSHUB_EVENT_IMPORT_KEY')`Event import key (system-managed crews only)`cache.path``carshub`Subdirectory under `storage/` for JSON files`cache.ttl.pages``86400`Page cache TTL in seconds (24 h)`cache.ttl.events``3600`Events cache TTL in seconds (1 h)`cache.ttl.members``3600`Members cache TTL in seconds (1 h)`sync_on_boot``true`Dispatch a sync job on first boot if cache is empty`timeout``10`HTTP request timeout in secondsCache files
-----------

[](#cache-files)

Cached data is stored as JSON files under `storage/carshub/`:

```
storage/carshub/
  pages.json                  ← all 6 page configs (bulk endpoint, refreshed daily)
  pages/
    home.json                 ← only written if you call CarsHub::page('home') directly
    about.json
    …
  events/
    upcoming.json
    past.json
    detail/
      3.json                  ← written on first CarsHub::eventDetail(3) call
  members.json
  cars.json
  stats.json

```

Each file looks like:

```
{
  "fetched_at": 1718000000,
  "data": { ... }
}
```

You can safely delete any of these files — the connector will re-fetch on next read.

Troubleshooting
---------------

[](#troubleshooting)

**Pages return `null`**Check that `CARSHUB_API_KEY` and `CARSHUB_CREW_SLUG` are set and that the Website Sync module is enabled in your crew settings on CarsHub.

**Cache is always stale**Run `php artisan carshub:status` to see when each key was last fetched. Run `php artisan carshub:sync --force` to refresh immediately. Make sure `schedule:run` is registered in your crontab.

**Events don't update**Events refresh every hour. Run `php artisan carshub:sync --type=events --force` to refresh now.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance77

Regular maintenance activity

Popularity16

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% 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 ~3 days

Total

7

Last Release

25d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2891c6fdb9394dd7f0d11cc85b5d98ae15eefc13c3fea732183471fa9b518637?d=identicon)[iriks-it](/maintainers/iriks-it)

---

Top Contributors

[![iriks-it](https://avatars.githubusercontent.com/u/28785662?v=4)](https://github.com/iriks-it "iriks-it (6 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

---

Tags

laravelsynccarshubcrew

###  Code Quality

TestsPest

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/carshub-carshub-connector/health.svg)

```
[![Health](https://phpackages.com/badges/carshub-carshub-connector/health.svg)](https://phpackages.com/packages/carshub-carshub-connector)
```

###  Alternatives

[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77922.3M186](/packages/laravel-mcp)[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M348](/packages/psalm-plugin-laravel)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M250](/packages/laravel-ai)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)

PHPackages © 2026

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