| 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 | use WMDE\BannerServer\InvalidConfigurationValueException; |
||
| 13 | |||
| 14 | /** |
||
| 15 | * @license GPL-2.0-or-later |
||
| 16 | */ |
||
| 17 | class CampaignConfigurationLoader { |
||
| 18 | |||
| 19 | private string $configFile; |
||
| 20 | |||
| 21 | 7 | public function __construct( string $configFile ) { |
|
| 22 | 7 | $this->configFile = $configFile; |
|
| 23 | } |
||
| 24 | |||
| 25 | 7 | public function getCampaignCollection(): CampaignCollection { |
|
| 26 | 7 | $campaigns = []; |
|
| 27 | 7 | foreach ( $this->parseConfiguration() as $campaignName => $campaignData ) { |
|
| 28 | 6 | $campaign = $this->buildCampaignFromData( $campaignName, $campaignData ); |
|
| 29 | 2 | $campaigns[] = $campaign; |
|
| 30 | } |
||
| 31 | 2 | return new CampaignCollection( ...$campaigns ); |
|
| 32 | } |
||
| 33 | |||
| 34 | 6 | private function buildCampaignFromData( string $campaignName, array $campaignData ): Campaign { |
|
| 35 | 6 | $buckets = $this->buildBucketsFromData( $campaignData ); |
|
| 36 | 4 | if ( empty( $buckets ) ) { |
|
| 37 | throw new InvalidConfigurationValueException( 'Campaign contains no buckets.' ); |
||
| 38 | } |
||
| 39 | 4 | if ( empty( $campaignData['start'] ) || empty( $campaignData['end'] ) || !isset( $campaignData['trafficLimit'] ) ) { |
|
| 40 | 1 | throw new InvalidConfigurationValueException( 'Campaign data is incomplete.' ); |
|
| 41 | } |
||
| 42 | 3 | $minDisplayWidth = $this->integerOrNullValue( $campaignData, 'minDisplayWidth' ); |
|
| 43 | 3 | $maxDisplayWidth = $this->integerOrNullValue( $campaignData, 'maxDisplayWidth' ); |
|
| 44 | 3 | if ( $minDisplayWidth && $maxDisplayWidth && $minDisplayWidth > $maxDisplayWidth ) { |
|
|
0 ignored issues
–
show
The expression
$minDisplayWidth of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
Loading history...
|
|||
| 45 | 1 | throw new InvalidConfigurationValueException( |
|
| 46 | 1 | 'Campaign data display width values are invalid (if defined, max must be higher than min).' |
|
| 47 | 1 | ); |
|
| 48 | } |
||
| 49 | 2 | return new Campaign( |
|
| 50 | 2 | $campaignName, |
|
| 51 | 2 | new \DateTime( $campaignData['start'] ), |
|
| 52 | 2 | new \DateTime( $campaignData['end'] ), |
|
| 53 | 2 | (int)$campaignData['trafficLimit'], |
|
| 54 | 2 | $campaignData['category'] ?? 'default', |
|
| 55 | 2 | new SystemRandomIntegerGenerator(), |
|
| 56 | 2 | $minDisplayWidth, |
|
| 57 | 2 | $maxDisplayWidth, |
|
| 58 | 2 | array_shift( $buckets ), |
|
| 59 | 2 | ...$buckets |
|
| 60 | 2 | ); |
|
| 61 | } |
||
| 62 | |||
| 63 | 6 | private function buildBucketsFromData( array $campaignData ): array { |
|
| 64 | 6 | $buckets = []; |
|
| 65 | 6 | foreach ( $campaignData['buckets'] as $bucketData ) { |
|
| 66 | 6 | $bucket = $this->buildBucketFromData( $bucketData ); |
|
| 67 | 4 | $buckets[] = $bucket; |
|
| 68 | } |
||
| 69 | 4 | return $buckets; |
|
| 70 | } |
||
| 71 | |||
| 72 | 6 | private function buildBucketFromData( array $bucketData ): Bucket { |
|
| 73 | 6 | if ( !isset( $bucketData['name'] ) ) { |
|
| 74 | 1 | throw new InvalidConfigurationValueException( 'A configured bucket has no name.' ); |
|
| 75 | } |
||
| 76 | 5 | if ( !isset( $bucketData['banners'] ) ) { |
|
| 77 | 1 | throw new InvalidConfigurationValueException( 'A configured bucket has no associated banners.' ); |
|
| 78 | } |
||
| 79 | 4 | $banners = $this->buildBannersFromData( $bucketData['banners'] ); |
|
| 80 | 4 | if ( empty( $banners ) ) { |
|
| 81 | throw new InvalidConfigurationValueException( 'A configured bucket has no valid banners associated with it.' ); |
||
| 82 | } |
||
| 83 | 4 | return new Bucket( $bucketData['name'], array_shift( $banners ), ...$banners ); |
|
| 84 | } |
||
| 85 | |||
| 86 | 4 | private function buildBannersFromData( array $bannerData ): array { |
|
| 87 | 4 | $banners = []; |
|
| 88 | 4 | foreach ( $bannerData as $bannerIdentifier ) { |
|
| 89 | 4 | if ( !$bannerIdentifier ) { |
|
| 90 | throw new InvalidConfigurationValueException( 'A configured banner has an empty name.' ); |
||
| 91 | } |
||
| 92 | 4 | $banners[] = new Banner( $bannerIdentifier ); |
|
| 93 | } |
||
| 94 | 4 | return $banners; |
|
| 95 | } |
||
| 96 | |||
| 97 | 7 | private function parseConfiguration(): array { |
|
| 98 | 7 | return Yaml::parseFile( $this->configFile ); |
|
| 99 | } |
||
| 100 | |||
| 101 | 3 | private function integerOrNullValue( array $campaignData, string $key ): ?int { |
|
| 102 | 3 | if ( !isset( $campaignData[$key] ) ) { |
|
| 103 | 2 | return null; |
|
| 104 | } |
||
| 105 | 3 | $value = $campaignData[$key]; |
|
| 106 | 3 | if ( !is_numeric( $value ) ) { |
|
| 107 | return null; |
||
| 108 | } |
||
| 109 | 3 | return intval( $value ); |
|
| 110 | } |
||
| 111 | } |
||
| 112 |
In PHP, under loose comparison (like
==, or!=, orswitchconditions), values of different types might be equal.For
integervalues, zero is a special case, in particular the following results might be unexpected: