glorpen/propel-bundle
Symfony bundle integrating Propel ORM: configuration, commands, connection management, and optional behaviors to use Propel smoothly in Symfony apps. Provides bridge services and tooling to generate models and manage schema/migrations.
Installation:
composer require glorpen/propel-bundle
Add to config/bundles.php:
return [
// ...
Glorpen\PropelBundle\GlorpenPropelBundle::class => ['all' => true],
];
First Use Case:
Extend a Propel model (e.g., User) with custom behavior:
use Glorpen\PropelBundle\Model\Base\BaseUser;
use Glorpen\PropelBundle\Model\Extend\UserExtend;
class User extends BaseUser {
public function getFullName() {
return $this->getFirstName() . ' ' . $this->getLastName();
}
}
Register the extended model in config/packages/glorpen_propel.yaml:
glorpen_propel:
models:
- { class: 'App\Model\User', extend: 'App\Model\Extend\UserExtend' }
Triggering Events:
Subscribe to Propel lifecycle events (e.g., postSave) in a Symfony service:
use Glorpen\PropelBundle\Event\PropelEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserEventSubscriber implements EventSubscriberInterface {
public static function getSubscribedEvents() {
return [
PropelEvent::POST_SAVE => 'onUserPostSave',
];
}
public function onUserPostSave(PropelEvent $event) {
if ($event->getModel() instanceof User) {
// Custom logic here
}
}
}
Base Model Inheritance:
Extend Propel’s auto-generated BaseModel classes to avoid overwriting migrations:
use Glorpen\PropelBundle\Model\Base\BaseUser;
class User extends BaseUser {
// Custom methods/properties
}
Event-Driven Logic: Use events for cross-cutting concerns (e.g., logging, notifications):
# config/packages/glorpen_propel.yaml
glorpen_propel:
events:
- { event: 'postSave', listener: 'App\EventListener\UserSaveListener' }
Dependency Injection: Inject services into extended models via Symfony’s container:
use Symfony\Component\DependencyInjection\ContainerInterface;
class User extends BaseUser {
private $container;
public function __construct(ContainerInterface $container) {
$this->container = $container;
}
public function sendWelcomeEmail() {
$mailer = $this->container->get('mailer');
// ...
}
}
Schema Customization:
Use glorpen_propel.schema to modify Propel’s schema without altering schema.xml:
glorpen_propel:
schema:
User:
columns:
- { name: 'full_name', type: 'VARCHAR', size: 255 }
Query Builder Extensions: Add custom query methods to models:
class UserQuery extends BaseUserQuery {
public function active() {
return $this->filterByIsActive(true);
}
}
Validation: Integrate with Symfony Validator by extending models:
use Symfony\Component\Validator\Constraints as Assert;
class User extends BaseUser {
/**
* @Assert\Email
*/
public $email;
}
Caching Conflicts:
Clear Propel’s cache (php bin/console propel:cache:build) after extending models or schema changes.
php bin/console propel:cache:build --no-debug
Event Ordering: Events fire in the order they’re registered. Use priorities in subscribers:
public static function getSubscribedEvents() {
return [
PropelEvent::POST_SAVE => ['onPostSave', 10], // Lower priority = later execution
];
}
Circular Dependencies: Avoid circular references between extended models and services. Use lazy-loading or interfaces.
Symfony 5+ Compatibility:
The bundle targets Symfony 2, so test thoroughly with newer versions. Use symfony/flex recipes if available.
Event Debugging: Log event payloads to inspect data:
public function onPostSave(PropelEvent $event) {
\Log::debug('Event data:', $event->getData());
}
Model Overrides:
Verify extended models are loaded by checking BaseModel inheritance:
var_dump(get_parent_class(new User())); // Should return Glorpen\PropelBundle\Model\Base\BaseUser
Custom Events: Dispatch custom Propel events:
use Glorpen\PropelBundle\Event\PropelEvent;
$event = new PropelEvent($model, 'custom.event');
$this->get('event_dispatcher')->dispatch($event, 'propel.custom');
Schema Plugins: Extend schema handling with custom plugins:
glorpen_propel:
schema_plugins:
- App\Propel\Schema\Plugin\CustomPlugin
Behavior Traits: Reuse logic across models with traits:
trait SoftDeletable {
public function delete() {
$this->setIsDeleted(true);
$this->save();
}
}
Propel Query Extensions:
Override buildPdo() in queries for custom SQL:
class UserQuery extends BaseUserQuery {
protected function buildPdo() {
$pdo = parent::buildPdo();
$pdo->select('CONCAT(first_name, " ", last_name) as full_name');
return $pdo;
}
}
How can I help you explore Laravel packages today?