Define data container configuration with classes/services instead of plain PHP files.
- Real Dependency Injection
- Don't deal with DCA files and wild names because of the prefixes like
tl_vendor_bundle_tablename
. Just define your table names one time and forget about it later. See advanced usage below. - Define private callbacks and logic methods in class scope like in Contao 2 or 3.
- Define whatever you need, it's your class.
- It's still possible to override definitions with dca files.
composer require tastaturberuf/contao-datacontainer-bundle
Define a class and implement DataContainerInterface
.
<?php
declare(strict_types=1);
namespace App;
use Contao\DC_Table;
use Tastaturberuf\ContaoDataContainerBundle\DataContainerInterface;
class DataContainer implements DataContainerInterface
{
// return the table name
public function getTable(): string
{
return 'tl_data_container';
}
// return the DCA config
public function getConfig(): array
{
return [
'config' => [
'container' => DC_Table::class
]
// ...
];
}
}
<?php
declare(strict_types=1);
namespace App;
use Ausi\SlugGenerator\SlugGenerator;
use Contao\CoreBundle\DependencyInjection\Attribute\AsCallback;
use Contao\CoreBundle\Intl\Countries;
use Contao\DC_Table;
use Contao\Model;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Tastaturberuf\ContaoDataContainerBundle\DataContainerInterface;
// App/Contao/Model/DataContainerModel.php
class DataContainerModel extends Model
{
// Every time you need the table name use this public constant!
public const TABLE = 'tl_data_container';
protected static $strTable = self::TABLE;
//...
}
// App/Contao/DataContainer/MyDataContainer.php
class MyDataContainer implements DataContainerInterface
{
/**
* Now you can use real dependency injection in DCC
*/
public function __construct(
private readonly SlugGenerator $slugGenerator,
private readonly Countries $countries,
#[Autowire(param: 'contao.image.valid_extensions')] // since Contao 5 / Symfony 6
privare readonly string $validImages
) {}
public function getTable(): string
{
// DRY: Use the model constant here
return DataContainerModel::TABLE;
}
/**
* Return the same array you would do in `dca/tl_i_hate_remember_prefixes_table.php`
*/
public function getConfig(): array
{
return [
'config' => [
'container' => DC_Table::class
]
// ...
'fields' => [
'alias' => [
'inputType' => 'text',
'save_callback' => $this->saveCallback(...)
//...
],
'country' => [
'inputType' => 'select'
//...
]
]
];
}
/**
* You can define private callbacks
*/
private function saveCallback(string $value): string
{
return $this->slugGenerator->generate($value);
}
/**
* You can define public callbacks (and may use the TABLE constant from the model)
*/
#[AsCallback(DataContainerModel::TABLE, 'fields.country.options')]
public function publicCallback(): array
{
return $this->countries->getCountries();
}
}
Tastaturberuf with ♥ and Contao