1 | <?php |
||
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 | 112 | { |
|
53 | 73 | continue; |
|
54 | } |
||
55 | 112 | if (!$filter->fromModel($model, $fieldMeta)) |
|
56 | 112 | { |
|
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 | 112 | } |
|
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 | 87 | { |
|
81 | 68 | $className = get_class($className); |
|
82 | 68 | } |
|
83 | 87 | if (!$className) |
|
84 | 87 | { |
|
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 | 87 | { |
|
103 | 8 | $model = $instance; |
|
104 | 8 | } |
|
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 | 87 | { |
|
120 | // Value is available in passed data |
||
121 | 87 | $value = $data[$name]; |
|
122 | 87 | } |
|
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 | 18 | $value = $fieldMeta->default; |
|
133 | } |
||
134 | 87 | if (!$filter->toModel($model, $fieldMeta)) |
|
135 | 87 | { |
|
136 | 23 | continue; |
|
137 | } |
||
138 | 87 | $decorator->read($name, $value); |
|
139 | 87 | $model->$name = $sanitizer->read($name, $model->$name); |
|
140 | 87 | } |
|
141 | 87 | $md->read($data); |
|
142 | |||
143 | 87 | return FinalizingManager::toModel(static::class, $model); |
|
144 | } |
||
145 | |||
146 | 128 | protected static function getMeta(AnnotatedInterface $model) |
|
150 | |||
151 | } |
||
152 |