ModuleEntryPoint::filterRequestMethod()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 8.7414

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 11
ccs 3
cts 9
cp 0.3333
rs 9.2
cc 4
eloc 7
nc 4
nop 0
crap 8.7414
1
<?php
2
3
namespace PPP\Module;
4
5
use Deserializers\Exceptions\DeserializationException;
6
use Exception;
7
use PPP\DataModel\DeserializerFactory;
8
use PPP\DataModel\SerializerFactory;
9
use PPP\Module\DataModel\Deserializers\ModuleRequestDeserializer;
10
use PPP\Module\DataModel\ModuleRequest;
11
use PPP\Module\DataModel\ModuleResponse;
12
use PPP\Module\DataModel\Serializers\ModuleResponseSerializer;
13
14
/**
15
 * Entry point for Modules
16
 *
17
 * @licence MIT
18
 * @author Thomas Pellissier Tanon
19
 */
20
class ModuleEntryPoint {
21
22
	/**
23
	 * @var RequestHandler
24
	 */
25
	private $requestHandler;
26
27
	/**
28
	 * @param RequestHandler $requestHandler
29
	 */
30 7
	public function __construct(RequestHandler $requestHandler) {
31 7
		$this->requestHandler = $requestHandler;
32 7
	}
33
34
	/**
35
	 * Main function
36
	 */
37 7
	public function exec() {
38
		try {
39 7
			$this->filterRequestMethod();
40 7
			$request = $this->getRequest();
41 6
			$responses = $this->requestHandler->buildResponse($request);
42 5
			$this->outputResponse($this->serializeResponse($this->cleanResponses($responses, $request)));
43 7
		} catch(HttpException $e) {
44 1
			$this->outputHttpException($e);
45 2
		} catch(Exception $e) {
46 1
			$this->outputHttpException(new HttpException($e->getMessage(), 500, $e));
47
		}
48 7
	}
49
50 7
	private function filterRequestMethod() {
0 ignored issues
show
Coding Style introduced by
filterRequestMethod uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
51 7
		if(!array_key_exists('REQUEST_METHOD', $_SERVER)) {
52 7
			return;
53
		}
54
		if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
55
			exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method filterRequestMethod() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
56
		}
57
		if($_SERVER['REQUEST_METHOD'] !== 'POST') {
58
			new HttpException('Bad request method: ' . $_SERVER['REQUEST_METHOD'], 405);
59
		}
60
	}
61
62
	/**
63
	 * @return ModuleRequest
64
	 */
65 7
	private function getRequest() {
66 7
		$requestJson = json_decode($this->getRequestBody(), true);
67
		try {
68 7
			return $this->buildRequestDeserializer()->deserialize($requestJson);
69 1
		} catch(DeserializationException $e) {
70 1
			throw new HttpException($e->getMessage(), 400, $e);
71
		}
72
	}
73
74
	public function getRequestBody() {
75
		return file_get_contents("php://input");
76
	}
77
78 5
	private function cleanResponses(array $responses, ModuleRequest $request) {
79 5
		$cleanedResponses = array();
80
81
		/** @var ModuleResponse $response */
82 5
		foreach($responses as $response) {
83 4
			if($request->getSentenceTree()->equals($response->getSentenceTree())) {
84
				continue;
85
			}
86
87
			/** @var ModuleResponse $existingResponse */
88 4
			foreach($cleanedResponses as $existingResponse) {
89 1
				if($existingResponse->getSentenceTree()->equals($response->getSentenceTree())) {
90 1
					continue 2;
91
				}
92 4
			}
93
94 4
			$cleanedResponses[] = new ModuleResponse(
95 4
				$response->getLanguageCode(),
96 4
				$response->getSentenceTree(),
97 4
				$response->getMeasures() + $request->getMeasures(),
98 4
				$response->getTrace()
99 4
			);
100 5
		}
101
102 5
		return $cleanedResponses;
103
	}
104
105 5
	private function outputResponse($serialization) {
106 5
		@header('Content-type: application/json');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
107 5
		echo json_encode($serialization);
108 5
	}
109
110 5
	private function serializeResponse(array $responses) {
111 5
		$serialization = array();
112 5
		foreach($responses as $response) {
113 4
			$serialization[] = $this->buildResponseSerializer()->serialize($response);
114 5
		}
115 5
		return $serialization;
116
	}
117
118 7
	private function buildRequestDeserializer() {
119 7
		$deserializerFactory = new DeserializerFactory($this->requestHandler->getCustomResourceNodeDeserializers());
120 7
		return new ModuleRequestDeserializer($deserializerFactory->newNodeDeserializer());
121
	}
122
123 4
	private function buildResponseSerializer() {
124 4
		$serializerFactory = new SerializerFactory($this->requestHandler->getCustomResourceNodeSerializers());
125 4
		return new ModuleResponseSerializer($serializerFactory->newNodeSerializer());
126
	}
127
128 2
	private function outputHttpException(HttpException $exception) {
129 2
		$this->setHttpResponseCode($exception->getCode());
130 2
		echo $exception->getMessage();
131 2
	}
132
133 2
	private function setHttpResponseCode($code) {
134 2
		if(function_exists('http_response_code')) {
135 2
			@http_response_code($code);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
136 2
		} else {
137
			@header('X-PHP-Response-Code: '. $code, true, $code);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
138
		}
139 2
	}
140
}
141