|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
/* |
|
4
|
|
|
* This file is part of the overtrue/easy-sms. |
|
5
|
|
|
* (c) overtrue <[email protected]> |
|
6
|
|
|
* This source file is subject to the MIT license that is bundled |
|
7
|
|
|
* with this source code in the file LICENSE. |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
namespace Overtrue\EasySms; |
|
11
|
|
|
|
|
12
|
|
|
use Closure; |
|
13
|
|
|
use InvalidArgumentException; |
|
14
|
|
|
use Overtrue\EasySms\Contracts\GatewayInterface; |
|
15
|
|
|
use Overtrue\EasySms\Contracts\MessageInterface; |
|
16
|
|
|
use Overtrue\EasySms\Support\Config; |
|
17
|
|
|
use RuntimeException; |
|
18
|
|
|
|
|
19
|
|
|
/** |
|
20
|
|
|
* Class EasySms. |
|
21
|
|
|
*/ |
|
22
|
|
|
class EasySms |
|
23
|
|
|
{ |
|
24
|
|
|
/** |
|
25
|
|
|
* @var \Overtrue\EasySms\Support\Config |
|
26
|
|
|
*/ |
|
27
|
|
|
protected $config; |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* @var string |
|
31
|
|
|
*/ |
|
32
|
|
|
protected $defaultGateway; |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* @var array |
|
36
|
|
|
*/ |
|
37
|
|
|
protected $customCreators = []; |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* @var array |
|
41
|
|
|
*/ |
|
42
|
|
|
protected $gateways = []; |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* @var \Overtrue\EasySms\Messenger |
|
46
|
|
|
*/ |
|
47
|
|
|
protected $messenger; |
|
48
|
|
|
|
|
49
|
|
|
/** |
|
50
|
|
|
* Constructor. |
|
51
|
|
|
* |
|
52
|
|
|
* @param array $config |
|
53
|
|
|
*/ |
|
54
|
|
|
public function __construct(array $config) |
|
55
|
|
|
{ |
|
56
|
|
|
$this->config = new Config($config); |
|
57
|
|
|
|
|
58
|
|
|
if (!empty($config['default'])) { |
|
59
|
|
|
$this->setDefaultGateway($config['default']); |
|
60
|
|
|
} |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* Send a message. |
|
65
|
|
|
* |
|
66
|
|
|
* @param string|array $to |
|
67
|
|
|
* @param \Overtrue\EasySms\Contracts\MessageInterface $message |
|
68
|
|
|
* |
|
69
|
|
|
* @return array |
|
70
|
|
|
*/ |
|
71
|
|
|
public function send($to, $message) |
|
72
|
|
|
{ |
|
73
|
|
|
$messenger = $this->getMessenger(); |
|
74
|
|
|
|
|
75
|
|
|
return $messenger->send($to, $message, $this->getMessageGateways($message)); |
|
|
|
|
|
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
/** |
|
79
|
|
|
* Create a gateway. |
|
80
|
|
|
* |
|
81
|
|
|
* @param string $name |
|
82
|
|
|
* |
|
83
|
|
|
* @return \Overtrue\EasySms\Contracts\GatewayInterface |
|
84
|
|
|
*/ |
|
85
|
|
|
public function gateway($name = null) |
|
86
|
|
|
{ |
|
87
|
|
|
$name = $name ?: $this->getDefaultGateway(); |
|
88
|
|
|
|
|
89
|
|
|
if (!isset($this->gateways[$name])) { |
|
90
|
|
|
$this->gateways[$name] = $this->createGateway($name); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
return $this->gateways[$name]; |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* Register a custom driver creator Closure. |
|
98
|
|
|
* |
|
99
|
|
|
* @param string $name |
|
100
|
|
|
* @param \Closure $callback |
|
101
|
|
|
* |
|
102
|
|
|
* @return $this |
|
103
|
|
|
*/ |
|
104
|
|
|
public function extend($name, Closure $callback) |
|
105
|
|
|
{ |
|
106
|
|
|
$this->customCreators[$name] = $callback; |
|
107
|
|
|
|
|
108
|
|
|
return $this; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Get default gateway name. |
|
113
|
|
|
* |
|
114
|
|
|
* @return string |
|
115
|
|
|
* |
|
116
|
|
|
* @throws if no default gateway configured |
|
117
|
|
|
*/ |
|
118
|
|
|
public function getDefaultGateway() |
|
119
|
|
|
{ |
|
120
|
|
|
if (empty($this->defaultGateway)) { |
|
121
|
|
|
throw new RuntimeException('No default gateway configured.'); |
|
122
|
|
|
} |
|
123
|
|
|
|
|
124
|
|
|
return $this->defaultGateway; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
/** |
|
128
|
|
|
* Set default gateway name. |
|
129
|
|
|
* |
|
130
|
|
|
* @param string $name |
|
131
|
|
|
* |
|
132
|
|
|
* @return $this |
|
133
|
|
|
*/ |
|
134
|
|
|
public function setDefaultGateway($name) |
|
135
|
|
|
{ |
|
136
|
|
|
$this->defaultGateway = $name; |
|
137
|
|
|
|
|
138
|
|
|
return $this; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* @return \Overtrue\EasySms\Messenger |
|
143
|
|
|
*/ |
|
144
|
|
|
public function getMessenger() |
|
145
|
|
|
{ |
|
146
|
|
|
return $this->messenger ?: $this->messenger = new Messenger($this); |
|
|
|
|
|
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
/** |
|
150
|
|
|
* @param \Overtrue\EasySms\Contracts\MessageInterface $message |
|
151
|
|
|
* |
|
152
|
|
|
* @return array |
|
153
|
|
|
*/ |
|
154
|
|
|
protected function getMessageGateways(MessageInterface $message) |
|
155
|
|
|
{ |
|
156
|
|
|
$gateways = []; |
|
157
|
|
|
|
|
158
|
|
|
foreach ($message->getGateways() as $gateway => $setting) { |
|
159
|
|
|
if (is_integer($gateway) && is_string($setting)) { |
|
160
|
|
|
$gateway = $setting; |
|
161
|
|
|
$setting = []; |
|
162
|
|
|
} |
|
163
|
|
|
$globalSetting = $this->config->get("gateways.{$gateway}", []); |
|
164
|
|
|
|
|
165
|
|
|
if (is_string($gateway) && !empty($globalSetting)) { |
|
166
|
|
|
$gateways[$gateway] = array_merge($globalSetting, (array) $setting); |
|
167
|
|
|
} |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
if ($this->config->get('shuffle_gateways')) { |
|
171
|
|
|
uasort($gateways, function () { |
|
172
|
|
|
return mt_rand() - mt_rand(); |
|
173
|
|
|
}); |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
return $gateways; |
|
177
|
|
|
} |
|
178
|
|
|
|
|
179
|
|
|
/** |
|
180
|
|
|
* Create a new driver instance. |
|
181
|
|
|
* |
|
182
|
|
|
* @param string $name |
|
183
|
|
|
* |
|
184
|
|
|
* @throws \InvalidArgumentException |
|
185
|
|
|
* |
|
186
|
|
|
* @return GatewayInterface |
|
187
|
|
|
*/ |
|
188
|
|
|
protected function createGateway($name) |
|
189
|
|
|
{ |
|
190
|
|
|
if (isset($this->customCreators[$name])) { |
|
191
|
|
|
$gateway = $this->callCustomCreator($name); |
|
192
|
|
|
} else { |
|
193
|
|
|
$className = $this->formatGatewayClassName($name); |
|
194
|
|
|
$gateway = $this->makeGateway($className, $this->config->get("gateways.{$name}", [])); |
|
195
|
|
|
} |
|
196
|
|
|
|
|
197
|
|
|
if (!($gateway instanceof GatewayInterface)) { |
|
198
|
|
|
throw new InvalidArgumentException(sprintf('Gateway "%s" not inherited from %s.', $name, GatewayInterface::class)); |
|
199
|
|
|
} |
|
200
|
|
|
|
|
201
|
|
|
return $gateway; |
|
202
|
|
|
} |
|
203
|
|
|
|
|
204
|
|
|
/** |
|
205
|
|
|
* Make gateway instance. |
|
206
|
|
|
* |
|
207
|
|
|
* @param string $gateway |
|
208
|
|
|
* @param array $config |
|
209
|
|
|
* |
|
210
|
|
|
* @return \Overtrue\EasySms\Contracts\GatewayInterface |
|
211
|
|
|
*/ |
|
212
|
|
|
protected function makeGateway($gateway, $config) |
|
213
|
|
|
{ |
|
214
|
|
|
if (!class_exists($gateway)) { |
|
215
|
|
|
throw new InvalidArgumentException(sprintf('Gateway "%s" not exists.', $gateway)); |
|
216
|
|
|
} |
|
217
|
|
|
|
|
218
|
|
|
return new $gateway($config); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** |
|
222
|
|
|
* Format gateway name. |
|
223
|
|
|
* |
|
224
|
|
|
* @param string $name |
|
225
|
|
|
* |
|
226
|
|
|
* @return string |
|
227
|
|
|
*/ |
|
228
|
|
|
protected function formatGatewayClassName($name) |
|
229
|
|
|
{ |
|
230
|
|
|
if (class_exists($name)) { |
|
231
|
|
|
return $name; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
$name = ucfirst(str_replace(['-', '_', ''], '', $name)); |
|
235
|
|
|
|
|
236
|
|
|
return __NAMESPACE__."\\Gateways\\{$name}Gateway"; |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
/** |
|
240
|
|
|
* Call a custom gateway creator. |
|
241
|
|
|
* |
|
242
|
|
|
* @param string $gateway |
|
243
|
|
|
* |
|
244
|
|
|
* @return mixed |
|
245
|
|
|
*/ |
|
246
|
|
|
protected function callCustomCreator($gateway) |
|
247
|
|
|
{ |
|
248
|
|
|
return call_user_func($this->customCreators[$gateway], $this->config->get($gateway, [])); |
|
249
|
|
|
} |
|
250
|
|
|
|
|
251
|
|
|
/** |
|
252
|
|
|
* Dynamically call the default gateway instance. |
|
253
|
|
|
* |
|
254
|
|
|
* @param string $method |
|
255
|
|
|
* @param array $parameters |
|
256
|
|
|
* |
|
257
|
|
|
* @return mixed |
|
258
|
|
|
*/ |
|
259
|
|
|
public function __call($method, $parameters) |
|
260
|
|
|
{ |
|
261
|
|
|
return call_user_func_array([$this->gateway(), $method], $parameters); |
|
262
|
|
|
} |
|
263
|
|
|
} |
|
264
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.