Completed
Pull Request — master (#39)
by
unknown
116:52 queued 56:06
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
	protected string $cookieLifetime;
15
16
	public function __construct( string $cookieLifetime ) {
17
		$this->cookieLifetime = $cookieLifetime;
18
	}
19
20
	public function index( Request $request ): Response {
21
		$categories = trim( $request->query->get( self::CATEGORY_PARAM, '' ) );
22
		if ( $categories === '' || !preg_match( '/^[-0-9a-zA-Z_,]+$/', $categories ) ) {
23
			return $this->newHtmlResponse( 'No donation category specified', Response::HTTP_BAD_REQUEST );
24
		}
25
		if ( $this->isImageRequest( $request ) ) {
26
			$response = $this->newImageResponse();
27
		} else {
28
			$response = $this->newHtmlResponse( 'Thank you for donating' );
29
		}
30
31
		$expiry = ( new \DateTime() )->add( new \DateInterval( $this->cookieLifetime ) );
32
		$response->headers->setCookie( Cookie::create(
33
			BannerSelectionController::CATEGORY_COOKIE,
34
			$categories,
35
			$expiry,
36
			'/',
37
			null,
38
			true,
39
			true,
40
			false,
41
			Cookie::SAMESITE_NONE
42
		) );
43
		return $response;
44
	}
45
46
	private function newHtmlResponse( string $message, int $status = Response::HTTP_OK ): Response {
47
		$html = "<!DOCTYPE html><html lang='en'><head><title>WMDE Banner Server</title>" .
48
			"<meta charset=utf-8></head><body>$message</body></html>";
49
		return new Response( $html, $status, [ 'content-type' => 'text/html' ] );
50
	}
51
52
	private function isImageRequest( Request $request ): bool {
53
		$contentTypes = $request->getAcceptableContentTypes();
54
		if ( count( $contentTypes ) < 1 ) {
55
			return false;
56
		}
57
		$preferredContent = $contentTypes[0];
58
		return strpos( $preferredContent, 'image/' ) === 0;
59
	}
60
61
	private function newImageResponse(): Response {
62
		return new Response( '', Response::HTTP_OK, [
63
			'content-type' => 'image/png',
64
		] );
65
	}
66
}