Completed
Pull Request — master (#24)
by Gabriel
02:37
created

buildBannersFromData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 3
nop 1
dl 0
loc 9
ccs 6
cts 7
cp 0.8571
crap 3.0261
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\BannerServer\Utils;
6
7
use Symfony\Component\Yaml\Yaml;
8
use WMDE\BannerServer\Entity\BannerSelection\Banner;
9
use WMDE\BannerServer\Entity\BannerSelection\Bucket;
10
use WMDE\BannerServer\Entity\BannerSelection\Campaign;
11
use WMDE\BannerServer\Entity\BannerSelection\CampaignCollection;
12
13
/**
14
 * @license GNU GPL v2+
15
 */
16
class CampaignConfigurationLoader {
17
18
	private $configFile;
19
20 5
	public function __construct( string $configFile ) {
21 5
		$this->configFile = $configFile;
22 5
	}
23
24
	/**
25
	 * @throws \DomainException
26
	 * @throws \Symfony\Component\Yaml\Exception\ParseException
27
	 */
28 5
	public function getCampaignCollection(): CampaignCollection {
29 5
		$campaigns = [];
30 5
		foreach ( $this->parseConfiguration() as $campaignName => $campaignData ) {
31 4
				$campaign = $this->buildCampaignFromData( $campaignName, $campaignData );
32 1
				$campaigns[] = $campaign;
33
		}
34 1
		return new CampaignCollection( ...$campaigns );
35
	}
36
37
	/**
38
	 * @throws \DomainException
39
	 */
40 4
	private function buildCampaignFromData( string $campaignName, array $campaignData ): Campaign {
41 4
		$buckets = $this->buildBucketsFromData( $campaignData );
42 2
		if ( empty( $buckets ) ) {
43
			throw new \DomainException( 'Campaign contains no buckets.' );
44
		}
45 2
		if ( empty( $campaignData['start'] ) || empty( $campaignData['end'] ) || !isset( $campaignData['trafficLimit'] ) ) {
46 1
			throw new \DomainException( 'Campaign data is incomplete.' );
47
		}
48 1
		return new Campaign(
49 1
			$campaignName,
50 1
			new \DateTime( $campaignData['start'] ),
51 1
			new \DateTime( $campaignData['end'] ),
52 1
			(int)$campaignData['trafficLimit'],
53 1
			new SystemRandomIntegerGenerator(),
54 1
			array_shift( $buckets ),
55 1
			...$buckets
56
		);
57
	}
58
59
	/**
60
	 * @throws \DomainException
61
	 */
62 4
	private function buildBucketsFromData( array $campaignData ): array {
63 4
		$buckets = [];
64 4
		foreach ( $campaignData['buckets'] as $bucketData ) {
65 4
			$bucket = $this->buildBucketFromData( $bucketData );
66 2
			$buckets[] = $bucket;
67
		}
68 2
		return $buckets;
69
	}
70
71
	/**
72
	 * @throws \DomainException
73
	 */
74 4
	private function buildBucketFromData( array $bucketData ): Bucket {
75 4
		if ( !isset( $bucketData['name'] ) ) {
76 1
			throw new \DomainException( 'A configured bucket has no name.' );
77
		}
78 3
		if ( !isset( $bucketData['banners'] ) ) {
79 1
			throw new \DomainException( 'A configured bucket has no associated banners.' );
80
		}
81 2
		$banners = $this->buildBannersFromData( $bucketData['banners'] );
82 2
		if ( empty( $banners ) ) {
83
			throw new \DomainException( 'A configured bucket has no valid banners associated with it.' );
84
		}
85 2
		return new Bucket( $bucketData['name'], array_shift( $banners ), ...$banners );
86
	}
87
88
	/**
89
	 * @throws \DomainException
90
	 */
91 2
	private function buildBannersFromData( array $bannerData ): array {
92 2
		$banners = [];
93 2
		foreach ( $bannerData as $bannerIdentifier ) {
94 2
			if ( !$bannerIdentifier ) {
95
				throw new \DomainException( 'A configured banner has an empty name.' );
96
			}
97 2
			$banners[] = new Banner( $bannerIdentifier );
98
		}
99 2
		return $banners;
100
	}
101
102
	/**
103
	 * @throws \Symfony\Component\Yaml\Exception\ParseException
104
	 */
105 5
	private function parseConfiguration(): array {
106 5
		return Yaml::parseFile( $this->configFile );
107
	}
108
}