Blame | Letzte Änderung | Log anzeigen | RSS feed
<?phpnamespace Illuminate\Pipeline;use Closure;use Illuminate\Contracts\Container\Container;use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;use RuntimeException;use Throwable;class Pipeline implements PipelineContract{/*** The container implementation.** @var \Illuminate\Contracts\Container\Container|null*/protected $container;/*** The object being passed through the pipeline.** @var mixed*/protected $passable;/*** The array of class pipes.** @var array*/protected $pipes = [];/*** The method to call on each pipe.** @var string*/protected $method = 'handle';/*** Create a new class instance.** @param \Illuminate\Contracts\Container\Container|null $container* @return void*/public function __construct(Container $container = null){$this->container = $container;}/*** Set the object being sent through the pipeline.** @param mixed $passable* @return $this*/public function send($passable){$this->passable = $passable;return $this;}/*** Set the array of pipes.** @param array|mixed $pipes* @return $this*/public function through($pipes){$this->pipes = is_array($pipes) ? $pipes : func_get_args();return $this;}/*** Push additional pipes onto the pipeline.** @param array|mixed $pipes* @return $this*/public function pipe($pipes){array_push($this->pipes, ...(is_array($pipes) ? $pipes : func_get_args()));return $this;}/*** Set the method to call on the pipes.** @param string $method* @return $this*/public function via($method){$this->method = $method;return $this;}/*** Run the pipeline with a final destination callback.** @param \Closure $destination* @return mixed*/public function then(Closure $destination){$pipeline = array_reduce(array_reverse($this->pipes()), $this->carry(), $this->prepareDestination($destination));return $pipeline($this->passable);}/*** Run the pipeline and return the result.** @return mixed*/public function thenReturn(){return $this->then(function ($passable) {return $passable;});}/*** Get the final piece of the Closure onion.** @param \Closure $destination* @return \Closure*/protected function prepareDestination(Closure $destination){return function ($passable) use ($destination) {try {return $destination($passable);} catch (Throwable $e) {return $this->handleException($passable, $e);}};}/*** Get a Closure that represents a slice of the application onion.** @return \Closure*/protected function carry(){return function ($stack, $pipe) {return function ($passable) use ($stack, $pipe) {try {if (is_callable($pipe)) {// If the pipe is a callable, then we will call it directly, but otherwise we// will resolve the pipes out of the dependency container and call it with// the appropriate method and arguments, returning the results back out.return $pipe($passable, $stack);} elseif (! is_object($pipe)) {[$name, $parameters] = $this->parsePipeString($pipe);// If the pipe is a string we will parse the string and resolve the class out// of the dependency injection container. We can then build a callable and// execute the pipe function giving in the parameters that are required.$pipe = $this->getContainer()->make($name);$parameters = array_merge([$passable, $stack], $parameters);} else {// If the pipe is already an object we'll just make a callable and pass it to// the pipe as-is. There is no need to do any extra parsing and formatting// since the object we're given was already a fully instantiated object.$parameters = [$passable, $stack];}$carry = method_exists($pipe, $this->method)? $pipe->{$this->method}(...$parameters): $pipe(...$parameters);return $this->handleCarry($carry);} catch (Throwable $e) {return $this->handleException($passable, $e);}};};}/*** Parse full pipe string to get name and parameters.** @param string $pipe* @return array*/protected function parsePipeString($pipe){[$name, $parameters] = array_pad(explode(':', $pipe, 2), 2, []);if (is_string($parameters)) {$parameters = explode(',', $parameters);}return [$name, $parameters];}/*** Get the array of configured pipes.** @return array*/protected function pipes(){return $this->pipes;}/*** Get the container instance.** @return \Illuminate\Contracts\Container\Container** @throws \RuntimeException*/protected function getContainer(){if (! $this->container) {throw new RuntimeException('A container instance has not been passed to the Pipeline.');}return $this->container;}/*** Set the container instance.** @param \Illuminate\Contracts\Container\Container $container* @return $this*/public function setContainer(Container $container){$this->container = $container;return $this;}/*** Handle the value returned from each pipe before passing it to the next.** @param mixed $carry* @return mixed*/protected function handleCarry($carry){return $carry;}/*** Handle the given exception.** @param mixed $passable* @param \Throwable $e* @return mixed** @throws \Throwable*/protected function handleException($passable, Throwable $e){throw $e;}}