Completed
Push — master ( 79b3f6...e22a5e )
by Peter
11:15
created

Factory::createForField()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 40
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7.049

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 18
cts 20
cp 0.9
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 20
nc 5
nop 3
crap 7.049
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL or Commercial license.
5
 *
6
 * @package maslosoft/mangan
7
 * @licence AGPL or Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]>
9
 * @copyright Copyright (c) Maslosoft
10
 * @copyright Copyright (c) Others as mentioned in code
11
 * @link https://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Helpers\Decorator;
15
16
use Maslosoft\Mangan\Decorators\Undecorated;
17
use Maslosoft\Mangan\Exceptions\ManganException;
18
use Maslosoft\Mangan\Interfaces\Decorators\Model\ModelDecoratorInterface;
19
use Maslosoft\Mangan\Interfaces\Decorators\Property\DecoratorInterface;
20
use Maslosoft\Mangan\Mangan;
21
use Maslosoft\Mangan\Meta\DocumentPropertyMeta;
22
use Maslosoft\Mangan\Meta\DocumentTypeMeta;
23
use ReflectionClass;
24
25
/**
26
 * Factory for creating decorators
27
 *
28
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
29
 */
30
class Factory
31
{
32
33
	/**
34
	 * Decorator class names
35
	 * @var bool[][][]
36
	 */
37
	private static $configs = [];
38
39
	/**
40
	 * Model decorators
41
	 * @var ModelDecoratorInterface[]
42
	 */
43
	private static $modelDecorators = [];
44
45
	private static $c = [];
46
47
	/**
48
	 * Create decorator
49
	 * @param string $transformatorClass
50
	 * @param DocumentTypeMeta $modelMeta
51
	 * @param DocumentPropertyMeta $meta
52
	 * @return Undecorated|CompoundDecorator|DecoratorInterface
53
	 */
54 69
	public static function createForField($transformatorClass, DocumentTypeMeta $modelMeta, DocumentPropertyMeta $meta)
55
	{
56 69
		$key = $modelMeta->name . $modelMeta->connectionId . $meta->name . $transformatorClass;
57
58 69
		if(isset(self::$c[$key]))
59
		{
60
			return self::$c[$key];
61
		}
62
63 69
		if ($meta->decorators)
64
		{
65 39
			$activeDecorators = self::getManganDecorators($modelMeta->connectionId, $transformatorClass);
66 39
			$decorators = [];
67
			/**
68
			 * TODO This is workaround, it not should be required to do array_unique
69
			 * Further investigation needed
70
			 */
71 39
			if (!is_array($meta->decorators))
72
			{
73
				throw new ManganException('Meta `decorators` should be array');
74
			}
75 39
			foreach (array_unique($meta->decorators) as $decoratorName)
76
			{
77 39
				if (!isset($activeDecorators[$decoratorName]))
78
				{
79 23
					continue;
80
				}
81 30
				$decorators[] = new $decoratorName;
82
			}
83 39
			if ($decorators)
84
			{
85 30
				$decorator = new CompoundDecorator($decorators);
86 30
				self::$c[$key] = $decorator;
87 30
				return $decorator;
88
			}
89
		}
90 67
		$decorator = new Undecorated();
91 67
		self::$c[$key] = $decorator;
92 67
		return $decorator;
93
	}
94
95
	/**
96
	 * Create decorators for model. This returns all de
97
	 * @param string $transformatorClass
98
	 * @param DocumentTypeMeta $modelMeta
99
	 * @return CompoundModelDecorator
100
	 */
101 128
	public static function createForModel($transformatorClass, DocumentTypeMeta $modelMeta)
102
	{
103 128
		if (!isset(self::$modelDecorators[$modelMeta->connectionId]) || !isset(self::$modelDecorators[$modelMeta->connectionId][$transformatorClass]))
104
		{
105
106 6
			$decorators = [];
107 6
			foreach (self::getManganDecorators($modelMeta->connectionId, $transformatorClass) as $decoratorName => $active)
108
			{
109 6
				if ((new ReflectionClass($decoratorName))->implementsInterface(ModelDecoratorInterface::class))
110
				{
111 6
					$decorators[] = new $decoratorName;
112
				}
113
			}
114 6
			self::$modelDecorators[$modelMeta->connectionId][$transformatorClass] = new CompoundModelDecorator($decorators);
115
		}
116 128
		return self::$modelDecorators[$modelMeta->connectionId][$transformatorClass];
117
	}
118
119
	/**
120
	 * Get mangan decorators for selected connection id
121
	 * @param string $connectionId
122
	 * @param string $transformatorClass
123
	 * @return bool[]
124
	 */
125 42
	private static function getManganDecorators($connectionId, $transformatorClass)
126
	{
127 42
		if (!isset(self::$configs[$connectionId]))
128
		{
129 1
			self::$configs[$connectionId] = [];
130
		}
131 42
		if (!isset(self::$configs[$connectionId][$transformatorClass]))
132
		{
133 18
			self::$configs[$connectionId] = [];
134 18
			self::$configs[$connectionId][$transformatorClass] = [];
135 18
			$mangan = Mangan::fly($connectionId);
136 18
			$transformator = new $transformatorClass;
137 18
			foreach ($mangan->decorators as $implementer => $decoratorClasses)
138
			{
139 18
				foreach ($decoratorClasses as $decoratorClass)
140
				{
141 18
					if ($transformator instanceof $implementer)
142
					{
143 18
						self::$configs[$connectionId][$transformatorClass][$decoratorClass] = true;
144
					}
145
				}
146
			}
147
		}
148 42
		return self::$configs[$connectionId][$transformatorClass];
149
	}
150
151
}
152