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

Sulu Picture Placeholder Generator Bundle Laravel Package

olivier127/sulu-picture-placeholder-generator-bundle

A Sulu bundle for generating placeholder pictures when media is missing or not yet available. It helps editors keep pages visually complete during development, content entry, and testing by providing simple placeholder image generation for Sulu’s picture handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Start with the service provider, not the README. Open src/*ServiceProvider.php first to see what is registered (mergeConfigFrom, publishes, singletons, commands, migrations) — that tells you the intended integration surface faster than prose docs.

Minimal bootstrap:

composer require vendor/package
php artisan vendor:publish --provider="Vendor\Package\PackageServiceProvider"

Then check three things before writing any code:

  1. Config file — published to config/package.php. Read every key; the defaults encode opinionated behavior you will likely need to override per environment.
  2. Environment variables — scan config/package.php for env() calls and add them to .env and .env.example. Missing keys are the single most common source of "works locally, breaks in CI".
  3. Migration/queue requirements — if the provider registers migrations or queue jobs, run php artisan migrate and confirm your queue connection is set before your first real call.

First use case: pick the package's single simplest entry point (usually a facade call or an injected interface) and exercise it in php artisan tinker before wiring it into a controller. This isolates configuration problems from application problems.

php artisan tinker
>>> app(Vendor\Package\Contracts\Client::class)->ping();

If that works, you know the provider, config, and credentials are all resolved correctly and any subsequent failure is in your code.

Implementation Patterns

Resolve through the container, not the facade, in domain code. Facades are fine in controllers and Blade, but anything you want to unit test should take the contract or concrete class as a constructor dependency. Bind defaults in a small app-level service provider if you need environment-specific implementations.

Wrap it in a thin adapter. Even a one-method wrapper buys you: a stable seam for tests, a place to normalize exceptions into your app's exception hierarchy, and a straightforward migration path if you swap packages later.

final class InvoiceGateway
{
    public function __construct(private readonly VendorClient $client) {}

    public function create(array $payload): Invoice
    {
        try {
            return Invoice::fromResponse($this->client->invoices()->create($payload));
        } catch (VendorException $e) {
            throw new GatewayException($e->getMessage(), previous: $e);
        }
    }
}

Prefer the package's testing fakes over HTTP mocking. Most mature Laravel packages ship Package::fake() or an equivalent. Fakes assert intent (Package::assertSent(...)); HTTP fakes assert wire format. The former survives library upgrades, the latter does not.

protected function setUp(): void
{
    parent::setUp();
    Package::fake();
}

Keep long-running calls out of the request cycle. If the package makes network calls, wrap them in a job with retries and a timeout. Use the package's own retry semantics if it exposes them — do not stack $tries on the job and the client, or you get multiplicative retries that are hard to reason about during incidents.

final class SyncCustomer implements ShouldQueue
{
    public int $tries = 3;
    public int $backoff = [10, 60, 300];
}

Instrument the boundary once. Add a single middleware/job-middleware or a wrapper that logs request ID, duration, and outcome for every package call. When something breaks at 2am, you want one grep, not a tour through vendor code.

Register event listeners for package-emitted events rather than polling or re-querying. Check Event::listen discoveries in the provider — these are usually the cleanest integration point for side effects (notifications, cache busting, audit logs).

In tests, freeze time and seed determinism. Any package doing scheduling, TTLs, or signed payloads will flake without Carbon::setTestNow() and fixed IDs.

Gotchas and Tips

Config cache is not optional in production. php artisan config:cache will make env() calls inside vendor config return null if the config file was published before the env var existed. Always config:clear after touching .env in local and staging.

Watch for double-publishing. Running vendor:publish twice can overwrite local config modifications or duplicate migration files (causing "table already exists"). Prefer --tag= and check git status before committing the result.

Version-pin the config contract. If the package adds a config key in a patch release, your cached, fully-populated config file will mask it and the feature will silently no-op. Re-publish to a temp path and diff on upgrade:

php artisan vendor:publish --provider="..." --tag=config --force
git diff config/package.php

Debugging order of operations — work outward from the container:

  1. app(Vendor\Package\PackageServiceProvider::class) resolves? If not, the package isn't auto-discovered (check composer.json extra.laravel.providers, and that you're not on a cached bootstrap/cache/packages.php).
  2. config('package') non-empty? If not, the provider's register() didn't run or the config was never published.
  3. Client resolves from container? If not, a binding is missing — check provides() on the provider.
  4. Call fails? Now it's credentials/network/API — inspect the package's exception classes for the actual upstream message, which is often nested and swallowed by a generic wrapper.

Extension points to look for before forking: custom HTTP client injection (withClient/setClient), custom transports, Macroable traits, and bind/singleton overrides in register(). Any of these is preferable to editing vendor/.

Queue + serialization trap. Jobs that hold package objects may fail to serialize if the object wraps a Guzzle client or a closure. Store scalar IDs in the job payload and re-resolve the client in handle().

Timeouts compound. Laravel's HTTP client timeout, the package's own timeout, your queue worker's --timeout, and PHP's max_execution_time are four separate knobs. Set them in descending order, or workers get killed mid-call and jobs are retried without ever surfacing an error.

Test against the fake, but smoke-test against a sandbox. Fakes can drift from real behavior — particularly around pagination, rate limits, and error shapes. Keep one or two integration tests hitting a sandbox environment behind a separate test suite/group so they don't slow the main run.

Log the resolved config at boot in non-production. A single Log::debug('package config', config('package')) behind if (! app()->isProduction()) in a local service provider saves hours of guessing which values actually took effect.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect