Installation
composer require edemy/customerbundle
Ensure eDemyFramework is installed and configured as a base dependency.
Bundle Registration
Add to config/bundles.php:
return [
// ...
Edemy\CustomerBundle\EdemyCustomerBundle::class => ['all' => true],
];
First Use Case Create a customer entity via CLI:
php bin/console make:customer --name="John Doe" --email="john@example.com"
Verify in the database (customers table) and via Tinker:
$customer = \Edemy\CustomerBundle\Entity\Customer::find(1);
Key Files to Review
src/Entity/Customer.php (Core model)src/Resources/config/doctrine/Customer.orm.yml (Schema)src/DependencyInjection/Configuration.php (Configurable options)Manual Entity Approach
use Edemy\CustomerBundle\Entity\Customer;
use Edemy\CustomerBundle\Factory\CustomerFactory;
$factory = new CustomerFactory();
$customer = $factory->createNamed('Jane Smith')
->setEmail('jane@example.com')
->setActive(true)
->save();
return $customer->getId();
Form Integration
// src/Form/CustomerType.php
use Edemy\CustomerBundle\Form\CustomerType;
class RegistrationForm extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('customer', CustomerType::class);
}
}
Repository Usage
$repository = $this->getDoctrine()
->getRepository(\Edemy\CustomerBundle\Entity\Customer::class);
$activeCustomers = $repository->findBy(['active' => true]);
$customer = $repository->findOneByEmail('test@example.com');
QueryBuilder Extensions
// Custom query in a service
public function getCustomersByRole($role) {
return $this->customerRepo->createQueryBuilder('c')
->where('c.role = :role')
->setParameter('role', $role)
->getQuery()
->getResult();
}
Subscribing to Events
// src/EventListener/CustomerListener.php
use Edemy\CustomerBundle\Event\CustomerEvents;
class CustomerListener {
public static function getSubscribedEvents() {
return [
CustomerEvents::PRE_SAVE => 'onPreSave',
CustomerEvents::POST_SAVE => 'onPostSave',
];
}
public function onPreSave(CustomerEvent $event) {
$customer = $event->getCustomer();
$customer->setUpdatedAt(new \DateTime());
}
}
Triggering Events Manually
$event = new CustomerEvent($customer, 'custom_action');
$this->dispatcher->dispatch(CustomerEvents::CUSTOM_ACTION, $event);
API Resource (API Platform Style)
# config/api/resources.yaml
resources:
Edemy\CustomerBundle\Entity\Customer:
collectionOperations:
get:
method: GET
path: /customers
itemOperations:
get:
method: GET
path: /customers/{id}
put:
method: PUT
Custom Serialization
// src/Serializer/CustomerNormalizer.php
use Edemy\CustomerBundle\Entity\Customer;
class CustomerNormalizer implements NormalizerInterface {
public function normalize($object, $format = null, array $context = []) {
return [
'id' => $object->getId(),
'name' => $object->getFullName(),
'email' => $object->getEmail(),
'active' => $object->isActive(),
];
}
}
Missing eDemy Framework Dependencies
eDemyFramework is installed. If missing, expect:
ClassNotFoundException for core services (e.g., Dispatcher).edemy/framework first or mock dependencies in tests.Doctrine Schema Conflicts
customers table. If your app already has a customers table:
Column 'id' already exists.Customer entity to avoid conflicts.Event Dispatcher Not Injected
EventDispatcherInterface:
Call to a member function dispatch() on null.public function __construct(private EventDispatcherInterface $dispatcher) {}
Factory Overrides Not Applied
// ❌ Won't save
$customer = $factory->createNamed('Test');
// ✅ Will save
$customer = $factory->createNamed('Test')->save();
Enable SQL Logging
Add to .env:
DOCTRINE_ORM_LOGGING=true
DOCTRINE_ORM_LOGGING_PARAMS=true
Check Event Dispatch Temporarily add a logger to events:
public function onPreSave(CustomerEvent $event) {
\Log::debug('Customer pre-save', ['customer' => $event->getCustomer()->toArray()]);
}
Validate Entity States
Use the isValid() method on the Customer entity to check constraints:
if (!$customer->isValid()) {
foreach ($customer->getErrors() as $error) {
\Log::error($error->getMessage());
}
}
Custom Fields
Extend the Customer entity:
// src/Entity/ExtendedCustomer.php
use Edemy\CustomerBundle\Entity\Customer;
class ExtendedCustomer extends Customer {
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customField;
// Getters/setters...
}
Override Factory Create a custom factory class:
// src/Factory/CustomCustomerFactory.php
use Edemy\CustomerBundle\Factory\CustomerFactory;
class CustomCustomerFactory extends CustomerFactory {
public function createWithDefaultRole($name) {
return $this->createNamed($name)->setRole('default');
}
}
Modify Serialization Override the normalizer:
# config/services.yaml
services:
App\Serializer\CustomerNormalizer:
tags: [serializer.normalizer]
arguments: ['@app.customer.normalizer.inner']
Add Custom Queries Extend the repository:
// src/Repository/CustomerRepository.php
use Edemy\CustomerBundle\Repository\CustomerRepository as BaseRepository;
class CustomerRepository extends BaseRepository {
public function findByRole($role) {
return $this->createQueryBuilder('c')
->where('c.role = :role')
->setParameter('role', $role)
->getQuery()
->getResult();
}
}
Default Values
The bundle sets active = false by default. Override in config/packages/edemy_customer.yaml:
edemy_customer:
default_active: true
Entity Manager If using multiple Doctrine connections, specify the target entity manager:
$customer = $this->getDoctrine()->getManager('custom_em')->find(Customer::class, 1);
Validation Groups
The bundle uses the Default validation group. Add custom groups in Customer.php:
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\Email(groups={"registration"})
*/
private $email;
How can I help you explore Laravel packages today?