Completed
Push — master ( 6fb532...fb357f )
by Peter
10:26 queued 03:50
created

Transformer::toModel()   C

Complexity

Conditions 10
Paths 86

Size

Total Lines 69
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 10.001

Importance

Changes 0
Metric Value
dl 0
loc 69
ccs 44
cts 45
cp 0.9778
rs 6.0493
c 0
b 0
f 0
cc 10
eloc 35
nc 86
nop 3
crap 10.001

How to fix   Long Method    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 http://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Transformers;
15
16
use Maslosoft\Addendum\Interfaces\AnnotatedInterface;
17
use Maslosoft\Mangan\Exceptions\TransformatorException;
18
use Maslosoft\Mangan\Helpers\Decorator\Decorator;
19
use Maslosoft\Mangan\Helpers\Decorator\ModelDecorator;
20
use Maslosoft\Mangan\Helpers\Finalizer\FinalizingManager;
21
use Maslosoft\Mangan\Helpers\PropertyFilter\Filter;
22
use Maslosoft\Mangan\Helpers\Sanitizer\Sanitizer;
23
use Maslosoft\Mangan\Meta\DocumentPropertyMeta;
24
use Maslosoft\Mangan\Meta\ManganMeta;
25
26
/**
27
 * Transformer
28
 *
29
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
30
 */
31
abstract class Transformer
32
{
33
34
	/**
35
	 * Returns the given object as an associative array
36
	 * @param AnnotatedInterface|object $model
37
	 * @param string[] $fields Fields to transform
38
	 * @return array an associative array of the contents of this object
39
	 */
40 107
	public static function fromModel(AnnotatedInterface $model, $fields = [])
41
	{
42 107
		$meta = static::getMeta($model);
43 107
		$calledClass = get_called_class();
44 107
		$decorator = new Decorator($model, $calledClass, $meta);
45 107
		$md = new ModelDecorator($model, $calledClass, $meta);
46 107
		$sanitizer = new Sanitizer($model, $calledClass, $meta);
47 107
		$filter = new Filter($model, $calledClass, $meta);
48 107
		$arr = [];
49 107
		foreach ($meta->fields() as $name => $fieldMeta)
50
		{
51 107
			if (!empty($fields) && !in_array($name, $fields))
52 107
			{
53 28
				continue;
54
			}
55 107
			if (!$filter->fromModel($model, $fieldMeta))
56 107
			{
57 36
				continue;
58
			}
59 107
			$model->$name = $sanitizer->write($name, $model->$name);
60 107
			$decorator->write($name, $arr);
61 107
			$model->$name = $sanitizer->read($name, $model->$name);
62 107
		}
63 107
		$md->write($arr);
64 107
		return FinalizingManager::fromModel($arr, static::class, $model);
65
	}
66
67
	/**
68
	 * Create document from array
69
	 *
70
	 * @param mixed[] $data
71
	 * @param string|object $className
72
	 * @param AnnotatedInterface $instance
73
	 * @return AnnotatedInterface
74
	 * @throws TransformatorException
75
	 */
76 84
	public static function toModel($data, $className = null, AnnotatedInterface $instance = null)
77
	{
78 84
		$data = (array) $data;
79 84
		if (is_object($className))
80 84
		{
81 65
			$className = get_class($className);
82 65
		}
83 84
		if (!$className)
84 84
		{
85 44
			if (array_key_exists('_class', $data))
86 44
			{
87 42
				$className = $data['_class'];
88 42
			}
89
			else
90
			{
91 2
				if (null !== $instance)
92 2
				{
93 2
					$className = get_class($instance);
94 2
				}
95
				else
96
				{
97
					throw new TransformatorException('Could not determine document type');
98
				}
99
			}
100 44
		}
101
		if ($instance)
102 84
		{
103 8
			$model = $instance;
104 8
		}
105
		else
106
		{
107 80
			$model = new $className;
108
		}
109 84
		$meta = static::getMeta($model);
110 84
		$calledClass = get_called_class();
111 84
		$decorator = new Decorator($model, $calledClass, $meta);
112 84
		$md = new ModelDecorator($model, $calledClass, $meta);
113 84
		$sanitizer = new Sanitizer($model, $calledClass, $meta);
114 84
		$filter = new Filter($model, $calledClass, $meta);
115 84
		foreach ($meta->fields() as $name => $fieldMeta)
116
		{
117
			/* @var $fieldMeta DocumentPropertyMeta */
118 84
			if (array_key_exists($name, $data))
119 84
			{
120
				// Value is available in passed data
121 84
				$value = $data[$name];
122 84
			}
123 22
			elseif (!empty($instance))
124
			{
125
				// Take value from existing instance
126
				// NOTE: We could `continue` here but value should be sanitized anyway
127 5
				$value = $model->$name;
128 5
			}
129
			else
130
			{
131
				// As a last resort set to default
132 20
				$value = $fieldMeta->default;
133
			}
134 84
			if (!$filter->toModel($model, $fieldMeta))
135 84
			{
136 23
				continue;
137
			}
138 84
			$decorator->read($name, $value);
139 84
			$model->$name = $sanitizer->read($name, $model->$name);
140 84
		}
141 84
		$md->read($data);
142
143 84
		return FinalizingManager::toModel(static::class, $model);
144
	}
145
146 123
	protected static function getMeta(AnnotatedInterface $model)
147
	{
148 123
		return ManganMeta::create($model);
149
	}
150
151
}
152