Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Persistence Bundle Laravel Package

aaronadal/persistence-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require aaronadal/persistence-bundle
    

    Register the bundle in config/app.php under providers:

    Aaronadal\PersistenceBundle\PersistenceServiceProvider::class,
    
  2. Basic Configuration Publish the config file:

    php artisan vendor:publish --provider="Aaronadal\PersistenceBundle\PersistenceServiceProvider" --tag="config"
    

    Edit config/persistence.php to define your default repository and entity mappings.

  3. First Use Case: Querying Entities Inject the PersistenceManager into a service/controller:

    use Aaronadal\PersistenceBundle\PersistenceManager;
    
    class UserController extends Controller
    {
        protected $persistence;
    
        public function __construct(PersistenceManager $persistence)
        {
            $this->persistence = $persistence;
        }
    
        public function index()
        {
            $users = $this->persistence->findAll(User::class);
            return view('users.index', compact('users'));
        }
    }
    

Implementation Patterns

Repository Abstraction

  1. Define Custom Repositories Extend Aaronadal\PersistenceBundle\AbstractRepository for domain-specific logic:

    namespace App\Repositories;
    
    use Aaronadal\PersistenceBundle\AbstractRepository;
    use App\Models\User;
    
    class UserRepository extends AbstractRepository
    {
        public function findActiveUsers()
        {
            return $this->createQueryBuilder('u')
                ->where('u.is_active = :active')
                ->setParameter('active', true)
                ->getQuery()
                ->getResult();
        }
    }
    
  2. Register Repositories Bind repositories in PersistenceServiceProvider or via config:

    $this->app->bind(UserRepository::class, function ($app) {
        return new UserRepository($app->make('doctrine')->getManager());
    });
    

Query Building

  1. Fluent Query Interface Use the PersistenceManager to build queries dynamically:

    $query = $this->persistence
        ->createQueryBuilder(User::class, 'u')
        ->where('u.email LIKE :email')
        ->setParameter('email', '%@example.com')
        ->orderBy('u.created_at', 'DESC')
        ->getQuery();
    
  2. Pagination Integrate with Laravel’s pagination:

    use Aaronadal\PersistenceBundle\Pagination\Paginator;
    
    $paginator = new Paginator($this->persistence);
    $users = $paginator->paginate(User::class, request('page', 1), 10);
    

Integration with Laravel

  1. Service Container Binding Bind the PersistenceManager to a custom interface for better testability:

    $this->app->bind(
        \App\Contracts\PersistenceInterface::class,
        \Aaronadal\PersistenceBundle\PersistenceManager::class
    );
    
  2. Event Listeners Attach listeners to repository events (e.g., prePersist, postRemove):

    $this->persistence->getEventManager()->addEventListener(
        \Doctrine\ORM\Events::prePersist,
        function ($event) {
            $entity = $event->getEntity();
            if ($entity instanceof User) {
                $entity->setUpdatedAt(new \DateTime());
            }
        }
    );
    

Gotchas and Tips

Pitfalls

  1. Entity Manager Injection

    • The bundle assumes a single EntityManager. If using multiple managers (e.g., default and read), configure the bundle explicitly in config/persistence.php:
      'entity_managers' => [
          'default' => 'doctrine.orm.entity_manager',
          'read' => 'doctrine.orm.read_entity_manager',
      ],
      
  2. Query Caching

    • By default, queries may not leverage Doctrine’s second-level cache. Enable it in config/persistence.php:
      'query_cache' => true,
      
  3. Repository Autowiring

    • Avoid autowiring repositories directly. Instead, use the PersistenceManager to fetch repositories dynamically:
      // ❌ Avoid (tight coupling)
      public function __construct(UserRepository $repository) {}
      
      // ✅ Preferred
      public function __construct(PersistenceManager $persistence) {
          $this->repository = $this->persistence->getRepository(User::class);
      }
      

Debugging

  1. Query Logging Enable SQL logging in config/persistence.php:

    'logging' => true,
    

    Logs will appear in storage/logs/laravel.log.

  2. Event Debugging Dump event arguments for debugging:

    $this->persistence->getEventManager()->addEventListener(
        \Doctrine\ORM\Events::onFlush,
        function ($event) {
            \Log::debug('Flush event:', $event->getEntityManager()->getUnitOfWork()->getScheduledEntityInsertions());
        }
    );
    

Extension Points

  1. Custom Query Types Extend the bundle’s QueryBuilder to support custom DQL functions:

    namespace Aaronadal\PersistenceBundle\Query;
    
    class CustomQueryBuilder extends QueryBuilder
    {
        public function distance($x, $y)
        {
            return $this->expr()->func('DISTANCE', [$x, $y]);
        }
    }
    

    Register the custom builder in the service provider.

  2. Repository Factories Override the default repository factory to enforce custom implementations:

    $this->app->bind(
        \Aaronadal\PersistenceBundle\RepositoryFactory::class,
        function ($app) {
            return new CustomRepositoryFactory($app);
        }
    );
    
  3. Transaction Management Use the bundle’s transaction helpers for complex operations:

    $this->persistence->transactional(function () {
        $user = $this->persistence->find(User::class, 1);
        $user->update(['role' => 'admin']);
        $this->persistence->flush();
    });
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme