- Published on
TYPO3 CLI/Symfony Command, Extbase Data Import & Validation
- Authors
- Name
- Susanne Moog
Recently I wanted to write an import script and instead of using the DataHandler, I used my existing Extbase repository and Extbase’s validation. Here’s a minimal example to get you started.
1) Register the Symfony Command
Configuration/Services.yaml
:
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Vendor\MyExt\Command\ImportCommand:
tags: ['console.command']
2) Implement the Command
Classes/Command/ImportCommand.php
:
<?php
declare(strict_types=1);
namespace Vendor\MyExt\Command;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use Vendor\MyExt\Domain\Repository\CustomerRepository;
use Vendor\MyExt\Domain\Model\Customer;
use TYPO3\CMS\Extbase\Validation\ValidatorResolver;
#[AsCommand(name: 'myext:import')]
final class ImportCommand extends Command
{
public function __construct(
private readonly CustomerRepository $customers,
private readonly ValidatorResolver $validatorResolver,
) {
parent::__construct();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$data = [
['name' => 'Ada Lovelace', 'email' => 'ada@example.org'],
// ...
];
foreach ($data as $row) {
$customer = new Customer();
$customer->setName($row['name']);
$customer->setEmail($row['email']);
$validator = $this->validatorResolver->getBaseValidatorConjunction(Customer::class);
$result = $validator->validate($customer);
if ($result->hasErrors()) {
$output->writeln('<error>Invalid row: ' . (string)$result . '</error>');
continue;
}
$this->customers->add($customer);
}
$this->customers->persistAll();
$output->writeln('<info>Import done.</info>');
return self::SUCCESS;
}
}
3) Domain model & validation
Classes/Domain/Model/Customer.php
(simplified):
<?php
namespace Vendor\MyExt\Domain\Model;
use TYPO3\CMS\Extbase\Annotation as Extbase;
final class Customer extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
{
#[Extbase\Validate(['validator' => 'NotEmpty'])]
protected string $name = '';
#[Extbase\Validate(['validator' => 'EmailAddress'])]
protected string $email = '';
public function setName(string $name): void { $this->name = $name; }
public function setEmail(string $email): void { $this->email = $email; }
}
4) Run it
vendor/bin/typo3 myext:import
Notes
- Use repositories for persistence; call
persistAll()
after batching - Favor attribute-based validators in TYPO3 v12+
- Add DTOs and mappers for complex imports
This approach leverages Extbase validation and repositories directly in a Symfony Console command, keeping your import logic testable and clean.