Completed
Push — refactor_entities ( a4ea86...1ff9b4 )
by Armando
03:32
created

Entity::reflect()   C

Complexity

Conditions 20
Paths 30

Size

Total Lines 69
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 29.328

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 69
ccs 30
cts 42
cp 0.7143
rs 5.6072
cc 20
eloc 43
nc 30
nop 1
crap 29.328

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot\Entities;
12
13
use Exception;
14
use Longman\TelegramBot\Entities\InlineQuery\InlineEntity;
15
use ReflectionObject;
16
17
/**
18
 * Class Entity
19
 *
20
 * This is the base class for all entities.
21
 */
22
abstract class Entity
23
{
24
    /**
25
     * @var string
26
     */
27
    protected $bot_name;
28
29
    /**
30
     * Get bot name
31
     *
32
     * @return string
33
     */
34
    public function getBotName()
35
    {
36
        return $this->bot_name;
37
    }
38
39
    /**
40
     * Entity constructor.
41
     *
42
     * @todo Get rid of the $bot_name, it shouldn't be here!
43
     *
44
     * @param        $data
45
     * @param string $bot_name
46
     *
47
     * @throws \Longman\TelegramBot\Exception\TelegramException
48
     */
49 58
    public function __construct($data, $bot_name = '')
50
    {
51 58
        $this->assignMemberVariables($data);
52 58
        $this->validate();
53 49
        $this->bot_name = $bot_name;
54 49
    }
55
56
    /**
57
     * Perform to json
58
     *
59
     * @return string
60
     */
61 1
    public function toJson()
62
    {
63 1
        return json_encode($this->reflect($this));
64
    }
65
66
    /**
67
     * Reflect
68
     *
69
     * @param null $object
70
     *
71
     * @return array
72
     */
73 1
    public function reflect($object = null)
74
    {
75 1
        if ($object === null) {
76
            $object = $this;
77
        }
78
79 1
        $reflection = new ReflectionObject($object);
80 1
        $properties = $reflection->getProperties();
81
82 1
        $fields = [];
83
84 1
        foreach ($properties as $property) {
85 1
            $name = $property->getName();
86 1
            if ($name === 'bot_name') {
87 1
                continue;
88
            }
89
90 1
            if (!$property->isPrivate()) {
91 1
                $array_of_obj       = false;
92 1
                $array_of_array_obj = false;
93 1
                if (is_array($object->$name)) {
94 1
                    $array_of_obj       = true;
95 1
                    $array_of_array_obj = true;
96 1
                    foreach ($object->$name as $elm) {
97 1
                        if (!is_object($elm)) {
98
                            //echo $name . " not array of object \n";
99 1
                            $array_of_obj = false;
100
                            //break;
101
                        }
102 1
                        if (is_array($elm)) {
103 1
                            foreach ($elm as $more_net) {
104 1
                                if (!is_object($more_net)) {
105 1
                                    $array_of_array_obj = false;
106
                                }
107
                            }
108
                        }
109
                    }
110
                }
111
112 1
                if (is_object($object->$name)) {
113
                    $fields[$name] = $this->reflect($object->$name);
114 1
                } elseif ($array_of_obj) {
115
                    foreach ($object->$name as $elm) {
116
                        $fields[$name][] = $this->reflect($elm);
117
                    }
118 1
                } elseif ($array_of_array_obj) {
119
                    foreach ($object->$name as $elm) {
120
                        $temp = null;
121
                        if (!is_array($elm) && !is_object($elm)) {
122
                            continue;
123
                        }
124
                        foreach ($elm as $obj) {
125
                            $temp[] = $this->reflect($obj);
126
                        }
127
                        $fields[$name][] = $temp;
128
                    }
129
                } else {
130 1
                    $property->setAccessible(true);
131 1
                    $value = $property->getValue($object);
132 1
                    if (null === $value) {
133
                        continue;
134
                    }
135 1
                    $fields[$name] = $value;
136
                }
137
            }
138
        }
139
140 1
        return $fields;
141
    }
142
143
    /**
144
     * Perform to string
145
     *
146
     * @return string
147
     */
148
    public function __toString()
149
    {
150
        return $this->toJson();
151
    }
152
153
    /**
154
     * Helper to set member variables
155
     *
156
     * @param array $data
157
     */
158 58
    protected function assignMemberVariables(array $data)
159
    {
160 58
        foreach ($data as $key => $value) {
161 56
            $this->$key = $value;
162
        }
163 58
    }
164
165
    /**
166
     * Get the list of the properties that are themselves Entities
167
     *
168
     * @return array
169
     */
170 36
    protected function subEntities()
171
    {
172 36
        return [];
173
    }
174
175
    /**
176
     * Perform any special entity validation
177
     *
178
     * @throws \Longman\TelegramBot\Exception\TelegramException
179
     */
180 31
    protected function validate()
181
    {
182 31
    }
183
184
    /**
185
     * Get a property from the current Entity
186
     *
187
     * @param mixed $property
188
     * @param mixed $default
189
     *
190
     * @return mixed
191
     */
192 53
    public function getProperty($property, $default = null)
193
    {
194 53
        if (isset($this->$property)) {
195 51
            return $this->$property;
196
        }
197
198 37
        return $default;
199
    }
200
201
    /**
202
     * Return the variable for the called getter or magically set properties dynamically.
203
     *
204
     * @param $method
205
     * @param $args
206
     *
207
     * @return mixed|null
208
     */
209 39
    public function __call($method, $args)
210
    {
211
        //Convert method to snake_case (which is the name of the property)
212 39
        $property_name = ltrim(strtolower(preg_replace('/[A-Z]/', '_$0', substr($method, 3))), '_');
213
214 39
        $action = substr($method, 0, 3);
215 39
        if ($action === 'get') {
216 39
            $property = $this->getProperty($property_name);
217
218 39
            if ($property !== null) {
219
                //Get all sub-Entities of the current Entity
220 39
                $sub_entities = $this->subEntities();
221
222 39
                if (isset($sub_entities[$property_name])) {
223 15
                    return new $sub_entities[$property_name]($property);
224
                }
225
226 38
                return $property;
227
            }
228 3
        } elseif ($action === 'set') {
229
            // Limit setters to specific classes.
230 3
            if ($this instanceof InlineEntity || $this instanceof Keyboard || $this instanceof KeyboardButton) {
231 3
                $this->$property_name = $args[0];
232
233 3
                return $this;
234
            }
235
        }
236
237 23
        return null;
238
    }
239
240
    /**
241
     * Return an array of nice objects from an array of object arrays
242
     *
243
     * This method is used to generate pretty object arrays
244
     * mainly for PhotoSize and Entities object arrays.
245
     *
246
     * @param string $class
247
     * @param string $property
248
     *
249
     * @return array
250
     */
251 6
    protected function makePrettyObjectArray($class, $property)
252
    {
253 6
        $new_objects = [];
254
255
        try {
256 6
            if ($objects = $this->getProperty($property)) {
257
                foreach ($objects as $object) {
258
                    if (!empty($object)) {
259 6
                        $new_objects[] = new $class($object);
260
                    }
261
                }
262
            }
263
        } catch (Exception $e) {
264
            $new_objects = [];
265
        }
266
267 6
        return $new_objects;
268
    }
269
270
    /**
271
     * Escape markdown special characters
272
     *
273
     * @param string $string
274
     *
275
     * @return string
276
     */
277 1
    public function escapeMarkdown($string)
278
    {
279 1
        return str_replace(
280 1
            ['[', '`', '*', '_',],
281 1
            ['\[', '\`', '\*', '\_',],
282
            $string
283
        );
284
    }
285
286
    /**
287
     * Try to mention the user
288
     *
289
     * Mention the user with the username otherwise print first and last name
290
     * if the $escape_markdown argument is true special characters are escaped from the output
291
     *
292
     * @param bool $escape_markdown
293
     *
294
     * @return string|null
295
     */
296 3
    public function tryMention($escape_markdown = false)
297
    {
298
        //TryMention only makes sense for the User and Chat entity.
299 3
        if (!($this instanceof User || $this instanceof Chat)) {
300
            return null;
301
        }
302
303
        //Try with the username first...
304 3
        $name = $this->getProperty('username');
305 3
        $is_username = $name !== null;
306
307 3
        if ($name === null) {
308
            //...otherwise try with the names.
309 3
            $name      = $this->getProperty('first_name');
310 3
            $last_name = $this->getProperty('last_name');
311 3
            if ($last_name !== null) {
312 3
                $name .= ' ' . $last_name;
313
            }
314
        }
315
316 3
        if ($escape_markdown) {
317 1
            $name = $this->escapeMarkdown($name);
318
        }
319
320 3
        return ($is_username ? '@' : '') . $name;
321
    }
322
}
323