NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

The package works with zero configuration. The published config/connections.php in full:

return [

    // The Eloquent model used to represent a connection. Swap it for your own
    // subclass of RoundlyConsulting\Connections\Models\Connection to extend behaviour.
    'model' => RoundlyConsulting\Connections\Models\Connection::class,

    // The database table that stores connections. The migration reads this value.
    'table' => env('CONNECTIONS_TABLE', 'connections'),

    // Key type of the connector / connectable morph columns: bigint, uuid or ulid.
    // Read by the migration — choose it before you publish and run it.
    'key_type' => env('CONNECTIONS_KEY_TYPE', 'bigint'),

    // In-request memoisation of resolved connections. Writes invalidate it automatically,
    // and it is dropped at the start of every request / queued job (Octane included).
    'cache' => [
        'enabled' => env('CONNECTIONS_CACHE_ENABLED', true),
    ],

    // Dispatch lifecycle events as connections change.
    'events' => [
        'enabled' => env('CONNECTIONS_EVENTS_ENABLED', true),
    ],

    // Register a Gate::before check so $user->can('permission', $connectable) works.
    'register_gate' => env('CONNECTIONS_REGISTER_GATE', false),

    // Permissions applied to a new connection when the caller supplies none.
    'default_permissions' => [],

    // Status a connection is created with when none is given (pending|accepted|blocked).
    'default_status' => env('CONNECTIONS_DEFAULT_STATUS', 'accepted'),

    // When true, access checks only count active (accepted + not expired) connections.
    'enforce_active_on_check' => env('CONNECTIONS_ENFORCE_ACTIVE_ON_CHECK', true),

    // Default expiry for new connections: a relative string ("30 days") or seconds.
    'expiry' => [
        'default' => env('CONNECTIONS_EXPIRY_DEFAULT'),
    ],

];

Every key

KeyEnvDefaultPurpose
model—Connection::classConnection model. Must be Models\Connection or a subclass — anything else throws InvalidConfigurationException naming the key.
tableCONNECTIONS_TABLEconnectionsTable that stores connections; read by the migration and the model. Blank = not set (connections); any other value must be a string.
key_typeCONNECTIONS_KEY_TYPEbigintKey type of the polymorphic connector / connectable columns: bigint, uuid or ulid (anything else throws InvalidConfigurationException). Read by the migration, so set it before migrating.
cache.enabledCONNECTIONS_CACHE_ENABLEDtrueIn-request connection cache, scoped to one request / queued job. Disable to always re-query.
events.enabledCONNECTIONS_EVENTS_ENABLEDtrueDispatch lifecycle events.
register_gateCONNECTIONS_REGISTER_GATEfalseFall a host Gate check through to connection permissions.
default_permissions—[]Permissions applied when a connection is created with none. An explicit empty set stays empty. Not set (null or blank) = none; otherwise a list of non-empty permission names.
default_statusCONNECTIONS_DEFAULT_STATUSacceptedStatus new connections start in: pending, accepted or blocked; anything else throws InvalidConfigurationException. Never applied to an existing connection.
enforce_active_on_checkCONNECTIONS_ENFORCE_ACTIVE_ON_CHECKtrueRequire accepted + not expired for access checks. false = status and expiry are advisory; any stored connection counts.
expiry.defaultCONNECTIONS_EXPIRY_DEFAULTnullDefault expiry for new connections when none is given: a positive relative string (30 days) or a number of seconds ≥ 1 — an integer or a numeric env string. Not set (null or blank) = never.

Environment

Every key except model and default_permissions is env-backed, so you rarely need to publish the config at all:

CONNECTIONS_TABLE=connections
CONNECTIONS_KEY_TYPE=bigint
CONNECTIONS_CACHE_ENABLED=true
CONNECTIONS_EVENTS_ENABLED=true
CONNECTIONS_REGISTER_GATE=false
CONNECTIONS_DEFAULT_STATUS=accepted
CONNECTIONS_ENFORCE_ACTIVE_ON_CHECK=true
CONNECTIONS_EXPIRY_DEFAULT="30 days"

Boolean keys read env strings the usual way: true, 1, on or yes switch a flag on; false, 0, off or no switch it off, and anything else (a typo such as =disabled) throws InvalidConfigurationException instead of quietly reading as the default. expiry.default takes a relative string such as 30 days or seconds — an integer, or a numeric env string such as CONNECTIONS_EXPIRY_DEFAULT=3600. It applies to new connections only.

A key that is not set (absent, null, or blank: '' or whitespace, as a bare CONNECTIONS_DEFAULT_STATUS= line gives) takes its default. Anything else that doesn’t fit throws InvalidConfigurationException naming the key rather than falling back: an expiry Carbon can’t parse (thirty days), a zero or negative one, a non-string or non-integer expiry, a permission list that isn’t a list of names (a blank name in the list included), a non-string table, an unknown key_type or default_status, or a model that isn’t a Connection.

Access checks need an active connection

enforce_active_on_check is on by default: permission checks, the Gate hook, isConnectedTo() and the other connected-to checks only count active connections — accepted and not expired. An expired or non-accepted connection grants no permission. Set the flag to false to treat status and expiry as advisory, so any stored connection counts.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.