Passed
Push — master ( 4c2b59...061776 )
by Shahrad
02:09
created

Entity::__call()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 33
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 17
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 33
rs 9.0777
1
<?php
2
3
namespace TelegramBot;
4
5
/**
6
 * Entity class
7
 *
8
 * This is the base class for all entities.
9
 *
10
 * @link https://core.telegram.org/bots/api#available-types
11
 */
12
abstract class Entity
13
{
14
15
    /**
16
     * @var array The raw data passed to this entity
17
     */
18
    protected array $raw_data = [];
19
20
    /**
21
     * Entity constructor.
22
     *
23
     * @param ?array $data The raw data passed to this entity
24
     */
25
    public function __construct(?array $data)
26
    {
27
        if (!empty($data)) {
28
            $this->assignMemberVariables(($this->raw_data = $data));
29
            $this->validate();
30
        }
31
    }
32
33
    /**
34
     * Helper to set member variables
35
     *
36
     * @param array $data
37
     * @return void
38
     */
39
    protected function assignMemberVariables(array $data): void
40
    {
41
        foreach ($data as $key => $value) {
42
            $this->$key = $value;
43
        }
44
    }
45
46
    /**
47
     * Perform any special entity validation
48
     *
49
     * @return void
50
     */
51
    protected function validate(): void
52
    {
53
        // Do nothing by default
54
    }
55
56
    /**
57
     * Escape markdown (v1) special characters
58
     *
59
     * @see https://core.telegram.org/bots/api#markdown-style
60
     *
61
     * @param string $string
62
     *
63
     * @return string
64
     */
65
    public static function escapeMarkdown(string $string): string
66
    {
67
        return str_replace(
68
            ['[', '`', '*', '_',],
69
            ['\[', '\`', '\*', '\_',],
70
            $string
71
        );
72
    }
73
74
    /**
75
     * Escape markdown (v2) special characters
76
     *
77
     * @see https://core.telegram.org/bots/api#markdownv2-style
78
     *
79
     * @param string $string
80
     *
81
     * @return string
82
     */
83
    public static function escapeMarkdownV2(string $string): string
84
    {
85
        return str_replace(
86
            ['_', '*', '[', ']', '(', ')', '~', '`', '>', '#', '+', '-', '=', '|', '{', '}', '.', '!'],
87
            ['\_', '\*', '\[', '\]', '\(', '\)', '\~', '\`', '\>', '\#', '\+', '\-', '\=', '\|', '\{', '\}', '\.', '\!'],
88
            $string
89
        );
90
    }
91
92
    /**
93
     * Get the raw data passed to this entity
94
     *
95
     * @param bool $associated
96
     * @return array|string
97
     */
98
    public function getRawData(bool $associated = true): array|string
99
    {
100
        return $associated ? $this->raw_data : json_encode($this->raw_data);
101
    }
102
103
    /**
104
     * @param string $name The name of the property
105
     * @param array $arguments The arguments passed to the method
106
     * @return mixed
107
     */
108
    public function __call(string $name, array $arguments): mixed
109
    {
110
        if (method_exists($this, $name)) {
111
            return $this->{$name}(...$arguments);
112
        }
113
114
        if (str_starts_with($name, 'get')) {
115
            $property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
116
117
            $property = $this->getProperty($property_name);
118
            $sub_entities = $this->subEntities() ?? [];
119
120
            if (isset($sub_entities[$property_name])) {
121
                $class_name = $sub_entities[$property_name];
122
                return Factory::resolveEntityClass($class_name, $property);
123
            }
124
125
            return $property ?? null;
126
        }
127
128
        if (str_starts_with($name, 'set')) {
129
            $property_name = strtolower(ltrim(preg_replace('/[A-Z]/', '_$0', substr($name, 3)), '_'));
130
131
            if (property_exists($this, $property_name)) {
132
                $this->{$property_name} = $arguments[0];
133
                $this->raw_data[$property_name] = $arguments[0];
134
135
                return $this;
136
            }
137
138
        }
139
140
        throw new \BadMethodCallException("Method '$name' does not exist");
141
    }
142
143
    /**
144
     * Get a property from the current Entity
145
     *
146
     * @param string $property
147
     * @param mixed $default
148
     *
149
     * @return mixed
150
     */
151
    public function getProperty(string $property, mixed $default = null): mixed
152
    {
153
        return $this->raw_data[$property] ?? $default;
154
    }
155
156
    /**
157
     * Get the list of the properties that are themselves Entities
158
     *
159
     * @return array
160
     */
161
    protected function subEntities(): array
162
    {
163
        return [];
164
    }
165
166
}