districtweb/cmsconfiguratorbundle
Symfony bundle for building and managing application configuration via a “configurator” approach. Provides structure to define, load, and persist configurable settings for your CMS or app, with tooling aimed at simplifying configuration workflows.
Installation Require the package via Composer:
composer require districtweb/cmsconfiguratorbundle
Register the bundle in config/app.php under the providers array:
DistrictWeb\CmsConfiguratorBundle\DistrictWebCmsConfiguratorBundle::class,
First Use Case: Dynamic CMS Configuration
Create a configuration entity (e.g., PageLayout) and annotate it with the bundle’s traits:
namespace App\Entities;
use DistrictWeb\CmsConfiguratorBundle\Entity\ConfigurableTrait;
use DistrictWeb\CmsConfiguratorBundle\Entity\ConfigurableInterface;
class PageLayout implements ConfigurableInterface
{
use ConfigurableTrait;
protected $name;
protected $template;
protected $isActive;
}
Database Setup Publish and run migrations:
php artisan vendor:publish --provider="DistrictWeb\CmsConfiguratorBundle\DistrictWebCmsConfiguratorBundle" --tag="migrations"
php artisan migrate
Access Configuration in Code Retrieve configurations via the bundle’s service container:
$pageLayout = $this->container->get('district_web.cms_configurator')->getConfig('page_layout');
Configuration Definition
Define configurations as PHP classes implementing ConfigurableInterface:
class FeatureToggle implements ConfigurableInterface
{
use ConfigurableTrait;
protected $featureName;
protected $isEnabled;
protected $environment;
}
Configuration Management Use the bundle’s CLI commands for CRUD operations:
# Create a new configuration entry
php artisan district_web:config:create FeatureToggle
# Update an existing configuration
php artisan district_web:config:update FeatureToggle --feature-name="new_feature" --is-enabled=true
# List all configurations
php artisan district_web:config:list
Integration with Laravel Services Bind configurations to Laravel’s service container for dependency injection:
$this->app->bind('config.feature_toggle', function ($app) {
return $app->make('district_web.cms_configurator')->getConfig('feature_toggle');
});
Dynamic Configuration Loading Load configurations dynamically in routes, controllers, or middleware:
public function showPage(Request $request)
{
$layout = $this->container->get('district_web.cms_configurator')->getConfig('page_layout');
return view('pages.index', ['layout' => $layout]);
}
Configuration Validation
Implement custom validation logic in the validate() method of your configuration class:
public function validate()
{
if ($this->isActive && empty($this->template)) {
throw new \InvalidArgumentException("Active layouts must have a template.");
}
}
Configuration Events Subscribe to configuration change events for real-time updates:
$this->events->listen('district_web.config.updated', function ($config) {
// Trigger cache invalidation or other side effects
Cache::forget('config.' . $config->getName());
});
Multi-Tenant Configurations Scope configurations by tenant using middleware or service providers:
public function boot()
{
$this->app->resolving('district_web.cms_configurator', function ($configurator, $app) {
$tenant = $app['tenant'];
$configurator->setTenant($tenant);
});
}
Namespace Conflicts The bundle uses Symfony’s dependency injection, which may conflict with Laravel’s container. Ensure proper binding:
$this->app->bind('district_web.cms_configurator', function ($app) {
return new \DistrictWeb\CmsConfiguratorBundle\Service\Configurator(
$app['config'],
$app['db']
);
});
Migration Issues The bundle’s migrations assume a specific database schema. Customize them by publishing and modifying:
php artisan vendor:publish --provider="DistrictWeb\CmsConfiguratorBundle\DistrictWebCmsConfiguratorBundle" --tag="migrations"
Caching Quirks Configurations loaded via the bundle are not automatically cached by Laravel. Implement manual caching:
$config = Cache::remember("config.{$configName}", 60, function () use ($configName) {
return $this->container->get('district_web.cms_configurator')->getConfig($configName);
});
Symfony Dependency Overhead
The bundle pulls in Symfony components (e.g., Yaml, Config). If this causes bloat, consider forking and replacing Symfony-specific logic with Laravel equivalents.
Enable Debug Mode
Set APP_DEBUG=true in .env to get detailed error messages for configuration loading issues.
Log Configuration Changes Add logging to track configuration updates:
$this->events->listen('district_web.config.updated', function ($config) {
\Log::info("Configuration updated: {$config->getName()}", ['data' => $config->toArray()]);
});
Check for Deprecated Methods The bundle may use Symfony’s deprecated APIs. Update them in a fork if needed:
// Example: Replace deprecated YamlFileLoader
$loader = new \Symfony\Component\Config\Loader\LoaderResolver();
Custom Configuration Storage
Override the default storage backend by implementing ConfigStorageInterface:
class CustomConfigStorage implements ConfigStorageInterface
{
public function save(ConfigurableInterface $config)
{
// Custom logic (e.g., Redis, S3)
}
public function find($name)
{
// Custom logic
}
}
Add Configuration Types Extend the bundle’s configuration system by creating new traits or interfaces:
trait MultiTenantConfigurableTrait
{
public function setTenant($tenant)
{
$this->tenant = $tenant;
}
}
Integrate with Laravel’s Config System
Sync bundle configurations with Laravel’s config/ directory:
$this->app->booting(function () {
$configurator = $this->app->make('district_web.cms_configurator');
$configs = $configurator->getAllConfigs();
foreach ($configs as $config) {
config([$config->getName() => $config->toArray()]);
}
});
Avoid Over-Fetching Load only the configurations you need:
$configurator->getConfig('specific_config_name'); // Instead of getAllConfigs()
Batch Database Operations For bulk updates, use transactions:
DB::transaction(function () use ($configurator, $configs) {
foreach ($configs as $config) {
$configurator->updateConfig($config);
}
});
Lazy-Load Configurations Defer loading configurations until they’re needed:
$configurator->lazyLoad('expensive_config');
How can I help you explore Laravel packages today?