deozza/philarmony-core-bundle
Installation
composer require deozza/philarmony-core-bundle
Ensure your project uses Symfony 4.2+ and PHP 7.2+.
Configuration
Create config/packages/philarmony.yaml with a basic structure:
deozza_philarmony:
directory:
entity: "%kernel.project_dir%/src/Entity"
repository: "%kernel.project_dir%/src/Repository"
controller: "%kernel.project_dir%/src/Controller"
form: "%kernel.project_dir%/src/Form"
dto: "%kernel.project_dir%/src/DTO"
database_driver: "doctrine" # or "eloquent" if using Laravel (not natively supported)
First Use Case: Generate a CRUD Module
Run the Philarmony command to scaffold a new module (e.g., User):
php bin/console philarmony:generate:module User
This creates:
src/Entity/User.php)src/Repository/UserRepository.php)src/Controller/UserController.php)src/Form/UserType.php)src/DTO/UserDTO.php)Test the API at /api/users (default routes are auto-generated).
Modular API Development
philarmony:generate:module for rapid scaffolding.UserController methods like index() or store()).// src/Controller/UserController.php
public function store(Request $request, UserDTO $dto): Response
{
$dto->setCustomField('metadata', ['created_by' => $this->getUser()->getId()]);
return parent::store($request, $dto);
}
DTO-Driven Validation
// src/DTO/UserDTO.php
#[Assert\NotBlank]
private ?string $email;
#[Assert\Length(min: 8)]
private ?string $password;
Repository Patterns
PhilarmonyRepository for custom queries:
// src/Repository/UserRepository.php
public function findActiveUsers(): array
{
return $this->createQueryBuilder('u')
->where('u.is_active = :active')
->setParameter('active', true)
->getQuery()
->getResult();
}
Authorization
# config/packages/security.yaml
security:
access_control:
- { path: ^/api/users, roles: ROLE_USER }
// src/Security/Voter/UserVoter.php
public function supportsAttribute($attribute): bool
{
return $attribute === 'EDIT_USER';
}
public function vote(AuthenticatedToken $token, $object, array $attributes): bool
{
return $token->getUser()->getId() === $object->getId();
}
API Versioning
philarmony.yaml:
deozza_philarmony:
versioning: true
/api/v1/users or /api/v2/users.Doctrine vs. Eloquent
DatabaseDriver service or use a wrapper.Custom Serialization
PhilarmonySerializer to modify JSON output:
// src/Serializer/CustomSerializer.php
public function serialize($data, $format, array $context = [])
{
$context['groups'] = ['api', 'custom_group'];
return parent::serialize($data, $format, $context);
}
Event Listeners
prePersist):
// src/EventListener/UserListener.php
public function onPrePersist(User $user): void
{
$user->setCreatedAt(new \DateTime());
}
Register in services.yaml:
services:
App\EventListener\UserListener:
tags:
- { name: 'kernel.event_listener', event: 'philarmony.pre_persist', method: 'onPrePersist' }
Testing
// tests/Controller/UserControllerTest.php
public function testCreateUser()
{
$client = static::createClient();
$client->request('POST', '/api/users', [
'json' => ['name' => 'Test', 'email' => 'test@example.com']
]);
$this->assertResponseStatusCodeSame(201);
}
Namespace Conflicts
directory paths in philarmony.yaml match your project’s autoloading (e.g., src/ vs. app/).composer.json autoload paths and clear cache:
composer dump-autoload
php bin/console cache:clear
DTO Validation Overrides
#[Assert\Callback] for complex rules:
#[Assert\Callback]
public function validate(ExecutionContextInterface $context, $payload): void
{
if ($payload['email'] === 'admin@example.com') {
$context->buildViolation('Admin emails are restricted.')
->atPath('email')
->addViolation();
}
}
Repository Caching Issues
public function __construct(EntityManagerInterface $em)
{
parent::__construct($em);
$this->setCacheable(true);
}
Symfony 5+ Deprecations
Attribute router) may require manual adjustments.Missing Dependencies
composer require doctrine/doctrine-bundle symfony/serializer-pack
Enable Verbose Logging
Add to config/packages/dev/philarmony.yaml:
deozza_philarmony:
debug: true
Logs appear in var/log/dev.log.
Command-Line Debugging
Use philarmony:debug to inspect generated modules:
php bin/console philarmony:debug
Common Errors
| Error | Solution |
|---|---|
Class not found |
Verify directory paths in philarmony.yaml and run composer dump-autoload. |
Validation failed |
Check DTO constraints and request payloads. |
Route not found |
Ensure versioning is configured and routes are flushed (php bin/console router:debug). |
Database connection failed |
Validate DATABASE_URL in .env and Doctrine configuration. |
Custom Generators
Extend the ModuleGenerator class to add fields or logic during scaffolding:
// src/Generator/CustomModuleGenerator.php
public function generateModule(string $moduleName): void
{
parent::generateModule($moduleName);
$this->addCustomField($moduleName, 'is_active', 'boolean', false);
}
API Middleware Add middleware to Philarmony’s pipeline:
# config/packages/philarmony.yaml
deozza_philarmony:
middleware:
- App\Middleware\LogApiRequests
Database Drivers
Implement a custom DatabaseDriverInterface for non-Doctrine/Eloquent databases (e.g., MongoDB):
class MongoDriver implements DatabaseDriverInterface
{
public function find($entity, $id): ?object
{
// Custom MongoDB logic
}
}
How can I help you explore Laravel packages today?