AbstractCookieController::index()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 24
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 19
c 1
b 0
f 0
dl 0
loc 24
ccs 16
cts 16
cp 1
rs 9.6333
cc 4
nc 3
nop 1
crap 4
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\BannerServer\Controller;
6
7
use Symfony\Component\HttpFoundation\Cookie;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpFoundation\Response;
10
11
abstract class AbstractCookieController {
12
	public const CATEGORY_PARAM = 'c';
13
14
	public function index( Request $request ): Response {
15
		$categories = trim( (string)$request->query->get( self::CATEGORY_PARAM, '' ) );
16 4
		if ( $categories === '' || !preg_match( '/^[-0-9a-zA-Z_,]+$/', $categories ) ) {
17 4
			return $this->newHtmlResponse( 'No donation category specified', Response::HTTP_BAD_REQUEST );
18
		}
19
		if ( $this->isImageRequest( $request ) ) {
20 4
			$response = $this->newImageResponse();
21 4
		} else {
22 4
			$response = $this->newHtmlResponse( 'Thank you for donating' );
23 2
		}
24
25 2
		$expiry = ( new \DateTime() )->add( $this->getCookieLifetime() );
26 1
		$response->headers->setCookie( Cookie::create(
27
			BannerSelectionController::CATEGORY_COOKIE,
28 1
			$categories,
29
			$expiry,
30
			'/',
31 2
			null,
32 2
			true,
33 2
			true,
34 2
			false,
35 2
			Cookie::SAMESITE_NONE
36 2
		) );
37 2
		return $response;
38 2
	}
39 2
40 2
	abstract protected function getCookieLifetime(): \DateInterval;
41 2
42 2
	private function newHtmlResponse( string $message, int $status = Response::HTTP_OK ): Response {
43 2
		$html = "<!DOCTYPE html><html lang='en'><head><title>WMDE Banner Server</title>" .
44
			"<meta charset=utf-8></head><body>$message</body></html>";
45
		return new Response( $html, $status, [ 'content-type' => 'text/html' ] );
46 3
	}
47 3
48 3
	private function isImageRequest( Request $request ): bool {
49 3
		$contentTypes = $request->getAcceptableContentTypes();
50
		if ( count( $contentTypes ) < 1 ) {
51
			return false;
52 2
		}
53 2
		$preferredContent = $contentTypes[0];
54 2
		return strpos( $preferredContent, 'image/' ) === 0;
55 1
	}
56
57 1
	private function newImageResponse(): Response {
58 1
		return new Response( '', Response::HTTP_OK, [
59
			'content-type' => 'image/png',
60
		] );
61 1
	}
62
}
63