tourze/campaign-bundle
Tourze Campaign Bundle is a Symfony bundle for campaign management, providing reusable campaign entities, services, and admin integration to organize, track, and manage marketing or promotional campaigns in PHP applications with minimal configuration.
tourze/campaign-bundle shipped 0.0.1, an initial release whose only published note is a link to the commit list — there is no changelog, no upgrade guide, and no documented public API. Treat everything below as "verify in vendor/tourze/campaign-bundle before relying on it."
Minimal steps:
composer require tourze/campaign-bundle:0.0.1 — pin the exact version. A 0.0.x line can change shape in any patch.composer.json (PHP/Symfony constraint ranges), src/ for the *Bundle class, then any DependencyInjection/, Entity/, Repository/, and Resources/config/ directories.-bundle suffix and the tourze namespace point to a Symfony bundle, not a Laravel package. Search for Illuminate\ or ServiceProvider in src/; if you find none, Laravel will not auto-discover it and you own the wiring.CampaignServiceProvider in your app (or a thin adapter package) that binds the bundle's interfaces into the container. Do not edit vendor/.If step 2 turns up no Laravel-facing code and no Doctrine ORM dependency your app already uses, stop and evaluate the cost of the adapter before building on it.
Adapter over inheritance. Keep the bundle at arm's length behind your own interfaces. Define App\Contracts\CampaignRepository and implement it with a class that delegates to the bundle's service. When 0.0.2 renames something, you change one file.
Service provider as the seam. Bind all package contracts in one provider so the rest of the app never references a Tourze\ class directly:
public function register(): void
{
$this->app->singleton(CampaignRepository::class, PackageCampaignRepository::class);
$this->app->bind(SegmentResolver::class, fn ($app) =>
new PackageSegmentResolver($app->make('tourze.campaign.resolver'))
);
}
Two-worlds mapping. If the bundle brings Doctrine entities and your app is Eloquent, convert at the boundary: read the package object, hydrate your own model/DTO, and never let a Doctrine entity reach a Blade view, JSON resource, or queued job payload (serialising Doctrine proxies into a queue is a reliable way to produce unreadable failures).
Queue-friendly sends. Campaign dispatch is the obvious long-running path. Wrap the package's send/evaluate call in a job with $tries, $backoff, and an idempotency key derived from campaign ID + recipient ID, so a retry cannot double-send.
Config and migrations. If Resources/config/ or a Doctrine migration path exists, publish and own those files rather than reading them from vendor/ at runtime — you will need to edit table names and indexes for your schema.
Testability. Bind a fake implementation of your contract in tests/TestCase. For a smoke test of the package itself, orchestra/testbench plus a manual provider registration gives you a container without touching your real app.
Version discipline. Commit composer.lock. Before any upgrade, run composer update tourze/campaign-bundle --dry-run --with-dependencies and diff the src/ tree; that diff is the changelog, because 0.0.1 does not provide one.
extra.laravel.providers in the package composer.json, facades, config merging, and vendor:publish tags are all absent. Budget for a provider and a config file of your own.symfony/* packages to arrive as transitive dependencies. Check for version-range conflicts with your existing Symfony components (common via laravel/framework internals) using composer why-not tourze/campaign-bundle 0.0.1.0.0.x means no semver promise. Composer's ^0.0.1 constraint is effectively >=0.0.1 <0.0.2, so you are pinned anyway — but do not loosen it to ^0.0 and assume API stability. Read every release's source diff.src/ are your specification. Write your own notes the first time you trace a behaviour; you will be the only source of truth for your team.$fillable-style expectations, missing timestamps, and identity-map surprises (the same row returned as two different objects). Keep conversions explicit.php artisan tinker → inspect bound instances, or app()->getLoadedProviders()) instead of assuming CampaignService::class resolves.Log::debug() calls at your adapter boundary — not inside vendor/ — so the traces survive composer install.How can I help you explore Laravel packages today?