BannerSelectionController::selectBanner()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
dl 0
loc 21
rs 9.7998
c 1
b 0
f 0
ccs 16
cts 16
cp 1
cc 3
nc 3
nop 1
crap 3
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\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use WMDE\BannerServer\Entity\Visitor;
12
use WMDE\BannerServer\UseCase\BannerSelection\BannerSelectionUseCase;
13
14
/**
15
 * @license GPL-2.0-or-later
16
 */
17
class BannerSelectionController {
18
19
	public const IMPRESSION_COUNT_COOKIE = 'impCount';
20
	public const BUCKET_COOKIE = 'b';
21
	public const CATEGORY_COOKIE = 'cat';
22
23 5
	public function __construct(
24
		private readonly BannerSelectionUseCase $useCase,
25
		private readonly string $bannerPath
26
	) {
27 5
	}
28
29 5
	public function selectBanner( Request $request ): Response {
30 5
		$bannerResponseData = $this->useCase->selectBanner( $this->buildValuesFromRequest( $request ) );
31 5
		if ( !$bannerResponseData->displayBanner() ) {
32 3
			$response = new Response( '// Sorry, no banner for you!' );
33 3
			$response->headers->set( 'Content-Type', 'application/javascript; charset=UTF-8' );
34 3
			return $response;
35
		}
36
37 2
		$response = new RedirectResponse(
38 2
			$this->getBannerUrl( $bannerResponseData->getBannerIdentifier() ),
39 2
			Response::HTTP_FOUND
40 2
		);
41
42 2
		foreach ( $this->getCookies(
43 2
			$bannerResponseData->getVisitorData(),
44 2
			$bannerResponseData->getCampaignEnd()->modify( '+2 week' )
45 2
		) as $cookie ) {
46 2
			$response->headers->setCookie( $cookie );
47
		}
48
49 2
		return $response;
50
	}
51
52 5
	private function buildValuesFromRequest( Request $request ): Visitor {
53 5
		$rawCategories = (string)$request->cookies->get( self::CATEGORY_COOKIE, '' );
54 5
		$categories = array_filter( explode( ',', $rawCategories ) );
55 5
		return new Visitor(
56 5
			$request->cookies->getInt( self::IMPRESSION_COUNT_COOKIE, 0 ),
57 5
			(string)$request->cookies->get( self::BUCKET_COOKIE, null ) ?: null,
58 5
			$request->query->getInt( 'vWidth' ),
59 5
			...$categories
60 5
		);
61
	}
62
63 2
	private function getBannerUrl( string $bannerIdentifier ): string {
64 2
		return $this->bannerPath . $bannerIdentifier . '.js';
65
	}
66
67
	/**
68
	 * @param Visitor $visitor
69
	 * @param \DateTime $cookieExpirationDate
70
	 *
71
	 * @return Cookie[]
72
	 * @throws \Exception
73
	 */
74 2
	private function getCookies( Visitor $visitor, \DateTime $cookieExpirationDate ): array {
75 2
		return [
76 2
			Cookie::create( self::BUCKET_COOKIE, $visitor->getBucketIdentifier(), $cookieExpirationDate ),
77 2
			Cookie::create(
78 2
				self::IMPRESSION_COUNT_COOKIE,
79 2
				(string)$visitor->getTotalImpressionCount(),
80 2
				new \DateTime( 'midnight first day of january next year' )
81 2
			)
82 2
		];
83
	}
84
}
85