Completed
Push — master ( 0a999d...b4b35b )
by Peter
13:24 queued 02:45
created

Transformer   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 8

Test Coverage

Coverage 98.04%

Importance

Changes 0
Metric Value
wmc 16
lcom 0
cbo 8
dl 0
loc 121
ccs 50
cts 51
cp 0.9804
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B fromModel() 0 26 5
C toModel() 0 69 10
A getMeta() 0 4 1
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\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 112
	public static function fromModel(AnnotatedInterface $model, $fields = [])
41
	{
42 112
		$meta = static::getMeta($model);
43 112
		$calledClass = get_called_class();
44 112
		$decorator = new Decorator($model, $calledClass, $meta);
45 112
		$md = new ModelDecorator($model, $calledClass, $meta);
46 112
		$sanitizer = new Sanitizer($model, $calledClass, $meta);
47 112
		$filter = new Filter($model, $calledClass, $meta);
48 112
		$arr = [];
49 112
		foreach ($meta->fields() as $name => $fieldMeta)
50
		{
51 112
			if (!empty($fields) && !in_array($name, $fields))
52
			{
53 73
				continue;
54
			}
55 112
			if (!$filter->fromModel($model, $fieldMeta))
56
			{
57 36
				continue;
58
			}
59 112
			$model->$name = $sanitizer->write($name, $model->$name);
60 112
			$decorator->write($name, $arr);
61 112
			$model->$name = $sanitizer->read($name, $model->$name);
62
		}
63 112
		$md->write($arr);
64 112
		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 87
	public static function toModel($data, $className = null, AnnotatedInterface $instance = null)
77
	{
78 87
		$data = (array) $data;
79 87
		if (is_object($className))
80
		{
81 68
			$className = get_class($className);
82
		}
83 87
		if (!$className)
84
		{
85 44
			if (array_key_exists('_class', $data))
86
			{
87 42
				$className = $data['_class'];
88
			}
89
			else
90
			{
91 2
				if (null !== $instance)
92
				{
93 2
					$className = get_class($instance);
94
				}
95
				else
96
				{
97
					throw new TransformatorException('Could not determine document type');
98
				}
99
			}
100
		}
101 87
		if ($instance)
102
		{
103 8
			$model = $instance;
104
		}
105
		else
106
		{
107 83
			$model = new $className;
108
		}
109 87
		$meta = static::getMeta($model);
110 87
		$calledClass = get_called_class();
111 87
		$decorator = new Decorator($model, $calledClass, $meta);
112 87
		$md = new ModelDecorator($model, $calledClass, $meta);
113 87
		$sanitizer = new Sanitizer($model, $calledClass, $meta);
114 87
		$filter = new Filter($model, $calledClass, $meta);
115 87
		foreach ($meta->fields() as $name => $fieldMeta)
116
		{
117
			/* @var $fieldMeta DocumentPropertyMeta */
118 87
			if (array_key_exists($name, $data))
119
			{
120
				// Value is available in passed data
121 87
				$value = $data[$name];
122
			}
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
			}
129
			else
130
			{
131
				// As a last resort set to default
132 18
				$value = $fieldMeta->default;
133
			}
134 87
			if (!$filter->toModel($model, $fieldMeta))
135
			{
136 23
				continue;
137
			}
138 87
			$decorator->read($name, $value);
139 87
			$model->$name = $sanitizer->read($name, $model->$name);
140
		}
141 87
		$md->read($data);
142
143 87
		return FinalizingManager::toModel(static::class, $model);
144
	}
145
146 128
	protected static function getMeta(AnnotatedInterface $model)
147
	{
148 128
		return ManganMeta::create($model);
149
	}
150
151
}
152