Completed
Push — cargo ( c7a763...bb6ae5 )
by Jeroen De
03:23
created

CargoOutputBuilder::setIconUrl()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 8
cp 0
rs 9.9666
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 12
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace Maps\Map\CargoFormat;
6
7
use CargoFieldDescription;
8
use DataValues\Geo\Values\LatLongValue;
9
use Maps\DataAccess\ImageRepository;
10
use Maps\Map\MapData;
11
use Maps\Map\MapOutput;
12
use Maps\Map\MapOutputBuilder;
13
use Maps\Map\Marker;
14
use Maps\MappingService;
15
use Maps\MappingServices;
16
use ParamProcessor\ParamDefinitionFactory;
17
use ParamProcessor\Processor;
18
19
class CargoOutputBuilder {
20
21
	private $outputBuilder;
22
	private $services;
23
	private $paramDefinitionFactory;
24
	private $imageRepository;
25
26
	public function __construct( MapOutputBuilder $outputBuilder, MappingServices $services,
27
		ParamDefinitionFactory $paramDefinitionFactory, ImageRepository $imageRepository ) {
28
29
		$this->outputBuilder = $outputBuilder;
30
		$this->services = $services;
31
		$this->paramDefinitionFactory = $paramDefinitionFactory;
32
		$this->imageRepository = $imageRepository;
33
	}
34
35
	public function buildOutputFromCargoData( array $values, array $formattedValues, array $fieldDescriptions, array $displayParams ): MapOutput {
0 ignored issues
show
Unused Code introduced by
The parameter $values is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
36
		$service = $this->services->getDefaultService();
37
38
		$mapData = $service->newMapDataFromProcessingResult( $this->processParameters( $service, $displayParams ) );
39
		$mapData->setMarkers( $this->createMarkers( $formattedValues, $fieldDescriptions, $mapData ) );
40
41
		return $this->outputBuilder->buildOutput(
42
			$service,
43
			$mapData
44
		);
45
	}
46
47
	private function createMarkers( array $formattedValues, array $fieldDescriptions, MapData $mapData ): array {
48
		$markers = $this->cargoValuesToMarkers(
49
			$formattedValues,
50
			$fieldDescriptions
51
		);
52
53
		$this->setIconUrl( $markers, $mapData->getParameters()['icon'] );
54
55
		return $markers;
56
	}
57
58
	private function setIconUrl( array $markers, string $iconParameter ): void {
59
		if ( $iconParameter !== '' ) {
60
			$iconUrl = $this->imageRepository->getByName( $iconParameter )->getUrl();
61
62
			foreach ( $markers as $marker ) {
63
				$marker->setIconUrl( $iconUrl );
64
			}
65
		}
66
	}
67
68
	private function processParameters( MappingService $service, array $displayParams ) {
69
		$processor = Processor::newDefault();
70
71
		$processor->setParameters( $displayParams );
72
		$processor->setParameterDefinitions( $this->getParameterDefinitions( $service ) );
73
74
		return $processor->processParameters();
75
	}
76
77
	private function getParameterDefinitions( MappingService $service ): array {
78
		return $this->paramDefinitionFactory->newDefinitionsFromArrays( $service->getParameterInfo() ) ;
79
	}
80
81
	/**
82
	 * @return Marker[]
83
	 */
84
	private function cargoValuesToMarkers( array $formattedValues, array $fieldDescriptions ): array {
85
		$coordinateFields = $this->getCoordinateFieldNames( $fieldDescriptions );
86
		$markers = [];
87
88
		foreach ( $formattedValues as $valuesRow ) {
89
			foreach ( $coordinateFields as $coordinateField ) {
90
				$markers[] = $this->newMarker( $valuesRow, $coordinateField, $coordinateFields );
91
			}
92
		}
93
94
		return $markers;
95
	}
96
97
	/**
98
	 * @param CargoFieldDescription[] $fieldDescriptions
99
	 * @return string[]
100
	 */
101
	private function getCoordinateFieldNames( array $fieldDescriptions ): array {
102
		$names = [];
103
104
		foreach ( $fieldDescriptions as $fieldName => $field ) {
105
			if ( $field->mType === 'Coordinates' ) {
106
				$names[] = str_replace( ' ', '_', $fieldName );
107
			}
108
		}
109
110
		return $names;
111
	}
112
113
	private function newMarker( array $valuesRow, string $coordinateField, array $coordinateFields ): Marker {
114
		$marker = new Marker( new LatLongValue(
115
			(float)$valuesRow[$coordinateField . '  lat'],
116
			(float)$valuesRow[$coordinateField . '  lon']
117
		) );
118
119
		$marker->setText(
120
			( new PopupContent(
121
				array_shift( $valuesRow ) ?? '',
122
				$this->getPropertyValuesToDisplay( $valuesRow, $coordinateFields )
123
			) )->getHtml()
124
		);
125
126
		return $marker;
127
	}
128
129
	private function getPropertyValuesToDisplay( array $valuesRow, array $coordinateFields ): array {
130
		$propertyValues = [];
131
132
		foreach ( $valuesRow as $name => $value ) {
133
			if ( $this->shouldDisplayValue( $name, $coordinateFields ) ) {
134
				$propertyValues[$name] = $value;
135
			}
136
		}
137
138
		return $propertyValues;
139
	}
140
141
	private function shouldDisplayValue( string $name, array $coordinateFields ): bool {
142
		$hiddenFields = [];
143
144
		foreach ( $coordinateFields as $field ) {
145
			$hiddenFields[] = $field;
146
			$hiddenFields[] = $field . '  lat';
147
			$hiddenFields[] = $field . '  lon';
148
		}
149
150
		return !in_array( $name, $hiddenFields );
151
	}
152
153
}
154