This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Veto. |
||
4 | * PHP Microframework. |
||
5 | * |
||
6 | * @author Damien Walsh <[email protected]> |
||
7 | * @copyright Damien Walsh 2013-2014 |
||
8 | * @version 0.1 |
||
9 | * @package veto |
||
10 | */ |
||
11 | namespace Veto\Layer; |
||
12 | |||
13 | use Veto\DependencyInjection\AbstractContainerAccessor; |
||
14 | use Veto\Http\Request; |
||
15 | use Veto\Http\Response; |
||
16 | |||
17 | /** |
||
18 | * LayerChain |
||
19 | * |
||
20 | * Groups layers together to form a Request->Response flow |
||
21 | */ |
||
22 | class LayerChain extends AbstractContainerAccessor |
||
23 | { |
||
24 | /** |
||
25 | * An associative, 2D array of layers that are configured. |
||
26 | * Layers are stored here keyed by priority then name. |
||
27 | * |
||
28 | * @var array |
||
29 | */ |
||
30 | private $layers = array(); |
||
31 | |||
32 | /** |
||
33 | * Add a layer to this LayerChain. |
||
34 | * |
||
35 | * @param object $layer |
||
36 | * @param int $priority |
||
37 | */ |
||
38 | public function addLayer($layer, $priority = 0) |
||
39 | { |
||
40 | // Enforce the type of $layer |
||
41 | if (!($layer instanceof InboundLayerInterface || $layer instanceof OutboundLayerInterface)) { |
||
42 | throw new \InvalidArgumentException( |
||
43 | 'Argument 1 of ' . __CLASS__ . '::' . __METHOD__ . |
||
44 | ' must be either an InboundLayerInterface or an OutboundLayerInterface instance.' |
||
45 | ); |
||
46 | } |
||
47 | |||
48 | $this->layers[$priority][] = $layer; |
||
49 | |||
50 | // TODO: Improve the efficiency of this by _not_ sorting after every insertion |
||
51 | ksort($this->layers); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * @param Request $request |
||
56 | * @return Response |
||
57 | * @throws \RuntimeException |
||
58 | */ |
||
59 | public function processLayers(Request $request) |
||
60 | { |
||
61 | // There must be at least one inbound layer, otherwise our Request will never become a Response |
||
62 | if (0 === count($this->layers)) { |
||
63 | throw new \RuntimeException( |
||
64 | 'At least one layer must be defined in order to handle requests.' |
||
65 | ); |
||
66 | } |
||
67 | |||
68 | $response = $this->processInboundLayers($request); |
||
69 | |||
70 | // By the end of the inbound layer list, a response should have been obtained |
||
71 | if (!$response instanceof Response) { |
||
72 | throw new \RuntimeException( |
||
73 | 'At least one inbound layer must produce a Response instance. ' . |
||
74 | 'The final processed layer returned a "' . gettype($response) . '".' |
||
75 | ); |
||
76 | } |
||
77 | |||
78 | // The response should now be processed by the outbound layers |
||
79 | return $this->processOutboundLayers($response); |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * @param Request $request |
||
84 | * @return Request |
||
85 | */ |
||
86 | View Code Duplication | private function processInboundLayers(Request $request) |
|
0 ignored issues
–
show
|
|||
87 | { |
||
88 | $result = $request; |
||
89 | |||
90 | // Pass through layers inwards |
||
91 | foreach ($this->layers as $priority => $layers) { |
||
92 | foreach ($layers as $layerName => $layer) { |
||
93 | |||
94 | if (!($layer instanceof InboundLayerInterface)) { |
||
95 | continue; |
||
96 | } |
||
97 | |||
98 | $result = $layer->in($result); |
||
99 | |||
100 | // If the layer produces a response, no more inbound layers may execute |
||
101 | if ($result instanceof Response) { |
||
102 | return $result; |
||
0 ignored issues
–
show
The return type of
return $result; (Veto\Http\Response ) is incompatible with the return type documented by Veto\Layer\LayerChain::processInboundLayers of type Veto\Http\Request .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
103 | } |
||
104 | |||
105 | if (!$result instanceof Request) { |
||
106 | throw new \RuntimeException( |
||
107 | 'Each inbound layer of the chain must produce a Request or Response type. ' . |
||
108 | 'The "' . $layerName . '" layer returned ' . gettype($request) . '.' |
||
109 | ); |
||
110 | } |
||
111 | } |
||
112 | } |
||
113 | |||
114 | return $result; |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * @param Response $response |
||
119 | * @return Response |
||
120 | */ |
||
121 | View Code Duplication | private function processOutboundLayers(Response $response) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
122 | { |
||
123 | $result = $response; |
||
124 | |||
125 | foreach ($this->layers as $priority => $layers) { |
||
126 | foreach ($layers as $layerName => $layer) { |
||
127 | |||
128 | if (!($layer instanceof OutboundLayerInterface)) { |
||
129 | continue; |
||
130 | } |
||
131 | |||
132 | $result = $layer->out($result); |
||
133 | |||
134 | if (!$result instanceof Response) { |
||
135 | throw new \RuntimeException( |
||
136 | 'Each outbound layer of the chain must produce a Response type. ' . |
||
137 | 'The "' . $layerName . '" layer returned ' . gettype($response) . '.' |
||
138 | ); |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | |||
143 | return $result; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Get the layers currently added to this LayerChain, keyed by priority group. |
||
148 | * |
||
149 | * @return array[] |
||
150 | */ |
||
151 | public function getLayers() |
||
152 | { |
||
153 | return $this->layers; |
||
154 | } |
||
155 | } |
||
156 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.