Passed
Push — develop ( ba2584...7c9857 )
by Armando
02:05 queued 10s
created

Entity::__call()   B

Complexity

Conditions 9
Paths 6

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 14
nc 6
nop 2
dl 0
loc 29
ccs 15
cts 15
cp 1
crap 9
rs 8.0555
c 0
b 0
f 0
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 10
                    return new $sub_entities[$property_name]($property, $this->getProperty('bot_username'));
142
                }
143
144 57
                return $property;
145
            }
146 3
        } elseif ($action === 'set') {
147
            // Limit setters to specific classes.
148 3
            if ($this instanceof InlineEntity || $this instanceof InputMedia || $this instanceof Keyboard || $this instanceof KeyboardButton) {
149 3
                $this->$property_name = $args[0];
150
151 3
                return $this;
152
            }
153
        }
154
155 29
        return null;
156
    }
157
158
    /**
159
     * Return an array of nice objects from an array of object arrays
160
     *
161
     * This method is used to generate pretty object arrays
162
     * mainly for PhotoSize and Entities object arrays.
163
     *
164
     * @param string $class
165
     * @param string $property
166
     *
167
     * @return array
168
     */
169 7
    protected function makePrettyObjectArray($class, $property)
170
    {
171 7
        $new_objects = [];
172
173
        try {
174 7
            if ($objects = $this->getProperty($property)) {
175 7
                foreach ($objects as $object) {
176 1
                    if (!empty($object)) {
177 1
                        $new_objects[] = new $class($object);
178
                    }
179
                }
180
            }
181
        } catch (Exception $e) {
182
            $new_objects = [];
183
        }
184
185 7
        return $new_objects;
186
    }
187
188
    /**
189
     * Escape markdown special characters
190
     *
191
     * @param string $string
192
     *
193
     * @return string
194
     */
195 1
    public function escapeMarkdown($string)
196
    {
197 1
        return str_replace(
198 1
            ['[', '`', '*', '_',],
199 1
            ['\[', '\`', '\*', '\_',],
200
            $string
201
        );
202
    }
203
204
    /**
205
     * Try to mention the user
206
     *
207
     * Mention the user with the username otherwise print first and last name
208
     * if the $escape_markdown argument is true special characters are escaped from the output
209
     *
210
     * @param bool $escape_markdown
211
     *
212
     * @return string|null
213
     */
214 3
    public function tryMention($escape_markdown = false)
215
    {
216
        //TryMention only makes sense for the User and Chat entity.
217 3
        if (!($this instanceof User || $this instanceof Chat)) {
218
            return null;
219
        }
220
221
        //Try with the username first...
222 3
        $name        = $this->getProperty('username');
223 3
        $is_username = $name !== null;
224
225 3
        if ($name === null) {
226
            //...otherwise try with the names.
227 3
            $name      = $this->getProperty('first_name');
228 3
            $last_name = $this->getProperty('last_name');
229 3
            if ($last_name !== null) {
230 3
                $name .= ' ' . $last_name;
231
            }
232
        }
233
234 3
        if ($escape_markdown) {
235 1
            $name = $this->escapeMarkdown($name);
236
        }
237
238 3
        return ($is_username ? '@' : '') . $name;
239
    }
240
}
241