PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.22
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.22
2.1.0 2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 All 42 releases
fluent-boards / vendor / wpfluent / framework / src / WPFluent / Support / Pipeline.php

Pipeline.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.22, at vendor/wpfluent/framework/src/WPFluent/Support/Pipeline.php

259 lines 6.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\Framework\Support;
4
5 use Closure;
6 use Throwable;
7 use RuntimeException;
8 use FluentBoards\Framework\Container\Container;
9
10 class Pipeline
11 {
12 /**
13 * The container implementation.
14 *
15 * @var \FluentBoards\Framework\Container\Container
16 */
17 protected $container;
18
19 /**
20 * The object being passed through the pipeline.
21 *
22 * @var mixed
23 */
24 protected $passable;
25
26 /**
27 * The array of class pipes.
28 *
29 * @var array
30 */
31 protected $pipes = [];
32
33 /**
34 * The method to call on each pipe.
35 *
36 * @var string
37 */
38 protected $method = 'handle';
39
40 /**
41 * Create a new class instance.
42 *
43 * @param \FluentBoards\Framework\Container\Container|null $container
44 * @return void
45 */
46 public function __construct(Container $container = null)
47 {
48 $this->container = $container;
49 }
50
51 /**
52 * Set the object being sent through the pipeline.
53 *
54 * @param mixed $passable
55 * @return $this
56 */
57 public function send($passable)
58 {
59 $this->passable = $passable;
60
61 return $this;
62 }
63
64 /**
65 * Set the array of pipes.
66 *
67 * @param array|mixed $pipes
68 * @return $this
69 */
70 public function through($pipes)
71 {
72 $this->pipes = is_array($pipes) ? $pipes : func_get_args();
73
74 return $this;
75 }
76
77 /**
78 * Set the method to call on the pipes.
79 *
80 * @param string $method
81 * @return $this
82 */
83 public function via($method)
84 {
85 $this->method = $method;
86
87 return $this;
88 }
89
90 /**
91 * Run the pipeline with a final destination callback.
92 *
93 * @param \Closure $destination
94 * @return mixed
95 */
96 public function then(Closure $destination)
97 {
98 $pipeline = array_reduce(
99 array_reverse($this->pipes()), $this->carry(), $this->prepareDestination($destination)
100 );
101
102 return $pipeline($this->passable);
103 }
104
105 /**
106 * Run the pipeline and return the result.
107 *
108 * @return mixed
109 */
110 public function thenReturn()
111 {
112 return $this->then(function ($passable) {
113 return $passable;
114 });
115 }
116
117 /**
118 * Get the final piece of the Closure onion.
119 *
120 * @param \Closure $destination
121 * @return \Closure
122 */
123 protected function prepareDestination(Closure $destination)
124 {
125 return function ($passable) use ($destination) {
126 try {
127 return $destination($passable);
128 } catch (Throwable $e) {
129 return $this->handleException($passable, $e);
130 }
131 };
132 }
133
134 /**
135 * Get a Closure that represents a slice of the application onion.
136 *
137 * @return \Closure
138 */
139 protected function carry()
140 {
141 return function ($stack, $pipe) {
142 return function ($passable) use ($stack, $pipe) {
143 try {
144 if (is_callable($pipe)) {
145 // If the pipe is a callable, then we will call it directly, but otherwise we
146 // will resolve the pipes out of the dependency container and call it with
147 // the appropriate method and arguments, returning the results back out.
148 return $pipe($passable, $stack);
149 }
150 if (! is_object($pipe)) {
151 [$name, $parameters] = $this->parsePipeString($pipe);
152
153 // If the pipe is a string we will parse the string and resolve the class out
154 // of the dependency injection container. We can then build a callable and
155 // execute the pipe function giving in the parameters that are required.
156 $pipe = $this->getContainer()->make($name);
157
158 $parameters = array_merge([$passable, $stack], $parameters);
159 } else {
160 // If the pipe is already an object we'll just make a callable and pass it to
161 // the pipe as-is. There is no need to do any extra parsing and formatting
162 // since the object we're given was already a fully instantiated object.
163 $parameters = [$passable, $stack];
164 }
165
166 $carry = method_exists($pipe, $this->method)
167 ? $pipe->{$this->method}(...$parameters)
168 : $pipe(...$parameters);
169
170 return $this->handleCarry($carry);
171 } catch (Throwable $e) {
172 return $this->handleException($passable, $e);
173 }
174 };
175 };
176 }
177
178 /**
179 * Parse full pipe string to get name and parameters.
180 *
181 * @param string $pipe
182 * @return array
183 */
184 protected function parsePipeString($pipe)
185 {
186 [$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, []);
187
188 if (is_string($parameters)) {
189 $parameters = explode(',', $parameters);
190 }
191
192 return [$name, $parameters];
193 }
194
195 /**
196 * Get the array of configured pipes.
197 *
198 * @return array
199 */
200 protected function pipes()
201 {
202 return $this->pipes;
203 }
204
205 /**
206 * Get the container instance.
207 *
208 * @return \FluentBoards\Framework\Container\Container
209 *
210 * @throws \RuntimeException
211 */
212 protected function getContainer()
213 {
214 if (! $this->container) {
215 throw new RuntimeException('A container instance has not been passed to the Pipeline.');
216 }
217
218 return $this->container;
219 }
220
221 /**
222 * Set the container instance.
223 *
224 * @param \FluentBoards\Framework\Container\Container $container
225 * @return $this
226 */
227 public function setContainer(Container $container)
228 {
229 $this->container = $container;
230
231 return $this;
232 }
233
234 /**
235 * Handle the value returned from each pipe before passing it to the next.
236 *
237 * @param mixed $carry
238 * @return mixed
239 */
240 protected function handleCarry($carry)
241 {
242 return $carry;
243 }
244
245 /**
246 * Handle the given exception.
247 *
248 * @param mixed $passable
249 * @param \Throwable $e
250 * @return mixed
251 *
252 * @throws \Throwable
253 */
254 protected function handleException($passable, Throwable $e)
255 {
256 throw $e;
257 }
258 }
259