Passed
Pull Request — master (#5)
by Lynh
24:43 queued 09:52
created

InteractsWithConfiguration::middleware()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Jenky\Hermes\Concerns;
4
5
use GuzzleHttp\HandlerStack;
6
use Illuminate\Support\Str;
7
use Jenky\Hermes\LazyEvaluation;
8
9
trait InteractsWithConfiguration
10
{
11
    /**
12
     * Make the Guzzle client options from config.
13
     *
14
     * @param  array $config
15
     * @return array
16
     */
17
    public function makeClientOptions(array $config)
18
    {
19
        $options = $config['options'] ?? [];
20
        $options['handler'] = $options['handler'] ?? $this->createHandler($config);
21
22
        return $options;
23
    }
24
25
    /**
26
     * Create the client handler stack instance.
27
     *
28
     * @param  array $config
29
     * @return \GuzzleHttp\HandlerStack
30
     */
31
    public function createHandler(array $config = [])
32
    {
33
        return $this->prepareHandler(
34
            HandlerStack::create($this->handler($config)), $config
35
        );
36
    }
37
38
    /**
39
     * Get the handle stack's handler instance.
40
     *
41
     * @param  array $config
42
     * @return mixed
43
     */
44
    public function handler(array $config)
45
    {
46
        if (empty($config['handler'])) {
47
            return;
48
        }
49
50
        $factory = is_callable($handler = $config['handler'])
51
            ? $handler
52
            : $this->app->make($handler, $config['with'] ?? []);
53
54
        return $factory($config);
55
    }
56
57
    /**
58
     * Prepare handler stack for usage by Guzzle client.
59
     *
60
     * @param  \GuzzleHttp\HandlerStack $handler
61
     * @param  array $config
62
     * @return \GuzzleHttp\HandlerStack
63
     */
64
    protected function prepareHandler(HandlerStack $handler, array $config = [])
65
    {
66
        foreach ($this->middleware($config) as [$middleware, $name]) {
67
            $handler->push($middleware, $name);
68
        }
69
70
        return $this->tap($handler, $config);
71
    }
72
73
    /**
74
     * Apply the configured taps for the handle stack.
75
     *
76
     * @param  \GuzzleHttp\HandlerStack  $handler
77
     * @param  array  $config
78
     * @return \GuzzleHttp\HandlerStack
79
     */
80
    protected function tap(HandlerStack $handler, array $config = [])
81
    {
82
        foreach ($config['tap'] ?? [] as $tap) {
83
            [$class, $arguments] = $this->parseTap($tap);
84
85
            $this->app->make($class)->__invoke(
86
                $handler, ...array_filter(explode(',', $arguments))
87
            );
88
        }
89
90
        return $handler;
91
    }
92
93
    /**
94
     * Parse the given tap class string into a class name and arguments string.
95
     *
96
     * @param  string  $tap
97
     * @return array
98
     */
99
    protected function parseTap($tap)
100
    {
101
        return Str::contains($tap, ':') ? explode(':', $tap, 2) : [$tap, ''];
102
    }
103
104
    /**
105
     * Parse the given class string into a class name and arguments array.
106
     *
107
     * @param  mixed $key
108
     * @param  mixed $value
109
     * @return array
110
     */
111
    protected function parseClassAndArguments($key, $value)
112
    {
113
        if (is_string($key) && is_array($value)) {
114
            return [$key, $value];
115
        }
116
117
        return [$value, []];
118
    }
119
120
    /**
121
     * Get all middleware that will be pushed to handle stack instance.
122
     *
123
     * @param  array $config
124
     * @return array
125
     */
126
    public function middleware(array $config)
127
    {
128
        $middleware = [];
129
130
        foreach (array_merge($config['middleware'] ?? [], $config['interceptors'] ?? []) as $key => $value) {
131
            $middleware[] = $this->parseMiddleware($key, $value);
132
        }
133
134
        return $middleware;
135
    }
136
137
    /**
138
     * Parse the given middleware and create middleware instance with it's parameters.
139
     *
140
     * @param  mixed $key
141
     * @param  mixed $value
142
     * @return array
143
     */
144
    protected function parseMiddleware($key, $value)
145
    {
146
        $name = is_numeric($key) ? '' : $key;
147
148
        if (is_callable($value)) {
149
            // $value = $this->isLazyEvaluable($value) ? $this->app->call($value) : $value;
150
            $value = $this->isLazyEvaluable($value) ? $value() : $value;
151
152
            return [$value, $name];
153
        }
154
155
        [$class, $arguments] = $this->parseClassAndArguments($key, $value);
156
157
        return [$this->app->make($class, $arguments), $class];
158
    }
159
160
    /**
161
     * Determine if the callable is lazy evaluated.
162
     *
163
     * @return bool
164
     */
165
    protected function isLazyEvaluable(callable $callable)
166
    {
167
        return $callable instanceof LazyEvaluation;
168
    }
169
}
170