DEPRECATION WARNING
This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.
Mixed types service¶
This service allows properties types to be dynamically fetched.
For instance, in a configuration object which contains a list of employees, every employee can have a different role; in this case, roles can be divided into PHP classes. This service will allow the implementation of a method that will be called to resolve which class should be used. Take a look at the example below for more information.
Usage¶
You can activate this service for a given configuration object by attaching it to the ServiceFactory
in the static function getConfigurationObjectServices()
. Use the constant ServiceInterface::SERVICE_MIXED_TYPES
as an identifier for this service (see example below).
You have two possibilities to use it on properties:
- Solution 1: you can use the annotation
@mixedTypesResolver
on the property that needs it, filled with a class name that implements the interfaceMixedTypesInterface
. - Solution 2: the type of the variable can be the resolver class, for instance an abstract class.
The resolver class has to implement the interface MixedTypesInterface
, and have its own public static function getInstanceClassName(MixedTypesResolver $resolver)
implementation.
Example¶
Solution 1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | class Configuration implements ConfigurationObjectInterface
{
use DefaultConfigurationObjectTrait;
/**
* @var FooInterface[]
* @mixedTypesResolver FooResolver
*/
protected $foo;
}
class FooResolver implements MixedTypesInterface
{
/**
* @inheritdoc
*/
public static function getInstanceClassName(MixedTypesResolver $resolver)
{
$data = $resolver->getData();
$type = ($data['type'] === 'foo')
? Foo::class
: Bar::class;
$resolver->setObjectType($type);
}
}
class Foo implements FooInterface
{
// Some code...
}
class Bar implements FooInterface
{
// Some other code...
}
|
Solution 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | use Romm\ConfigurationObject\ConfigurationObjectInterface;
use Romm\ConfigurationObject\Service\ServiceInterface;
use Romm\ConfigurationObject\Traits\ConfigurationObject\DefaultConfigurationObjectTrait;
use Romm\ConfigurationObject\Traits\ConfigurationObject\MagicMethodsTrait;
use Romm\ConfObjTest\Model\Company\Employee\AbstractEmployee;
use Romm\ConfigurationObject\Service\Items\MixedTypes\MixedTypesInterface;
use Romm\ConfigurationObject\Service\Items\MixedTypes\MixedTypesResolver;
/**
* COMPANY
*/
class Company implements ConfigurationObjectInterface
{
use DefaultConfigurationObjectTrait;
use MagicMethodsTrait;
/**
* @var string
*/
protected $name;
/**
* @var \ArrayObject<AbstractEmployee>
*/
protected $employees;
/**
* @return ServiceFactory
*/
public static function getConfigurationObjectServices()
{
return DefaultConfigurationObjectTrait::getConfigurationObjectServices()
->attach(ServiceInterface::SERVICE_MIXED_TYPES);
}
}
/**
* ABSTRACT EMPLOYEE
*/
abstract class AbstractEmployee implements MixedTypesInterface
{
use MagicMethodsTrait;
const TYPE_MECHANIC = Mechanic::class;
const TYPE_SECRETARY = Secretary::class;
/**
* @var array
*/
protected static $allowedTypes = [self::TYPE_MECHANIC, self::TYPE_SECRETARY];
/**
* @var string
*/
protected $name;
/**
* The employee doing his job.
*/
abstract public function work();
/**
* The employee talking.
*
* @param string $message
*/
public function talk($message)
{
echo $message;
}
/**
* @inheritdoc
*/
public static function getInstanceClassName(MixedTypesResolver $resolver)
{
$data = $resolver->getData();
if (in_array($data['type'], self::$allowedTypes)) {
$type = $data['type'];
$resolver->setObjectType($type);
} else {
$error = new Error(
'Type for this property is not correct, it should be one of the ' .
'following values: "'. implode('", "', self::$allowedTypes) .
'". Current value: "' . $data['type'] . '".',
1471871884
);
$resolver->addError($error);
}
}
}
/**
* MECHANIC EMPLOYEE
*/
class Mechanic extends AbstractEmployee
{
/**
* @inheritdoc
*/
public function work()
{
$sentence = 'Hello my name is "' . $this->getName() . '" and I am ' .
'currently repairing a car.';
$this->talk($sentence);
}
}
/**
* SECRETARY EMPLOYEE
*/
class Secretary extends AbstractEmployee
{
/**
* @inheritdoc
*/
public function work()
{
$sentence = 'Hello my name is "' . $this->getName() . '" and I am ' .
'currently organizing meetings.';
$this->talk($sentence);
}
}
$companyConfigurationArray = [
'name' => 'My Company',
'employees' => [
[
'name' => 'John Doe',
'type' => AbstractEmployee::TYPE_MECHANIC
],
[
'name' => 'Jane Doe',
'type' => AbstractEmployee::TYPE_SECRETARY
]
]
];
$myCompany = ConfigurationObjectFactory::convert(
Company::class,
$companyConfigurationArray
);
|