guyliangilsing/php-class-mapper

A simple package that provides you with a simple class mapping system.

1.1.2 2022-11-23 13:02 UTC

This package is auto-updated.

Last update: 2024-04-23 16:20:15 UTC


README

A simple package that provides you with a simple class mapping system.

Table of Contents

Features

PHPClassMapper comes with the following features:

  • Class to class mapping
  • Array to class mapping
  • Class to array mapping

Installation

$ composer require guyliangilsing/php-class-mapper

usage

Class to class mapping

Configuring the mapper

You need to supply a configuration class before you can create the mapper class. You can create a configuration as follows:

use PHPClassMapper\Configuration\MapperConfiguration;

$configuration = new MapperConfiguration();

In this configuration you can add a mapping with the following code:

use PHPClassMapper\Configuration\MapperConfiguration;

$configuration = new MapperConfiguration();
$configuration->addMapping(Source::class, Destination::class, new MyMapping());

Creating a mapping

To let the mapper know how to map your classes, you need to provide it with a mapping. A mapping can be created as follows:

use PHPClassMapper\Exceptions\MissingContextDataFieldException;
use PHPClassMapper\Exceptions\MissingMappingException;
use PHPClassMapper\MapperInterface;

class MyMapping implements MappingInterface
{
    /**
     * Maps one class into another class.
     *
     * @param object $source The class that needs to be mapped to a different class.
     * @param array<string, mixed> $contextData An associative array (key => value) that gives the mapper additional
     * data to work with.
     * @param MapperInterface $mapper An extra mapper instance to map objects with.
     *
     * @throws InvalidArgumentException when a `MyClass::name` string refers to a class that does not exist.
     * @throws MissingMappingException when a mapping between two class types can't be found.
     * @throws MissingContextDataFieldException when a specific context data field can't be found.
     */
    public function mapObject(object $source, array $contextData, MapperInterface $mapper): object;
    {
        if (!($source instanceof Source))
        {
            throw new MissingMappingException($source::class, Destination::class);
        }

        return new Destination();
    }
}

Creating the mapper

Once you have your configuration, you can instantiate a mapper:

use PHPClassMapper\Configuration\MapperConfiguration;
use PHPClassMapper\Mapper;

$configuration = new MapperConfiguration();

// Do your configuration logic here...

$mapper = new Mapper($configuration);

Using the mapper

Once you have the mapper instantiated, you can use it in the following way:

use PHPClassMapper\Configuration\MapperConfiguration;
use PHPClassMapper\Mapper;

$configuration = new MapperConfiguration();

// Do your configuration logic here...

$mapper = new Mapper($configuration);

// Without contextvariables
$mapper->map($source, Destination::class);

// With context variables
$mappedClass = $mapper->map($source, Destination::class, [
    'contextFieldOne' => 'Hello',
    'contextFieldTwo' => 'World'
]);

Array mapping

Configuring the mapper

You need to supply a configuration class before you can create the mapper class. You can create a configuration as follows:

use PHPClassMapper\Configuration\ArrayMapperConfiguration;

$configuration = new ArrayMapperConfiguration();

In this configuration you can add two different mapping types:

  • To array mapping (class -> array)
  • From array mapping (array -> class)

To array mapping

use PHPClassMapper\Configuration\ArrayMapperConfiguration;

$configuration = new ArrayMapperConfiguration();
$configuration->addToArrayMapping(Source::class, new ToArrayMapping());

From array mapping

use PHPClassMapper\Configuration\ArrayMapperConfiguration;

$configuration = new ArrayMapperConfiguration();
$configuration->addFromArrayMapping(Destination::class, new FromArrayMapping());

Creating a mapping

Since you can map arrays in two different ways, two different interfaces are being used:

  • ToArrayMappingInterface
  • FromArrayMappingInterface

To array mapping

use PHPClassMapper\ArrayMapperInterface;
use PHPClassMapper\Configuration\ToArrayMappingInterface;

final class ToArrayMapping implements ToArrayMappingInterface
{
    /**
     * Maps an object into an array.
     *
     * @param object $source The class that needs to be mapped to an array.
     * @param array<string, mixed> $contextData An associative array (key => value) that gives the mapper additional
     * data to work with.
     * @param ArrayMapperInterface $mapper An extra mapper instance to map objects with.
     *
     * @throws InvalidArgumentException when a `MyClass::name` string refers to a class that does not exist.
     * @throws MissingMappingException when a mapping between two class types can't be found.
     * @throws MissingContextDataFieldException when a specific context data field can't be found.
     *
     * @return array<mixed>
     */
    public function mapObject(object $source, array $contextData, ArrayMapperInterface $mapper): array;
    {
        return [];
    }
}

From array mapping

use PHPClassMapper\ArrayMapperInterface;
use PHPClassMapper\Configuration\FromArrayMappingInterface;

final class FromArrayMapping implements FromArrayMappingInterface
{
    /**
     * Maps an array into an object.
     *
     * @param array<string, mixed> $source The class that needs to be mapped to a different class.
     * @param array<string, mixed> $contextData An associative array (key => value) that gives the mapper additional
     * data to work with.
     * @param ArrayMapperInterface $mapper An extra mapper instance to map nested arrays with.
     *
     * @throws InvalidArgumentException when a `MyClass::name` string refers to a class that does not exist.
     * @throws MissingMappingException when a mapping between two class types can't be found.
     * @throws MissingContextDataFieldException when a specific context data field can't be found.
     */
    public function mapObject(array $source, array $contextData, ArrayMapperInterface $mapper): object;
    {
        return new Destination();
    }
}

Creating the mapper

Once you have your configuration, you can instantiate a mapper:

use PHPClassMapper\Configuration\ArrayMapperConfiguration;
use PHPClassMapper\ArrayMapper;

$configuration = new ArrayMapperConfiguration();

// Do your configuration logic here...

$mapper = new ArrayMapper($configuration);

Using the mapper

Once you have the mapper instantiated, you can use it in the following way:

use PHPClassMapper\Configuration\ArrayMapperConfiguration;
use PHPClassMapper\ArrayMapper;

$configuration = new ArrayMapperConfiguration();

// Do your configuration logic here...

$mapper = new ArrayMapper($configuration);

// To array mapping
$objToMap = // Your object here...
$mappedArray = $mapper->toArray($objToMap);

// From array mapping
$mappedObject = $mapper->fromArray([], Destination::class);

Dependency injection containers

You can register the mapper with your favorite dependency injection container by using the MapperInterface and MapperConfigurationInterface interfaces.