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

Models Management Bundle Laravel Package

dmytrof/models-management-bundle

Symfony 4/5 bundle to manage models and entities from databases and external sources (e.g., third-party APIs). Provides a unified way to organize, handle, and work with your application’s domain data.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install and Enable:

    composer require dmytrof/models-management-bundle
    

    Enable in config/bundles.php:

    return [
        // ...
        Dmytrof\ModelsManagementBundle\DmytrofModelsManagementBundle::class => ['all' => true],
    ];
    
  2. Define a Model Manager: Create a service extending AbstractModelManager for your entity (e.g., User):

    // src/ModelManager/UserManager.php
    namespace App\ModelManager;
    
    use Dmytrof\ModelsManagementBundle\ModelManager\AbstractModelManager;
    use App\Entity\User;
    
    class UserManager extends AbstractModelManager
    {
        protected static $modelClass = User::class;
        protected static $repositoryClass = 'App\Repository\UserRepository';
    }
    
  3. Tag the Manager as a Service: In config/services.yaml:

    services:
        App\ModelManager\UserManager:
            tags: ['dmytrof.model_manager']
    
  4. First Usage: Inject the manager and fetch a model:

    use App\ModelManager\UserManager;
    
    class SomeService {
        public function __construct(private UserManager $userManager) {}
    
        public function getUser(int $id) {
            return $this->userManager->find($id);
        }
    }
    
  5. Verify Configuration: Check config/packages/dmytrof_models_management.yaml for bundle-specific settings (e.g., caching, event listeners).


Implementation Patterns

Core Workflows

  1. Model Management:

    • CRUD Operations: Use find(), findAll(), create(), update(), and delete() methods from AbstractModelManager.
    • Example:
      $user = $userManager->find(1);
      $user->setEmail('new@example.com');
      $userManager->update($user);
      
  2. Hybrid Data Sources:

    • Extend AbstractModelManager to support non-Doctrine sources (e.g., APIs) by overriding fetch():
      protected function fetch($id, array $criteria = [])
      {
          $response = $this->apiClient->get("/users/{$id}");
          return $this->transformer->toModel($response);
      }
      
  3. Event-Driven Extensions:

    • Listen to model events (e.g., ModelLoadedEvent) to add logic:
      // src/EventListener/UserModelListener.php
      use Dmytrof\ModelsManagementBundle\Event\ModelLoadedEvent;
      use Symfony\Component\EventDispatcher\EventSubscriberInterface;
      
      class UserModelListener implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  ModelLoadedEvent::class => 'onModelLoaded',
              ];
          }
      
          public function onModelLoaded(ModelLoadedEvent $event)
          {
              if ($event->getModel() instanceof User) {
                  $event->getModel()->setLastFetched(new \DateTime());
              }
          }
      }
      
  4. Bulk Operations:

    • Use findAll() with criteria for filtering:
      $activeUsers = $userManager->findAll(['active' => true]);
      
  5. Caching:

    • Enable Symfony cache for model managers:
      # config/packages/dmytrof_models_management.yaml
      dmytrof_models_management:
          cache: true
          cache_pool: 'app.cache.doctrine'
      

Integration Tips

  • Doctrine Integration:

    • Ensure repository classes are properly configured in AbstractModelManager::$repositoryClass.
    • Use doctrine.orm.entity_manager as a service dependency if needed.
  • API Clients:

    • Wrap third-party API clients in a service and inject them into custom AbstractModelManager subclasses.
  • Validation:

    • Add validation constraints to entities and use Symfony’s validator component:
      use Symfony\Component\Validator\Constraints as Assert;
      
      class User {
          /**
           * @Assert\Email
           */
          private $email;
      }
      
  • Testing:

    • Mock AbstractModelManager in unit tests:
      $mockManager = $this->createMock(UserManager::class);
      $mockManager->method('find')->willReturn(new User());
      

Gotchas and Tips

Pitfalls

  1. Symfony Version Mismatch:

    • The bundle targets Symfony 4/5. For Symfony 6+, check compatibility or fork the bundle. Look for deprecation warnings in logs.
  2. Missing Configuration:

    • Forgetting to tag services with dmytrof.model_manager will prevent autoloading. Always verify:
      tags: ['dmytrof.model_manager']
      
  3. Overriding Core Methods:

    • Custom fetch() or save() methods may break if the bundle’s internal logic changes. Prefer extending via events.
  4. Caching Quirks:

    • Caching is opt-in and may not work as expected for dynamic data (e.g., API responses). Test with cache: false first.
  5. Event Dispatching:

    • Events like ModelLoadedEvent are not dispatched by default. Ensure your listeners are properly subscribed.
  6. Doctrine Repository Conflicts:

    • If using custom repositories, ensure they are compatible with the bundle’s expected methods (e.g., find(), save()).

Debugging Tips

  1. Enable Debug Mode:

    • Symfony’s debug toolbar can show dispatched events and service calls. Enable in .env:
      APP_DEBUG=1
      
  2. Log Model Events:

    • Add a listener to log events for debugging:
      public function onModelLoaded(ModelLoadedEvent $event)
      {
          \Log::debug('Model loaded:', [
              'class' => get_class($event->getModel()),
              'id' => $event->getModel()->getId(),
          ]);
      }
      
  3. Check Bundle Configuration:

    • Validate config/packages/dmytrof_models_management.yaml for typos or missing keys.
  4. Verify Service Autowiring:

    • If injection fails, check bin/console debug:container for service definitions.
  5. Test with Minimal Data:

    • Start with a single entity and expand gradually to isolate issues.

Extension Points

  1. Custom Model Transformers:

    • Implement Dmytrof\ModelsManagementBundle\Transformer\ModelTransformerInterface to handle non-standard data formats.
  2. Additional Model Sources:

    • Extend AbstractModelManager to support new sources (e.g., Elasticsearch, MongoDB) by overriding fetch() and save().
  3. Custom Events:

    • Dispatch your own events (e.g., ModelPreSaveEvent) for pre/post-processing:
      $dispatcher->dispatch(new ModelPreSaveEvent($model));
      
  4. Configuration Overrides:

    • Override bundle defaults in config/packages/dmytrof_models_management.yaml:
      dmytrof_models_management:
          default_cache_lifetime: 3600
          enabled_listeners: ['cache_listener', 'validation_listener']
      
  5. Performance Optimizations:

    • Add lazy loading or batch fetching for large datasets by extending AbstractModelManager.

Configuration Quirks

  • Cache Pool:

    • Ensure the specified cache pool (e.g., app.cache.doctrine) exists in config/packages/cache.yaml.
  • Event Priorities:

    • Set listener priorities to control execution order:
      public static function getSubscribedEvents()
      {
          return [
              ModelLoadedEvent::class => ['onModelLoaded', 20], // Higher priority = earlier execution
          ];
      }
      
  • Model Class Validation:

    • The bundle assumes $modelClass in AbstractModelManager is a valid entity. Use is_subclass_of() to validate dynamically:
      if (!is_subclass_of(static::$modelClass, Entity::class)) {
          throw new \InvalidArgumentException('Invalid model class');
      }
      
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.
graham-campbell/flysystem
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/opensearch-client
directorytree/opensearch-adapter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin