Completed
Push — master ( f04bbc...eab9d5 )
by Jeroen De
07:09
created

SemanticMaps/src/forminputs/SM_FormInput.php (1 issue)

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
use Maps\Elements\Location;
4
use ParamProcessor\ParamDefinition;
5
use ParamProcessor\ProcessingError;
6
use ParamProcessor\Processor;
7
8
/**
9
 * Base form input class.
10
 *
11
 * @licence GNU GPL v2+
12
 * @author Jeroen De Dauw < [email protected] >
13
 */
14
class SMFormInput {
15
16
	/**
17
	 * @since 1.0
18
	 * 
19
	 * @var iMappingService
20
	 */
21
	protected $service;		
22
	
23
	/**
24
	 * A character to separate multiple locations with.
25
	 * 
26
	 * @since 1.0
27
	 * 
28
	 * @var string
29
	 */
30
	const SEPARATOR = ';';
31
	
32
	/**
33
	 * Constructor.
34
	 * 
35
	 * @since 1.0
36
	 * 
37
	 * @param iMappingService $service
38
	 */
39
	public function __construct( iMappingService $service ) {
40
		$this->service = $service;
41
	}
42
	
43
	/**
44
	 * Returns an array containing the parameter info.
45
	 * 
46
	 * @since 1.0
47
	 * 
48
	 * @return array
49
	 */
50
	protected function getParameterInfo() {
51
		$params = ParamDefinition::getCleanDefinitions( MapsMapper::getCommonParameters() );
52
53
		$this->service->addParameterInfo( $params );
54
55
		$params['zoom']['default'] = false;
56
		$params['zoom']['manipulatedefault'] = false;
57
58
		return array_merge( $params, $this->getParameterDefinitions() );
59
	}
60
61
	protected function getParameterDefinitions() {
62
		global $smgFIFieldSize;
63
64
		$params = [];
65
66
		$params['fieldsize'] = [
67
			'type' => 'integer',
68
			'default' => $smgFIFieldSize,
69
			'range' => [ 5, 100 ],
70
		];
71
72
		$params['icon'] = [
73
			'default' => '',
74
		];
75
76
		$params['locations'] = [
77
			'type' => 'mapslocation',
78
			'aliases' => [ 'points' ],
79
			'default' => [],
80
			'islist' => true,
81
			'delimiter' => self::SEPARATOR,
82
		];
83
84
		$params['geocodecontrol'] = [
85
			'type' => 'boolean',
86
			'default' => true,
87
		];
88
89
		// Messages:
90
		// semanticmaps-par-staticlocations, semanticmaps-par-showtitle,
91
		// semanticmaps-par-hidenamespace, semanticmaps-par-centre, semanticmaps-par-template,
92
		// semanticmaps-par-geocodecontrol, semanticmaps-par-activeicon
93
		foreach ( $params as $name => &$param ) {
94
			$param['message'] = 'semanticmaps-par-' . $name;
95
		}
96
97
		return $params;
98
	}
99
	
100
	/**
101
	 * @since 1.0
102
	 * 
103
	 * @param string $coordinates
104
	 * @param string $inputName
105
	 * @param boolean $isMandatory
106
	 * @param boolean $isDisabled
107
	 * @param array $params
108
	 * 
109
	 * @return string
110
	 */
111
	public function getInputOutput( $coordinates, $inputName, $isMandatory, $isDisabled, array $params ) {
112
		$parameters = [];
113
		foreach ( $params as $key => $value ) {
114
			if ( !is_array( $value ) && !is_object( $value ) && !is_null( $value ) ) {
115
				$parameters[$key] = $value;
116
			}
117
		}
118
119
		if ( !is_null( $coordinates ) ) {
120
			$parameters['locations'] = $coordinates;
121
		}
122
123
		$validator = Processor::newDefault();
124
		$validator->setParameters( $parameters, $this->getParameterInfo() );
125
		$processingResult = $validator->processParameters();
126
127
		if ( $processingResult->hasFatal() ) {
128
			return $this->getFatalOutput( $validator->getErrors() );
129
		}
130
		else {
131
			return $this->getMapOutput( $validator->getParameterValues(), $inputName );
132
		}			
133
	}
134
135
	private function getMapOutput( array $params, $inputName ) {
136
		global $wgParser;
137
138
		if ( is_object( $params['centre'] ) ) {
139
			$params['centre'] = $params['centre']->getJSONObject();
140
		}
141
142
		// We can only take care of the zoom defaulting here,
143
		// as not all locations are available in whats passed to Validator.
144
		if ( $params['zoom'] === false && count( $params['locations'] ) <= 1 ) {
145
			$params['zoom'] = $this->service->getDefaultZoom();
146
		}
147
148
		$mapName = $this->service->getMapId();
149
150
		$params['inputname'] = $inputName;
151
152
		$output = $this->getInputHTML( $params, $wgParser, $mapName );
153
154
		$this->service->addResourceModules( $this->getResourceModules() );
155
156
		$configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() );
157
158
		if ( true /* !is_null( $wgTitle ) && $wgTitle->isSpecialPage() */ ) { // TODO
159
			global $wgOut;
160
161
			$this->service->addDependencies( $wgOut );
162
163
			$wgOut->addScript( $configVars );
164
		}
165
		else {
166
			$this->service->addDependencies( $wgParser );
167
		}
168
169
		return $output;
170
	}
171
172
	/**
173
	 * @param ProcessingError[] $errors
174
	 *
175
	 * @return string
176
	 */
177
	private function getFatalOutput( array $errors ) {
178
		$html = '';
179
180
		foreach ( $errors as $error ) {
181
			if ( $error->isFatal() ) {
182
				$html .= $this->errorToHtml( $error );
183
			}
184
		}
185
186
		return $html;
187
	}
188
189
	private function errorToHtml( ProcessingError $error ) {
190
		return
191
			'<span class="errorbox">' .
192
			htmlspecialchars( wfMessage( 'validator-fatal-error', $error->getMessage() )->text() ) .
193
			'</span>';
194
	}
195
196
	/**
197
	 * @since 2.0
198
	 *
199
	 * @param string $coordinates
200
	 * @param string $input_name
201
	 * @param boolean $isMandatory
202
	 * @param boolean $isDisabled
203
	 * @param array $params
204
	 *
205
	 * @return string
206
	 */
207
	public function getEditorInputOutput( $coordinates, $input_name, $isMandatory, $isDisabled, array $params ) {
208
		global $wgOut;
209
210
		$wgOut->addHTML( MapsGoogleMaps3::getApiScript(
211
			'en',
212
			[ 'libraries' => 'drawing' ]
213
		) );
214
215
		$wgOut->addModules( 'mapeditor' );
216
217
		$html = Html::element(
218
			'div',
219
			[
220
				'id' => 'map-polygon',
221
				'name' => $input_name,
222
				'cols' => 4,
223
				'rows' => 2,
224
			],
225
			$coordinates
226
		);
227
228
		$editorHtml = new MapEditorHtml( $this->getAttribs() );
229
230
		return $html . $editorHtml->getEditorHTML();
231
	}
232
	
233
	/**
234
	 * Returns the HTML to display the map input.
235
	 * 
236
	 * @since 1.0
237
	 * 
238
	 * @param array $params
239
	 * @param Parser $parser
240
	 * @param string $mapName
241
	 * 
242
	 * @return string
243
	 */
244
	protected function getInputHTML( array $params, Parser $parser, $mapName ) {
245
		return Html::rawElement(
246
			'div',
247
			[
248
				'id' => $mapName . '_forminput',
249
				'style' => 'display: inline',
250
				'class' => 'sminput sminput-' . $this->service->getName()
251
			],
252
			wfMessage( 'semanticmaps-loading-forminput' )->escaped() .
253
				Html::element(
254
					'div',
255
					[ 'style' => 'display:none', 'class' => 'sminputdata' ],
256
					FormatJson::encode( $this->getJSONObject( $params, $parser ) )
257
				)
258
		);
259
	}
260
	
261
	/**
262
	 * Returns a PHP object to encode to JSON with the map data.
263
	 *
264
	 * @since 1.0
265
	 *
266
	 * @param array $params
267
	 * @param Parser $parser
268
	 * 
269
	 * @return mixed
270
	 */	
271
	protected function getJSONObject( array $params, Parser $parser ) {
0 ignored issues
show
The parameter $parser 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...
272
		/**
273
		 * @var Location $location
274
		 */
275
		foreach ( $params['locations'] as &$location ) {
276
			$location = $location->getJSONObject();
277
		}
278
279
		return $params;
280
	}
281
	
282
	/**
283
	 * @since 1.0
284
	 * 
285
	 * @return array of string
286
	 */
287
	protected function getResourceModules() {
288
		return [ 'ext.sm.forminputs' ];
289
	}
290
291
	/**
292
	 * @since 2.1
293
	 *
294
	 * @return string
295
	 */
296
	protected function getAttribs(){
297
		return [
298
			'id' => 'map-canvas',
299
			'context' => 'forminput',
300
			'style' => 'width:600px; height:400px'
301
		];
302
	}
303
304
}
305