PHP code example of pixelshaped / flat-mapper-bundle

1. Go to this page and download the library: Download pixelshaped/flat-mapper-bundle library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

pixelshaped / flat-mapper-bundle example snippets


// Result from: SELECT author.*, book.* FROM authors LEFT JOIN books ON books.author_id = authors.id
$queryResults = [
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 1, 'book_name' => 'Travelling as a group'],
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 2, 'book_name' => 'My journeys'],
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 3, 'book_name' => 'Coding on the road'],
    ['author_id' => 2, 'author_name' => 'Bob Schmo',   'book_id' => 4, 'book_name' => 'My best recipes'],
];

[
    AuthorDTO(
        id: 1,
        name: 'Alice Brian',
        books: [
            BookDTO(id: 1, name: 'Travelling as a group'),
            BookDTO(id: 2, name: 'My journeys'),
            BookDTO(id: 3, name: 'Coding on the road'),
        ]
    ),
    AuthorDTO(
        id: 2,
        name: 'Bob Schmo',
        books: [
            BookDTO(id: 4, name: 'My best recipes'),
        ]
    ),
]

use Pixelshaped\FlatMapperBundle\Mapping\{Identifier, Scalar, ReferenceArray};

class AuthorDTO
{
    public function __construct(
        #[Identifier]
        #[Scalar('author_id')]
        public int $id,

        #[Scalar('author_name')]
        public string $name,

        #[ReferenceArray(BookDTO::class)]
        public array $books,
    ) {}
}

class BookDTO
{
    public function __construct(
        #[Identifier('book_id')]
        public int $id,

        #[Scalar('book_name')]
        public string $name,
    ) {}
}

use Pixelshaped\FlatMapperBundle\FlatMapper;

$flatMapper = new FlatMapper();
$authors = $flatMapper->map(AuthorDTO::class, $queryResults);

// As a property attribute (when you need the ID in your DTO)
class AuthorDTO {
    public function __construct(
        #[Identifier]
        #[Scalar('author_id')]
        public int $id,
        // ...
    ) {}
}

// As a class attribute (when you only need it for internal tracking)
#[Identifier('product_id')]
class ProductDTO {
    public function __construct(
        #[Scalar('product_sku')]
        public string $sku,
        // ...
    ) {}
}

class BookDTO {
    public function __construct(
        public int $id,              // Looks for 'id' column
        #[Scalar('book_name')]
        public string $name,         // Looks for 'book_name' column
    ) {}
}

class AuthorDTO {
    public function __construct(
        #[Identifier('author_id')]
        public int $id,

        #[ReferenceArray(BookDTO::class)]
        public array $books,  // Will contain BookDTO instances
    ) {}
}

class CustomerDTO {
    public function __construct(
        #[Identifier('customer_id')]
        public int $id,

        #[ScalarArray('shopping_list_id')]
        public array $shoppingListIds,  // [1, 2, 3, ...]
    ) {}
}

use Pixelshaped\FlatMapperBundle\Mapping\NameTransformation;

// Add a prefix to all column lookups
#[NameTransformation(columnPrefix: 'author_')]
class AuthorDTO {
    public function __construct(
        #[Identifier]
        public int $id,        // Looks for 'author_id'
        public string $name,   // Looks for 'author_name'
    ) {}
}

// Convert camelCase to snake_case
#[NameTransformation(snakeCaseColumns: true)]
class ProductDTO {
    public function __construct(
        #[Identifier]
        public int $productId,      // Looks for 'product_id'
        public string $productName, // Looks for 'product_name'
    ) {}
}

// Combine both
#[NameTransformation(columnPrefix: 'usr_', snakeCaseColumns: true)]
class UserDTO {
    public function __construct(
        #[Identifier]
        public int $userId,      // Looks for 'usr_user_id'
        public string $fullName, // Looks for 'usr_full_name'
    ) {}
}

$results = [
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 1, 'book_name' => 'Travelling as a group', 'book_publisher_name' => 'TravelBooks'],
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 2, 'book_name' => 'My journeys', 'book_publisher_name' => 'Lorem Press'],
    ['author_id' => 1, 'author_name' => 'Alice Brian', 'book_id' => 3, 'book_name' => 'Coding on the road', 'book_publisher_name' => 'Ipsum Books'],
    ['author_id' => 2, 'author_name' => 'Bob Schmo', 'book_id' => 1, 'book_name' => 'Travelling as a group', 'book_publisher_name' => 'TravelBooks'],
    ['author_id' => 2, 'author_name' => 'Bob Schmo', 'book_id' => 4, 'book_name' => 'My best recipes', 'book_publisher_name' => 'Cooking and Stuff'],
];

$authors = $flatMapper->map(AuthorDTO::class, $results);

Array
(
    [1] => AuthorDTO Object
        (
            [id] => 1
            [name] => Alice Brian
            [books] => Array
                (
                    [1] => BookDTO Object
                        (
                            [id] => 1
                            [name] => Travelling as a group
                            [publisherName] => TravelBooks
                        )
                    [2] => BookDTO Object
                        (
                            [id] => 2
                            [name] => My journeys
                            [publisherName] => Lorem Press
                        )
                    [3] => BookDTO Object
                        (
                            [id] => 3
                            [name] => Coding on the road
                            [publisherName] => Ipsum Books
                        )
                )
        )
    [2] => AuthorDTO Object
        (
            [id] => 2
            [name] => Bob Schmo
            [books] => Array
                (
                    [1] => BookDTO Object
                        (
                            [id] => 1
                            [name] => Travelling as a group
                            [publisherName] => TravelBooks
                        )
                    [4] => BookDTO Object
                        (
                            [id] => 4
                            [name] => My best recipes
                            [publisherName] => Cooking and Stuff
                        )
                )
        )
)

$results = [
    ['object1_id' => 1, 'object1_name' => 'Root 1', 'object2_id' => 1],
    ['object1_id' => 1, 'object1_name' => 'Root 1', 'object2_id' => 2],
    ['object1_id' => 1, 'object1_name' => 'Root 1', 'object2_id' => 3],
    ['object1_id' => 2, 'object1_name' => 'Root 2', 'object2_id' => 1],
    ['object1_id' => 2, 'object1_name' => 'Root 2', 'object2_id' => 4],
];

Array
(
    [1] => ScalarArrayDTO Object
        (
            [id] => 1
            [name] => Root 1
            [object2s] => Array
                (
                    [0] => 1
                    [1] => 2
                    [2] => 3
                )
        )
    [2] => ScalarArrayDTO Object
        (
            [id] => 2
            [name] => Root 2
            [object2s] => Array
                (
                    [0] => 1
                    [1] => 4
                )
        )
)

$result = $entityManager->createQueryBuilder()
    ->select('customer.id AS customer_id, customer.name AS customer_name, shopping_list.id AS shopping_list_id')
    ->from(Customer::class, 'customer')
    ->leftJoin('customer.shoppingLists', 'shopping_list')
    ->getQuery()
    ->getResult();

$customers = $flatMapper->map(CustomerDTO::class, $result);

$qb = $customerRepository->createQueryBuilder('customer')
    ->leftJoin('customer.addresses', 'address')
    ->select('customer.id AS customer_id, customer.ref AS customer_ref, address.id AS address_id')
    ->setFirstResult(0)
    ->setMaxResults(10);

$paginator = new Paginator($qb->getQuery(), fetchJoinCollection: true);
$paginator->setUseOutputWalkers(false);

$customers = $flatMapper->map(CustomerWithAddressesDTO::class, $paginator);

use Pixelshaped\FlatMapperBundle\FlatMapper;

$flatMapper = new FlatMapper();

// Optional: configure for production
$flatMapper->setCacheService($cache);      // Any Symfony\Contracts\Cache\CacheInterface implementation
$flatMapper->setValidateMapping(false);    // Skip validation checks

// Optional: declare mappings outside PHP attributes
$flatMapper->setYamlMappings([
    AuthorDTO::class => [
        'properties' => [
            'id' => ['Identifier' => null, 'Scalar' => 'author_id'],
            'books' => ['ReferenceArray' => BookDTO::class],
        ],
    ],
]);

$result = $flatMapper->map(AuthorDTO::class, $queryResults);

$dtoClasses = [CustomerDTO::class, OrderDTO::class, ProductDTO::class];

foreach ($dtoClasses as $class) {
    $flatMapper->createMapping($class);
}

$flatMapper->setValidateMapping(false);

$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, e.email, a.city) FROM Customer c JOIN c.email e JOIN c.address a');
$customers = $query->getResult(); // array<CustomerDTO>