Completed
Push — master ( 6dc7d8...407c40 )
by Karsten
15:45
created

formats/filtered/src/View/MapView.php (1 issue)

Check that a foreach expression is traversable

Bug Major

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace SRF\Filtered\View;
4
5
use DataValues\Geo\Parsers\LatLongParser;
6
use Exception;
7
use Message;
8
use SMWPropertyValue;
9
use SRF\Filtered\ResultItem;
10
11
class MapView extends View {
12
13
	private static $viewParams = null;
14
15
	private $mapProvider = null;
16
17
	/**
18
	 * @param null $mapProvider
19
	 */
20 2
	public function setMapProvider( $mapProvider ) {
21 2
		$this->mapProvider = $mapProvider;
22 2
	}
23
24
	/**
25
	 * @return null
26
	 */
27 2
	public function getMapProvider() {
28 2
		if ( $this->mapProvider === null ) {
29 2
			$this->setMapProvider( isset( $GLOBALS['srfgMapProvider'] ) ? $GLOBALS['srfgMapProvider'] : '' );
30
		}
31
32 2
		return $this->mapProvider;
33
	}
34
35
	/**
36
	 * @param ResultItem $row
37
	 *
38
	 * @return array|null
39
	 */
40 1
	public function getJsDataForRow( ResultItem $row ) {
41
42 1
		$markerPositionPropertyName = str_replace(
43 1
			' ',
44 1
			'_',
45 1
			$this->getActualParameters()['map view marker position property']
46
		);
47
48 1
		foreach ( $row->getValue() as $field ) {
49
50 1
			$printRequest = $field->getPrintRequest();
51 1
			$field->reset();
52
53 1
			$value = $field->getNextDataItem();
54 1
			if ( $printRequest->getData() instanceof SMWPropertyValue &&
55 1
				$printRequest->getData()->getInceptiveProperty()->getKey() === $markerPositionPropertyName &&
56 1
				( $value instanceof \SMWDIGeoCoord || $value instanceof \SMWDIBlob )
57
			) {
58
				$values = []; // contains plain text
59
60
				if ( $value instanceof \SMWDIGeoCoord ) {
61
62
					while ( $value instanceof \SMWDIGeoCoord ) {
63
						$values[] = [ 'lat' => $value->getLatitude(), 'lng' => $value->getLongitude() ];
64
						$value = $field->getNextDataItem();
65
					}
66
67
				} elseif ( class_exists( 'DataValues\Geo\Parsers\GeoCoordinateParser' ) ) {
68
69
					$coordParser = new LatLongParser();
70
					while ( $value instanceof \SMWDataItem ) {
71
						try {
72
							$latlng = $coordParser->parse( $value->getSerialization() );
73
							$values[] = [ 'lat' => $latlng->getLatitude(), 'lng' => $latlng->getLongitude() ];
74
							$value = $field->getNextDataItem();
75
						}
76
						catch ( Exception $exception ) {
77
							$this->getQueryPrinter()->addError( "Error on '$value': " . $exception->getMessage() );
78
						}
79
					}
80
81
				} else {
82
					$this->getQueryPrinter()->addError(
83
						Message::newFromKey( 'srf-filtered-map-geocoordinateparser-missing-error' )->inContentLanguage(
84
						)->text()
85
					);
86
				}
87
88 1
				return [ 'positions' => $values, ];
89
			}
90
		}
91
92 1
		return null;
93
	}
94
95
	/**
96
	 * Returns an array of config data for this view to be stored in the JS
97
	 *
98
	 * @return array
99
	 */
100 1
	public function getJsConfig() {
101 1
		$config = parent::getJsConfig();
102
103
		$jsConfigKeys = [
104 1
			'height',
105
			'zoom',
106
			'minZoom',
107
			'maxZoom',
108
			'marker cluster',
109
			'marker cluster max zoom',
110
			'maxClusterRadius',
111
			'zoomToBoundsOnClick',
112
		];
113
114 1
		foreach ( $jsConfigKeys as $key ) {
115 1
			$this->addToConfig( $config, $key );
116
		}
117
118 1
		$this->addMarkerIconSetupToConfig( $config );
119
120 1
		$config['map provider'] = $this->getMapProvider();
121
122 1
		return $config;
123
	}
124
125
	/**
126
	 * A function to describe the allowed parameters of a query for this view.
127
	 *
128
	 * @return array of Parameter
129
	 */
130 2
	public static function getParameters() {
131
132 2
		if ( self::$viewParams === null ) {
133
134 1
			$params = parent::getParameters();
135
136 1
			$params['marker position property'] = [
137
				// 'type' => 'string',
138
				'name' => 'map view marker position property',
139
				'message' => 'srf-paramdesc-filtered-map-position',
140
				'default' => '',
141
				// 'islist' => false,
142
			];
143
144 1
			$params['marker icon property'] = [
145
				// 'type' => 'string',
146
				'name' => 'map view marker icon property',
147
				'message' => 'srf-paramdesc-filtered-map-icon',
148
				'default' => '',
149
				// 'islist' => false,
150
			];
151
152 1
			$params['marker icons'] = [
153
				// 'type' => 'string',
154
				'name' => 'map view marker icons',
155
				'message' => 'srf-paramdesc-filtered-map-icons',
156
				'default' => [],
157
				'islist' => true,
158
			];
159
160 1
			$params['height'] = [
161
				'type' => 'dimension',
162
				'name' => 'map view height',
163
				'message' => 'srf-paramdesc-filtered-map-height',
164
				'default' => 'auto',
165
				// 'islist' => false,
166
			];
167
168 1
			$params['zoom'] = [
169
				'type' => 'integer',
170
				'name' => 'map view zoom',
171
				'message' => 'srf-paramdesc-filtered-map-zoom',
172
				'default' => '',
173
				// 'islist' => false,
174
			];
175
176 1
			$params['minZoom'] = [
177
				'type' => 'integer',
178
				'name' => 'map view min zoom',
179
				'message' => 'srf-paramdesc-filtered-map-min-zoom',
180
				'default' => '',
181
				// 'islist' => false,
182
			];
183
184 1
			$params['maxZoom'] = [
185
				'type' => 'integer',
186
				'name' => 'map view max zoom',
187
				'message' => 'srf-paramdesc-filtered-map-max-zoom',
188
				'default' => '',
189
				// 'islist' => false,
190
			];
191
192
			//markercluster
193 1
			$params['marker cluster'] = [
194
				'type' => 'boolean',
195
				'name' => 'map view marker cluster',
196
				'message' => 'srf-paramdesc-filtered-map-marker-cluster',
197
				'default' => true,
198
				// 'islist' => false,
199
			];
200
201 1
			$params['marker cluster max zoom'] = [
202
				'type' => 'integer',
203
				'name' => 'map view marker cluster max zoom',
204
				'message' => 'srf-paramdesc-filtered-map-marker-cluster-max-zoom',
205
				'default' => '',
206
				// 'islist' => false,
207
			];
208
209
			//clustermaxradius - maxClusterRadius: The maximum radius that a cluster will cover from the central marker (in pixels). Default 80.
210 1
			$params['maxClusterRadius'] = [
211
				'type' => 'integer',
212
				'name' => 'map view marker cluster radius',
213
				'message' => 'srf-paramdesc-filtered-map-marker-cluster-max-radius',
214
				'default' => '',
215
				// 'islist' => false,
216
			];
217
218
			//clusterzoomonclick - zoomToBoundsOnClick: When you click a cluster we zoom to its bounds.
219 1
			$params['zoomToBoundsOnClick'] = [
220
				'type' => 'boolean',
221
				'name' => 'map view marker cluster zoom on click',
222
				'message' => 'srf-paramdesc-filtered-map-marker-cluster-zoom-on-click',
223
				'default' => true,
224
				// 'islist' => false,
225
			];
226
227 1
			self::$viewParams = $params;
228
		}
229
230 2
		return self::$viewParams;
231
	}
232
233
	/**
234
	 * Returns the name of the resource module to load.
235
	 *
236
	 * @return string
237
	 */
238 1
	public function getResourceModules() {
239 1
		return 'ext.srf.filtered.map-view';
240
	}
241
242
	/**
243
	 * @param array $config
244
	 * @param string $key
245
	 */
246 1
	private function addToConfig( &$config, $key ) {
247
248 1
		$paramDefinition = self::getParameters()[$key];
249
250 1
		$param = $this->getActualParameters()[$paramDefinition['name']];
251
252 1
		if ( $param !== $paramDefinition['default'] ) {
253
			$config[$key] = $param;
254
		}
255
256 1
	}
257
258
	/**
259
	 * @param $config
260
	 */
261 1
	protected function addMarkerIconSetupToConfig( &$config ) {
262
263 1
		$param = $this->getActualParameters()['map view marker icon property'];
264
265 1
		if ( $param !== '' ) {
266
			$config['marker icon property'] = $this->getPropertyId( $param );
267
		}
268
269 1
		$config['marker icons'] = $this->getMarkerIcons();
270 1
	}
271
272
	/**
273
	 * @param $prop
274
	 *
275
	 * @return array
276
	 */
277
	protected function getPropertyId( $prop ) {
278
279
		$prop = strtr( $prop, ' ', '_' );
280
281
		$printrequests = $this->getQueryPrinter()->getPrintrequests();
282
		$cur = reset( $printrequests );
283
284
		while ( $cur !== false && ( !array_key_exists( 'property', $cur ) || $cur['property'] !== $prop ) ) {
285
			$cur = next( $printrequests );
286
		}
287
288
		return key( $printrequests );
289
	}
290
291
	/**
292
	 * @return array
293
	 */
294 1
	private function getMarkerIcons() {
295
296 1
		$ret = [];
297
298 1
		$actualParameters = self::getActualParameters()['map view marker icons'];
299
300 1
		foreach ( $actualParameters as $relation ) {
0 ignored issues
show
The expression $actualParameters of type string is not traversable.
Loading history...
301
302
			$relation = explode( '=', $relation, 2 );
303
304
			if ( count( $relation ) === 1 ) {
305
				$key = 'default';
306
				$icon = $relation[0];
307
			} else {
308
				$key = $relation[0];
309
				$icon = $relation[1];
310
			}
311
312
			$file = \WikiPage::factory( \Title::newFromText( $icon, NS_FILE ) )->getFile();
313
314
			if ( $file->exists() ) {
315
				$ret[$key] = $file->getUrl();
316
			} else {
317
				// TODO: $this->getQueryPrinter()->addError( NO_SUCH_FILE );
318
			}
319
		}
320
321 1
		return $ret;
322
	}
323
324
	/**
325
	 * @return bool
326
	 */
327 2
	public function getInitError() {
328 2
		return $this->getMapProvider() === '' ? 'srf-filtered-map-provider-missing-error' : null;
329
	}
330
331
}