goldenplanetdk/gpp-app-bundle
gpp-app-bundle is a PHP application bundle from Golden Planet that packages shared setup and integration code for GPP projects. It offers a reusable foundation for standardizing common app functionality, configuration, and service wiring across applications, reducing duplicated boilerplate.
Read this first: the package is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/*.php publish tag, and no facade. It cannot be composer required into a Laravel app and expected to boot. Treat it as something you either (a) run inside a Symfony application, or (b) integrate with from Laravel over HTTP/queue boundaries. Any assessment of "day-to-day leverage" has to start with that constraint.
Minimal steps inside a Symfony host:
composer require goldenplanetdk/gpp-app-bundle
# Symfony Flex may auto-register; if not, add to config/bundles.php:
# GoldenPlanet\GPPAppBundle\GPPAppBundle::class => ['all' => true]
php bin/console debug:container --parameter=kernel.bundles # confirm registration
php bin/console list gpp # see exposed commands
php bin/console debug:config gpp_app # dump resolved bundle config
Where to look first, in this order:
vendor/goldenplanetdk/gpp-app-bundle/README.md — likely thin; do not assume it is complete.src/DependencyInjection/GPPAppExtension.php and Configuration.php — this is the real API surface. The extension alias tells you the YAML root key (almost certainly gpp_app).src/DependencyInjection/CompilerPass*.php — compiler passes reveal tagged services and implicit extension points, which are documented nowhere else.src/Resources/config/services.*.yaml — every service ID you can inject or decorate.src/Command/ — the fastest way to understand what the bundle actually does operationally.A realistic first use case: instantiate the bundle in a fresh Symfony skeleton app, wire its config block with your database/messaging credentials, and run one of its console commands end-to-end against a scratch database. Because the repo has 0 stars and 0 dependents, do that smoke test in a throwaway project before it touches anything shared.
Inject by service ID, not by class name. Bundles of this vintage frequently register services with explicit IDs rather than autowired FQCNs. Verify with:
php bin/console debug:container --show-private | grep -i gpp
Then inject explicitly in config/services.yaml:
services:
App\Service\MyThing:
arguments:
$client: '@gpp_app.client' # confirm the real ID first
Configuration as the integration seam. Everything you'd normally do via a Laravel config file happens in config/packages/gpp_app.yaml plus env vars:
# config/packages/gpp_app.yaml
gpp_app:
# keys come from Configuration.php — read it, don't guess
api:
base_uri: '%env(GPP_API_BASE_URI)%'
cache:
pool: 'cache.app'
Keep secrets in .env.local and reference them only through %env()%. If the bundle reads $_ENV directly instead of going through the container, that's a smell worth noting.
Decorate rather than fork. When bundle behavior is almost right, use Symfony's decoration instead of copying classes into src/:
services:
App\Gpp\DecoratingClient:
decorates: gpp_app.client
arguments: ['@.inner']
This survives composer update. Copying a vendor class into your app does not.
Listen, don't patch. Check for dispatched events (GPPAppEvents, or string event names in src/Event/). Subscribing to a bundle event is the cheapest extension point and the least likely to break on upgrade.
Laravel-side integration. If the surrounding product is Laravel, keep the boundary explicit:
Http::baseUrl(config('services.gpp.url'))->withToken(...), or push jobs onto a shared broker (SQS/Redis) and let the Symfony worker consume them.Testing. Unit-test your decorations and listeners against the bundle's interfaces, not its concrete classes. For integration, boot a minimal Symfony kernel in a test case and assert on container compilation — lint:container in CI catches 90% of wiring mistakes before runtime.
Treat this as unvetted code. Zero stars, zero dependents, and a very recent last release mean there is no ecosystem feedback loop. Before adopting: pin an exact version in composer.json (not ^), read composer.json for its own dependency ranges, and grep for exec, eval, file_get_contents on URLs, and hard-coded credentials. Vendor it or fork it internally if it becomes load-bearing.
The config root key is the whole API. Guessing gpp_app when it's actually gpp produces a confusing "unrecognized option" error inside Configuration.php's tree builder, not a helpful message. Always derive it: debug:config <key> tells you instantly whether you guessed right.
Bundle auto-registration is not guaranteed. Older bundles lack a Flex recipe, so config/bundles.php edits are manual. A bundle that isn't registered silently ignores its config block — you get defaults and no error. Confirm registration before debugging anything else.
Service IDs are private by default in modern Symfony. debug:container without --show-private will hide exactly the services you're trying to inject. Learn this flag early; it saves an hour of "the service doesn't exist" confusion.
No documentation means the changelog is the documentation. Diff src/ between release tags before upgrading. With a package this small, an "internal refactor" release can rename service IDs or drop a config key with no deprecation path.
Beware the hard-coded global. Small internal bundles often reach for $_SERVER, getcwd(), or a static singleton for paths and credentials. Those break under test, under php-fpm with a different working directory, and in Messenger workers. If you find one, wrap it behind your own service rather than scattering the global through your codebase.
Extension points, ranked by durability: event subscribers > service decoration > tagged-service registration > compiler passes > forking. If your only option is forking, that's the signal the bundle is being pushed past its design — budget for owning that fork permanently.
Debugging sequence when something is silently wrong: lint:container → debug:config gpp_app → debug:container --show-private | grep gpp → check var/log/dev.log for the bundle's channel. Nine times out of ten it's a config key name or a private service ID, not a logic bug.
Laravel developers, specifically: don't try to bridge this with symfony/http-kernel adapters inside a Laravel app. You'll fight two container models, two config systems, and two event dispatchers for no benefit. The sidecar-service pattern is duller and dramatically cheaper to operate.
How can I help you explore Laravel packages today?