HasPipeline::getPipeline()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 13
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Conveyor\SocketHandlers\Traits;
4
5
use Exception;
6
use InvalidArgumentException;
7
use League\Pipeline\Pipeline;
8
use League\Pipeline\PipelineBuilder;
9
use Conveyor\Exceptions\InvalidActionException;
10
use Conveyor\Actions\Interfaces\ActionInterface;
11
use Conveyor\SocketHandlers\Abstractions\SocketHandler;
12
13
trait HasPipeline
14
{
15
    /** @var array */
16
    protected $pipelineMap = [];
17
18
    /** @var array */
19
    protected $handlerMap = [];
20
21
    /** @var array */
22
    protected $parsedData;
23
24
    /**
25
     * @param string   $data   Data to be processed.
26
     * @param int|null $fd     File descriptor (connection).
27
     * @param mixed    $server Server object, e.g. Swoole\WebSocket\Frame.
28
     *
29
     * @throws Exception
30
     */
31
    public function __invoke(string $data, $fd = null, $server = null)
32
    {
33
        /** @var ActionInterface */
34
        $action = $this->parseData($data);
0 ignored issues
show
Bug introduced by
It seems like parseData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

34
        /** @scrutinizer ignore-call */ 
35
        $action = $this->parseData($data);
Loading history...
35
36
        /** @var Pipeline */
37
        $pipeline = $this->getPipeline($action->getName());
38
39
        /** @throws Exception */
40
        $pipeline->process($this);
41
42
        $this->maybeSetFd($fd);
0 ignored issues
show
Bug introduced by
It seems like maybeSetFd() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

42
        $this->/** @scrutinizer ignore-call */ 
43
               maybeSetFd($fd);
Loading history...
43
        $this->maybeSetServer($server);
0 ignored issues
show
Bug introduced by
It seems like maybeSetServer() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

43
        $this->/** @scrutinizer ignore-call */ 
44
               maybeSetServer($server);
Loading history...
44
45
        return $action->execute($this->parsedData);
46
    }
47
48
    /**
49
     * @return array
50
     */
51
    public function getParsedData() : array
52
    {
53
        return $this->parsedData;
54
    }
55
56
    /**
57
     * Prepare pipeline based on the current prepared handlers.
58
     *
59
     * @param string $action
60
     *
61
     * @return Pipeline
62
     */
63
    public function getPipeline(string $action) : Pipeline
64
    {
65
        $pipelineBuilder = new PipelineBuilder;
66
67
        if (!isset($this->pipelineMap[$action])) {
68
            return $pipelineBuilder->build();
69
        }
70
71
        foreach ($this->pipelineMap[$action] as $actionName => $middleware) {
72
            $pipelineBuilder->add($middleware);
73
        }
74
75
        return $pipelineBuilder->build();
76
    }
77
78
    /**
79
     * Add an action to be handled. It returns a pipeline for
80
     * eventual middlewares to be added for each.
81
     *
82
     * @param ActionInterface $actionHandler
83
     *
84
     * @return SocketHandler
85
     */
86
    public function add(ActionInterface $actionHandler) : SocketHandler
87
    {
88
        $actionName = $actionHandler->getName();
89
        $this->handlerMap[$actionName] = $actionHandler;
90
        
91
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Conveyor\SocketHandlers\Traits\HasPipeline which is incompatible with the type-hinted return Conveyor\SocketHandlers\Abstractions\SocketHandler.
Loading history...
92
    }
93
94
    /**
95
     * Add a step for the current's action middleware.
96
     *
97
     * @param string $action
98
     * @param Callable $middleware
99
     *
100
     * @return void
101
     */
102
    public function middleware(string $action, callable $middleware) : void
103
    {
104
        if (!isset($this->pipelineMap[$action])) {
105
            $this->pipelineMap[$action] = [];
106
        }
107
108
        $this->pipelineMap[$action][] = $middleware;
109
    }
110
111
    /**
112
     * @param array $data
113
     *
114
     * @return void
115
     *
116
     * @throws InvalidArgumentException|InvalidActionException
117
     */
118
    final public function validateData(array $data) : void
119
    {
120
        if (!isset($data['action'])) {
121
            throw new InvalidArgumentException('Missing action key in data!');
122
        }
123
124
        if (!isset($this->handlerMap[$data['action']])) {
125
            throw new InvalidActionException('Invalid Action! This action (' . $data['action'] . ') is not set.');
126
        }
127
    }
128
129
    /**
130
     * Get an Action by name
131
     *
132
     * @param string $name
133
     *
134
     * @return ActionInterface|null
135
     */
136
    public function getAction(string $name)
137
    {
138
        return $this->handlerMap[$name];
139
    }
140
}
141