danilovl/entity-data-list-console-bundle
Symfony bundle adding a console command to list Doctrine ORM entity records in a formatted table. Configure which fields and associations to display, with automatic date formatting and pagination via --limit and --offset. Works by passing the entity class name.
Installation:
composer require danilovl/entity-data-list-console-bundle
Register the bundle in config/bundles.php:
Danilovl\EntityDataListConsoleBundle\EntityDataListConsoleBundle::class => ['all' => true]
First Use Case:
Run the default command to inspect an entity (e.g., App\Entity\User):
php bin/console danilovl:entity-data-list:orm App\Entity\User
This displays a tabular output of the first 10 records with default fields.
danilovl:entity-data-list:orm for core functionality.EntityDataListCommand abstract class for extending behavior.OrmTranslatableEntityDataListCommand for translatable entities (e.g., Gedmo\Translatable).Basic Entity Inspection:
php bin/console danilovl:entity-data-list:orm App\Entity\Order --limit=50
Order entities with default fields.Field Customization:
Extend EntityDataListCommand to define specific fields:
protected function getFields(ClassMetadata $metadata): array {
return ['id', 'orderNumber', 'customer.email', 'totalAmount'];
}
customer.email).Association Handling:
php bin/console danilovl:entity-data-list:orm App\Entity\Product --associations-ignore=reviews,images
php bin/console danilovl:entity-data-list:orm App\Entity\Product --associations-limit=2
Custom Commands: Create reusable commands for frequent queries:
#[AsCommand('app:orders-export')]
class OrdersExportCommand extends EntityDataListCommand {
protected function getEntityClass(): string { return Order::class; }
protected function getFields(ClassMetadata $metadata): array {
return ['id', 'createdAt', 'status', 'customer.name'];
}
}
console.command events to log command usage or validate inputs.Stof\DoctrineExtensionsBundle for advanced field types (e.g., Sluggable, Timestampable).renderRow() to customize table formatting (e.g., add colors, truncate long text):
protected function renderRow(array $row): string {
return sprintf("<fg=blue>%s</> | %s", $row['id'], substr($row['description'], 0, 30));
}
Performance:
--limit. Use --offset cautiously for deep pagination.protected function getLimit(): int { return 100; }
Circular References:
User → Orders → Products → Categories) may cause infinite loops.--associations-ignore=orders.products.categories
Locale Mismatches:
OrmTranslatableEntityDataListCommand defaults to en_US. Override getLocale() if your app uses a different default:
protected function getLocale(): string { return 'fr_FR'; }
Field Access Errors:
getFields() to explicitly list accessible fields or implement __get() in entities.Enable Verbose Output:
php bin/console danilovl:entity-data-list:orm App\Entity\User -v
Reveals SQL queries and entity hydration issues.
Check Metadata: Inspect Doctrine metadata for field names:
$metadata = $this->entityManager->getClassMetadata(User::class);
print_r($metadata->getFieldNames());
Test with Simple Entities:
Start with entities without complex associations (e.g., User) to isolate issues.
Custom Field Processors:
Override processRow() to transform data before rendering:
protected function processRow(object $entity, array $fields, ClassMetadata $metadata): array {
$row = parent::processRow($entity, $fields, $metadata);
$row['price'] = '$' . number_format($row['price'], 2);
return $row;
}
Dynamic Field Selection: Use runtime logic to select fields:
protected function getFields(ClassMetadata $metadata): array {
return array_filter($metadata->getFieldNames(), fn($field) => str_contains($field, 'date'));
}
Export Formats:
Extend the command to output CSV/JSON by overriding renderTable():
protected function renderTable(array $rows): string {
$csv = fopen('php://temp', 'r+');
foreach ($rows as $row) {
fputcsv($csv, $row);
}
rewind($csv);
return stream_get_contents($csv);
}
Bundle Registration:
Ensure the bundle is enabled in bundles.php after Doctrine bundles (e.g., Doctrine\Bundle\DoctrineBundle).
PHP 8.5+ Features: Leverage named arguments in custom commands:
#[AsCommand('app:user-list', description: 'List users with custom fields')]
Environment Variables:
Inject configuration via Symfony’s ParameterBagInterface:
public function __construct(private ParameterBagInterface $params) {}
protected function getLimit(): int { return (int)$this->params->get('user_list_limit', 50); }
How can I help you explore Laravel packages today?