Passed
Pull Request — master (#579)
by Songda
03:46
created

Pay::setContainer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay;
6
7
use Closure;
8
use Psr\Container\ContainerInterface;
9
use Psr\Container\NotFoundExceptionInterface;
10
use Throwable;
11
use Yansongda\Pay\Contract\ServiceProviderInterface;
12
use Yansongda\Pay\Exception\ContainerException;
13
use Yansongda\Pay\Exception\ContainerNotFoundException;
14
use Yansongda\Pay\Exception\ServiceNotFoundException;
15
use Yansongda\Pay\Provider\Alipay;
16
use Yansongda\Pay\Provider\Wechat;
17
use Yansongda\Pay\Service\AlipayServiceProvider;
18
use Yansongda\Pay\Service\ConfigServiceProvider;
19
use Yansongda\Pay\Service\EventServiceProvider;
20
use Yansongda\Pay\Service\HttpServiceProvider;
21
use Yansongda\Pay\Service\LoggerServiceProvider;
22
use Yansongda\Pay\Service\WechatServiceProvider;
23
24
/**
25
 * @method static Alipay alipay(array $config = [])
26
 * @method static Wechat wechat(array $config = [])
27
 */
28
class Pay
29
{
30
    /**
31
     * 正常模式.
32
     */
33
    public const MODE_NORMAL = 0;
34
35
    /**
36
     * 沙箱模式.
37
     */
38
    public const MODE_SANDBOX = 1;
39
40
    /**
41
     * 服务商模式.
42
     */
43
    public const MODE_SERVICE = 2;
44
45
    /**
46
     * @var string[]
47
     */
48
    protected $service = [
49
        AlipayServiceProvider::class,
50
        WechatServiceProvider::class,
51
    ];
52
53
    /**
54
     * @var string[]
55
     */
56
    private $coreService = [
57
        ConfigServiceProvider::class,
58
        LoggerServiceProvider::class,
59
        EventServiceProvider::class,
60
        HttpServiceProvider::class,
61
    ];
62
63
    /**
64
     * @var \Closure|\Psr\Container\ContainerInterface|\Yansongda\Pay\Contract\ContainerInterface|null
65
     */
66
    private static $container = null;
67
68
    /**
69
     * Bootstrap.
70
     *
71
     * @param \Closure|\Psr\Container\ContainerInterface|\Yansongda\Pay\Contract\ContainerInterface|null $container
72
     *
73
     * @throws \Yansongda\Pay\Exception\ContainerException
74
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
75
     */
76
    private function __construct(array $config, $container = null)
77
    {
78
        self::$container = $container;
79
80
        $this->registerServices($config);
81
    }
82
83
    /**
84
     * __callStatic.
85
     *
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)) {
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
     * @param \Closure|\Psr\Container\ContainerInterface|\Yansongda\Pay\Contract\ContainerInterface|null $container
104
     *
105
     * @throws \Yansongda\Pay\Exception\ContainerException
106
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
107
     */
108
    public static function config(array $config = [], $container = null): Pay
109
    {
110
        if ($config['_force'] ?? false) {
111
            return new self($config, $container);
112
        }
113
114
        return self::get(Pay::class);
115
    }
116
117
    /**
118
     * 定义.
119
     *
120
     * @param mixed $value
121
     *
122
     * @throws \Yansongda\Pay\Exception\ContainerException
123
     */
124
    public static function set(string $name, $value): void
125
    {
126
        try {
127
            $container = Pay::getContainer();
128
129
            if ($container instanceof Contract\ContainerInterface || method_exists($container, 'set')) {
130
                $container->set(...func_get_args());
131
            }
132
        } catch (ContainerNotFoundException $e) {
133
            throw $e;
134
        } catch (Throwable $e) {
135
            throw new ContainerException($e->getMessage());
136
        }
137
    }
138
139
    /**
140
     * @throws \Yansongda\Pay\Exception\ContainerException
141
     *
142
     * @return mixed
143
     */
144
    public static function make(string $service, array $parameters = [])
145
    {
146
        try {
147
            $container = Pay::getContainer();
148
149
            if ($container instanceof Contract\ContainerInterface || method_exists($container, 'make')) {
150
                return $container->make(...func_get_args());
0 ignored issues
show
Bug introduced by
func_get_args() is expanded, but the parameter $name of Yansongda\Pay\Contract\ContainerInterface::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

150
                return $container->make(/** @scrutinizer ignore-type */ ...func_get_args());
Loading history...
151
            }
152
        } catch (ContainerNotFoundException $e) {
153
            throw $e;
154
        } catch (Throwable $e) {
155
            throw new ContainerException($e->getMessage());
156
        }
157
158
        $parameters = array_values($parameters);
159
160
        return new $service(...$parameters);
161
    }
162
163
    /**
164
     * 获取服务.
165
     *
166
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
167
     * @throws \Yansongda\Pay\Exception\ContainerException
168
     *
169
     * @return mixed
170
     */
171
    public static function get(string $service)
172
    {
173
        try {
174
            return Pay::getContainer()->get($service);
175
        } catch (NotFoundExceptionInterface $e) {
176
            throw new ServiceNotFoundException($e->getMessage());
177
        } catch (Throwable $e) {
178
            throw new ContainerException($e->getMessage());
179
        }
180
    }
181
182
    /**
183
     * @throws \Yansongda\Pay\Exception\ContainerException
184
     */
185
    public static function has(string $service): bool
186
    {
187
        return Pay::getContainer()->has($service);
188
    }
189
190
    /**
191
     * @param \Closure|\Psr\Container\ContainerInterface|\Yansongda\Pay\Contract\ContainerInterface|null $container
192
     */
193
    public static function setContainer($container): void
194
    {
195
        self::$container = $container;
196
    }
197
198
    /**
199
     * getContainer.
200
     *
201
     * @throws \Yansongda\Pay\Exception\ContainerNotFoundException
202
     */
203
    public static function getContainer(): ContainerInterface
204
    {
205
        if (self::$container instanceof ContainerInterface) {
206
            return self::$container;
207
        }
208
209
        if (self::$container instanceof Closure) {
210
            return (self::$container)();
211
        }
212
213
        throw new ContainerNotFoundException('You should init/config PAY first', Exception\Exception::CONTAINER_NOT_FOUND);
214
    }
215
216
    /**
217
     * clear.
218
     */
219
    public static function clear(): void
220
    {
221
        self::$container = null;
222
    }
223
224
    /**
225
     * 注册服务.
226
     *
227
     * @throws \Yansongda\Pay\Exception\ContainerException
228
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
229
     */
230
    public static function registerService(string $service, array $config): void
231
    {
232
        $var = self::get($service);
233
234
        if ($var instanceof ServiceProviderInterface) {
235
            $var->register(self::get(Pay::class), $config);
236
        }
237
    }
238
239
    /**
240
     * register services.
241
     *
242
     * @throws \Yansongda\Pay\Exception\ContainerException
243
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
244
     */
245
    private function registerServices(array $config): void
246
    {
247
        foreach (array_merge($this->coreService, $this->service) as $service) {
248
            self::registerService($service, $config);
249
        }
250
    }
251
}
252