AbstractObject::__toString()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 1
Metric Value
eloc 1
c 2
b 0
f 1
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * Copyright (c) 2018 - present
5
 * Google Maps PHP - AbstractObject.php
6
 * author: Roberto Belotti - [email protected]
7
 * web : robertobelotti.com, github.com/biscolab
8
 * Initial version created on: 5/9/2018
9
 * MIT license: https://github.com/biscolab/google-maps-php/blob/master/LICENSE
10
 */
11
12
namespace Biscolab\GoogleMaps\Abstracts;
13
14
use Biscolab\GoogleMaps\Exception\Exception;
15
use function Biscolab\GoogleMaps\camel2Snake;
16
17
/**
18
 * Class AbstractObject
19
 * @package Biscolab\GoogleMaps\Abstracts
20
 */
21
abstract class AbstractObject
22
{
23
24
	/**
25
	 * @var array
26
	 */
27
	protected $typeCheck = [];
28
29
	/**
30
	 * @var array
31
	 */
32
	protected $required = [];
33
34
	/**
35
	 * @var array
36
	 */
37
	protected $errors = [];
38
39
	/**
40
	 * AbstractObject constructor.
41
	 *
42
	 * @param array $args
43
	 */
44 25
	public function __construct(?array $args = [])
45
	{
46
47 25
		if (is_null($args)) {
0 ignored issues
show
introduced by
The condition is_null($args) is always false.
Loading history...
48
			$args = [];
49
		}
50
51 25
		$this->setArgs($args);
52 25
	}
53
54
	/**
55
	 * @param array $args
56
	 *
57
	 * @throws Exception
58
	 */
59 25
	protected function setArgs(array $args)
60
	{
61
62 25
		foreach ($this->typeCheck as $field_name => $field_type) {
63 25
			if (empty($args[$field_name]) || is_null($args[$field_name])) {
64 11
				if ($this->isFieldRequired($field_name)) {
65 11
					$this->addError('Missing "' . $field_name . '" in ' . static::class);
66
				}
67
			} else {
68 25
				$this->$field_name = $this->parseFieldValue($field_type, $args[$field_name]);
69
			}
70
		}
71 25
		$this->throwErrors();
72 25
	}
73
74
	/**
75
	 * @param string $field_name
76
	 *
77
	 * @return bool
78
	 */
79 11
	protected function isFieldRequired(string $field_name): bool
80
	{
81
82 11
		return in_array($field_name, $this->required);
83
	}
84
85
	/**
86
	 * @param string $error
87
	 *
88
	 * @return array
89
	 */
90
	protected function addError(string $error): array
91
	{
92
93
		array_push($this->errors, $error);
94
95
		return $this->errors;
96
	}
97
98
	/**
99
	 * @param string $field_type
100
	 * @param string $field_value
101
	 *
102
	 * @return mixed
103
	 */
104 25
	protected function parseFieldValue(string $field_type, $field_value)
105
	{
106
107
		switch ($field_type) {
108 25
			case 'string':
109 24
			case 'int':
110 22
			case 'float':
111 12
			case 'array':
112 9
			case 'json':
113 9
			case 'bool':
114 25
				return $field_value;
115
			default:
116 9
				return ($field_value instanceof $field_type) ? $field_value : new $field_type($field_value);
117
		}
118
	}
119
120
	/**
121
	 * @throws Exception
122
	 */
123 25
	protected function throwErrors()
124
	{
125
126 25
		if (count($this->errors)) {
127
			throw new Exception(implode(', ', $this->errors));
128
		}
129 25
	}
130
131
	/**
132
	 * @return string
133
	 */
134
	public function toJson(): string
135
	{
136
137
		return json_encode($this->toArray());
138
	}
139
140
	/**
141
	 * @return array
142
	 */
143 6
	public function toArray(): array
144
	{
145
146 6
		$fields = get_object_vars($this);
147
148 6
		foreach ($fields as $field_name => $field_value) {
149
150 6
			if (!is_scalar($field_value) && method_exists($field_value, 'toJson')) {
151 6
				$fields[$field_name] = $field_value->toArray();
152
			}
153
		}
154
155 6
		return $fields;
156
	}
157
158
	/**
159
	 * @return string
160
	 */
161
	public function __toString(): string
162
	{
163
164
		return implode(',', $this->toArray());
165
	}
166
167
	/**
168
	 * @param $name
169
	 * @param $arguments
170
	 *
171
	 * @return mixed
172
	 */
173 12
	public function __call($name, $arguments)
174
	{
175
176 12
		preg_match('/(?<=(g|s)et)([A-Za-z0-9])\w+/', $name, $match);
177
178 12
		$camel_field = (empty($match[0])) ? '' : $match[0];
179
180 12
		$snake_field = $this->getFieldName($camel_field);
181
182 12
		$field_type = (empty($this->typeCheck[$snake_field])) ? null : $this->typeCheck[$snake_field];
183
184 12
		if (!empty($match[1]) && $field_type) {
185 12
			switch ($match[1]) {
186 12
				case 's':
187 8
					return $this->$snake_field = $this->parseFieldValue($field_type, current($arguments));
188 8
				case 'g':
189 8
					return $this->$snake_field;
190
			}
191
		}
192
	}
193
194
	/**
195
	 * @param string $initial_field_name
196
	 *
197
	 * @return string
198
	 */
199 10
	protected function getFieldName(string $initial_field_name): string
200
	{
201
202 10
		return camel2Snake($initial_field_name);
203
	}
204
}
205