Completed
Push — master ( 34418f...bffe6c )
by Sébastien
01:55
created

Pipeline::__clone()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Bdf\Pipeline;
4
5
use Bdf\Pipeline\Processor\StackProcessor;
6
7
/**
8
 * Pipeline
9
 *
10
 * @author Johnmeurt
11
 */
12
final class Pipeline
13
{
14
    /**
15
     * The pipe processor
16
     *
17
     * @var ProcessorInterface
18
     */
19
    private $processor;
20
21
    /**
22
     * The first pipe from the chain
23
     *
24
     * @var Pipe
25
     */
26
    private $first;
27
28
    /**
29
     * The last pipe from the chain
30
     *
31
     * @var Pipe
32
     */
33
    private $last;
34
35
    /**
36
     * The destination of the last pipe
37
     *
38
     * @var callable
39
     */
40
    private $outlet;
41
42
    /**
43
     * Pipeline constructor.
44
     *
45
     * @param array $pipes
46
     * @param ProcessorInterface $processor
47
     */
48
    public function __construct(array $pipes = [], ProcessorInterface $processor = null)
49
    {
50
        $this->processor = $processor ?: new StackProcessor();
51
52
        // Set the default outlet
53
        $this->outlet = function($payload) {
54
            return $payload;
55
        };
56
57
        foreach ($pipes as $pipe) {
58
            $this->pipe($pipe);
59
        }
60
    }
61
62
    /**
63
     * Add a pipe at the beginning of the chain
64
     *
65
     * @param callable $first
66
     */
67
    public function prepend($first)
68
    {
69
        $this->add($first, true);
70
    }
71
72
    /**
73
     * Add a pipe
74
     *
75
     * @param callable $last
76
     */
77
    public function pipe($last)
78
    {
79
        $this->add($last);
80
    }
81
82
    /**
83
     * Add a pipe
84
     *
85
     * @param callable $pipe
86
     * @param boolean  $prepend
87
     */
88
    private function add($pipe, $prepend = false)
89
    {
90
        // Set the outlet on last pipe
91
        $pipe = new Pipe($this->processor, $pipe);
92
        $pipe->setNext($this->outlet);
93
94
        // Detect the first pipe
95
        if ($this->first === null) {
96
            $this->first = $pipe;
97
            $this->last = $pipe;
98
        } elseif ($prepend === false) {
99
            $this->last->setNext($pipe);
100
            $this->last = $pipe;
101
        } else {
102
            $pipe->setNext($this->first);
103
            $this->first = $pipe;
104
        }
105
    }
106
107
    /**
108
     * Set the pipeline outlet
109
     *
110
     * @param callable $outlet
111
     */
112
    public function outlet(callable $outlet)
113
    {
114
        $this->outlet = $outlet;
115
116
        if ($this->last !== null) {
117
            $this->last->setNext($outlet);
118
        }
119
    }
120
121
    /**
122
     * Send the payload into the pipeline.
123
     *
124
     * @param array $payload
125
     *
126
     * @return mixed
127
     */
128
    public function send(...$payload)
129
    {
130
        $callback = $this->first ?: $this->outlet;
131
132
        return $callback(...$payload);
133
    }
134
135
    /**
136
     * Clone the pipes
137
     */
138
    public function __clone()
139
    {
140
        if ($this->first !== null) {
141
            $this->first = clone $this->first;
142
        }
143
    }
144
}
145