Projekt

Obecné

Profil

Stáhnout (4.45 KB) Statistiky
| Větev: | Revize:
1
<?php
2

    
3
namespace Illuminate\Pipeline;
4

    
5
use Closure;
6
use Illuminate\Contracts\Container\Container;
7
use Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;
8

    
9
class Pipeline implements PipelineContract
10
{
11
    /**
12
     * The container implementation.
13
     *
14
     * @var \Illuminate\Contracts\Container\Container
15
     */
16
    protected $container;
17

    
18
    /**
19
     * The object being passed through the pipeline.
20
     *
21
     * @var mixed
22
     */
23
    protected $passable;
24

    
25
    /**
26
     * The array of class pipes.
27
     *
28
     * @var array
29
     */
30
    protected $pipes = [];
31

    
32
    /**
33
     * The method to call on each pipe.
34
     *
35
     * @var string
36
     */
37
    protected $method = 'handle';
38

    
39
    /**
40
     * Create a new class instance.
41
     *
42
     * @param  \Illuminate\Contracts\Container\Container  $container
43
     * @return void
44
     */
45
    public function __construct(Container $container)
46
    {
47
        $this->container = $container;
48
    }
49

    
50
    /**
51
     * Set the object being sent through the pipeline.
52
     *
53
     * @param  mixed  $passable
54
     * @return $this
55
     */
56
    public function send($passable)
57
    {
58
        $this->passable = $passable;
59

    
60
        return $this;
61
    }
62

    
63
    /**
64
     * Set the array of pipes.
65
     *
66
     * @param  array|mixed  $pipes
67
     * @return $this
68
     */
69
    public function through($pipes)
70
    {
71
        $this->pipes = is_array($pipes) ? $pipes : func_get_args();
72

    
73
        return $this;
74
    }
75

    
76
    /**
77
     * Set the method to call on the pipes.
78
     *
79
     * @param  string  $method
80
     * @return $this
81
     */
82
    public function via($method)
83
    {
84
        $this->method = $method;
85

    
86
        return $this;
87
    }
88

    
89
    /**
90
     * Run the pipeline with a final destination callback.
91
     *
92
     * @param  \Closure  $destination
93
     * @return mixed
94
     */
95
    public function then(Closure $destination)
96
    {
97
        $firstSlice = $this->getInitialSlice($destination);
98

    
99
        $pipes = array_reverse($this->pipes);
100

    
101
        return call_user_func(
102
            array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable
103
        );
104
    }
105

    
106
    /**
107
     * Get a Closure that represents a slice of the application onion.
108
     *
109
     * @return \Closure
110
     */
111
    protected function getSlice()
112
    {
113
        return function ($stack, $pipe) {
114
            return function ($passable) use ($stack, $pipe) {
115
                if ($pipe instanceof Closure) {
116
                    // If the pipe is an instance of a Closure, we will just call it directly but
117
                    // otherwise we'll resolve the pipes out of the container and call it with
118
                    // the appropriate method and arguments, returning the results back out.
119
                    return call_user_func($pipe, $passable, $stack);
120
                } elseif (! is_object($pipe)) {
121
                    list($name, $parameters) = $this->parsePipeString($pipe);
122

    
123
                    // If the pipe is a string we will parse the string and resolve the class out
124
                    // of the dependency injection container. We can then build a callable and
125
                    // execute the pipe function giving in the parameters that are required.
126
                    $pipe = $this->container->make($name);
127

    
128
                    $parameters = array_merge([$passable, $stack], $parameters);
129
                } else {
130
                    // If the pipe is already an object we'll just make a callable and pass it to
131
                    // the pipe as-is. There is no need to do any extra parsing and formatting
132
                    // since the object we're given was already a fully instantiated object.
133
                    $parameters = [$passable, $stack];
134
                }
135

    
136
                return call_user_func_array([$pipe, $this->method], $parameters);
137
            };
138
        };
139
    }
140

    
141
    /**
142
     * Get the initial slice to begin the stack call.
143
     *
144
     * @param  \Closure  $destination
145
     * @return \Closure
146
     */
147
    protected function getInitialSlice(Closure $destination)
148
    {
149
        return function ($passable) use ($destination) {
150
            return call_user_func($destination, $passable);
151
        };
152
    }
153

    
154
    /**
155
     * Parse full pipe string to get name and parameters.
156
     *
157
     * @param  string $pipe
158
     * @return array
159
     */
160
    protected function parsePipeString($pipe)
161
    {
162
        list($name, $parameters) = array_pad(explode(':', $pipe, 2), 2, []);
163

    
164
        if (is_string($parameters)) {
165
            $parameters = explode(',', $parameters);
166
        }
167

    
168
        return [$name, $parameters];
169
    }
170
}
(2-2/4)