Completed
Push — master ( 971f99...10707b )
by Peter
07:20 queued 02:39
created

Transformer   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 8

Test Coverage

Coverage 97.92%

Importance

Changes 5
Bugs 2 Features 0
Metric Value
wmc 15
lcom 0
cbo 8
dl 0
loc 115
ccs 47
cts 48
cp 0.9792
rs 10
c 5
b 2
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B fromModel() 0 25 5
C toModel() 0 69 10
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 = ManganMeta::create($model);
43 107
		$calledClass = get_called_class();
44 107
		$decorator = new Decorator($model, $calledClass);
45 107
		$md = new ModelDecorator($model, $calledClass);
46 107
		$sanitizer = new Sanitizer($model, $calledClass);
47 107
		$filter = new Filter($model, $calledClass);
48 107
		$arr = [];
49 107
		foreach ($meta->fields() as $name => $fieldMeta)
50
		{
51 107
			if (!empty($fields) && !in_array($name, $fields))
52
			{
53 28
				continue;
54
			}
55 107
			if (!$filter->fromModel($model, $fieldMeta))
56
			{
57 36
				continue;
58
			}
59 107
			$model->$name = $sanitizer->write($name, $model->$name);
60 107
			$decorator->write($name, $arr);
61
		}
62 107
		$md->write($arr);
63 107
		return FinalizingManager::fromModel($arr, static::class, $model);
64
	}
65
66
	/**
67
	 * Create document from array
68
	 *
69
	 * @param mixed[] $data
70
	 * @param string|object $className
71
	 * @param AnnotatedInterface $instance
72
	 * @return AnnotatedInterface
73
	 * @throws TransformatorException
74
	 */
75 82
	public static function toModel($data, $className = null, AnnotatedInterface $instance = null)
76
	{
77 82
		$data = (array) $data;
78 82
		if (is_object($className))
79
		{
80 65
			$className = get_class($className);
81
		}
82 82
		if (!$className)
83
		{
84 42
			if (array_key_exists('_class', $data))
85
			{
86 40
				$className = $data['_class'];
87
			}
88
			else
89
			{
90 2
				if (null !== $instance)
91
				{
92 2
					$className = get_class($instance);
93
				}
94
				else
95
				{
96
					throw new TransformatorException('Could not determine document type');
97
				}
98
			}
99
		}
100 82
		if ($instance)
101
		{
102 8
			$model = $instance;
103
		}
104
		else
105
		{
106 78
			$model = new $className;
107
		}
108 82
		$meta = ManganMeta::create($model);
109 82
		$calledClass = get_called_class();
110 82
		$decorator = new Decorator($model, $calledClass);
111 82
		$md = new ModelDecorator($model, $calledClass);
112 82
		$sanitizer = new Sanitizer($model, $calledClass);
113 82
		$filter = new Filter($model, $calledClass);
114 82
		foreach ($meta->fields() as $name => $fieldMeta)
115
		{
116
			/* @var $fieldMeta DocumentPropertyMeta */
117 82
			if (array_key_exists($name, $data))
118
			{
119
				// Value is available in passed data
120 82
				$value = $data[$name];
121
			}
122 22
			elseif (!empty($instance))
123
			{
124
				// Take value from existing instance
125
				// NOTE: We could `continue` here but value should be sanitized anyway
126 5
				$value = $model->$name;
127
			}
128
			else
129
			{
130
				// As a last resort set to default
131 20
				$value = $fieldMeta->default;
132
			}
133 82
			if (!$filter->toModel($model, $fieldMeta))
134
			{
135 23
				continue;
136
			}
137 82
			$decorator->read($name, $value);
138 82
			$model->$name = $sanitizer->read($name, $model->$name);
139
		}
140 82
		$md->read($data);
141
142 82
		return FinalizingManager::toModel(static::class, $model);
143
	}
144
145
}
146