Passed
Branch master (41ef34)
by Roberto
04:08
created

AbstractObject::__call()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 18
c 0
b 0
f 0
rs 8.8333
cc 7
nc 16
nop 2
1
<?php
2
/**
3
 * Copyright (c) 2018 - present
4
 * Google Maps PHP - AbstractObject.php
5
 * author: Roberto Belotti - [email protected]
6
 * web : robertobelotti.com, github.com/biscolab
7
 * Initial version created on: 5/9/2018
8
 * MIT license: https://github.com/biscolab/google-maps-php/blob/master/LICENSE
9
 */
10
11
namespace Biscolab\GoogleMaps\Abstracts;
12
13
use Biscolab\GoogleMaps\Exception\Exception;
14
use function Biscolab\GoogleMaps\camel2Snake;
15
16
/**
17
 * Class AbstractObject
18
 * @package Biscolab\GoogleMaps\Abstracts
19
 */
20
abstract class AbstractObject {
21
22
	/**
23
	 * @var array
24
	 */
25
	protected $typeCheck = [];
26
27
	/**
28
	 * @var array
29
	 */
30
	protected $required = [];
31
32
	/**
33
	 * @var array
34
	 */
35
	protected $errors = [];
36
37
	/**
38
	 * AbstractObject constructor.
39
	 *
40
	 * @param array $args
41
	 */
42
	public function __construct(?array $args = []) {
43
44
		$this->setArgs($args);
0 ignored issues
show
Bug introduced by
It seems like $args can also be of type null; however, parameter $args of Biscolab\GoogleMaps\Abst...stractObject::setArgs() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

44
		$this->setArgs(/** @scrutinizer ignore-type */ $args);
Loading history...
45
	}
46
47
	/**
48
	 * @param array $args
49
	 *
50
	 * @throws Exception
51
	 */
52
	protected function setArgs(array $args) {
53
54
		foreach ($this->typeCheck as $field_name => $field_type) {
55
			if (empty($args[$field_name]) || is_null($args[$field_name])) {
56
				if ($this->isFieldRequired($field_name)) {
57
					$this->addError('Missing "' . $field_name . '" in ' . static::class);
58
				}
59
			} else {
60
				$this->$field_name = $this->parseFieldValue($field_type, $args[$field_name]);
61
			}
62
		}
63
		$this->throwErrors();
64
	}
65
66
	/**
67
	 * @param string $field_name
68
	 *
69
	 * @return bool
70
	 */
71
	protected function isFieldRequired(string $field_name): bool {
72
73
		return in_array($field_name, $this->required);
74
	}
75
76
	/**
77
	 * @param string $error
78
	 *
79
	 * @return array
80
	 */
81
	protected function addError(string $error): array {
82
83
		array_push($this->errors, $error);
84
85
		return $this->errors;
86
	}
87
88
	/**
89
	 * @param string $field_type
90
	 * @param string $field_value
91
	 *
92
	 * @return mixed
93
	 */
94
	protected function parseFieldValue(string $field_type, $field_value) {
95
96
		switch ($field_type) {
97
			case 'string':
98
			case 'int':
99
			case 'float':
100
			case 'array':
101
				return $field_value;
102
			default:
103
				return ($field_value instanceof $field_type) ? $field_value : new $field_type($field_value);
104
		}
105
	}
106
107
	/**
108
	 * @throws Exception
109
	 */
110
	protected function throwErrors() {
111
112
		if (count($this->errors)) {
113
			throw new Exception(implode(', ', $this->errors));
114
		}
115
	}
116
117
	/**
118
	 * @return string
119
	 */
120
	public function toJson(): string {
121
122
		return json_encode($this->toArray());
123
	}
124
125
	/**
126
	 * @return array
127
	 */
128
	public function toArray(): array {
129
130
		$fields = get_object_vars($this);
131
132
		foreach ($fields as $field_name => $field_value) {
133
134
			if (!is_scalar($field_value) && method_exists($field_value, 'toJson')) {
135
				$fields[$field_name] = $field_value->toArray();
136
			}
137
		}
138
139
		return $fields;
140
	}
141
142
	/**
143
	 * @return string
144
	 */
145
	public function __toString(): string {
146
147
		return implode(',', $this->toArray());
148
	}
149
150
	/**
151
	 * @param $name
152
	 * @param $arguments
153
	 *
154
	 * @return mixed
155
	 */
156
	public function __call($name, $arguments) {
157
158
		// TODO: Implement __call() method.
159
		$action = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $action is dead and can be removed.
Loading history...
160
		preg_match('/(?<=(g|s)et)([A-Za-z0-9])\w+/', $name, $match);
161
162
		$camel_field = (empty($match[0])) ? null : $match[0];
163
164
		$snake_field = camel2Snake($camel_field);
0 ignored issues
show
Bug introduced by
It seems like $camel_field can also be of type null; however, parameter $camel of Biscolab\GoogleMaps\camel2Snake() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
		$snake_field = camel2Snake(/** @scrutinizer ignore-type */ $camel_field);
Loading history...
165
166
		$field_type = (empty($this->typeCheck[$snake_field])) ? null : $this->typeCheck[$snake_field];
167
168
		if (!empty($match[1]) && $field_type) {
169
			switch ($match[1]) {
170
				case 's':
171
					return $this->$snake_field = $this->parseFieldValue($field_type, current($arguments));
172
				case 'g':
173
					return $this->$snake_field;
174
			}
175
		}
176
	}
177
178
}