PHP code example of articus / data-transfer

1. Go to this page and download the library: Download articus/data-transfer 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/ */

    

articus / data-transfer example snippets


// Full example configuration in YAML just for readability
$configContent = <<<'CONFIG'
# Required container services
dependencies:
  factories:
    # Service to inject wherever you need data transfer
    Articus\DataTransfer\Service: Articus\DataTransfer\Factory
    # ..and its dependencies
    Articus\DataTransfer\MetadataProvider\Annotation: Articus\DataTransfer\MetadataProvider\Factory\Annotation
    Articus\DataTransfer\Strategy\PluginManager: Articus\DataTransfer\Strategy\Factory\LaminasPluginManager
    Articus\DataTransfer\Validator\PluginManager: Articus\DataTransfer\Validator\Factory\LaminasPluginManager
    # Optional - only if you want to use validators from laminas/laminas-validator
    Laminas\Validator\ValidatorPluginManager: Laminas\Validator\ValidatorPluginManagerFactory
  # Default metadata provider service allows to get metadata both for classes and for class fields so two aliases for single service
  aliases:
    Articus\DataTransfer\ClassMetadataProviderInterface: Articus\DataTransfer\MetadataProvider\Annotation
    Articus\DataTransfer\FieldMetadataProviderInterface: Articus\DataTransfer\MetadataProvider\Annotation

# Configure metadata provider
Articus\DataTransfer\MetadataProvider\Annotation:
  # Configure directory to store cached class metadata
  cache:
    directory: ./data
  # ... or use existing service implementing Psr\SimpleCache\CacheInterface (PSR-16)
  #cache: MyMetadataCache

# Configure strategy plugin manager using options supported by Laminas\ServiceManager\AbstractPluginManager
Articus\DataTransfer\Strategy\PluginManager:
  invokables:
    MySampleStrategy: My\SampleStrategy

# Configure validator plugin manager using options supported by Laminas\ServiceManager\AbstractPluginManager
Articus\DataTransfer\Validator\PluginManager:
  invokables:
    MySampleValidator: My\SampleValidator

CONFIG;
$config = yaml_parse($configContent);

$container = new Laminas\ServiceManager\ServiceManager($config['dependencies']);
$container->setService('config', $config);

/** @var Articus\DataTransfer\Service $service */
$service = $container->get(Articus\DataTransfer\Service::class);


ll example configuration in YAML just for readability
$configContent = <<<'CONFIG'
# Required container services
dependencies:
  factories:
    # Service to inject wherever you need data transfer
    Articus\DataTransfer\Service: Articus\DataTransfer\Factory
    # ..and its dependencies
    Articus\DataTransfer\MetadataProvider\Annotation: Articus\DataTransfer\MetadataProvider\Factory\Annotation
    Articus\DataTransfer\Strategy\PluginManager: Articus\DataTransfer\Strategy\Factory\SimplePluginManager
    Articus\DataTransfer\Validator\PluginManager: Articus\DataTransfer\Validator\Factory\SimplePluginManager
  # Default metadata provider service allows to get metadata both for classes and for class fields so two aliases for single service
  aliases:
    Articus\DataTransfer\ClassMetadataProviderInterface: Articus\DataTransfer\MetadataProvider\Annotation
    Articus\DataTransfer\FieldMetadataProviderInterface: Articus\DataTransfer\MetadataProvider\Annotation

# Configure metadata provider
Articus\DataTransfer\MetadataProvider\Annotation:
  # Configure directory to store cached class metadata
  cache:
    directory: ./data
  # ... or use existing service implementing Psr\SimpleCache\CacheInterface (PSR-16)
  #cache: MyMetadataCache

# Configure strategy plugin manager, check Articus\PluginManager\Options\Simple for supported options
Articus\DataTransfer\Strategy\PluginManager:
  invokables:
    MySampleStrategy: My\SampleStrategy

# Configure validator plugin manager, check Articus\PluginManager\Options\Simple for supported options
Articus\DataTransfer\Validator\PluginManager:
  invokables:
    MySampleValidator: My\SampleValidator

CONFIG;
$config = yaml_parse($configContent);

$container = new Symfony\Component\DependencyInjection\ContainerBuilder();
$containerRef = new Symfony\Component\DependencyInjection\Reference('service_container');
foreach ($config['dependencies']['factories'] as $serviceName => $factoryClass)
{
	$container->register($factoryClass);
	$container->register($serviceName)
		->setFactory(new Symfony\Component\DependencyInjection\Reference($factoryClass))
		->setArguments([$containerRef, $serviceName])
		->setPublic(true)
	;
}
foreach ($config['dependencies']['aliases'] as $alias => $serviceName)
{
	$container->setAlias($alias, $serviceName)->setPublic(true);
}
// Just to reduce sample code size - there should be a dedicated factory class for normal usage
$configFactory = new class ($config)
{
	protected ArrayAccess $config;
	public function __construct(array $config) { $this->config = new ArrayObject($config); }
	public function getConfig(): ArrayAccess { return $this->config; }
};
$container->register('config', ArrayAccess::class)->setFactory([$configFactory, 'getConfig'])->setPublic(true);
$container->compile();

/** @var Articus\DataTransfer\Service $service */
$service = $container->get(Articus\DataTransfer\Service::class);


use Articus\DataTransfer\Annotation as DTA;

/**
 * Default metadata subset.
 * @DTA\Strategy(name="MySampleStrategy")
 * @DTA\Validator(name="MySampleValidator")
 *
 * Metadata subset with several validators.
 * They will be checked in the same order they declared or according priority.
 * If validator is "blocker" then all following validators will be skipped when it finds violations.
 * @DTA\Strategy(name="MySampleStrategy", subset="several-validators")
 * @DTA\Validator(name="MySampleValidator2", subset="several-validators", blocker=true)
 * @DTA\Validator(name="MySampleValidator3", subset="several-validators")
 * @DTA\Validator(name="MySampleValidator1", priority=2, subset="several-validators")
 *
 * Strategies and validators are constructed via plugin managers from articus/plugin-manager,
 * so you may pass options to their factories.
 * Check Articus\DataTransfer\Strategy\Factory\SimplePluginManager and Articus\DataTransfer\Validator\Factory\SimplePluginManager for details.
 * @DTA\Strategy(name="MySampleStrategy", options={"test":123}, subset="with-options")
 * @DTA\Validator(name="MySampleValidator", options={"test":123}, subset="with-options")
 */
class Sample
{
}


use Articus\DataTransfer\Annotation as DTA;

class Sample
{
	/**
	 * Usual public property will be accessed directly
	 * @DTA\Data()
	 */
	public $property;

	/**
	 * Property name and untyped data field for extraction/hydration may differ
	 * @DTA\Data(field="fancy-property")
	 */
	public $renamedProperty;

	/**
	 * Protected or private property will be accessed by conventional getter and setter if they exist
	 * @DTA\Data()
	 */
	protected $propertyWithAccessors;
	public function getPropertyWithAccessors()
	{
		return $this->propertyWithAccessors;
	}
	public function setPropertyWithAccessors($propertyWithAccessors)
	{
		$this->propertyWithAccessors = $propertyWithAccessors;
	}

	/**
	 * And that is how you can set custom getter and setter names for protected or private property
	 * @DTA\Data(getter="customGetAccessor", setter="customSetAccessor")
	 */
	protected $propertyWithCustomAccessors;
	public function customGetAccessor()
	{
		return $this->propertyWithCustomAccessors;
	}
	public function customSetAccessor($propertyWithCustomAccessors)
	{
		$this->propertyWithCustomAccessors = $propertyWithCustomAccessors;
	}

	/**
	 * If you property does not have setter (or getter) just set empty string.
	 * Property without setter will not be hydrated, property without getter will not be extracted.
	 * @DTA\Data(setter="")
	 */
	protected $propertyWithoutSetter;
	public function getPropertyWithoutSetter()
	{
		return $this->propertyWithoutSetter;
	}

	/**
	 * You can also use your own strategy and/or your own validators for property like for whole class
	 * @DTA\Data()
	 * @DTA\Strategy(name="MyStrategy")
	 * @DTA\Validator(name="MyValidator")
	 * @var mixed
	 */
	public $customValue;

	/**
	 * Library provides simple strategy and simple validator for embedded objects.
	 * Check Articus\DataTransfer\Strategy\Factory\NoArgObject and Articus\DataTransfer\Validator\Factory\TypeCompliant for details.
	 * @DTA\Data()
	 * @DTA\Strategy(name="Object", options={"type":MyClass::class})
	 * @DTA\Validator(name="TypeCompliant", options={"type":MyClass::class})
	 * @var MyClass
	 */
	public $objectValue;

	/**
	 * ... and simple strategy for lists of embedded objects and simple validator for lists
	 * Check Articus\DataTransfer\Strategy\Factory\NoArgObjectList and Articus\DataTransfer\Validator\Factory\Collection for details.
	 * @DTA\Data()
	 * @DTA\Strategy(name="ObjectArray", options={"type":MyClass::class})
	 * @DTA\Validator(name="Collection",options={"validators":{
	 *     {"name": "TypeCompliant", "options": {"type":MyClass::class}},
	 * }})
	 * @var MyClass[]
	 */
	public $objectArray;

	/**
	 * Even if there is no validators value will be tested not to be null.
	 * Mark property "nullable" if you do not want that.
	 * And if you set any validators for nullable property they will be executed only for not null value.
	 * @DTA\Data(nullable=true)
	 * @DTA\Validator(name="MyValidatorForNotNullValue")
	 * @var string
	 */
	public $nullableString;

	/**
	 * Library provides simple abstract factory to use validators from laminas/laminas-validator seamlessly.
	 * If you enable this integration in your container configuration (check configuration sample for details) 
	 * you may use any validator registered in Laminas\Validator\ValidatorPluginManager.
	 * @DTA\Data()
	 * @DTA\Validator(name="StringLength",options={"min": 1, "max": 5})
	 * @DTA\Validator(name="Hex")
	 */
	public $laminasValidated;
}