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

formats/filtered/src/View/MapView.php (5 issues)

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() {
0 ignored issues
show
getMapProvider uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
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 &&
0 ignored issues
show
The class SMWPropertyValue does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
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();
0 ignored issues
show
Are you sure the assignment to $config['map provider'] is correct as $this->getMapProvider() (which targets SRF\Filtered\View\MapView::getMapProvider()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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 {
0 ignored issues
show
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
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
}