Passed
Push — master ( 819724...3e0e00 )
by Songda
02:34 queued 10s
created

Pay::make()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
eloc 8
c 7
b 1
f 0
dl 0
loc 10
rs 10
cc 4
nc 4
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay;
6
7
use DI\Container;
8
use DI\ContainerBuilder;
9
use DI\DependencyException;
10
use DI\NotFoundException;
11
use Throwable;
12
use Yansongda\Pay\Contract\ContainerInterface;
13
use Yansongda\Pay\Contract\ServiceProviderInterface;
14
use Yansongda\Pay\Exception\ContainerDependencyException;
15
use Yansongda\Pay\Exception\ContainerException;
16
use Yansongda\Pay\Exception\ContainerNotFoundException;
17
use Yansongda\Pay\Exception\ServiceNotFoundException;
18
use Yansongda\Pay\Service\AlipayServiceProvider;
19
use Yansongda\Pay\Service\ConfigServiceProvider;
20
use Yansongda\Pay\Service\EventServiceProvider;
21
use Yansongda\Pay\Service\HttpServiceProvider;
22
use Yansongda\Pay\Service\LoggerServiceProvider;
23
use Yansongda\Pay\Service\WechatServiceProvider;
24
25
class Pay
26
{
27
    /**
28
     * 正常模式.
29
     */
30
    public const MODE_NORMAL = 0;
31
32
    /**
33
     * 沙箱模式.
34
     */
35
    public const MODE_SANDBOX = 1;
36
37
    /**
38
     * 服务商模式.
39
     */
40
    public const MODE_SERVICE = 2;
41
42
    /**
43
     * @var string[]
44
     */
45
    protected $service = [
46
        AlipayServiceProvider::class,
47
        WechatServiceProvider::class,
48
    ];
49
50
    /**
51
     * @var string[]
52
     */
53
    private $coreService = [
54
        ConfigServiceProvider::class,
55
        LoggerServiceProvider::class,
56
        EventServiceProvider::class,
57
        HttpServiceProvider::class,
58
    ];
59
60
    /**
61
     * @var \DI\Container
62
     */
63
    private static $container = null;
64
65
    /**
66
     * Bootstrap.
67
     *
68
     * @author yansongda <[email protected]>
69
     *
70
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
71
     * @throws \Yansongda\Pay\Exception\ContainerException
72
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
73
     */
74
    private function __construct(array $config)
75
    {
76
        $this->initContainer();
77
        $this->registerServices($config);
78
    }
79
80
    /**
81
     * __callStatic.
82
     *
83
     * @author yansongda <[email protected]>
84
     *
85
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
86
     * @throws \Yansongda\Pay\Exception\ContainerException
87
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
88
     *
89
     * @return mixed
90
     */
91
    public static function __callStatic(string $service, array $config)
92
    {
93
        if (!empty($config) && !self::hasContainer()) {
94
            self::config(...$config);
0 ignored issues
show
Bug introduced by
$config is expanded, but the parameter $config of Yansongda\Pay\Pay::config() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
            self::config(/** @scrutinizer ignore-type */ ...$config);
Loading history...
95
        }
96
97
        return self::get($service);
98
    }
99
100
    /**
101
     * 初始化容器、配置等信息.
102
     *
103
     * @author yansongda <[email protected]>
104
     *
105
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
106
     * @throws \Yansongda\Pay\Exception\ContainerException
107
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
108
     */
109
    public static function config(array $config = []): Pay
110
    {
111
        if (empty($config) && self::hasContainer()) {
112
            return self::get(Pay::class);
113
        }
114
115
        return new self($config);
116
    }
117
118
    /**
119
     * 定义.
120
     *
121
     * @author yansongda <[email protected]>
122
     *
123
     * @param mixed $value
124
     *
125
     * @throws \Yansongda\Pay\Exception\ContainerException
126
     */
127
    public static function set(string $name, $value): void
128
    {
129
        Pay::getContainer()->set($name, $value);
130
    }
131
132
    /**
133
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
134
     * @throws \Yansongda\Pay\Exception\ContainerException
135
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
136
     *
137
     * @return mixed
138
     */
139
    public static function make(string $service, array $parameters = [])
140
    {
141
        try {
142
            return Pay::getContainer()->make(...func_get_args());
0 ignored issues
show
Bug introduced by
func_get_args() is expanded, but the parameter $name of DI\Container::make() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

142
            return Pay::getContainer()->make(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
143
        } catch (NotFoundException $e) {
144
            throw new ServiceNotFoundException($e->getMessage());
145
        } catch (DependencyException $e) {
146
            throw new ContainerDependencyException($e->getMessage());
147
        } catch (Throwable $e) {
148
            throw new ContainerException($e->getMessage());
149
        }
150
    }
151
152
    /**
153
     * 获取服务.
154
     *
155
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
156
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
157
     * @throws \Yansongda\Pay\Exception\ContainerException
158
     *
159
     * @return mixed
160
     */
161
    public static function get(string $service)
162
    {
163
        try {
164
            return Pay::getContainer()->get($service);
165
        } catch (NotFoundException $e) {
166
            throw new ServiceNotFoundException($e->getMessage());
167
        } catch (DependencyException $e) {
168
            throw new ContainerDependencyException($e->getMessage());
169
        } catch (Throwable $e) {
170
            throw new ContainerException($e->getMessage());
171
        }
172
    }
173
174
    /**
175
     * @throws \Yansongda\Pay\Exception\ContainerException
176
     */
177
    public static function has(string $service): bool
178
    {
179
        return Pay::getContainer()->has($service);
180
    }
181
182
    /**
183
     * getContainer.
184
     *
185
     * @author yansongda <[email protected]>
186
     *
187
     * @throws \Yansongda\Pay\Exception\ContainerNotFoundException
188
     */
189
    public static function getContainer(): Container
190
    {
191
        if (self::hasContainer()) {
192
            return self::$container;
193
        }
194
195
        throw new ContainerNotFoundException('You should init/config PAY first', ContainerException::CONTAINER_NOT_FOUND);
196
    }
197
198
    /**
199
     * has Container.
200
     *
201
     * @author yansongda <[email protected]>
202
     */
203
    public static function hasContainer(): bool
204
    {
205
        return isset(self::$container) && self::$container instanceof Container;
206
    }
207
208
    /**
209
     * clear.
210
     *
211
     * @author yansongda <[email protected]>
212
     */
213
    public static function clear(): void
214
    {
215
        self::$container = null;
216
    }
217
218
    /**
219
     * 注册服务.
220
     *
221
     * @author yansongda <[email protected]>
222
     *
223
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
224
     * @throws \Yansongda\Pay\Exception\ContainerException
225
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
226
     */
227
    public static function registerService(string $service, array $config): void
228
    {
229
        $var = self::get($service);
230
231
        if ($var instanceof ServiceProviderInterface) {
232
            $var->register(self::get(Pay::class), $config);
233
        }
234
    }
235
236
    /**
237
     * initContainer.
238
     *
239
     * @author yansongda <[email protected]>
240
     *
241
     * @throws \Yansongda\Pay\Exception\ContainerException
242
     */
243
    private function initContainer(): void
244
    {
245
        $builder = new ContainerBuilder();
246
        $builder->useAnnotations(false);
247
248
        try {
249
            $container = $builder->build();
250
            $container->set(ContainerInterface::class, $container);
251
            $container->set(\Psr\Container\ContainerInterface::class, $container);
252
            $container->set(Pay::class, $this);
253
254
            self::$container = $container;
255
        } catch (Throwable $e) {
256
            throw new ContainerException($e->getMessage());
257
        }
258
    }
259
260
    /**
261
     * register services.
262
     *
263
     * @author yansongda <[email protected]>
264
     *
265
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
266
     * @throws \Yansongda\Pay\Exception\ContainerException
267
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
268
     */
269
    private function registerServices(array $config): void
270
    {
271
        foreach (array_merge($this->coreService, $this->service) as $service) {
272
            self::registerService($service, $config);
273
        }
274
    }
275
}
276