Test Setup Failed
Push — new-cookie-route ( 6ee6e7 )
by Gabriel
65:17
created

AbstractCookieController::newHtmlResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 2
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
		if ( $categories === '' || !preg_match( '/^[-0-9a-zA-Z_,]+$/', $categories ) ) {
17
			return $this->newHtmlResponse( 'No donation category specified', Response::HTTP_BAD_REQUEST );
18
		}
19
		if ( $this->isImageRequest( $request ) ) {
20
			$response = $this->newImageResponse();
21
		} else {
22
			$response = $this->newHtmlResponse( 'Thank you for donating' );
23
		}
24
25
		$expiry = ( new \DateTime() )->add( $this->getCookieLifetime() );
26
		$response->headers->setCookie( Cookie::create(
27
			BannerSelectionController::CATEGORY_COOKIE,
28
			$categories,
29
			$expiry,
30
			'/',
31
			null,
32
			true,
33
			true,
34
			false,
35
			Cookie::SAMESITE_NONE
36
		) );
37
		return $response;
38
	}
39
40
	abstract protected function getCookieLifetime(): \DateInterval;
41
42
	private function newHtmlResponse( string $message, int $status = Response::HTTP_OK ): Response {
43
		$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
	}
47
48
	private function isImageRequest( Request $request ): bool {
49
		$contentTypes = $request->getAcceptableContentTypes();
50
		if ( count( $contentTypes ) < 1 ) {
51
			return false;
52
		}
53
		$preferredContent = $contentTypes[0];
54
		return strpos( $preferredContent, 'image/' ) === 0;
55
	}
56
57
	private function newImageResponse(): Response {
58
		return new Response( '', Response::HTTP_OK, [
59
			'content-type' => 'image/png',
60
		] );
61
	}
62
}
63