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 = []) |
|
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 | 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) |
|
150 | |||
151 | } |
||
152 |