Completed
Push — master ( 2619a6...f0b1d8 )
by Peter
39:31 queued 14:37
created

Transformer::toModel()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4.0313

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 21
ccs 14
cts 16
cp 0.875
rs 9.0534
cc 4
eloc 11
nc 6
nop 3
crap 4.0313
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 83
	public static function fromModel(AnnotatedInterface $model, $fields = [])
41
	{
42 83
		$meta = ManganMeta::create($model);
43 83
		$calledClass = get_called_class();
44 83
		$decorator = new Decorator($model, $calledClass);
45 83
		$md = new ModelDecorator($model, $calledClass);
46 83
		$sanitizer = new Sanitizer($model, $calledClass);
47 83
		$filter = new Filter($model, $calledClass);
48 83
		$arr = [];
49 83
		foreach ($meta->fields() as $name => $fieldMeta)
50
		{
51 83
			if (!empty($fields) && !in_array($name, $fields))
52 83
			{
53 18
				continue;
54
			}
55 83
			if (!$filter->fromModel($model, $fieldMeta))
56 83
			{
57 29
				continue;
58
			}
59 83
			$model->$name = $sanitizer->write($name, $model->$name);
60 83
			$decorator->write($name, $arr);
61 83
		}
62 83
		$md->write($arr);
63 83
		return FinalizingManager::fromModel($arr, static::class, $model);
64
	}
65
66
	/**
67
	 * Create document from array
68
	 * TODO Enforce $className if collection is homogenous
69
	 * @param mixed[] $data
70
	 * @param string|object $className
71
	 * @param AnnotatedInterface $instance
72
	 * @return AnnotatedInterface
73
	 * @throws TransformatorException
74
	 */
75 58
	public static function toModel($data, $className = null, AnnotatedInterface $instance = null)
76
	{
77 58
		$data = (array) $data;
78 58
		if (is_object($className))
79
		{
80
			$className = get_class($className);
81 58
		}
82 58
		if (!$className)
83 58
		{
84 48
			if (array_key_exists('_class', $data))
85 48
			{
86 58
				$className = $data['_class'];
87 58
			}
88 27
			else
89 27
			{
90 27
				throw new TransformatorException('Could not determine document type');
91 27
			}
92
		}
93
		$model = self::_toDocument($className, $data, $instance);
94
		return FinalizingManager::toModel(static::class, $model);
95
	}
96 27
97 58
	private static function _toDocument($className, $data, $instance)
98 58
	{
99
		if ($instance)
100
		{
101 58
			$model = $instance;
102
		}
103
		else
104 58
		{
105 3
			$model = new $className;
106 3
		}
107
		$meta = ManganMeta::create($model);
108
		$calledClass = get_called_class();
109 55
		$decorator = new Decorator($model, $calledClass);
110
		$md = new ModelDecorator($model, $calledClass);
111 58
		$sanitizer = new Sanitizer($model, $calledClass);
112 58
		$filter = new Filter($model, $calledClass);
113 58
		foreach ($data as $name => $value)
114 58
		{
115 58
			$fieldMeta = $meta->$name;
116 58
			/* @var $fieldMeta DocumentPropertyMeta */
117 58
			if (!$fieldMeta)
118
			{
119 58
				continue;
120
			}
121 58
			if (!$filter->toModel($model, $fieldMeta))
122 58
			{
123 42
				continue;
124
			}
125 58
			$decorator->read($name, $value);
126 58
			$model->$name = $sanitizer->read($name, $model->$name);
127 17
		}
128
		$md->read($data);
129 58
		return $model;
130 58
	}
131 58
132
}
133