Test Setup Failed
Pull Request — master (#37)
by Gabriel
62:16
created

DonationFinishedController::index()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 10
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 14
rs 9.9332
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
/**
12
 * @license GNU GPL v2+
13
 */
14
class DonationFinishedController {
15
	public const CATEGORY_PARAM = 'c';
16
17
	private $donationFinishedCookieLifetime;
18
19
	/**
20
	 * @param string $donationFinishedCookieLifetime PHP {@link \DateInterval} string, e.g. 'P180D' or 'P6M'
21
	 */
22
	public function __construct( string $donationFinishedCookieLifetime ) {
23
		$this->donationFinishedCookieLifetime = $donationFinishedCookieLifetime;
24
	}
25
26
	public function index( Request $request ): Response {
27
		$categories = trim( $request->query->get( self::CATEGORY_PARAM, '' ) );
28
		if ( $categories === '' || !preg_match( '/^[-0-9a-zA-Z_,]+$/', $categories ) ) {
29
			return $this->newHtmlResponse( 'No donation category specified', Response::HTTP_BAD_REQUEST );
30
		}
31
		if ( $this->isImageRequest( $request ) ) {
32
			$response = $this->newImageResponse();
33
		} else {
34
			$response = $this->newHtmlResponse( 'Thank you for donating' );
35
		}
36
37
		$expiry = ( new \DateTime() )->add( new \DateInterval( $this->donationFinishedCookieLifetime ) );
38
		$response->headers->setCookie( Cookie::create( BannerSelectionController::CATEGORY_COOKIE, $categories, $expiry, '/', null, false, false ) );
39
		return $response;
40
	}
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
}