Weave 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

Uberall Bundle Laravel Package

localfr/uberall-bundle

A Symfony bundle for integrating the Uberall location marketing platform into PHP applications. It provides configuration and service wrappers for managing business listings, locations, and related Uberall API data. Use it to connect your app to Uberall APIs for local SEO and directory management.

View on GitHub
Deep Wiki
Context7

Getting Started

The first hour of evaluation should confirm what this package actually is: a Symfony bundle, not a Laravel package. There is no composer require → php artisan path. Open the repo and read, in this order:

  1. composer.json — confirm the Symfony constraint (symfony/framework-bundle:^5.4|^6|^7) and whether there is a separate Uberall API client dependency (e.g. localfr/uberall-api or uberall/php-sdk). The bundle is almost certainly a thin DI/config wrapper; the client is where the value sits.
  2. DependencyInjection/UberallExtension.php and Resources/config/services.yaml — this is the real documentation. It enumerates the services the bundle registers, the config tree (account_id, private_key, base_uri, etc.), and how the client is constructed.
  3. The service classes themselves — check whether they are PSR-4 autoloaded and constructor-injected (ClientInterface) or ContainerAware. Framework-agnostic classes can be lifted into Laravel; ContainerAware ones cannot.

For a Laravel codebase: do not install the bundle. Use the repo as a reference implementation and build a single App\Services\Uberall\UberallClient over Laravel's Http facade. Bind it as a singleton in App\Providers\UberallServiceProvider, config under config/services.php → uberall key, credentials in .env (UBERALL_PRIVATE_KEY, UBERALL_ACCOUNT_ID).

For a Symfony codebase: composer require localfr/uberall-bundle, register the bundle in config/bundles.php, publish config to config/packages/uberall.yaml, inject the client. This is the only stack where the bundle scaffolding pays for itself.

First use case — always read-only. Call the list-locations endpoint and dump the response. This validates three things in one shot: credentials are wired correctly, base URI and API version are what you expect, and the wrapper shapes pagination the way Uberall's docs describe. Do this before writing a single line of sync logic.

Implementation Patterns

Wrap, don't leak. Define your own UberallClientInterface with typed methods (locations(): array, upsertLocation(LocationDto $dto): LocationDto, listings(string $locationId): array). Implement it over the bundle's extracted client, or Http::withToken(...)->baseUrl(...). Every call site depends on your interface, not the third-party class — this is what makes the eventual fork-and-replace cheap.

Config-cache friendly setup. Credentials go in .env; everything else (base URI, timeout, retry counts, queue name) goes in config/services.php. Never read env() outside a config file — php artisan config:cache will null it out in production.

Queue every write. Uberall propagates mutations to Google, Apple, Facebook, Yelp and friends. A bad payload is externally visible and slow to unwind. Everything that is not a GET goes behind a job:

final class SyncLocationToListings implements ShouldQueue
{
    public int $tries = 5;
    public array $backoff = [10, 30, 60, 180, 600];
    public function __construct(public readonly string $locationId) {}
}

Use a dedicated uberall queue with its own worker and concurrency cap so a bulk location import doesn't starve interactive traffic or trip 429s. Attach an idempotency key to each job payload and log per-location outcomes.

DTOs at the boundary. Hydrate responses into LocationDto, ListingDto, ReviewDto with explicit field mapping. Log unknown keys at debug level so upstream schema drift shows up in logs before it shows up as a null-pointer.

Read-then-write sequencing. Ship in this order: locations → listings → insights → reviews → writes. Validate data parity against whatever process you're replacing before enabling any POST/PUT. Shadow-run reads against production data for a few days.

Testing. If you extracted the client behind your interface, bind a fake in the container and assert job dispatch. If you wrote it over Http, use Http::fake(['api.uberall.com/*' => Http::response($fixture)]). Never let the real API into the test suite.

Pagination helper. A small paginate(callable $fetch) over Uberall's page/offset semantics saves repeating the loop in every resource method.

Gotchas and Tips

  • The bundle will not autoload in Laravel. There is no bundle loader, no Kernel, no DependencyInjection\Extension execution. Any tutorial assuming Symfony boot will silently fail. Confirm this before estimating effort — it's a one-line finding that changes the whole plan.
  • Composer constraint collisions are the first real blocker. Laravel 11/12 ride Symfony 7.x components; if the bundle pins symfony/framework-bundle:^5.4|^6, you cannot install it alongside Laravel without dragging in framework-bundle and creating an upgrade tax. Check composer why-not before you argue about code quality.
  • ContainerAware services don't port. If the bundle's service classes resolve collaborators from the container or use ContainerAwareInterface, extraction to Laravel means rewriting them anyway. Only constructor-injected, framework-free classes are worth copying.
  • Credentials are per-account, not per-location. Confirm the auth model — public key + private key, scoped to an account, with location operations hanging off the account. Storing one key set per location is a common misread of the Uberall docs.
  • 401/403 needs an alert, not a retry loop. Uberall key rotations and expiries will surface as auth failures on every call. Alert on the first 401 in a 5-minute window; do not let a job retry until dead-letter before anyone notices.
  • 429 with exponential backoff and jitter. Cap retries (5 is a reasonable default), dead-letter on exhaustion, and expose the DLQ depth in your monitoring. Burst behaviour is undocumented — assume per-account limits and design for them.
  • Partial-sync is the default failure mode. A bulk sync where 200 of 500 locations succeed is normal, not an exception. Track per-location status rows with attempted_at, last_error, succeeded_at so you can replay failures without re-running the batch.
  • Writes need a read-back reconciliation job. Uberall accepting a write is not the same as Google accepting it. Schedule a periodic verifyListings() job that re-reads directory status and alerts on drift.
  • The package will not warn you about Uberall API version changes. You own deprecation tracking. Pin the API version in your base URI and read Uberall's changelog manually on a schedule.
  • Treat it as a fork from day one. One star, zero dependents, single maintainer, no security disclosure path. If you do adopt it in Symfony, vendor it under internals/ in composer.json (VCS or path repo) so patching is a normal PR, not a composer.json hack that your next developer inherits as archaeology.
  • Don't make it load-bearing on a revenue path. For an internal tool with a runbook owner, fine. For a customer-facing sync with an SLA, write the ~200-line Laravel-native client against Uberall's REST docs instead — you'll spend two days on it versus roughly one engineer-week adapting, forking, and instrumenting the bundle.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core