space-monkeys/common-bundle
Space Monkeys Common Bundle collects reusable PHP components and shared conventions into one installable bundle, helping teams standardize common functionality and reduce duplication across applications. It provides a consistent foundation for shared services, helpers, and configuration.
Reality check before anything else. space-monkeys/common-bundle is a Symfony bundle (usually type: symfony-bundle) targeting Sulu CMS, not a Laravel package. It will not register via Laravel's package discovery, its YAML config tree is not a config/*.php file, and its services assume a Symfony container with compiler passes. There is no version of "install and use it day-to-day in a Laravel app." What you can actually do is mine it for portable utilities and re-express its conventions idiomatically — treat it as a reference implementation, not a dependency.
Minimal steps to get value:
# 1. Get the source somewhere you can read it (not inside your app's vendor/)
git clone https://github.com/space-monkeys/common-bundle /tmp/common-bundle
cd /tmp/common-bundle
# 2. Read the map, in this order
cat composer.json # type, PHP/Symfony/Sulu constraints, PSR-4 namespace
ls src/ src/DependencyInjection/ src/Resources/config/
cat src/*Bundle.php # DI extension? prepend config? compiler passes?
cat src/DependencyInjection/Configuration.php # the real API surface
Where to look first, in order:
composer.json — the type, require, and autoload (likely SpaceMonkeys\CommonBundle\). Constraints tell you instantly whether this targets Sulu 2.x / Symfony 5–6 / PHP 8.x or an older stack. If the constraints pin PHP < 8.1 or Symfony < 5.4, stop — the source likely predates modern Laravel and you are copying legacy patterns.prependExtension, or compiler passes. This is your table of contents.src/DependencyInjection/Configuration.php — the config tree is the documented behavior. Read it before the README, because the README is probably thin.src/Resources/config/services.xml (or .yaml) — enumerate every service it registers. This is your inventory. Classify each as pure utility / framework-coupled / Sulu-coupled.src/Twig/), Form types (src/Form/), and any EventListener/ or EventSubscriber/ directories — these are the pieces most likely to be genuinely reusable and most likely to hide Sulu dependencies.First use case to extract: pick the single most obviously pure class — a string formatter, a date helper, a value object, a validator — and port it into app/Support/ (or a small internal packages/ Composer package). Write a unit test against it before you copy, because the upstream bundle has no test signal to lean on. That one port tells you whether the effort scales to the rest, cheaply.
Pattern 1: Mine-and-port, not install-and-configure. The bundle's services assume a Symfony container. In Laravel you re-express them as plain classes with constructor injection, bound in a service provider:
// app/Providers/CommonBundleServiceProvider.php
public function register(): void
{
$this->mergeConfigFrom(__DIR__.'/../../config/common.php', 'common');
$this->app->singleton(ContentResolver::class, fn ($app) =>
new ContentResolver($app['config']->get('common.resolver'))
);
}
Port only the pure tier. Discard bundle registration, DI extension classes, services.xml, and anything touching Sulu's content model or admin UI — those are not portable and never will be.
Pattern 2: Translate Symfony config into Laravel config. Symfony YAML parameters and a config tree become config/common.php plus mergeConfigFrom and publishes:
// config/common.php
return [
'cache' => [
'store' => env('COMMON_CACHE_STORE', 'redis'),
'ttl' => env('COMMON_CACHE_TTL', 3600),
],
];
Do not port the Configuration.php tree node-for-node — a Symfony tree encodes validation and defaults for a container; Laravel config files just are the defaults. Keep only what you actually use, and make environment-driven values env() calls rather than YAML parameters.
Pattern 3: Twig extensions → Blade directives or helpers. A Symfony AbstractExtension with filters like |markdown becomes an app/Support/helpers.php function or a Blade::directive. Keep the underlying PHP logic and throw away the extension registration.
Pattern 4: Symfony Form types → FormRequests and validation rules. If the bundle ships form types (a very "common bundle" thing to do), the reusable part is the validation intent, not the AbstractType scaffolding. Lift the constraints into a FormRequest::rules() or a custom Rule object.
Pattern 5: Compiler passes and tags → contextual/tagged bindings. Symfony's tagged-service / compiler-pass idiom maps roughly to Laravel's $bindings, tagged(), or contextual binding. If the bundle uses tags to assemble a collection of handlers, replicate with a tagged() binding and an iterable resolution.
Pattern 6: Keep the fork as a read-only mirror. Vendor the repo outside your app, and if you expect upstream commits, keep a local mirror you can git diff against manually. Do not re-introduce it as a Composer dependency later — someone will, and it will drag the Symfony bundle plumbing back in.
Workflow that actually works:
composer.json (license, constraints) — one readbox, no engineering.services.xml and classify.composer require will likely succeed and leave you with nothing that runs. The package has no laravel section, no service provider, no discovery. A clean install is not evidence of integration — you will have added a dormant dependency and a transitive Symfony pin set.console, http-foundation, process, etc.), an abandoned bundle often pins an older Symfony range. Run composer require <pkg> --dry-run in a throwaway app before committing anything; if it conflicts, copy source rather than forcing resolution.Sulu\Component\* is unrecoverable in a Laravel context — discard, don't port.kernel.event_subscriber, it is doing work on every request in Symfony and has no analogue you can copy blindly into Laravel middleware — behavior and ordering both differ. Either reimplement deliberately as middleware or drop it.Configuration.php as a spec, not README.md.dev-main.composer require, register in config/bundles.php, import the extension config, and it may be a modest win. This assessment is for a Laravel target — confirm which one you're in before acting.How can I help you explore Laravel packages today?