Completed
Push — feature/refactor-app-design ( 84f9ff...b18d21 )
by Avtandil
04:09
created

Entity::tryMention()   C

Complexity

Conditions 7
Paths 13

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7.0222

Importance

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