daikazu/eloquent-salesforce-objects
Laravel Eloquent-style models for Salesforce sObjects. Query and sync Salesforce data using familiar Eloquent patterns, with object mapping and relationships to work with Accounts, Contacts, and more from your Laravel app.
Fixes a production failure mode where concurrent workers all hammered the Salesforce OAuth endpoint after a token-cache miss, triggering recurring 400 unknown_error / retry your request responses.
Forrest::authenticate() with a double-check inside the lock. Concurrent callers reuse the freshly-cached token instead of issuing parallel OAuth POSTs.400 unknown_error / retry your request envelopeConnectExceptioninvalid_grant, credential failures, and other 4xx — retrying those just makes things worse.sha1(consumer_key) so multi-org setups don't collide.This release adds a new authentication block to config/eloquent-salesforce-objects.php. If you've published the config previously, re-publish to pick up the new keys (or copy them in manually). Defaults preserve existing behavior on the hot path — you don't need to change .env to benefit.
php artisan vendor:publish --tag="eloquent-salesforce-objects-config" --force
All env-tunable, defaults conservative:
'authentication' => [
'retry_attempts' => env('SALESFORCE_AUTH_RETRY_ATTEMPTS', 3),
'retry_base_delay_ms' => env('SALESFORCE_AUTH_RETRY_BASE_DELAY_MS', 250),
'lock_wait_seconds' => env('SALESFORCE_AUTH_LOCK_WAIT_SECONDS', 8),
'lock_ttl_seconds' => env('SALESFORCE_AUTH_LOCK_TTL_SECONDS', 10),
],
| Key | Default | Description |
|---|---|---|
authentication.retry_attempts |
3 |
Total OAuth attempts (incl. first). Only retries on transient errors. |
authentication.retry_base_delay_ms |
250 |
Base delay between retries (ms). Backoff is exponential + jitter. |
authentication.lock_wait_seconds |
8 |
How long a worker waits to acquire the single-flight auth lock. |
authentication.lock_ttl_seconds |
10 |
Max time the auth lock is held. |
See docs/configuration.md → Authentication Resilience and docs/troubleshooting.md for details.
The public API of AuthenticationManager is unchanged. On cache miss, Forrest::hasToken() is now called twice (outer fast-path + double-check inside the lock). The hot path (token already cached) is unchanged. Tests that mocked hasToken() with ->once() on the cache-miss path need to be updated to ->twice().
forceReauthenticate semantics.Full Changelog: https://github.com/daikazu/eloquent-salesforce-objects/compare/v1.0.3...v1.1.0
describe(), picklistValues(), and related metadata calls on models whose object name matches a registered global alias (e.g. Event, Task, User, Note, Case) were throwing "Class must extend SalesforceModel". resolveObjectName() now only treats a string as a class when it contains a namespace separator, so bare SF object names are passed through to the API as intended.Full Changelog: https://github.com/daikazu/eloquent-salesforce-objects/compare/v1.0.2...v1.0.3
apexRest() no longer strips trailing slashes from paths. Salesforce treats /CreateOrder and /CreateOrder/ as different endpoints, so the path is now preserved as provided. Only a leading slash is added if missing.describe(), picklistValues(), and fieldMetadata() on HasSalesforceMetadata trait callable statically (e.g. Account::describe())getPicklistValues() method — correct method is picklistValues()Full Changelog: https://github.com/daikazu/eloquent-salesforce-objects/compare/v1.0.0...v1.0.1
The first stable release of Eloquent Salesforce Objects — a Laravel package that lets you work with Salesforce objects using familiar Eloquent syntax.
SalesforceModel base classhasMany, belongsTo, and hasOne with Salesforce PascalCase foreign key conventionswhere, whereIn, whereNull, whereBetween, orderBy, limit, offset, scopes, and moreSalesforceBatchcount(), sum(), avg(), min(), max(), exists()paginate() and simplePaginate() with Laravel's built-in paginatorcursor() and automatic nextRecordsUrl handlingwithTrashed() and onlyTrashed() via Salesforce's queryAll and IsDeleted flagapexRest() supporting all HTTP methodsphp artisan make:salesforce-model scaffolds models from live Salesforce metadata with relationships, casts, and default columns$defaultColumns on models; override with allColumns() or explicit select()TODAY, LAST_N_DAYS:30, etc.)php artisan salesforce:test verifies your Salesforce connectionHeavily inspired by roblesterjr04/EloquentSalesForce, rewritten from the ground up with modern PHP 8.4+, full type safety, and a cleaner architecture.
Initial release for testing.
How can I help you explore Laravel packages today?