Completed
Pull Request — master (#56)
by lan tian
02:09
created

Sms::unserializeEnableAgents()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 11
rs 9.4285
ccs 8
cts 8
cp 1
cc 3
eloc 6
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Toplan\PhpSms;
4
5
use SuperClosure\Serializer;
6
use Toplan\TaskBalance\Balancer;
7
use Toplan\TaskBalance\Task;
8
9
/**
10
 * Class Sms
11
 *
12
 *
13
 * @author toplan<[email protected]>
14
 */
15
class Sms
16
{
17
    /**
18
     * The default name of balancing task.
19
     *
20
     * @var string
21
     */
22
    const TASK = 'PhpSms';
23
24
    /**
25
     * The instances of class [Toplan\PhpSms\Agent].
26
     *
27
     * @var array
28
     */
29
    protected static $agents = [];
30
31
    /**
32
     * The enabled agents` name.
33
     *
34
     * @var array
35
     */
36
    protected static $agentsName = [];
37
38
    /**
39
     * The enabled agents` configuration information.
40
     *
41
     * @var array
42
     */
43
    protected static $agentsConfig = [];
44
45
    /**
46
     * Whether to use the queue.
47
     *
48
     * @var bool
49
     */
50
    protected static $enableQueue = false;
51
52
    /**
53
     * How to use the queue.
54
     *
55
     * @var \Closure
56
     */
57
    protected static $howToUseQueue = null;
58
59
    /**
60
     * The enable hooks for balancing task.
61
     *
62
     * @var array
63
     */
64
    protected static $enableHooks = [
65
        'beforeRun',
66
        'beforeDriverRun',
67
        'afterDriverRun',
68
        'afterRun',
69
    ];
70
71
    /**
72
     * An instance of class [SuperClosure\Serializer] use for serialization closures.
73
     *
74
     * @var Serializer
75
     */
76
    protected static $serializer = null;
77
78
    /**
79
     * SMS/voice verify data container.
80
     *
81
     * @var array
82
     */
83
    protected $smsData = [
84
        'to'           => null,
85
        'templates'    => [],
86
        'content'      => null,
87
        'templateData' => [],
88
        'voiceCode'    => null,
89
    ];
90
91
    /**
92
     * The name of first agent.
93
     *
94
     * @var string|null
95
     */
96
    protected $firstAgent = null;
97
98
    /**
99
     * Whether the current instance has already pushed to the queue system.
100
     *
101
     * @var bool
102
     */
103
    protected $pushedToQueue = false;
104
105
    /**
106
     * Status container,
107
     * store some configuration information before serialize current instance(before enqueue).
108
     *
109
     * @var array
110
     */
111
    protected $_status_before_enqueue_ = [];
112
113
    /**
114
     * Constructor
115
     *
116
     * @param bool $autoBoot
117
     */
118
    public function __construct($autoBoot = true)
119 6
    {
120
        if ($autoBoot) {
121 6
            self::bootstrap();
122 3
        }
123 2
    }
124 6
125
    /**
126
     * Boot balancing task for send SMS/voice verify.
127
     */
128
    public static function bootstrap()
129 6
    {
130
        $task = self::getTask();
131 6
132
        //注意这里不能用'empty',因为其不能检查语句,
133
        //而恰巧Task实例获取drivers是通过魔术方法获取的.
134
        if (!count($task->drivers)) {
135 6
            self::configuration();
136 3
            self::createDrivers($task);
137 3
        }
138 2
    }
139 6
140
    /**
141
     * Get or generate a balancing task instance for send SMS/voice verify.
142
     *
143
     * @return Task
144
     */
145
    public static function getTask()
146 15
    {
147
        if (!Balancer::hasTask(self::TASK)) {
148 15
            Balancer::task(self::TASK);
149 3
        }
150 2
151
        return Balancer::getTask(self::TASK);
152 15
    }
153
154
    /**
155
     * Configuration.
156
     */
157
    protected static function configuration()
158 6
    {
159
        $config = [];
160 6
        if (empty(self::$agentsName)) {
161 6
            self::initEnableAgents($config);
162 3
        }
163 2
        $diff = array_diff_key(self::$agentsName, self::$agentsConfig);
164 6
        self::initAgentsConfig(array_keys($diff), $config);
165 6
        self::validateConfig();
166 6
    }
167 6
168
    /**
169
     * Try to read enable agents` name from config file.
170
     *
171
     * @param array $config
172
     */
173
    protected static function initEnableAgents(array &$config)
174 3
    {
175
        $config = empty($config) ? include __DIR__ . '/../config/phpsms.php' : $config;
176 3
        $enableAgents = isset($config['enable']) ? $config['enable'] : [];
177 3
        self::enable($enableAgents);
178 3
    }
179 3
180
    /**
181
     * Try to initialize the specified agents` configuration information.
182
     *
183
     * @param array $agents
184
     * @param array $config
185
     */
186
    protected static function initAgentsConfig(array $agents, array &$config)
187 6
    {
188
        if (empty($agents)) {
189 6
            return;
190 3
        }
191
        $config = empty($config) ? include __DIR__ . '/../config/phpsms.php' : $config;
192 3
        $agentsConfig = isset($config['agents']) ? $config['agents'] : [];
193 3
        foreach ($agents as $name) {
194 3
            $agentConfig = isset($agentsConfig[$name]) ? $agentsConfig[$name] : [];
195 3
            self::agents($name, $agentConfig);
196 3
        }
197 2
    }
198 3
199
    /**
200
     * validate configuration.
201
     *
202
     * @throws PhpSmsException
203
     */
204
    protected static function validateConfig()
205 6
    {
206
        if (empty(self::$agentsName)) {
207 6
            throw new PhpSmsException('Please configure at least one agent');
208
        }
209
    }
210 6
211
    /**
212
     * Create drivers for the balancing task.
213
     *
214
     * @param Task $task
215
     */
216
    protected static function createDrivers(Task $task)
217 18
    {
218
        foreach (self::$agentsName as $name => $options) {
219 3
            //获取代理器配置
220
            $configData = self::getAgentConfigData($name);
221 3
            //解析代理器数组模式的调度配置
222
            if (is_array($options)) {
223 3
                $data = self::parseAgentArrayOptions($options);
224 3
                $configData = array_merge($configData, $data);
225 3
                $options = $data['driverOpts'];
226 3
            }
227 2
            //创建任务驱动器
228
            $task->driver("$name $options")->data($configData)
229 3
                 ->work(function ($driver) {
230 18
                     $configData = $driver->getDriverData();
231 18
                     $agent = self::getSmsAgent($driver->name, $configData);
232 18
                     $smsData = $driver->getTaskData();
233 18
                     extract($smsData);
234 18
                     if (isset($smsData['voiceCode']) && $smsData['voiceCode']) {
235 18
                         $agent->voiceVerify($to, $voiceCode);
236
                     } else {
237
                         $template = isset($templates[$driver->name]) ? $templates[$driver->name] : 0;
238 18
                         $agent->sendSms($template, $to, $templateData, $content);
239 18
                     }
240
                     $result = $agent->result();
241 18
                     if ($result['success']) {
242 18
                         $driver->success();
243 18
                     }
244 12
                     unset($result['success']);
245 18
246
                     return $result;
247 18
                 });
248 3
        }
249 2
    }
250 3
251
    /**
252
     * Parsing scheduling configuration.
253
     * 解析代理器的数组模式的调度配置
254
     *
255
     * @param array $options
256
     *
257
     * @return array
258
     */
259
    protected static function parseAgentArrayOptions(array $options)
260 3
    {
261
        $agentClass = self::pullAgentOptionByName($options, 'agentClass');
262 3
        $sendSms = self::pullAgentOptionByName($options, 'sendSms');
263 3
        $voiceVerify = self::pullAgentOptionByName($options, 'voiceVerify');
264 3
        $backup = self::pullAgentOptionByName($options, 'backup') ? 'backup' : '';
265 3
        $driverOpts = implode(' ', array_values($options)) . " $backup";
266 3
267
        return compact('agentClass', 'sendSms', 'voiceVerify', 'driverOpts');
268 3
    }
269
270
    /**
271
     * Pull the value of the specified option out of the scheduling configuration.
272
     *
273
     * @param array  $options
274
     * @param string $name
275
     *
276
     * @return mixed
277
     */
278
    protected static function pullAgentOptionByName(array &$options, $name)
279 3
    {
280
        if (!isset($options[$name])) {
281 3
            return;
282 3
        }
283
        $value = $options[$name];
284 3
        unset($options[$name]);
285 3
286
        return $value;
287 3
    }
288
289
    /**
290
     * Get agent configuration information by name.
291
     *
292
     * @param string $name
293
     *
294
     * @return array
295
     */
296
    protected static function getAgentConfigData($name)
297 3
    {
298
        return isset(self::$agentsConfig[$name]) ? self::$agentsConfig[$name] : [];
299 3
    }
300
301
    /**
302
     * Get a sms agent instance by agent name,
303
     * if null, will try to create a new agent instance.
304
     *
305
     * @param string $name
306
     * @param array  $configData
307
     *
308
     * @throws PhpSmsException
309
     *
310
     * @return mixed
311
     */
312
    public static function getSmsAgent($name, array $configData)
313 21
    {
314
        if (!isset(self::$agents[$name])) {
315 21
            $configData['name'] = $name;
316 6
            $className = isset($configData['agentClass']) ? $configData['agentClass'] : ('Toplan\\PhpSms\\' . $name . 'Agent');
317 6
            if ((isset($configData['sendSms']) && is_callable($configData['sendSms'])) ||
318 6
                (isset($configData['voiceVerify']) && is_callable($configData['voiceVerify']))) {
319 6
                //创建寄生代理器
320
                $configData['agentClass'] = '';
321 3
                self::$agents[$name] = new ParasiticAgent($configData);
322 3
            } elseif (class_exists($className)) {
323 5
                //创建新代理器
324
                self::$agents[$name] = new $className($configData);
325 3
            } else {
326 2
                //无代理器可用
327
                throw new PhpSmsException("Do not support [$name] agent.");
328
            }
329
        }
330 4
331
        return self::$agents[$name];
332 21
    }
333
334
    /**
335
     * Set enable agents.
336
     *
337
     * @param mixed $agentName
338
     * @param mixed $options
339
     */
340
    public static function enable($agentName, $options = null)
341 6
    {
342
        if (is_array($agentName)) {
343 6
            foreach ($agentName as $name => $opt) {
344 6
                self::enable($name, $opt);
345 6
            }
346 4
        } elseif ($agentName && is_string($agentName) && $options !== null) {
347 6
            self::$agentsName["$agentName"] = is_array($options) ? $options : "$options";
348 3
        } elseif (is_int($agentName) && !is_array($options) && "$options") {
349 6
            self::$agentsName["$options"] = '1';
350 3
        } elseif ($agentName && $options === null) {
351 5
            self::$agentsName["$agentName"] = '1';
352 3
        }
353 2
    }
354 6
355
    /**
356
     * Set configuration information by agent name.
357
     *
358
     * @param array|string $agentName
359
     * @param array        $config
360
     *
361
     * @throws PhpSmsException
362
     */
363
    public static function agents($agentName, array $config = [])
364 6
    {
365
        if (is_array($agentName)) {
366 6
            foreach ($agentName as $name => $conf) {
367 3
                self::agents($name, $conf);
368 3
            }
369 2
        } elseif ($agentName && is_array($config)) {
370 6
            if (preg_match('/^[0-9]+$/', $agentName)) {
371 6
                throw new PhpSmsException("Agent name [$agentName] must be string, could not be a pure digital");
372
            }
373
            self::$agentsConfig["$agentName"] = $config;
374 6
        }
375 4
    }
376 6
377
    /**
378
     * Get the enabled agents` name.
379
     *
380
     * @return array
381
     */
382
    public static function getEnableAgents()
383 12
    {
384
        return self::$agentsName;
385 12
    }
386
387
    /**
388
     * Get the enabled agents` configuration information.
389
     *
390
     * @return array
391
     */
392
    public static function getAgentsConfig()
393 12
    {
394
        return self::$agentsConfig;
395 12
    }
396
397
    /**
398
     * Tear down enable agent and prepare to create and start a new balancing task,
399
     * so before do it must destroy old task instance.
400
     */
401
    public static function cleanEnableAgents()
402 6
    {
403
        Balancer::destroy(self::TASK);
404 6
        self::$agentsName = [];
405 6
    }
406 6
407
    /**
408
     * Tear down agent config and prepare to create and start a new balancing task,
409
     * so before do it must destroy old task instance.
410
     */
411
    public static function cleanAgentsConfig()
412 3
    {
413
        Balancer::destroy(self::TASK);
414 3
        self::$agentsConfig = [];
415 3
    }
416 3
417
    /**
418
     * Create a sms instance send SMS,
419
     * your can also set SMS templates or content at the same time.
420
     *
421
     * @param mixed $agentName
422
     * @param mixed $tempId
423
     *
424
     * @return Sms
425
     */
426
    public static function make($agentName = null, $tempId = null)
427
    {
428
        $sms = new self();
429
        if (is_array($agentName)) {
430
            $sms->template($agentName);
431
        } elseif ($agentName && is_string($agentName)) {
432
            if ($tempId === null) {
433
                $sms->content($agentName);
434
            } elseif (is_string("$tempId")) {
435
                $sms->template($agentName, $tempId);
436
            }
437
        }
438
439
        return $sms;
440
    }
441
442
    /**
443
     * Create a sms instance send voice verify,
444
     * your can also set verify code at the same time.
445
     *
446
     * @param string|int $code
447
     *
448
     * @return Sms
449
     */
450
    public static function voice($code)
451 3
    {
452
        $sms = new self();
453 3
        $sms->smsData['voiceCode'] = $code;
454 3
455
        return $sms;
456 3
    }
457
458
    /**
459
     * Set whether to use the queue system, and define how to use it.
460
     *
461
     * @param mixed $enable
462
     * @param mixed $handler
463
     *
464
     * @return bool
465
     */
466
    public static function queue($enable = null, $handler = null)
467 3
    {
468
        if ($enable === null && $handler === null) {
469 3
            return self::$enableQueue;
470 3
        }
471
        if (is_callable($enable)) {
472 3
            $handler = $enable;
473 3
            $enable = true;
474 3
        }
475 2
        self::$enableQueue = (bool) $enable;
476 3
        if (is_callable($handler)) {
477 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 object<Closure> 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...
478 3
        }
479 2
480
        return self::$enableQueue;
481 3
    }
482
483
    /**
484
     * Set the recipient`s mobile number.
485
     *
486
     * @param string $mobile
487
     *
488
     * @return $this
489
     */
490
    public function to($mobile)
491 6
    {
492
        $this->smsData['to'] = $mobile;
493 6
494
        return $this;
495 6
    }
496
497
    /**
498
     * Set the content for content SMS.
499
     *
500
     * @param string $content
501
     *
502
     * @return $this
503
     */
504
    public function content($content)
505 3
    {
506
        $this->smsData['content'] = trim((string) $content);
507 3
508
        return $this;
509 3
    }
510
511
    /**
512
     * Set the template id for template SMS.
513
     *
514
     * @param mixed $agentName
515
     * @param mixed $tempId
516
     *
517
     * @return $this
518
     */
519
    public function template($agentName, $tempId = null)
520 3
    {
521
        if (is_array($agentName)) {
522 3
            foreach ($agentName as $k => $v) {
523 3
                $this->template($k, $v);
524 3
            }
525 2
        } elseif ($agentName && $tempId) {
526 3
            if (!isset($this->smsData['templates']) || !is_array($this->smsData['templates'])) {
527 3
                $this->smsData['templates'] = [];
528
            }
529
            $this->smsData['templates']["$agentName"] = $tempId;
530 3
        }
531 2
532
        return $this;
533 3
    }
534
535
    /**
536
     * Set the template data for template SMS.
537
     *
538
     * @param array $data
539
     *
540
     * @return $this
541
     */
542
    public function data(array $data)
543 3
    {
544
        $this->smsData['templateData'] = $data;
545 3
546
        return $this;
547 3
    }
548
549
    /**
550
     * Set the first agent by name.
551
     *
552
     * @param string $name
553
     *
554
     * @return $this
555
     */
556
    public function agent($name)
557 3
    {
558
        $this->firstAgent = (string) $name;
559 3
560
        return $this;
561 3
    }
562
563
    /**
564
     * Start send SMS/voice verify.
565
     *
566
     * If give a true parameter, this system will immediately start request to send SMS/voice verify whatever whether to use the queue.
567
     * if you are already pushed sms instance to the queue, you can recall the method `send()` in queue system without `true` parameter,
568
     * so this mechanism in order to make you convenient use the method `send()` in queue system.
569
     *
570
     * @param bool $immediately
571
     *
572
     * @return mixed
573
     */
574
    public function send($immediately = false)
575 18
    {
576
        if (!self::$enableQueue || $this->pushedToQueue) {
577 18
            $immediately = true;
578 18
        }
579 12
        if ($immediately) {
580 18
            $result = Balancer::run(self::TASK, [
581 18
                'data'   => $this->getData(),
582 18
                'driver' => $this->firstAgent,
583 18
            ]);
584 12
        } else {
585 12
            $result = $this->push();
586 3
        }
587
588
        return $result;
589 18
    }
590
591
    /**
592
     * Push to the queue by a custom method.
593
     *
594
     * @throws \Exception | PhpSmsException
595
     *
596
     * @return mixed
597
     */
598
    public function push()
599 3
    {
600
        if (is_callable(self::$howToUseQueue)) {
601 3
            try {
602
                $this->pushedToQueue = true;
603 3
604
                return call_user_func_array(self::$howToUseQueue, [$this, $this->smsData]);
605 3
            } catch (\Exception $e) {
606
                $this->pushedToQueue = false;
607
                throw $e;
608
            }
609
        } else {
610
            throw new PhpSmsException('Please define how to use queue by method `queue($enable, $handler)`');
611
        }
612
    }
613
614
    /**
615
     * Get all the data of SMS/voice verify.
616
     *
617
     * @param null|string $name
618
     *
619
     * @return mixed
620
     */
621
    public function getData($name = null)
622 36
    {
623
        if (is_string($name) && isset($this->smsData["$name"])) {
624 36
            return $this->smsData[$name];
625 3
        }
626
627
        return $this->smsData;
628 36
    }
629
630
    /**
631
     * Overload static method.
632
     *
633
     * @param string $name
634
     * @param array  $args
635
     *
636
     * @throws PhpSmsException
637
     */
638
    public static function __callStatic($name, $args)
639 9
    {
640
        $name = $name === 'beforeSend' ? 'beforeRun' : $name;
641 9
        $name = $name === 'afterSend' ? 'afterRun' : $name;
642 9
        $name = $name === 'beforeAgentSend' ? 'beforeDriverRun' : $name;
643 9
        $name = $name === 'afterAgentSend' ? 'afterDriverRun' : $name;
644 9
        if (in_array($name, self::$enableHooks)) {
645 9
            $handler = $args[0];
646 9
            $override = isset($args[1]) ? (bool) $args[1] : false;
647 9
            if (is_callable($handler)) {
648 9
                $task = self::getTask();
649 9
                $task->hook($name, $handler, $override);
650 9
            } else {
651 6
                throw new PhpSmsException("Please give method $name() a callable parameter");
652 3
            }
653
        } else {
654 6
            throw new PhpSmsException("Dont find method $name()");
655
        }
656
    }
657 9
658
    /**
659
     * Overload method.
660
     *
661
     * @param string $name
662
     * @param array  $args
663
     *
664
     * @throws PhpSmsException
665
     * @throws \Exception
666
     */
667
    public function __call($name, $args)
668 3
    {
669
        try {
670
            $this->__callStatic($name, $args);
671 3
        } catch (\Exception $e) {
672 2
            throw $e;
673
        }
674
    }
675 3
676
    /**
677
     * Serialize magic method.
678
     *
679
     * @return array
680
     */
681
    public function __sleep()
682
    {
683 3
        try {
684
            $this->_status_before_enqueue_['enableAgents'] = self::serializeEnableAgents();
685
            $this->_status_before_enqueue_['agentsConfig'] = self::getAgentsConfig();
686 3
            $this->_status_before_enqueue_['handlers'] = self::serializeHandlers();
687 3
        } catch (\Exception $e) {
688 3
            //swallow exception
689 2
        }
690
691
        return ['pushedToQueue', 'smsData', 'firstAgent', '_status_before_enqueue_'];
692
    }
693 3
694
    /**
695
     * Deserialize magic method.
696
     */
697
    public function __wakeup()
698
    {
699
        if (empty($this->_status_before_enqueue_)) {
700 3
            return;
701
        }
702 3
        $status = $this->_status_before_enqueue_;
703
        self::$agentsName = self::deserializeEnableAgents($status['enableAgents']);
704
        self::$agentsConfig = $status['agentsConfig'];
705 3
        Balancer::destroy(self::TASK);
706 3
        self::bootstrap();
707 3
        self::reinstallHandlers($status['handlers']);
708 3
    }
709 3
710 3
    /**
711 3
     * Get a closure serializer.
712
     *
713
     * @return Serializer
714
     */
715
    public static function getSerializer()
716
    {
717
        if (!self::$serializer) {
718 3
            self::$serializer = new Serializer();
719
        }
720 3
721 3
        return self::$serializer;
722 2
    }
723
724 3
    /**
725
     * Serialize the configuration information of enabled agents.
726
     *
727
     * @return array
728
     */
729
    protected static function serializeEnableAgents()
730
    {
731
        $enableAgents = self::getEnableAgents();
732 3
        foreach ($enableAgents as $name => &$options) {
733
            if (is_array($options)) {
734 3
                self::serializeClosureAndReplace($options, 'sendSms');
735 3
                self::serializeClosureAndReplace($options, 'voiceVerify');
736 3
            }
737 3
        }
738 3
739 2
        return $enableAgents;
740 2
    }
741
742 3
    /**
743
     * Deserialize the configuration information of enabled agents.
744
     *
745
     * @param array $serialized
746
     *
747
     * @return mixed
748
     */
749
    protected static function deserializeEnableAgents(array $serialized)
750
    {
751
        foreach ($serialized as $name => &$options) {
752 3
            if (is_array($options)) {
753
                self::deserializeClosureAndReplace($options, 'sendSms');
754 3
                self::deserializeClosureAndReplace($options, 'voiceVerify');
755 3
            }
756 3
        }
757 3
758 2
        return $serialized;
759 2
    }
760
761 3
    /**
762
     * Serialize the hooks` handlers of balancing task
763
     *
764
     * @return array
765
     */
766
    protected static function serializeHandlers()
767
    {
768
        $task = self::getTask();
769
        $hooks = $task->handlers;
770 3
        foreach ($hooks as &$handlers) {
771
            foreach (array_keys($handlers) as $key) {
772 3
                self::serializeClosureAndReplace($handlers, $key);
773 3
            }
774 3
        }
775 2
776 3
        return $hooks;
777
    }
778
779
    /**
780
     * Reinstall hooks` handlers for balancing task.
781
     *
782
     * @param array $handlers
783
     */
784 3
    protected static function reinstallHandlers(array $handlers)
785
    {
786 3
        $serializer = self::getSerializer();
787 3
        foreach ($handlers as $hookName => $serializedHandlers) {
788 3
            foreach ($serializedHandlers as $index => $handler) {
789 2
                if (is_string($handler)) {
790 3
                    $handler = $serializer->unserialize($handler);
791
                }
792
                self::$hookName($handler, $index === 0);
793
            }
794
        }
795
    }
796
797
    /**
798 3
     * Serialize the specified closure and replace the origin value.
799
     *
800 3
     * @param array      $options
801 3
     * @param int|string $key
802 3
     */
803 3 View Code Duplication
    protected static function serializeClosureAndReplace(array &$options, $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
804 3
    {
805 3
        if (isset($options[$key]) && is_callable($options[$key])) {
806 3
            $serializer = self::getSerializer();
807 3
            $options[$key] = (string) $serializer->serialize($options[$key]);
808 2
        }
809 3
    }
810 2
811 2
    /**
812
     * Deserialize the specified closure and replace the origin value.
813 3
     *
814
     * @param array      $options
815
     * @param int|string $key
816
     */
817 View Code Duplication
    protected static function deserializeClosureAndReplace(array &$options, $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
818
    {
819
        if (isset($options[$key]) && is_string($options[$key])) {
820
            $serializer = self::getSerializer();
821 3
            $options[$key] = $serializer->unserialize($options[$key]);
822
        }
823 3
    }
824
}
825