edinaldofox/crud-generator-bundle
Installation
composer require petkopara/crud-generator-bundle
Add to config/bundles.php:
return [
// ...
Petkopara\CrudGeneratorBundle\PetkoparaCrudGeneratorBundle::class => ['all' => true],
];
First Command
Generate a CRUD for an existing entity (e.g., App\Entity\Product):
php bin/console petkopara:crud:generate Product
This creates:
src/Controller/ProductCrudController.php)templates/ProductCrud/)config/routes.yaml)First Use Case
Access the generated CRUD at /product/crud (or your configured route). The bundle auto-generates:
Generating CRUDs
php bin/console petkopara:crud:generate EntityName [--format=yml|xml|php]
php bin/console petkopara:crud:generate EntityName --template-dir=custom/templates/
config/packages/petkopara_crud_generator.yaml to set global defaults (e.g., page_size, default_sort).Extending Generated Code
configureList(), configureFields(), or configureActions().
Example:
// src/Controller/ProductCrudController.php
class ProductCrudController extends AbstractCrudController
{
public function configureFields(string $action): iterable
{
return parent::configureFields($action)
->add('price', 'currency', ['currency' => 'USD']);
}
}
Customizing Fields
configureFields():
->add('name', 'text', ['attr' => ['placeholder' => 'Product name']])
->add('category', 'entity', ['class' => Category::class, 'multiple' => true])
->add('isActive', 'checkbox', ['required' => false])
Adding Custom Actions
configureActions():
public function configureActions(Actions $actions): Actions
{
return $actions
->add('publish', Button::create('Publish')->setIcon('fas fa-rocket'))
->add('publish', Callback::create()->setCallback([$this, 'publishAction']));
}
Handling Associations
->add('author', 'entity', ['class' => Author::class, 'property' => 'fullName'])
Pagination and Filtering
configurePagination() and configureFilters():
public function configurePagination(OptionsResolver $resolver): void
{
$resolver->setDefaults(['page_size' => 20]);
}
Bulk Operations
configureActions():
->add('bulk_delete', BulkAction::create('Delete selected')->setIcon('fas fa-trash'))
Symfony Flex Compatibility
AppKernel.php.Doctrine Integration
Twig Customization
templates/bundles/PetkoparaCrudGenerator/. The bundle follows Symfony’s template inheritance.API-First Approach
Serializer and ApiPlatform:
# config/routes.yaml
petkopara_crud:
resource: '.'
type: petkopara_crud
prefix: /api
Testing
CrudTestCase (if provided) or mock the controller:
$client = static::createClient();
$client->request('GET', '/product/crud');
$this->assertResponseIsSuccessful();
Entity Naming Conflicts
User, Role). Prefix with App or use underscores:
php bin/console petkopara:crud:generate App_User
Template Caching
php bin/console cache:clear
Association Loading
ManyToOne) may cause NULL values in the UI. Use fetch="EAGER" in Doctrine or customize the query in configureList():
public function configureList(QueryBuilder $qb): void
{
$qb->leftJoin('p.author', 'a');
}
CSRF Protection
_csrf_token is included in forms or disable CSRF for bulk endpoints (not recommended for production).Field Type Mismatches
JsonType) may not render correctly. Override configureFields() to specify types explicitly:
->add('metadata', 'text', ['attr' => ['class' => 'json-editor']])
Route Conflicts
--route-name to customize:
php bin/console petkopara:crud:generate Product --route-name=admin_product
Log Generated SQL
Enable Doctrine logging in config/packages/dev/doctrine.yaml:
doctrine:
dbal:
logging: true
profiling: true
Check Generated Code
Inspect the generated controller and templates in var/cache/dev/ for errors. Use:
php bin/console debug:container Petkopara\CrudGeneratorBundle
Override Configuration
Debug issues by overriding bundle config in config/packages/petkopara_crud_generator.yaml:
petkopara_crud_generator:
default:
page_size: 5
debug: true # Shows generated SQL and template paths
Template Debugging
Use Twig’s dump() in custom templates to inspect variables:
{% dump app.request.attributes %}
Custom Field Types Extend the bundle by creating a custom field type. Example:
// src/Form/Extension/CustomFieldExtension.php
use Petkopara\CrudGeneratorBundle\Form\Type\FieldTypeExtensionInterface;
class CustomFieldExtension implements FieldTypeExtensionInterface
{
public function getExtendedTypes(): array
{
return ['custom_type'];
}
public function getType(FieldDefinitionInterface $field): string
{
return 'text';
}
public function getOptions(FieldDefinitionInterface $field): array
{
return ['attr' => ['class' => 'custom-class']];
}
}
Register the service in config/services.yaml:
services:
App\Form\Extension\CustomFieldExtension:
tags:
- { name: petkopara_crud_generator.field_type_extension }
Event Listeners
Hook into CRUD events (e.g., prePersist, postDelete) via Symfony’s event dispatcher:
// src/EventListener/CrudListener.php
use Petkopara\CrudGeneratorBundle\Event\CrudEvent;
class CrudListener
{
public function onPrePersist(CrudEvent $event)
{
$data = $event->getData();
$data->setCreatedAt(new \DateTime());
}
}
Register the listener:
services:
App\EventListener\CrudListener:
tags:
- { name: kernel.event_listener, event: petkopara_crud.pre_persist, method: onPrePersist }
Custom Actions
Create reusable actions by extending AbstractAction:
// src/Action/CustomAction.php
How can I help you explore Laravel packages today?