Completed
Push — newparam ( 9f04a0...72433c )
by Jeroen De
04:14 queued 02:51
created

DisplayMapRenderer::getMapHTML()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 11
cts 11
cp 1
rs 9.7333
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Maps\MediaWiki\ParserHooks;
4
5
use FormatJson;
6
use Html;
7
use Maps\DataAccess\MediaWikiFileUrlFinder;
8
use Maps\Elements\Location;
9
use Maps\MappingService;
10
use Maps\Presentation\ElementJsonSerializer;
11
use Maps\Presentation\MapHtmlBuilder;
12
use Maps\Presentation\WikitextParser;
13
use Maps\Presentation\WikitextParsers\LocationParser;
14
use Parser;
15
16
/**
17
 * Class handling the #display_map rendering.
18
 *
19
 * @licence GNU GPL v2+
20
 * @author Jeroen De Dauw < [email protected] >
21
 * @author Kim Eik
22
 */
23
class DisplayMapRenderer {
24
25
	public $service;
26
27
	/**
28
	 * @var LocationParser
29
	 */
30
	private $locationParser;
31
32
	/**
33
	 * @var MediaWikiFileUrlFinder
34
	 */
35
	private $fileUrlFinder;
36
37
	/**
38
	 * @var WikitextParser
39
	 */
40
	private $wikitextParser;
41
	/**
42
	 * @var ElementJsonSerializer
43
	 */
44
	private $elementSerializer;
45
46 21
	public function __construct( MappingService $service = null ) {
47 21
		$this->service = $service;
48 21
	}
49
50
	/**
51
	 * Handles the request from the parser hook by doing the work that's common for all
52
	 * mapping services, calling the specific methods and finally returning the resulting output.
53
	 *
54
	 * @param array $params
55
	 * @param Parser $parser
56
	 *
57
	 * @return string
58
	 */
59 21
	public final function renderMap( array $params, Parser $parser ) {
60 21
		$factory = \Maps\MapsFactory::newDefault();
61
62 21
		$this->locationParser = $factory->newLocationParser();
63 21
		$this->fileUrlFinder = $factory->getFileUrlFinder();
64
65 21
		$this->wikitextParser = new WikitextParser( clone $parser );
66 21
		$this->elementSerializer = new ElementJsonSerializer( $this->wikitextParser );
67
68 21
		$this->handleMarkerData( $params );
69
70 21
		$output = ( new MapHtmlBuilder() )->getMapHTML(
71 21
			$params,
72 21
			$this->service->newMapId(),
73 21
			$this->service->getName()
74
		);
75
76 21
		$dependencies = $this->service->getDependencyHtml( $params );
77
78
		// Only add a head item when there are dependencies.
79 21
		if ( $dependencies ) {
80 21
			$parser->getOutput()->addHeadItem( $dependencies );
81
		}
82
83 21
		$parser->getOutput()->addModules( $this->service->getResourceModules() );
84
85 21
		return $output;
86
	}
87
88
	/**
89
	 * Converts the data in the coordinates parameter to JSON-ready objects.
90
	 * These get stored in the locations parameter, and the coordinates on gets deleted.
91
	 */
92 21
	private function handleMarkerData( array &$params ) {
93 21
		$params['centre'] = $this->getCenter( $params['centre'] );
94
95 21
		if ( is_object( $params['wmsoverlay'] ) ) {
96
			$params['wmsoverlay'] = $params['wmsoverlay']->getJSONObject();
97
		}
98
99 21
		$params['locations'] = $this->getLocationJson( $params );
100
101 21
		unset( $params['coordinates'] );
102
103 21
		$this->handleShapeData( $params );
104 21
	}
105
106 21
	private function getCenter( $coordinatesOrAddress ) {
107 21
		if ( $coordinatesOrAddress === false ) {
108 21
			return false;
109
		}
110
111
		try {
112
			// FIXME: a Location makes no sense here, since the non-coordinate data is not used
113
			$location = $this->locationParser->parse( $coordinatesOrAddress );
114
		}
115
		catch ( \Exception $ex ) {
116
			// TODO: somehow report this to the user
117
			return false;
118
		}
119
120
		return $location->getJSONObject();
121
	}
122
123 21
	private function getLocationJson( array $params ) {
124 21
		$iconUrl = $this->fileUrlFinder->getUrlForFileName( $params['icon'] );
125 21
		$visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] );
126
127 21
		$locationJsonObjects = [];
128
129 21
		foreach ( $params['coordinates'] as $coordinatesOrAddress ) {
130
			try {
131 16
				$location = $this->locationParser->parse( $coordinatesOrAddress );
132
			}
133 1
			catch ( \Exception $ex ) {
134
				// TODO: somehow report this to the user
135 1
				continue;
136
			}
137
138 15
			$locationJsonObjects[] = $this->getLocationJsonObject(
139 15
				$location,
140 15
				$params,
141 15
				$iconUrl,
142 15
				$visitedIconUrl
143
			);
144
		}
145
146 21
		return $locationJsonObjects;
147
	}
148
149 15
	private function getLocationJsonObject( Location $location, array $params, $iconUrl, $visitedIconUrl ) {
150 15
		$jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl );
151
152 15
		$this->elementSerializer->titleAndText( $jsonObj );
153
154 15
		if ( isset( $jsonObj['inlineLabel'] ) ) {
155 1
			$jsonObj['inlineLabel'] = strip_tags(
156 1
				$this->wikitextParser->wikitextToHtml( $jsonObj['inlineLabel'] ),
157 1
				'<a><img>'
158
			);
159
		}
160
161 15
		return $jsonObj;
162
	}
163
164 21
	private function handleShapeData( array &$params ) {
165
		$textContainers = [
166 21
			&$params['lines'],
167 21
			&$params['polygons'],
168 21
			&$params['circles'],
169 21
			&$params['rectangles'],
170 21
			&$params['imageoverlays'], // FIXME: this is Google Maps specific!!
171
		];
172
173 21
		foreach ( $textContainers as &$textContainer ) {
174 21
			if ( is_array( $textContainer ) ) {
175 21
				foreach ( $textContainer as &$obj ) {
176 5
					$obj = $this->elementSerializer->elementToJson( $obj );
177
				}
178
			}
179
		}
180 21
	}
181
182
}
183