Installation Add the bundle via Composer:
composer require clamidity/base-bundle
Enable it in config/bundles.php (Symfony):
return [
// ...
Clamidity\BaseBundle\ClamidityBaseBundle::class => ['all' => true],
];
First Use Case
The bundle provides a BaseController trait for common CRUD operations. Extend it in your controller:
use Clamidity\BaseBundle\Controller\BaseController;
class ProductController extends AbstractController
{
use BaseController;
protected $entityClass = Product::class;
}
GET /products)GET /products/{id})GET/POST /products/new)GET/POST /products/{id}/edit)DELETE /products/{id})Where to Look First
src/Resources/doc/ for usage examples.BaseController and BaseEntity traits in src/Controller/ and src/Entity/.templates/base/ (default location: src/Resources/views/).Entity Management
getId(), getCreatedAt(), etc.
use Clamidity\BaseBundle\Entity\BaseEntity;
class Product extends BaseEntity
{
// Your fields...
}
prePersist(), preUpdate(), etc., via the trait.Controller Integration
BaseController (e.g., createAction(), updateAction()).
protected function createAction(Request $request)
{
$this->validateRequest($request); // Custom logic
return parent::createAction($request);
}
$this->createForm() and $this->getFormHandler() for DRY form logic.Routing
# config/routes.yaml
product:
resource: 'product'
type: 'clamidity_base'
prefix: '/products'
Twig Integration
src/Resources/views/base/ to templates/base/.base_path() or entity_url().Services
Clamidity\BaseBundle\Service\BaseService for reusable logic:
class ProductService extends BaseService
{
public function getActiveProducts()
{
return $this->repository->findBy(['active' => true]);
}
}
BaseEntity extends AbstractEntity (from the bundle).postCreate, preDelete) via the EventDispatcher in your controllers/services.BaseController and override methods to return JSON responses:
public function indexAction()
{
$data = parent::indexAction();
return $this->json($data);
}
Namespace Conflicts
Clamidity\BaseBundle namespace. Avoid naming your classes/traits similarly to prevent collisions.App\Controller\ProductController).Template Overrides
src/Resources/views/base/ to templates/base/ will use the bundle’s defaults, which may not match your design.{{ dump(app.request.uri) }} in Twig to debug template paths.Entity Inheritance
BaseEntity extends the bundle’s trait but also Doctrine’s AbstractEntity, ensure the trait is loaded after Doctrine’s base class to avoid conflicts.autoload-dev or composer dump-autoload after changes.Route Conflicts
_prefix in YAML:
product:
resource: 'product'
type: 'clamidity_base'
_prefix: '/admin/products'
Form Handling Quirks
id, createdAt). Customize via setFormOptions() in your controller:
protected function getFormOptions()
{
return [
'csrf_protection' => false, // Disable if using API
'allow_extra_fields' => true,
];
}
Enable Debug Mode
Set APP_DEBUG=true in .env to see detailed errors and template inheritance chains.
Log Events Dispatch custom events to track workflows:
$this->eventDispatcher->dispatch(new BaseEvent('preCreate', $entity));
Check Route Debug
Use Symfony’s route debugger (/debug/router) to verify auto-generated routes.
Custom Traits
Extend BaseController or BaseEntity to add domain-specific logic:
trait SoftDeletesTrait
{
public function delete()
{
$this->deletedAt = new \DateTime();
$this->save();
}
}
Event Subscribers
Listen to bundle events (e.g., base.entity.pre_persist) in your services.yaml:
services:
App\EventListener\ProductListener:
tags:
- { name: kernel.event_subscriber }
Override Services
Replace the bundle’s services (e.g., base.repository) in config/services.yaml:
Clamidity\BaseBundle\Repository\BaseRepository: '@app.custom_repository'
Add Fields Dynamically
Use the BaseEntity trait’s getDynamicFields() to include computed properties in forms:
public function getDynamicFields()
{
return ['fullName' => $this->getFirstName() . ' ' . $this->getLastName()];
}
BaseRepository::findWith() to preload associations:
$products = $this->repository->findWith(['category', 'images'], $criteria);
$cache = $this->container->get('cache.app');
$data = $cache->get('products_list', function() {
return $this->repository->findAll();
});
How can I help you explore Laravel packages today?