Completed
Push — master ( 24eb80...35cbfd )
by lan tian
02:46
created

Sms::content()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4286
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Toplan\PhpSms;
4
5
use Toplan\TaskBalance\Balancer;
6
7
/**
8
 * Class Sms
9
 */
10
class Sms
11
{
12
    /**
13
     * sms send task name
14
     */
15
    const TASK = 'PhpSms';
16
17
    /**
18
     * log agent`s name
19
     */
20
    const LOG_AGENT = 'Log';
21
22
    /**
23
     * agents instance
24
     */
25
    protected static $agents;
26
27
    /**
28
     * agents`s name
29
     *
30
     * @var
31
     */
32
    protected static $agentsName = [];
33
34
    /**
35
     * agents`s config
36
     *
37
     * @var
38
     */
39
    protected static $agentsConfig = [];
40
41
    /**
42
     * whether to enable queue
43
     *
44
     * @var bool
45
     */
46
    protected static $enableQueue = false;
47
48
    /**
49
     * queue work
50
     *
51
     * @var null
52
     */
53
    protected static $howToUseQueue = null;
54
55
    /**
56
     * sms already pushed to queue
57
     *
58
     * @var bool
59
     */
60
    protected $pushedToQueue = false;
61
62
    /**
63
     * hook handlers
64
     *
65
     * @var array
66
     */
67
    protected static $enableHooks = [
68
        'beforeRun',
69
        'afterRun',
70
    ];
71
72
    /**
73
     * sms data
74
     *
75
     * @var array
76
     */
77
    protected $smsData = [
78
        'to'           => null,
79
        'templates'    => [],
80
        'content'      => '',
81
        'templateData' => [],
82
        'voiceCode'    => null,
83
    ];
84
85
    /**
86
     * first agent for send sms/voice verify
87
     *
88
     * @var string
89
     */
90
    protected $firstAgent = null;
91
92
    /**
93
     * construct
94
     */
95 9
    public function __construct()
96
    {
97 9
        self::init();
98 9
    }
99
100
    /**
101
     * create sms instance and set templates
102
     *
103
     * @param null $agentName
104
     * @param null $tempId
105
     *
106
     * @return Sms
107
     */
108 3
    public static function make($agentName = null, $tempId = null)
109
    {
110 3
        $sms = new self();
111 3
        if (is_array($agentName)) {
112
            $sms->template($agentName);
113 3
        } elseif ($agentName && is_string($agentName)) {
114
            if ($tempId === null) {
115
                $sms->content($agentName);
116
            } elseif (is_string("$tempId")) {
117
                $sms->template($agentName, $tempId);
118
            }
119
        }
120
121 3
        return $sms;
122
    }
123
124
    /**
125
     * send voice verify
126
     *
127
     * @param $code
128
     *
129
     * @return Sms
130
     */
131 3
    public static function voice($code)
132
    {
133 3
        $sms = new self();
134 3
        $sms->smsData['voiceCode'] = $code;
135
136 3
        return $sms;
137
    }
138
139
    /**
140
     * set how to use queue.
141
     *
142
     * @param $enable
143
     * @param $handler
144
     *
145
     * @return bool
146
     */
147 3
    public static function queue($enable = null, $handler = null)
148
    {
149 3
        if ($enable === null && $handler === null) {
150 3
            return self::$enableQueue;
151
        }
152 3
        if (is_callable($enable)) {
153 3
            $handler = $enable;
154 3
            $enable = true;
155 3
        }
156 3
        self::$enableQueue = (bool) $enable;
157 3
        if (is_callable($handler)) {
158 3
            self::$howToUseQueue = $handler;
0 ignored issues
show
Documentation Bug introduced by
It seems like $handler of type callable is incompatible with the declared type null of property $howToUseQueue.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
159 3
        }
160
161 3
        return self::$enableQueue;
162
    }
163
164
    /**
165
     * set the mobile number
166
     *
167
     * @param $mobile
168
     *
169
     * @return $this
170
     */
171 6
    public function to($mobile)
172
    {
173 6
        $this->smsData['to'] = $mobile;
174
175 6
        return $this;
176
    }
177
178
    /**
179
     * set content for content sms
180
     *
181
     * @param $content
182
     *
183
     * @return $this
184
     */
185 3
    public function content($content)
186
    {
187 3
        $this->smsData['content'] = trim((String) $content);
188
189 3
        return $this;
190
    }
191
192
    /**
193
     * set template id for template sms
194
     *
195
     * @param $agentName
196
     * @param $tempId
197
     *
198
     * @return $this
199
     */
200 3
    public function template($agentName, $tempId = null)
201
    {
202 3
        if (is_array($agentName)) {
203 3
            foreach ($agentName as $k => $v) {
204 3
                $this->template($k, $v);
205 3
            }
206 3
        } elseif ($agentName && $tempId) {
207 3
            if (!isset($this->smsData['templates']) || !is_array($this->smsData['templates'])) {
208
                $this->smsData['templates'] = [];
209
            }
210 3
            $this->smsData['templates']["$agentName"] = $tempId;
211 3
        }
212
213 3
        return $this;
214
    }
215
216
    /**
217
     * set data for template sms
218
     *
219
     * @param array $data
220
     *
221
     * @return $this
222
     */
223 18
    public function data(array $data)
224
    {
225 18
        $this->smsData['templateData'] = $data;
226
227 3
        return $this;
228
    }
229
230
    /**
231
     * set the first agent
232
     *
233
     * @param $name
234
     *
235
     * @return $this
236
     */
237 3
    public function agent($name)
238
    {
239 3
        $this->firstAgent = (String) $name;
240
241 3
        return $this;
242
    }
243
244
    /**
245
     * start send
246
     *
247
     * @param bool $immediately
248
     *
249
     * @return mixed
250
     */
251 15
    public function send($immediately = false)
252
    {
253 15
        $this->validator();
254
255
        // if disable push to queue,
256
        // send the sms immediately.
257 15
        if (!self::$enableQueue) {
258 12
            $immediately = true;
259 12
        }
260
261
        // whatever 'PhpSms' whether to enable or disable push to queue,
262
        // if you are already pushed sms instance to queue,
263
        // you can recall the method `send()` in queue job without `true` parameter.
264
        //
265
        // So this mechanism in order to make you convenient use the method `send()` in queue system.
266 15
        if ($this->pushedToQueue) {
267 3
            $immediately = true;
268 3
        }
269
270
        // whether to send sms immediately,
271
        // or push it to queue.
272 15
        if ($immediately) {
273 15
            $result = Balancer::run(self::TASK, $this->getData(), $this->firstAgent);
0 ignored issues
show
Documentation introduced by
$this->getData() is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
274 15
        } else {
275 3
            $result = $this->push();
276
        }
277
278 15
        return $result;
279
    }
280
281
    /**
282
     * push sms send task to queue
283
     *
284
     * @throws \Exception | PhpSmsException
285
     *
286
     * @return mixed
287
     */
288 3
    protected function push()
289
    {
290 3
        if (is_callable(self::$howToUseQueue)) {
291
            try {
292 3
                $this->pushedToQueue = true;
293
294 3
                return call_user_func_array(self::$howToUseQueue, [$this, $this->smsData]);
295
            } catch (\Exception $e) {
296
                $this->pushedToQueue = false;
297
                throw $e;
298
            }
299
        } else {
300
            throw new PhpSmsException('Please define how to use queue by method `queue($enable, $handler)`');
301
        }
302
    }
303
304
    /**
305
     * get sms data
306
     *
307
     * @return array
308
     */
309 33
    public function getData()
310
    {
311 33
        return $this->smsData;
312
    }
313
314
    /**
315
     * init
316
     *
317
     * @return mixed
318
     */
319 15
    protected static function init()
320
    {
321 15
        self::configuration();
322
323 15
        return self::generatorTask();
324
    }
325
326
    /**
327
     * generator a sms send task
328
     *
329
     * @return null
330
     */
331 18
    public static function generatorTask()
332
    {
333 18
        if (!Balancer::getTask(self::TASK)) {
334
            Balancer::task(self::TASK, function ($task) {
335
                // create drivers
336 3
                self::createAgents($task);
337 3
            });
338 3
        }
339
340 18
        return Balancer::getTask(self::TASK);
341
    }
342
343
    /**
344
     * configuration
345
     */
346 15
    protected static function configuration()
347
    {
348 15
        $config = [];
349 15
        if (empty(self::$agentsName)) {
350 3
            $config = include __DIR__ . '/../config/phpsms.php';
351 3
            self::generatorAgentsName($config);
352 3
        }
353 15
        if (empty(self::$agentsConfig)) {
354 3
            $config = $config ?: include __DIR__ . '/../config/phpsms.php';
355 3
            self::generatorAgentsConfig($config);
356 3
        }
357 15
        self::configValidator();
358 15
    }
359
360
    /**
361
     * generate enabled agents name
362
     *
363
     * @param array $config
364
     */
365 3
    protected static function generatorAgentsName($config)
366
    {
367 3
        $config = isset($config['enable']) ? $config['enable'] : null;
368 3
        if ($config) {
369 3
            self::enable($config);
370 3
        }
371 3
    }
372
373
    /**
374
     * generator agents config
375
     *
376
     * @param array $config
377
     */
378 3
    protected static function generatorAgentsConfig($config)
379
    {
380 3
        $config = isset($config['agents']) ? $config['agents'] : [];
381 3
        self::agents($config);
382 3
    }
383
384
    /**
385
     * config value validator
386
     *
387
     * @throws PhpSmsException
388
     */
389 15
    protected static function configValidator()
390
    {
391 15
        if (!count(self::$agentsName)) {
392
            throw new PhpSmsException('Please set at least one enable agent in config file(config/phpsms.php) or use method enable()');
393
        }
394 15
        foreach (self::$agentsName as $agentName => $options) {
395 15
            if ($agentName === self::LOG_AGENT) {
396 15
                continue;
397
            }
398 9
            if (!isset(self::$agentsConfig[$agentName])) {
399
                throw new PhpSmsException("Please configuration [$agentName] agent in config file(config/phpsms.php) or use method agents()");
400
            }
401 15
        }
402 15
    }
403
404
    /**
405
     * create drivers for sms send task
406
     *
407
     * @param $task
408
     */
409 15
    protected static function createAgents($task)
410
    {
411 3
        foreach (self::$agentsName as $name => $options) {
412 3
            $configData = self::getAgentConfigData($name);
413 3
            $task->driver("$name $options")
414 3
                 ->data($configData)
415 15
                 ->work(function ($driver) {
416 15
                     $configData = $driver->getDriverData();
417 15
                     $agent = self::getSmsAgent($driver->name, $configData);
418 15
                     $smsData = $driver->getTaskData();
419 15
                     extract($smsData);
420 15
                     if (isset($smsData['voiceCode']) && $smsData['voiceCode']) {
421
                         $agent->voiceVerify($to, $voiceCode);
422
                     } else {
423 15
                         $template = isset($templates[$driver->name]) ? $templates[$driver->name] : 0;
424 15
                         $agent->sendSms($template, $to, $templateData, $content);
425
                     }
426 15
                     $result = $agent->getResult();
427 15
                     if ($result['success']) {
428 15
                         $driver->success();
429 15
                     }
430 15
                     unset($result['success']);
431
432 15
                     return $result;
433 3
                 });
434 3
        }
435 3
    }
436
437
    /**
438
     * get agent config data by name
439
     *
440
     * @param $name
441
     *
442
     * @return array
443
     */
444 3
    protected static function getAgentConfigData($name)
445
    {
446 3
        return isset(self::$agentsConfig[$name]) ?
447 3
               (Array) self::$agentsConfig[$name] : [];
448
    }
449
450
    /**
451
     * get a sms agent instance,
452
     * if null, will create a new agent instance
453
     *
454
     * @param       $name
455
     * @param array $configData
456
     *
457
     * @throws PhpSmsException
458
     *
459
     * @return mixed
460
     */
461 18
    public static function getSmsAgent($name, array $configData)
462
    {
463 18
        if (!isset(self::$agents[$name])) {
464 3
            $className = 'Toplan\\PhpSms\\' . $name . 'Agent';
465 3
            if (class_exists($className)) {
466 3
                self::$agents[$name] = new $className($configData);
467 3
            } else {
468
                throw new PhpSmsException("Agent [$name] not support.");
469
            }
470 3
        }
471
472 18
        return self::$agents[$name];
473
    }
474
475
    /**
476
     * validate
477
     *
478
     * @throws PhpSmsException
479
     */
480 18
    protected function validator()
481
    {
482 18
        if (!$this->smsData['to']) {
483
            throw new PhpSmsException('Please set send sms(or voice verify) to who use `to()` method.');
484
        }
485
486 18
        return true;
487
    }
488
489
    /**
490
     * set enable agents
491
     *
492
     * @param      $agentName
493
     * @param null $options
494
     */
495 6
    public static function enable($agentName, $options = null)
496
    {
497 6
        if (is_array($agentName)) {
498 6
            foreach ($agentName as $name => $opt) {
499 6
                self::enable($name, $opt);
500 6
            }
501 6
        } elseif ($agentName && is_string($agentName) && !is_array($options) && is_string("$options")) {
502 3
            self::$agentsName["$agentName"] = "$options";
503 6
        } elseif (is_int($agentName) && !is_array($options) && "$options") {
504 3
            self::$agentsName["$options"] = '1';
505 3
        } elseif ($agentName && $options === null) {
506
            self::$agentsName["$agentName"] = '1';
507
        }
508 6
    }
509
510
    /**
511
     * set config for available agents
512
     *
513
     * @param       $agentName
514
     * @param array $config
515
     *
516
     * @throws PhpSmsException
517
     */
518 6
    public static function agents($agentName, array $config = [])
519
    {
520 6
        if (is_array($agentName)) {
521 6
            foreach ($agentName as $name => $conf) {
522 6
                self::agents($name, $conf);
523 6
            }
524 6
        } elseif ($agentName && is_array($config)) {
525 6
            if (preg_match('/^[0-9]+$/', $agentName)) {
526
                throw new PhpSmsException("Agent name [$agentName] must be string, could not be a pure digital");
527
            }
528 6
            self::$agentsConfig["$agentName"] = $config;
529 6
        }
530 6
    }
531
532
    /**
533
     * get enable agents
534
     *
535
     * @return array
536
     */
537 9
    public static function getEnableAgents()
538
    {
539 9
        return self::$agentsName;
540
    }
541
542
    /**
543
     * get agents config info
544
     *
545
     * @return array
546
     */
547 9
    public static function getAgentsConfig()
548
    {
549 9
        return self::$agentsConfig;
550
    }
551
552
    /**
553
     * tear down enable agents
554
     */
555 3
    public static function cleanEnableAgents()
556
    {
557 3
        self::$agentsName = [];
558 3
    }
559
560
    /**
561
     * tear down agents config
562
     */
563 3
    public static function cleanAgentsConfig()
564
    {
565 3
        self::$agentsConfig = [];
566 3
    }
567
568
    /**
569
     * overload static method
570
     *
571
     * @param $name
572
     * @param $args
573
     *
574
     * @throws PhpSmsException
575
     */
576 6
    public static function __callStatic($name, $args)
577
    {
578 6
        $name = $name === 'beforeSend' ? 'beforeRun' : $name;
579 6
        $name = $name === 'afterSend' ? 'afterRun' : $name;
580 6
        if (in_array($name, self::$enableHooks)) {
581 6
            $handler = $args[0];
582 6
            $override = isset($args[1]) ? (bool) $args[1] : false;
583 6
            if ($handler && is_callable($handler)) {
584 6
                $task = self::init();
585 6
                $task->hook($name, $handler, $override);
586 6
            } else {
587
                throw new PhpSmsException("Please give method static $name() a callable parameter");
588
            }
589 6
        } else {
590
            throw new PhpSmsException("Do not find static method $name()");
591
        }
592 6
    }
593
594
    /**
595
     * overload method
596
     *
597
     * @param $name
598
     * @param $args
599
     *
600
     * @throws PhpSmsException
601
     * @throws \Exception
602
     */
603 3
    public function __call($name, $args)
604
    {
605
        try {
606 3
            $this->__callStatic($name, $args);
607 3
        } catch (\Exception $e) {
608
            throw $e;
609
        }
610 3
    }
611
}
612