sidus/base-bundle
Sidus BaseBundle for Symfony streamlines service loading and routing via action services, simplifies param converters, and adds helpful compiler passes and utilities. Includes DateTime/translation helpers, validator constraint loader, and form type extensions.
Installation:
composer require sidus/base-bundle
Add to config/bundles.php:
return [
// ...
Sidus\BaseBundle\SidusBaseBundle::class => ['all' => true],
];
First Use Case:
FooBarExtension extending SidusBaseExtension in DependencyInjection/:
namespace AppBundle\DependencyInjection;
use Sidus\BaseBundle\DependencyInjection\SidusBaseExtension;
class FooBarExtension extends SidusBaseExtension {}
Resources/config/services/*.yml (e.g., services/actions.yml):
AppBundle\Action\MyAction: ~
Resources/config/services.xml:
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<extensions>
<extension class="AppBundle\DependencyInjection\FooBarExtension"/>
</extensions>
</services>
</container>
Routing:
Define routes in Resources/config/routing.yml:
AppBundle_MyAction:
path: /my-action/{id}
defaults:
_service: AppBundle\Action\MyAction
_method: execute
Action-Based Controllers: Replace traditional controllers with service-based actions. Example:
// src/Action/MyAction.php
namespace AppBundle\Action;
class MyAction {
public function execute($id) {
return ['id' => $id];
}
}
Define in services.yml:
AppBundle\Action\MyAction:
arguments: ['@some.service']
tags: ['app.action']
Tagged Services:
Use GenericCompilerPass to inject tagged services (e.g., listeners, handlers):
# services.yml
AppBundle\Service\EventDispatcher:
tags: ['app.event_dispatcher']
Configure in config/packages/app.yaml:
sidus_base:
compiler_passes:
- { tag: 'app.event_dispatcher', target: 'AppBundle\Service\EventDispatcher' }
Param Converters:
Extend AbstractParamConverter for custom types:
namespace AppBundle\ParamConverter;
use Sidus\BaseBundle\ParamConverter\AbstractParamConverter;
class CustomConverter extends AbstractParamConverter {
public function supports(Parameter $parameter) { /* ... */ }
public function convert($value, Parameter $parameter) { /* ... */ }
}
Register in services.yml:
AppBundle\ParamConverter\CustomConverter:
tags: ['param_converter']
DateTimeUtility::parse for form type data transformers:
$date = DateTimeUtility::parse($rawInput, ['Y-m-d', 'd/m/Y']);
TranslatorUtility:
$translator = new TranslatorUtility($translator);
$message = $translator->trans([
'key1', 'key2', 'default'
], [], 'bundle');
$constraints = BaseLoader::loadConstraints([
'NotBlank',
'Length' => ['min' => 3]
]);
$validator->validate($data, $constraints);
Service Naming:
# Correct
AppBundle\Action\MyAction: ~ # Route: AppBundle_MyAction
# Incorrect (will fail silently)
app.my_action: ~ # Route: AppBundle_MyAction
bin/console debug:container to verify service IDs.Compiler Pass Timing:
GenericCompilerPass runs after services are loaded. Misconfigured passes may throw:
Service "foo.bar" has a dependency on another service "baz.qux" that does not exist.
priority in services.yml).Routing Overrides:
config/routes.yaml may break service-based routing. Prefer:
# config/routes.yaml
AppBundle_MyAction:
path: /custom-path/{id}
Deprecated Symfony 3:
AbstractParamConverter) may not work as expected in Symfony 4+. Test thoroughly.Service Dumping:
bin/console debug:container AppBundle\Action\MyAction
Check for missing arguments or circular references.
Compiler Pass Debugging:
bin/console debug:container --env=dev --dump=xml
var/cache/dev/.Routing Debugging:
bin/console debug:router
_service and _method are set correctly.Custom Compiler Passes:
Extend GenericCompilerPass for complex dependency injection:
namespace AppBundle\DependencyInjection\Compiler;
use Sidus\BaseBundle\DependencyInjection\Compiler\GenericCompilerPass;
class MyCustomPass extends GenericCompilerPass {
protected function getTag() { return 'app.my_tag'; }
protected function addServiceCall($service, $taggedServices) { /* ... */ }
}
Register in FooBarExtension:
public function load(array $configs, ContainerBuilder $container) {
$container->addCompilerPass(new MyCustomPass());
}
Param Converter Extensions:
Override supports() and convert() for custom types (e.g., UUIDs, nested objects).
Validator Extensions:
Extend BaseLoader to support custom constraint formats:
BaseLoader::addLoader('custom', function($config) {
return new CustomConstraint($config);
});
DateTimeUtility::parse defaults to DateTime::createFromFormat(). For timezone-aware parsing:
$date = DateTimeUtility::parse($input, ['Y-m-d'], new \DateTimeZone('UTC'));
TranslatorUtility uses the default domain unless specified:
$translator->trans(['key'], [], 'custom_domain');
BaseLoader ignores groups in constraints. Manually add:
$constraints = BaseLoader::loadConstraints([...]);
$constraints->groups = ['Default', 'CustomGroup'];
How can I help you explore Laravel packages today?