Since this package is Symfony Doctrine-focused, Laravel developers will need to bridge it with Laravel's Eloquent or use it in a Symfony-based service layer. Here’s how to start:
Install via Composer (if using Satis)
composer require awaresoft/doctrine
(Note: The package is not on Packagist; it’s hosted via Satis. Ensure your composer.json includes the Satis repo URL.)
Symlink the Vendor (if modifying locally)
Follow the README’s instructions to symlink /src/Awaresoft into your project. Run:
php artisan vendor:publish --provider="Awaresoft\Doctrine\DoctrineServiceProvider" --tag="config"
(If no provider exists, check the package’s src/ for a ServiceProvider class.)
First Use Case: Query Filtering The package likely extends Doctrine’s query capabilities. Example:
use Awaresoft\Doctrine\Query\FilterBuilder;
// In a Laravel service or controller:
$filter = new FilterBuilder();
$filter->add('active', true); // Example: Filter active records
$query = $entityManager->createQueryBuilder()
->where($filter->getExpression())
->getQuery();
Laravel Integration Tip Wrap Doctrine calls in a Service Class to abstract Symfony dependencies:
namespace App\Services;
use Doctrine\ORM\EntityManagerInterface;
use Awaresoft\Doctrine\Query\FilterBuilder;
class DoctrineService {
protected $em;
public function __construct(EntityManagerInterface $em) {
$this->em = $em;
}
public function getFilteredEntities(string $entityClass, array $filters) {
$filter = new FilterBuilder();
foreach ($filters as $field => $value) {
$filter->add($field, $value);
}
return $this->em->createQueryBuilder()
->from($entityClass, 'e')
->where($filter->getExpression())
->getQuery()
->getResult();
}
}
Register the service in Laravel’s IoC container:
$this->app->bind(DoctrineService::class, function ($app) {
return new DoctrineService($app->make(EntityManagerInterface::class));
});
Pattern: Use FilterBuilder for reusable query conditions.
// Example: Dynamic "where" clauses
$filter = new FilterBuilder();
$filter->add('status', 'published') // Exact match
->add('created_at', '>=' . now()->subDays(7)->format('Y-m-d')) // Date range
->add('tags', 'like', '%php%'); // Partial match
$query = $this->em->createQueryBuilder()
->from(User::class, 'u')
->where($filter->getExpression())
->getQuery();
Laravel Tip: Convert Doctrine queries to Eloquent-like syntax for consistency:
public function scopeFilter($query, array $filters) {
$filter = new FilterBuilder();
foreach ($filters as $field => $value) {
$filter->add($field, $value);
}
return $query->where($filter->getExpression());
}
// Usage: User::filter(['status' => 'active'])->get();
Pattern: Extend Doctrine’s hydration to return Laravel collections or DTOs.
use Awaresoft\Doctrine\Hydration\CustomHydrator;
$hydrator = new CustomHydrator();
$hydrator->addScalarMapping('id', 'user_id'); // Rename fields
$hydrator->addObjectMapping(User::class, 'user'); // Map to Eloquent model
$query = $this->em->createQuery('SELECT u FROM User u')
->setHydrationMode(CustomHydrator::HYDRATION_MODE);
$results = $query->getResult();
Laravel Tip: Use Hydrator in a repository pattern:
class UserRepository {
public function findWithHydration(array $criteria) {
$query = $this->em->createQueryBuilder()
->from(User::class, 'u')
->where(...);
$hydrator = new CustomHydrator();
$query->setHydrationMode($hydrator::HYDRATION_MODE);
return $query->getResult();
}
}
Pattern: Hook into Doctrine events (e.g., prePersist, postLoad) via Symfony’s event system.
use Awaresoft\Doctrine\Event\LifecycleEventArgs;
$eventManager = $this->em->getEventManager();
$eventManager->addEventListener(
'prePersist',
function (LifecycleEventArgs $args) {
$entity = $args->getEntity();
if ($entity instanceof User) {
$entity->setUpdatedAt(now());
}
}
);
Laravel Tip: Bind events in a service provider:
public function boot() {
$this->app->booted(function () {
$em = $this->app->make(EntityManagerInterface::class);
$em->getEventManager()->addEventListener(
'postLoad',
function ($args) {
// Post-load logic (e.g., lazy-loading relations)
}
);
});
}
Pattern: Use Doctrine’s BulkOperation for efficient updates/deletes.
use Awaresoft\Doctrine\Bulk\BulkOperation;
$bulk = new BulkOperation($this->em);
$bulk->update(User::class)
->set('status', 'inactive')
->where('last_login < ?', new \DateTime('-30 days'))
->execute();
Laravel Tip: Wrap in a command for CLI usage:
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Awaresoft\Doctrine\Bulk\BulkOperation;
class InactivateOldUsers extends Command {
protected $signature = 'users:inactivate-old';
public function handle() {
$bulk = new BulkOperation($this->em);
$bulk->update(User::class)
->set('status', 'inactive')
->where('last_login < ?', now()->subDays(30))
->execute();
$this->info('Inactivated ' . $bulk->getAffectedCount() . ' users.');
}
}
internal or experimental.interface FilterBuilderExtension {
public function addOrCondition(string $field, $value);
}
willdurand/faker-bundle (Symfony-specific) and assumes Doctrine ORM. Laravel’s Eloquent may clash.// In a Symfony-compatible service
$container = new Container();
$container->loadFromExtension('doctrine', [
'orm' => ['entity_managers' => ['default' => ['mappings' => [...]]]],
]);
$em = $container->get('doctrine.orm.entity_manager');
FilterBuilder may generate SQL that differs from Eloquent’s expectations (e.g., table aliases).$query = $this->em->createQueryBuilder()
->from(User::class, 'u')
->where($filter->getExpression())
->getQuery();
$sql = $query->getSQL(); // Debug SQL
$params = $query->getParameters();
# config/doctrine/orm/mappings/User.dcm.xml
<entity name="App\Models\User">
<indexes>
<index name="IDX_USER_STATUS" columns="status"/>
<index name="IDX_USER_LOGIN" columns="last_login"/>
</indexes>
</entity>
How can I help you explore Laravel packages today?