Completed
Push — return_empty_array_for_items ( c77ccd )
by Armando
03:00
created

Entity::getProperty()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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