Completed
Pull Request — master (#41)
by
unknown
63:48
created

BannerSelectionUseCase   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 8
eloc 30
c 4
b 0
f 0
dl 0
loc 54
ccs 23
cts 23
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A isRatioLimited() 0 2 1
B selectBanner() 0 32 6
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\BannerServer\UseCase\BannerSelection;
6
7
use WMDE\BannerServer\Entity\BannerSelection\Campaign;
8
use WMDE\BannerServer\Entity\BannerSelection\CampaignCollection;
9
use WMDE\BannerServer\Entity\BannerSelection\ImpressionThreshold;
10
use WMDE\BannerServer\Entity\BannerSelection\RandomIntegerGenerator;
11
use WMDE\BannerServer\Entity\Visitor;
12
13
/**
14
 * @license GNU GPL v2+
15
 */
16
class BannerSelectionUseCase {
17
18
	private $campaignCollection;
19
	private $impressionThreshold;
20
	private $rng;
21
22 5
	/**
23 5
	 * @var Campaign
24 5
	 */
25 5
	private $currentCampaign;
0 ignored issues
show
introduced by
The private property $currentCampaign is not used, and could be removed.
Loading history...
26 5
27
	public function __construct( CampaignCollection $campaignCollection, ImpressionThreshold $impressionThreshold, RandomIntegerGenerator $rng ) {
28 5
		$this->campaignCollection = $campaignCollection;
29 5
		$this->impressionThreshold = $impressionThreshold;
30 5
		$this->rng = $rng;
31 5
	}
32 5
33 2
	public function selectBanner( Visitor $visitor ): BannerSelectionData {
34
		$remainingCampaigns = $this->campaignCollection->filter(
35
			function ( Campaign $campaign ) use ( $visitor ): bool {
36 3
				return (
37 3
					$campaign->isInActiveDateRange( new \DateTime() ) &&
38
					$campaign->isInDisplayRange( $visitor->getDisplayWidth() ) &&
39
					!$this->impressionThreshold->isThresholdReached( $visitor->getTotalImpressionCount() ) &&
40 3
					!$visitor->inCategory( $campaign->getCategory() ) &&
41 3
					!$this->isRatioLimited( $campaign->getDisplayPercentage() )
42 3
				);
43 3
			}
44
		);
45
46
		if ( $remainingCampaigns->isEmpty() ) {
47 5
			return new EmptyBannerSelectionData( $visitor );
48 5
		}
49 5
50
		$selectedCampaign = $remainingCampaigns->getFirstCampaign();
51 5
52
		$visitorBucket = $selectedCampaign->selectBucket(
53
			$visitor->getBucketIdentifier()
54 5
		);
55 5
56
		return new ActiveBannerSelectionData(
57
			new Visitor(
58
				$visitor->getTotalImpressionCount() + 1,
59
				$visitorBucket->getIdentifier(),
60
				$visitor->getDisplayWidth(),
61
				...$visitor->getCategories()
62
			),
63
			$visitorBucket->getBanner( $visitor->getTotalImpressionCount() ),
64
			$selectedCampaign->getEnd()
65
		);
66
	}
67
68
	private function isRatioLimited( int $campaignDisplayPercent ): bool {
69
		return $this->rng->getRandomInteger( 1, 100 ) > $campaignDisplayPercent;
70
	}
71
}