Passed
Push — dev ( fad764...d2f61c )
by Marcin
09:22
created
src/Converter.php 1 patch
Indentation   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -23,27 +23,27 @@  discard block
 block discarded – undo
23 23
  */
24 24
 class Converter
25 25
 {
26
-    /** @var array */
27
-    protected $classes = [];
26
+	/** @var array */
27
+	protected $classes = [];
28 28
 
29
-    /** @var array */
30
-    protected $primitives = [];
29
+	/** @var array */
30
+	protected $primitives = [];
31 31
 
32
-    /** @var bool */
33
-    protected $debug_enabled = false;
32
+	/** @var bool */
33
+	protected $debug_enabled = false;
34 34
 
35
-    /**
36
-     * Converter constructor.
37
-     *
38
-     * @throws \RuntimeException
39
-     */
40
-    public function __construct()
41
-    {
42
-        $this->classes = static::getClassesMapping() ?? [];
43
-        $this->primitives = static::getPrimitivesMapping() ?? [];
35
+	/**
36
+	 * Converter constructor.
37
+	 *
38
+	 * @throws \RuntimeException
39
+	 */
40
+	public function __construct()
41
+	{
42
+		$this->classes = static::getClassesMapping() ?? [];
43
+		$this->primitives = static::getPrimitivesMapping() ?? [];
44 44
 
45
-	    $this->debug_enabled = Config::get(RB::CONF_KEY_DEBUG_CONVERTER_DEBUG_ENABLED, false);
46
-    }
45
+		$this->debug_enabled = Config::get(RB::CONF_KEY_DEBUG_CONVERTER_DEBUG_ENABLED, false);
46
+	}
47 47
 
48 48
 	/**
49 49
 	 * Returns "converter/primitives" entry for given primitive object or throws exception if no config found.
@@ -56,200 +56,200 @@  discard block
 block discarded – undo
56 56
 	 *
57 57
 	 * @throws \InvalidArgumentException
58 58
 	 */
59
-    protected function getPrimitiveMappingConfigOrThrow($data): array
60
-    {
61
-	    $result = null;
62
-
63
-	    $type = \gettype($data);
64
-	    $result = $this->primitives[ $type ] ?? null;
65
-	    if (!\is_array($result) && !empty($result)) {
66
-		    throw new \RuntimeException(sprintf('No data conversion mapping config for "%s" primitive.', $type));
67
-	    }
68
-
69
-	    if ($result === null) {
70
-		    throw new \RuntimeException(sprintf('No data conversion mapping configured for "%s" primitive.', $type));
71
-	    }
72
-
73
-	    if ($this->debug_enabled) {
74
-		    Log::debug(__CLASS__ . ": Converting primitive type of '{$type}' to data node '{$result[RB::KEY_KEY]}'.");
75
-	    }
76
-
77
-	    return $result;
78
-    }
79
-
80
-    /**
81
-     * Returns "converter/map" mapping configured for given $data object class or throws exception if not found.
82
-     * Throws \RuntimeException if there's no config "classes" mapping entry for this object configured.
83
-     * Throws \InvalidArgumentException if No data conversion mapping configured for given class.
84
-     *
85
-     * @param object $data Object to get config for.
86
-     *
87
-     * @return array
88
-     *
89
-     * @throws \InvalidArgumentException
90
-     */
91
-    protected function getClassMappingConfigOrThrow(object $data): array
92
-    {
93
-        $result = null;
94
-        $debug_result = '';
95
-
96
-        // check for exact class name match...
97
-        $cls = \get_class($data);
98
-        if (\is_string($cls)) {
99
-	        if (\array_key_exists($cls, $this->classes)) {
100
-		        $result = $this->classes[ $cls ];
101
-		        $debug_result = 'exact config match';
102
-	        } else {
103
-		        // no exact match, then lets try with `instanceof`
104
-		        foreach (\array_keys($this->classes) as $class_name) {
105
-			        if ($data instanceof $class_name) {
106
-				        $result = $this->classes[ $class_name ];
107
-				        $debug_result = "subclass of {$class_name}";
108
-				        break;
109
-			        }
110
-		        }
111
-	        }
112
-        }
113
-
114
-        if ($result === null) {
115
-            throw new \RuntimeException(sprintf('No data conversion mapping configured for "%s" class.', $cls));
116
-        }
117
-
118
-        if ($this->debug_enabled) {
59
+	protected function getPrimitiveMappingConfigOrThrow($data): array
60
+	{
61
+		$result = null;
62
+
63
+		$type = \gettype($data);
64
+		$result = $this->primitives[ $type ] ?? null;
65
+		if (!\is_array($result) && !empty($result)) {
66
+			throw new \RuntimeException(sprintf('No data conversion mapping config for "%s" primitive.', $type));
67
+		}
68
+
69
+		if ($result === null) {
70
+			throw new \RuntimeException(sprintf('No data conversion mapping configured for "%s" primitive.', $type));
71
+		}
72
+
73
+		if ($this->debug_enabled) {
74
+			Log::debug(__CLASS__ . ": Converting primitive type of '{$type}' to data node '{$result[RB::KEY_KEY]}'.");
75
+		}
76
+
77
+		return $result;
78
+	}
79
+
80
+	/**
81
+	 * Returns "converter/map" mapping configured for given $data object class or throws exception if not found.
82
+	 * Throws \RuntimeException if there's no config "classes" mapping entry for this object configured.
83
+	 * Throws \InvalidArgumentException if No data conversion mapping configured for given class.
84
+	 *
85
+	 * @param object $data Object to get config for.
86
+	 *
87
+	 * @return array
88
+	 *
89
+	 * @throws \InvalidArgumentException
90
+	 */
91
+	protected function getClassMappingConfigOrThrow(object $data): array
92
+	{
93
+		$result = null;
94
+		$debug_result = '';
95
+
96
+		// check for exact class name match...
97
+		$cls = \get_class($data);
98
+		if (\is_string($cls)) {
99
+			if (\array_key_exists($cls, $this->classes)) {
100
+				$result = $this->classes[ $cls ];
101
+				$debug_result = 'exact config match';
102
+			} else {
103
+				// no exact match, then lets try with `instanceof`
104
+				foreach (\array_keys($this->classes) as $class_name) {
105
+					if ($data instanceof $class_name) {
106
+						$result = $this->classes[ $class_name ];
107
+						$debug_result = "subclass of {$class_name}";
108
+						break;
109
+					}
110
+				}
111
+			}
112
+		}
113
+
114
+		if ($result === null) {
115
+			throw new \RuntimeException(sprintf('No data conversion mapping configured for "%s" class.', $cls));
116
+		}
117
+
118
+		if ($this->debug_enabled) {
119 119
 			Log::debug(__CLASS__ . ": Converting {$cls} using {$result[RB::KEY_HANDLER]} because: {$debug_result}.");
120
-        }
121
-
122
-	    return $result;
123
-    }
124
-
125
-    /**
126
-     * Main entry for data conversion
127
-     *
128
-     * @param object|array|null $data
129
-     *
130
-     * @return mixed|null
131
-     *
132
-     * @throws \InvalidArgumentException
133
-     */
134
-    public function convert($data = null): ?array
135
-    {
136
-        if ($data === null) {
137
-            return null;
138
-        }
139
-
140
-        $result = null;
141
-
142
-	    Validator::assertIsType('data', $data, [
143
-		    Type::ARRAY,
144
-		    Type::BOOLEAN,
145
-		    Type::DOUBLE,
146
-		    Type::INTEGER,
147
-		    Type::OBJECT,
148
-		    Type::STRING,
149
-	    ]);
150
-
151
-	    if ($result === null && \is_object($data)) {
152
-		    $cfg = $this->getClassMappingConfigOrThrow($data);
153
-		    $worker = new $cfg[ RB::KEY_HANDLER ]();
154
-		    $result = [$cfg[ RB::KEY_KEY ] => $worker->convert($data, $cfg)];
155
-	    }
156
-
157
-	    if ($result === null && \is_array($data)) {
158
-	        $cfg = $this->getPrimitiveMappingConfigOrThrow($data);
159
-
160
-		    $result = $this->convertArray($data);
161
-	        if (!Util::isArrayWithNonNumericKeys($data)){
162
-		        $result = [$cfg[ RB::KEY_KEY ] => $result];
163
-	        }
164
-        }
165
-
166
-	    if ( \is_bool($data) || \is_float($data) || \is_int($data) || \is_string($data)) {
167
-		    $result = [$this->getPrimitiveMappingConfigOrThrow($data)[ RB::KEY_KEY ] => $data];
168
-	    }
169
-
170
-	    return $result;
171
-    }
172
-
173
-    /**
174
-     * Recursively walks $data array and converts all known objects if found. Note
175
-     * $data array is passed by reference so source $data array may be modified.
176
-     *
177
-     * @param array $data array to recursively convert known elements of
178
-     *
179
-     * @return array
180
-     *
181
-     * @throws \RuntimeException
182
-     */
183
-    protected function convertArray(array $data): array
184
-    {
185
-        // This is to ensure that we either have array with user provided keys i.e. ['foo'=>'bar'], which will then
186
-        // be turned into JSON object or array without user specified keys (['bar']) which we would return as JSON
187
-        // array. But you can't mix these two as the final JSON would not produce predictable results.
188
-        $string_keys_cnt = 0;
189
-        $int_keys_cnt = 0;
190
-        foreach ($data as $key => $val) {
191
-            if (\is_int($key)) {
192
-                $int_keys_cnt++;
193
-            } else {
194
-                $string_keys_cnt++;
195
-            }
196
-
197
-            if (($string_keys_cnt > 0) && ($int_keys_cnt > 0)) {
198
-                throw new \RuntimeException(
199
-                    'Invalid data array. Either set own keys for all the items or do not specify any keys at all. ' .
200
-                    'Arrays with mixed keys are not supported by design.');
201
-            }
202
-        }
203
-
204
-        foreach ($data as $key => $val) {
205
-            if (\is_array($val)) {
206
-                $data[ $key ] = $this->convertArray($val);
207
-            } elseif (\is_object($val)) {
208
-                $cfg = $this->getClassMappingConfigOrThrow($val);
209
-                $worker = new $cfg[ RB::KEY_HANDLER ]();
210
-                $converted_data = $worker->convert($val, $cfg);
211
-                $data[ $key ] = $converted_data;
212
-            }
213
-        }
214
-
215
-        return $data;
216
-    }
217
-
218
-    /**
219
-     * Reads and validates "converter/map" config mapping
220
-     *
221
-     * @return array Classes mapping as specified in configuration or empty array if configuration found
222
-     *
223
-     * @throws \RuntimeException if config mapping is technically invalid (i.e. not array etc).
224
-     */
225
-    protected static function getClassesMapping(): array
226
-    {
227
-        $classes = Config::get(RB::CONF_KEY_CONVERTER_CLASSES) ?? [];
228
-
229
-	    if (!\is_array($classes)) {
230
-		    throw new \RuntimeException(
231
-			    \sprintf('CONFIG: "%s" mapping must be an array (%s found)', RB::CONF_KEY_CONVERTER_CLASSES, \gettype($classes)));
232
-	    }
233
-
234
-	    if (!empty($classes)) {
235
-		    $mandatory_keys = [
236
-			    RB::KEY_HANDLER,
237
-			    RB::KEY_KEY,
238
-		    ];
239
-		    foreach ($classes as $class_name => $class_config) {
240
-			    if (!\is_array($class_config)) {
241
-				    throw new \InvalidArgumentException(sprintf("CONFIG: Config for '{$class_name}' class must be an array (%s found).", \gettype($class_config)));
242
-			    }
243
-			    foreach ($mandatory_keys as $key_name) {
244
-				    if (!\array_key_exists($key_name, $class_config)) {
245
-					    throw new \RuntimeException("CONFIG: Missing '{$key_name}' entry in '{$class_name}' class mapping config.");
246
-				    }
247
-			    }
248
-		    }
249
-	    }
250
-
251
-        return $classes;
252
-    }
120
+		}
121
+
122
+		return $result;
123
+	}
124
+
125
+	/**
126
+	 * Main entry for data conversion
127
+	 *
128
+	 * @param object|array|null $data
129
+	 *
130
+	 * @return mixed|null
131
+	 *
132
+	 * @throws \InvalidArgumentException
133
+	 */
134
+	public function convert($data = null): ?array
135
+	{
136
+		if ($data === null) {
137
+			return null;
138
+		}
139
+
140
+		$result = null;
141
+
142
+		Validator::assertIsType('data', $data, [
143
+			Type::ARRAY,
144
+			Type::BOOLEAN,
145
+			Type::DOUBLE,
146
+			Type::INTEGER,
147
+			Type::OBJECT,
148
+			Type::STRING,
149
+		]);
150
+
151
+		if ($result === null && \is_object($data)) {
152
+			$cfg = $this->getClassMappingConfigOrThrow($data);
153
+			$worker = new $cfg[ RB::KEY_HANDLER ]();
154
+			$result = [$cfg[ RB::KEY_KEY ] => $worker->convert($data, $cfg)];
155
+		}
156
+
157
+		if ($result === null && \is_array($data)) {
158
+			$cfg = $this->getPrimitiveMappingConfigOrThrow($data);
159
+
160
+			$result = $this->convertArray($data);
161
+			if (!Util::isArrayWithNonNumericKeys($data)){
162
+				$result = [$cfg[ RB::KEY_KEY ] => $result];
163
+			}
164
+		}
165
+
166
+		if ( \is_bool($data) || \is_float($data) || \is_int($data) || \is_string($data)) {
167
+			$result = [$this->getPrimitiveMappingConfigOrThrow($data)[ RB::KEY_KEY ] => $data];
168
+		}
169
+
170
+		return $result;
171
+	}
172
+
173
+	/**
174
+	 * Recursively walks $data array and converts all known objects if found. Note
175
+	 * $data array is passed by reference so source $data array may be modified.
176
+	 *
177
+	 * @param array $data array to recursively convert known elements of
178
+	 *
179
+	 * @return array
180
+	 *
181
+	 * @throws \RuntimeException
182
+	 */
183
+	protected function convertArray(array $data): array
184
+	{
185
+		// This is to ensure that we either have array with user provided keys i.e. ['foo'=>'bar'], which will then
186
+		// be turned into JSON object or array without user specified keys (['bar']) which we would return as JSON
187
+		// array. But you can't mix these two as the final JSON would not produce predictable results.
188
+		$string_keys_cnt = 0;
189
+		$int_keys_cnt = 0;
190
+		foreach ($data as $key => $val) {
191
+			if (\is_int($key)) {
192
+				$int_keys_cnt++;
193
+			} else {
194
+				$string_keys_cnt++;
195
+			}
196
+
197
+			if (($string_keys_cnt > 0) && ($int_keys_cnt > 0)) {
198
+				throw new \RuntimeException(
199
+					'Invalid data array. Either set own keys for all the items or do not specify any keys at all. ' .
200
+					'Arrays with mixed keys are not supported by design.');
201
+			}
202
+		}
203
+
204
+		foreach ($data as $key => $val) {
205
+			if (\is_array($val)) {
206
+				$data[ $key ] = $this->convertArray($val);
207
+			} elseif (\is_object($val)) {
208
+				$cfg = $this->getClassMappingConfigOrThrow($val);
209
+				$worker = new $cfg[ RB::KEY_HANDLER ]();
210
+				$converted_data = $worker->convert($val, $cfg);
211
+				$data[ $key ] = $converted_data;
212
+			}
213
+		}
214
+
215
+		return $data;
216
+	}
217
+
218
+	/**
219
+	 * Reads and validates "converter/map" config mapping
220
+	 *
221
+	 * @return array Classes mapping as specified in configuration or empty array if configuration found
222
+	 *
223
+	 * @throws \RuntimeException if config mapping is technically invalid (i.e. not array etc).
224
+	 */
225
+	protected static function getClassesMapping(): array
226
+	{
227
+		$classes = Config::get(RB::CONF_KEY_CONVERTER_CLASSES) ?? [];
228
+
229
+		if (!\is_array($classes)) {
230
+			throw new \RuntimeException(
231
+				\sprintf('CONFIG: "%s" mapping must be an array (%s found)', RB::CONF_KEY_CONVERTER_CLASSES, \gettype($classes)));
232
+		}
233
+
234
+		if (!empty($classes)) {
235
+			$mandatory_keys = [
236
+				RB::KEY_HANDLER,
237
+				RB::KEY_KEY,
238
+			];
239
+			foreach ($classes as $class_name => $class_config) {
240
+				if (!\is_array($class_config)) {
241
+					throw new \InvalidArgumentException(sprintf("CONFIG: Config for '{$class_name}' class must be an array (%s found).", \gettype($class_config)));
242
+				}
243
+				foreach ($mandatory_keys as $key_name) {
244
+					if (!\array_key_exists($key_name, $class_config)) {
245
+						throw new \RuntimeException("CONFIG: Missing '{$key_name}' entry in '{$class_name}' class mapping config.");
246
+					}
247
+				}
248
+			}
249
+		}
250
+
251
+		return $classes;
252
+	}
253 253
 
254 254
 	/**
255 255
 	 * Reads and validates "converter/primitives" config mapping
Please login to merge, or discard this patch.