Weave 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

List Bundle Laravel Package

austral/list-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation Add the package via Composer:

    composer require austral/list-bundle
    

    Ensure austral/entity-bundle (v3.1+) and Symfony Routing (v5.4/v6.4) are installed.

  2. Register the Bundle In config/bundles.php, add:

    Austral\EntityBundle\EntityBundle::class => ['all' => true],
    Austral\ListBundle\ListBundle::class => ['all' => true],
    
  3. First Use Case: Basic List Mapping Define a mapper class (e.g., src/Mapper/UserListMapper.php):

    use Austral\ListBundle\Mapper\AbstractMapper;
    use Austral\EntityBundle\Entity\User;
    
    class UserListMapper extends AbstractMapper
    {
        public function map(array $data): array
        {
            return array_map(function ($item) {
                return new User($item['id'], $item['name'], $item['email']);
            }, $data);
        }
    }
    
  4. Dependency Injection Register the mapper in services.yaml:

    services:
        Austral\ListBundle\Mapper\UserListMapper:
            tags: ['austral.list_mapper']
    
  5. Usage in Controller

    use Austral\ListBundle\Mapper\ListMapperInterface;
    
    class UserController
    {
        public function __construct(private ListMapperInterface $listMapper) {}
    
        public function index(): array
        {
            $rawData = [['id' => 1, 'name' => 'John'], ['id' => 2, 'name' => 'Jane']];
            return $this->listMapper->map($rawData, UserListMapper::class);
        }
    }
    

Implementation Patterns

Core Workflows

  1. Mapper Inheritance Extend AbstractMapper for reusable logic:

    class BaseEntityMapper extends AbstractMapper
    {
        protected function hydrate(array $data, string $entityClass): object
        {
            return new $entityClass(...);
        }
    }
    
  2. Dynamic Mapping Use mapWith() for conditional logic:

    public function mapWith(array $data): array
    {
        return $this->map($data, function ($item) {
            return $item['active'] ? new ActiveUser($item) : new InactiveUser($item);
        });
    }
    
  3. Integration with Austral EntityBundle Leverage EntityManager for hydration:

    use Doctrine\ORM\EntityManagerInterface;
    
    class DoctrineUserMapper extends AbstractMapper
    {
        public function __construct(private EntityManagerInterface $em) {}
    
        public function map(array $data): array
        {
            return array_map(function ($item) {
                return $this->em->find(User::class, $item['id']);
            }, $data);
        }
    }
    
  4. Batch Processing For large datasets, implement chunked mapping:

    public function mapInBatches(array $data, int $batchSize = 100): array
    {
        $results = [];
        foreach (array_chunk($data, $batchSize) as $batch) {
            $results = array_merge($results, $this->map($batch));
        }
        return $results;
    }
    
  5. API Response Transformation Use mappers to convert entities to API responses:

    class UserResponseMapper extends AbstractMapper
    {
        public function map(array $users): array
        {
            return array_map(function ($user) {
                return [
                    'id' => $user->getId(),
                    'name' => $user->getName(),
                    'metadata' => $user->getMetadata()->toArray(),
                ];
            }, $users);
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Circular Dependencies Avoid circular references in mappers (e.g., MapperA depending on MapperB which depends on MapperA). Fix: Use dependency injection for complex mappers or refactor into smaller, single-purpose mappers.

  2. Performance with Large Datasets Lazy-load mappers or use generators to avoid memory issues:

    public function map(array $data): Generator
    {
        foreach ($data as $item) {
            yield $this->hydrate($item);
        }
    }
    
  3. Type Safety The package lacks built-in type hints for mapped entities. Use PHP 8.0+ return types and runtime checks:

    /** @return array<User> */
    public function map(array $data): array { ... }
    
  4. Configuration Overrides If using Austral’s config system, ensure list_mapper services are properly tagged:

    # config/packages/austral_list.yaml
    austral_list:
        mappers:
            - Austral\ListBundle\Mapper\UserListMapper
    

Debugging Tips

  1. Mapper Not Found Verify the service is tagged in services.yaml:

    tags: ['austral.list_mapper']  # Required for autowiring
    
  2. Data Mismatch Use dd() or var_dump() in map() to inspect input/output:

    public function map(array $data): array
    {
        dump($data); // Debug input
        $result = array_map(...);
        dump($result); // Debug output
        return $result;
    }
    
  3. Doctrine Hydration Issues If using EntityManager, ensure entities are properly configured in Doctrine:

    $user = $this->em->find(User::class, $id);
    if (!$user) {
        throw new \RuntimeException("User not found for ID: $id");
    }
    

Extension Points

  1. Custom Mapper Events Dispatch events before/after mapping (requires Symfony EventDispatcher):

    use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
    
    class EventfulMapper extends AbstractMapper
    {
        public function __construct(private EventDispatcherInterface $dispatcher) {}
    
        public function map(array $data): array
        {
            $this->dispatcher->dispatch(new PreMapEvent($data));
            $result = parent::map($data);
            $this->dispatcher->dispatch(new PostMapEvent($result));
            return $result;
        }
    }
    
  2. Validation Integration Combine with Laravel Validators or Symfony Validator:

    use Symfony\Component\Validator\Validator\ValidatorInterface;
    
    class ValidatedMapper extends AbstractMapper
    {
        public function __construct(private ValidatorInterface $validator) {}
    
        public function map(array $data): array
        {
            $errors = $this->validator->validate($data);
            if (count($errors) > 0) {
                throw new \InvalidArgumentException((string) $errors);
            }
            return parent::map($data);
        }
    }
    
  3. Caching Mapped Results Cache results for static or rarely changing data:

    use Symfony\Contracts\Cache\CacheInterface;
    
    class CachedMapper extends AbstractMapper
    {
        public function __construct(private CacheInterface $cache) {}
    
        public function map(array $data): array
        {
            $cacheKey = md5(serialize($data));
            return $this->cache->get($cacheKey, function () use ($data) {
                return parent::map($data);
            });
        }
    }
    
  4. Testing Mappers Mock dependencies and test edge cases:

    public function testMapperWithInvalidData()
    {
        $mapper = new UserListMapper();
        $this->expectException(\InvalidArgumentException::class);
        $mapper->map([['invalid' => 'data']]);
    }
    
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator