Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Eloquent Salesforce Objects Laravel Package

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.

View on GitHub
Deep Wiki
Context7
v1.1.0

Authentication Resilience

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.

What changed

  • Single-flight cache lock around Forrest::authenticate() with a double-check inside the lock. Concurrent callers reuse the freshly-cached token instead of issuing parallel OAuth POSTs.
  • Selective retry with exponential backoff + jitter on transient errors only:
    • Salesforce's documented 400 unknown_error / retry your request envelope
    • HTTP 5xx
    • Guzzle ConnectException
  • Fails fast on invalid_grant, credential failures, and other 4xx — retrying those just makes things worse.
  • Lock key scoped per connected app via sha1(consumer_key) so multi-org setups don't collide.

⚠️ Action required if you publish your config

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

New config keys

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.

Behavior note (non-breaking)

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().

Performance

  • Hot path (token cached): no measurable change.
  • Cache miss, single worker: +1–2ms for lock acquire.
  • Cache miss, high concurrency: large improvement — collapses N parallel OAuth POSTs into 1.
  • Transient failure with retry: up to ~1.5s of retry sleep traded for a successful request instead of a hard failure.

Test coverage

  • 18 new assertions covering lock double-check, transient retry, permanent fail-fast, retry exhaustion, and forceReauthenticate semantics.

Full Changelog: https://github.com/daikazu/eloquent-salesforce-objects/compare/v1.0.3...v1.1.0

v1.0.3

Fixed

  • Unqualified Salesforce object names no longer collide with Laravel facade aliasesdescribe(), 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

v1.0.2

Fixed

  • Apex REST trailing slash handlingapexRest() 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.
v1.0.1

Fixed

  • Made describe(), picklistValues(), and fieldMetadata() on HasSalesforceMetadata trait callable statically (e.g. Account::describe())
  • Fixed docs referencing non-existent getPicklistValues() method — correct method is picklistValues()

Full Changelog: https://github.com/daikazu/eloquent-salesforce-objects/compare/v1.0.0...v1.0.1

v1.0.0

v1.0.0 — Initial Stable Release

The first stable release of Eloquent Salesforce Objects — a Laravel package that lets you work with Salesforce objects using familiar Eloquent syntax.

Features

  • Eloquent-Style Models — Define Salesforce objects as Laravel models with SalesforceModel base class
  • Full CRUD — Create, read, update, and delete Salesforce records with automatic field filtering (updateable/createable)
  • RelationshipshasMany, belongsTo, and hasOne with Salesforce PascalCase foreign key conventions
  • SOQL Query Builder — Chainable query builder supporting where, whereIn, whereNull, whereBetween, orderBy, limit, offset, scopes, and more
  • Batch Queries — Execute multiple SOQL queries in a single API call via SalesforceBatch
  • Bulk Operations — Efficient bulk insert, update, and delete with automatic chunking (200 record limit)
  • Aggregate Functionscount(), sum(), avg(), min(), max(), exists()
  • Paginationpaginate() and simplePaginate() with Laravel's built-in paginator
  • Cursor Pagination — Memory-efficient streaming with cursor() and automatic nextRecordsUrl handling
  • Soft DeleteswithTrashed() and onlyTrashed() via Salesforce's queryAll and IsDeleted flag
  • Apex REST — Call custom Apex REST endpoints with apexRest() supporting all HTTP methods
  • Model Generatorphp artisan make:salesforce-model scaffolds models from live Salesforce metadata with relationships, casts, and default columns
  • Default Columns — Optimize queries by defining $defaultColumns on models; override with allColumns() or explicit select()
  • Metadata Caching — Salesforce describe results cached with configurable TTL
  • Picklist Values — Retrieve active picklist values for any field
  • SOQL Date Literals — Full support for Salesforce date literals (TODAY, LAST_N_DAYS:30, etc.)
  • Connection Testphp artisan salesforce:test verifies your Salesforce connection

Requirements

Test Coverage

  • 471 tests, 1184 assertions
  • 82% code coverage
  • Zero PHPStan errors at level 5

Credits

Heavily inspired by roblesterjr04/EloquentSalesForce, rewritten from the ground up with modern PHP 8.4+, full type safety, and a cleaner architecture.

v1.0.0-beta.1
v1.0.0-beta

Initial release for testing.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle