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

Mapper Laravel Package

pourbahrami/mapper

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require pourbahrami/mapper
    

    No publisher or service provider is required—use the package directly via the Mapper facade or helper.

  2. First Use Case: Map an array to an object (e.g., API response → Eloquent model):

    use Pourbahrami\Mapper\Facades\Mapper;
    
    $data = ['name' => 'John', 'email' => '[email protected]'];
    $user = Mapper::map($data, new \App\Models\User());
    

    Or map between objects:

    $source = new \App\Models\ApiUser($data);
    $destination = new \App\Models\User();
    Mapper::map($source, $destination);
    
  3. Where to Look First:


Implementation Patterns

Core Workflows

  1. Basic Mapping: Use Mapper::map() for simple array-to-object or object-to-object transformations.

    // Array → Model
    $model = Mapper::map($request->all(), new \App\Models\Post());
    
    // Object → Object
    $apiUser = new \App\DTOs\ApiUser($apiResponse);
    $user = new \App\Models\User();
    Mapper::map($apiUser, $user);
    
  2. Custom Mappers: Extend \Pourbahrami\Mapper\Contracts\Mapper for domain-specific logic:

    class UserMapper extends \Pourbahrami\Mapper\AbstractMapper
    {
        protected $sourceClass = \App\DTOs\ApiUser::class;
        protected $destinationClass = \App\Models\User::class;
    
        public function map()
        {
            $this->mapProperty('name', 'full_name');
            $this->mapProperty('email', 'email_address');
        }
    }
    

    Register via config or service provider.

  3. Nested Objects: Handle nested structures with dot notation:

    $data = ['author' => ['name' => 'Jane']];
    $post = new \App\Models\Post();
    Mapper::map($data, $post, ['author.name' => 'author_name']);
    
  4. Conditional Mapping: Use when() to apply logic:

    Mapper::map($data, $model)
        ->when(fn($src) => $src['is_admin'], fn($dst) => $dst->setRole('admin'));
    

Integration Tips

  • Form Requests: Map validated input directly to models:
    public function store(StoreUserRequest $request)
    {
        $user = Mapper::map($request->validated(), new \App\Models\User());
        $user->save();
    }
    
  • API Resources: Transform collections efficiently:
    $apiUsers = Mapper::mapCollection($apiResponse['data'], \App\DTOs\ApiUser::class);
    $users = Mapper::mapCollection($apiUsers, \App\Models\User::class);
    
  • Service Layer: Centralize mapping logic in services to avoid duplication.

Gotchas and Tips

Pitfalls

  1. Property Mismatches:

    • Issue: Undefined properties throw errors.
    • Fix: Use ignoreMissingProperties() or define explicit mappings:
      Mapper::map($data, $model, ['name' => 'full_name'])->ignoreMissingProperties();
      
  2. Circular References:

    • Issue: Nested objects with mutual references cause infinite loops.
    • Fix: Use Mapper::map() with depth parameter or implement Serializable in custom mappers.
  3. Type Conflicts:

    • Issue: Automatic type casting may fail (e.g., string → DateTime).
    • Fix: Use custom mappers or Mapper::cast():
      Mapper::map($data, $model)->cast('published_at', 'datetime');
      
  4. Performance:

    • Issue: Deeply nested mappings can be slow.
    • Fix: Pre-define mappings in custom mappers or use Mapper::batchMap() for collections.

Debugging

  • Enable Logging:
    Mapper::debug(true); // Logs all mapping operations to Laravel logs.
    
  • Inspect Mappings: Use Mapper::getMappings() to verify registered property mappings.

Extension Points

  1. Custom Strategies: Override \Pourbahrami\Mapper\Strategies\PropertyMapper for custom property handling (e.g., encryption).

  2. Event Hooks: Bind to mapping.before/mapping.after events for pre/post-processing:

    event(new \Pourbahrami\Mapper\Events\MappingEvent($source, $destination));
    
  3. Configuration: Override defaults in config/mapper.php:

    'default_strategy' => \App\Strategies\CustomMapper::class,
    'ignore_properties' => ['password', 'api_token'],
    
  4. Testing: Mock the Mapper facade or use Mapper::shouldReceive('map')->once() in PHPUnit tests.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo