Completed
Push — master ( 7f9d4c...0b1a65 )
by Peter
07:09
created

EmbeddedArrayDecorator::_getInstance()   C

Complexity

Conditions 12
Paths 31

Size

Total Lines 41

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 12.5669

Importance

Changes 0
Metric Value
dl 0
loc 41
ccs 16
cts 19
cp 0.8421
rs 6.9666
c 0
b 0
f 0
cc 12
nc 31
nop 5
crap 12.5669

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Decorators;
15
16
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
17
use Maslosoft\Mangan\Helpers\DbRefManager;
18
use Maslosoft\Mangan\Helpers\UnknownDocumentTypePanicker;
19
use Maslosoft\Mangan\Interfaces\Decorators\Property\DecoratorInterface;
20
use Maslosoft\Mangan\Interfaces\Transformators\TransformatorInterface;
21
22
/**
23
 * EmbeddedArrayDecorator
24
 *
25
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
26
 */
27
class EmbeddedArrayDecorator extends EmbeddedDecorator implements DecoratorInterface
28
{
29
30 9
	public function read($model, $name, &$dbValue, $transformatorClass = TransformatorInterface::class)
31
	{
32 9
		if (is_array($dbValue))
33
		{
34 9
			$docs = [];
35 9
			foreach ($dbValue as $key => $data)
36
			{
37 7
				static::ensureClass($model, $name, $data);
38
				// Set ensured class to $dbValue
39 7
				$instance = $this->_getInstance($model->$name, $dbValue, $data, $model, $name);
40 7
				$embedded = $transformatorClass::toModel($data, $instance, $instance, $model, $name);
41
42
				// Field was transformed from DB Ref
43 7
				$embedded = DbRefManager::maybeCreateInstanceFrom($embedded);
44
45 7
				$docs[] = $embedded;
46
			}
47 9
			$model->$name = $docs;
48
		}
49
		else
50
		{
51
			$model->$name = $dbValue;
52
		}
53 9
	}
54
55 9
	public function write($model, $name, &$dbValue, $transformatorClass = TransformatorInterface::class)
56
	{
57 9
		if (is_array($model->$name))
58
		{
59 9
			$dbValue[$name] = [];
60 9
			$key = 0;
61 9
			foreach ($model->$name as $key => $document)
62
			{
63 7
				$data = $transformatorClass::fromModel($document);
64 9
				$dbValue[$name][] = $data;
65
			}
66
		}
67
		else
68
		{
69
			$dbValue[$name] = $model->$name;
70
		}
71 9
	}
72
73
	/**
74
	 * TODO: This relies on _id
75
	 * @param AnnotatedInterface[] $instances
76
	 * @param mixed[] $dbValue
77
	 * @param mixed[] $data
78
	 * @return AnnotatedInterface|null
79
	 */
80 7
	private function _getInstance($instances, $dbValue, $data, $parent = null, $parentField = '')
81
	{
82 7
		if (!count($instances))
83
		{
84 6
			return null;
85
		}
86 3
		$map = [];
87
		/**
88
		 * TODO Workaround for manganel not having _id
89
		 */
90 3
		if (!isset($data['_id']) && isset($data['id']))
91
		{
92
			$data['_id'] = $data['id'];
93
		}
94 3
		foreach ($dbValue as $val)
95
		{
96
			/**
97
			 * TODO Workaround for manganel not having _id
98
			 */
99 3
			if (!isset($val['_id']) && isset($val['id']))
100
			{
101
				$val['_id'] = $val['id'];
102
			}
103 3
			if(empty($val['_class']))
104
			{
105
				UnknownDocumentTypePanicker::tryHandle($val, $parent, $parentField);
106
			}
107 3
			assert(array_key_exists('_id', $val), sprintf('_id not defined for %s', $val['_class']));
108 3
			$id = (string) $val['_id'];
109 3
			$map[$id] = true;
110
		}
111 3
		foreach ($instances as $instance)
112
		{
113 3
			$id = (string) $instance->_id;
114 3
			if (isset($map[$id]) && $data['_id'] == $id && $instance instanceof $data['_class'])
115
			{
116 3
				return $instance;
117
			}
118
		}
119 2
		return null;
120
	}
121
122
}
123