Passed
Push — master ( 7f7158...8d1ed5 )
by Armando
02:55
created

Entity::__call()   B

Complexity

Conditions 10
Paths 7

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 10

Importance

Changes 0
Metric Value
cc 10
eloc 17
nc 7
nop 2
dl 0
loc 35
ccs 18
cts 18
cp 1
crap 10
rs 7.6666
c 0
b 0
f 0

How to fix   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 Longman\TelegramBot\Entities\InputMedia\InputMedia;
16
17
/**
18
 * Class Entity
19
 *
20
 * This is the base class for all entities.
21
 *
22
 * @link https://core.telegram.org/bots/api#available-types
23
 *
24
 * @method array  getRawData()     Get the raw data passed to this entity
25
 * @method string getBotUsername() Return the bot name passed to this entity
26
 */
27
abstract class Entity
28
{
29
    /**
30
     * Entity constructor.
31
     *
32
     * @todo Get rid of the $bot_username, it shouldn't be here!
33
     *
34
     * @param array  $data
35
     * @param string $bot_username
36
     */
37 77
    public function __construct($data, $bot_username = '')
38
    {
39
        //Make sure we're not raw_data inception-ing
40 77
        if (array_key_exists('raw_data', $data)) {
41 10
            if ($data['raw_data'] === null) {
42 10
                unset($data['raw_data']);
43
            }
44
        } else {
45 71
            $data['raw_data'] = $data;
46
        }
47
48 77
        $data['bot_username'] = $bot_username;
49 77
        $this->assignMemberVariables($data);
50 77
        $this->validate();
51 68
    }
52
53
    /**
54
     * Perform to json
55
     *
56
     * @return string
57
     */
58 1
    public function toJson()
59
    {
60 1
        return json_encode($this->getRawData());
61
    }
62
63
    /**
64
     * Perform to string
65
     *
66
     * @return string
67
     */
68
    public function __toString()
69
    {
70
        return $this->toJson();
71
    }
72
73
    /**
74
     * Helper to set member variables
75
     *
76
     * @param array $data
77
     */
78 77
    protected function assignMemberVariables(array $data)
79
    {
80 77
        foreach ($data as $key => $value) {
81 77
            $this->$key = $value;
82
        }
83 77
    }
84
85
    /**
86
     * Get the list of the properties that are themselves Entities
87
     *
88
     * @return array
89
     */
90 47
    protected function subEntities()
91
    {
92 47
        return [];
93
    }
94
95
    /**
96
     * Perform any special entity validation
97
     */
98 52
    protected function validate()
99
    {
100 52
    }
101
102
    /**
103
     * Get a property from the current Entity
104
     *
105
     * @param mixed $property
106
     * @param mixed $default
107
     *
108
     * @return mixed
109
     */
110 71
    public function getProperty($property, $default = null)
111
    {
112 71
        if (isset($this->$property)) {
113 66
            return $this->$property;
114
        }
115
116 43
        return $default;
117
    }
118
119
    /**
120
     * Return the variable for the called getter or magically set properties dynamically.
121
     *
122
     * @param $method
123
     * @param $args
124
     *
125
     * @return mixed|null
126
     */
127 58
    public function __call($method, $args)
128
    {
129
        //Convert method to snake_case (which is the name of the property)
130 58
        $property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($method, 3)), '_'));
131
132 58
        $action = substr($method, 0, 3);
133 58
        if ($action === 'get') {
134 58
            $property = $this->getProperty($property_name);
135
136 58
            if ($property !== null) {
137
                //Get all sub-Entities of the current Entity
138 55
                $sub_entities = $this->subEntities();
139
140 55
                if (isset($sub_entities[$property_name])) {
141 11
                    $class = $sub_entities[$property_name];
142
143 11
                    if (is_array($class)) {
144 1
                        return $this->makePrettyObjectArray(reset($class), $property_name);
145
                    }
146
147 10
                    return new $class($property, $this->getProperty('bot_username'));
148
                }
149
150 57
                return $property;
151
            }
152 3
        } elseif ($action === 'set') {
153
            // Limit setters to specific classes.
154 3
            if ($this instanceof InlineEntity || $this instanceof InputMedia || $this instanceof Keyboard || $this instanceof KeyboardButton) {
155 3
                $this->$property_name = $args[0];
156
157 3
                return $this;
158
            }
159
        }
160
161 29
        return null;
162
    }
163
164
    /**
165
     * Return an array of nice objects from an array of object arrays
166
     *
167
     * This method is used to generate pretty object arrays
168
     * mainly for PhotoSize and Entities object arrays.
169
     *
170
     * @param string $class
171
     * @param string $property
172
     *
173
     * @return array
174
     */
175 1
    protected function makePrettyObjectArray($class, $property)
176
    {
177 1
        $new_objects = [];
178
179
        try {
180 1
            if ($objects = $this->getProperty($property)) {
181 1
                foreach ($objects as $object) {
182 1
                    if (!empty($object)) {
183 1
                        $new_objects[] = new $class($object);
184
                    }
185
                }
186
            }
187
        } catch (Exception $e) {
188
            $new_objects = [];
189
        }
190
191 1
        return $new_objects;
192
    }
193
194
    /**
195
     * Escape markdown special characters
196
     *
197
     * @param string $string
198
     *
199
     * @return string
200
     */
201 1
    public function escapeMarkdown($string)
202
    {
203 1
        return str_replace(
204 1
            ['[', '`', '*', '_',],
205 1
            ['\[', '\`', '\*', '\_',],
206
            $string
207
        );
208
    }
209
210
    /**
211
     * Try to mention the user
212
     *
213
     * Mention the user with the username otherwise print first and last name
214
     * if the $escape_markdown argument is true special characters are escaped from the output
215
     *
216
     * @param bool $escape_markdown
217
     *
218
     * @return string|null
219
     */
220 3
    public function tryMention($escape_markdown = false)
221
    {
222
        //TryMention only makes sense for the User and Chat entity.
223 3
        if (!($this instanceof User || $this instanceof Chat)) {
224
            return null;
225
        }
226
227
        //Try with the username first...
228 3
        $name        = $this->getProperty('username');
229 3
        $is_username = $name !== null;
230
231 3
        if ($name === null) {
232
            //...otherwise try with the names.
233 3
            $name      = $this->getProperty('first_name');
234 3
            $last_name = $this->getProperty('last_name');
235 3
            if ($last_name !== null) {
236 3
                $name .= ' ' . $last_name;
237
            }
238
        }
239
240 3
        if ($escape_markdown) {
241 1
            $name = $this->escapeMarkdown($name);
242
        }
243
244 3
        return ($is_username ? '@' : '') . $name;
245
    }
246
}
247