Completed
Push — master ( f67785...2177d9 )
by mw
07:32
created

src/SM_GeoCoordsValue.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 DataValues\Geo\Formatters\GeoCoordinateFormatter;
4
use DataValues\Geo\Parsers\GeoCoordinateParser;
5
use DataValues\Geo\Values\LatLongValue;
6
use ValueParsers\ParseException;
7
8
/**
9
 * Implementation of datavalues that are geographic coordinates.
10
 * 
11
 * @since 0.6
12
 * 
13
 * @file SM_GeoCoordsValue.php
14
 * @ingroup SemanticMaps
15
 * @ingroup SMWDataValues
16
 * 
17
 * @licence GNU GPL v2+
18
 * @author Jeroen De Dauw < [email protected] >
19
 * @author Markus Krötzsch
20
 */
21
class SMGeoCoordsValue extends SMWDataValue {
22
23
	protected $wikiValue;
24
25
	/**
26
	 * @see SMWDataValue::setDataItem
27
	 * 
28
	 * @since 1.0
29
	 * 
30
	 * @param SMWDataItem $dataItem
31
	 * 
32
	 * @return boolean
33
	 */
34 1
	protected function loadDataItem( SMWDataItem $dataItem ) {
35 1
		if ( $dataItem instanceof SMWDIGeoCoord ) {
36 1
			 $formattedValue = $this->getFormattedCoord( $dataItem );
37
38 1
			if ( $formattedValue !== null ) {
39 1
				$this->wikiValue = $formattedValue;
40 1
				$this->m_dataitem = $dataItem;
41 1
				return true;
42
			}
43
		}
44
45
		return false;
46
	}
47
48
	/**
49
	 * @since 3.0
50
	 *
51
	 * @param SMWDIGeoCoord $dataItem
52
	 * @param string|null $format
53
	 *
54
	 * @return string|null
55
	 */
56 1
	protected function getFormattedCoord( SMWDIGeoCoord $dataItem, $format = null ) {
57 1
		global $smgQPCoodFormat;
58
59 1
		$options = new \ValueFormatters\FormatterOptions( array(
60 1
			GeoCoordinateFormatter::OPT_FORMAT => $format === null ? $smgQPCoodFormat : $format, // TODO
61 1
		) );
62
63
		// TODO: $smgQPCoodDirectional
64
65 1
		$coordinateFormatter = new GeoCoordinateFormatter( $options );
66
67 1
		$value = new LatLongValue(
68 1
			$dataItem->getLatitude(),
69 1
			$dataItem->getLongitude()
70 1
		);
71
72 1
		return $coordinateFormatter->format( $value );
73
	}
74
	
75
	/**
76
	 * Overwrite SMWDataValue::getQueryDescription() to be able to process
77
	 * comparators between all values.
78
	 * 
79
	 * @since 0.6
80
	 * 
81
	 * @param string $value
82
	 * 
83
	 * @return SMWDescription
84
	 * @throws InvalidArgumentException
85
	 */
86 6
	public function getQueryDescription( $value ) {
87 6
		if ( !is_string( $value ) ) {
88
			throw new InvalidArgumentException( '$value needs to be a string' );
89
		}
90
91 6
		list( $distance, $comparator ) = $this->parseUserValue( $value );
92 6
		$distance = $this->parserDistance( $distance );
93
94 6
		$this->setUserValue( $value );
95
96
		switch ( true ) {
97 6
			case !$this->isValid() :
98
				return new SMWThingDescription();
99 6
			case $distance !== false :
100 3
				return new SMAreaValueDescription( $this->getDataItem(), $comparator, $distance );
101 3
			default :
102 3
				return new SMGeoCoordsValueDescription( $this->getDataItem(), null, $comparator );
103 3
		}
104
	}
105
106 6
	protected function parserDistance( $distance ) {
107 6
		if ( $distance !== false ) {
108 3
			$distance = substr( trim( $distance ), 0, -1 );
109
110 3
			if ( !MapsDistanceParser::isDistance( $distance ) ) {
111
				$this->addError( wfMessage( 'semanticmaps-unrecognizeddistance', $distance )->text() );
112
				$distance = false;
113
			}
114 3
		}
115
116 6
		return $distance;
117
	}
118
119
	/**
120
	 * @see SMWDataValue::parseUserValue
121
	 *
122
	 * @since 0.6
123
	 */
124 6
	protected function parseUserValue( $value ) {
125 6
		if ( !is_string( $value ) ) {
126
			throw new InvalidArgumentException( '$value needs to be a string' );
127
		}
128
129 6
		$this->wikiValue = $value;
130
131 6
		$comparator = SMW_CMP_EQ;
132 6
		$distance = false;
133
134 6
		if ( $value === '' ) {
135
			$this->addError( wfMessage( 'smw_novalues' )->text() );
136
		} else {
137 6
			SMWDataValue::prepareValue( $value, $comparator );
0 ignored issues
show
Deprecated Code introduced by
The method SMWDataValue::prepareValue() has been deprecated with message: 2.3

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
138
139 6
			list( $coordinates, $distance ) = $this->findValueParts( $value );
140
141 6
			$this->tryParseAndSetDataItem( $coordinates );
142
		}
143
144 6
		return array( $distance, $comparator );
145
	}
146
147 6
	protected function findValueParts( $value ) {
148 6
		$parts = explode( '(', $value );
149
150 6
		$coordinates = trim( array_shift( $parts ) );
151 6
		$distance = count( $parts ) > 0 ? trim( array_shift( $parts ) ) : false;
152
153 6
		return array( $coordinates, $distance );
154
	}
155
156
	/**
157
	 * @param string $coordinates
158
	 */
159 6
	protected function tryParseAndSetDataItem( $coordinates ) {
160 6
		$options = new \ValueParsers\ParserOptions();
161 6
		$parser = new GeoCoordinateParser( $options );
162
163
		try {
164 6
			$value = $parser->parse( $coordinates );
165 6
			$this->m_dataitem = new SMWDIGeoCoord( $value->getLatitude(), $value->getLongitude() );
166
		}
167 6
		catch ( ParseException $parseException ) {
168
			$this->addError( wfMessage( 'maps_unrecognized_coords', $coordinates, 1 )->text() );
169
170
			// Make sure this is always set
171
			// TODO: Why is this needed?!
172
			$this->m_dataitem = new SMWDIGeoCoord( array( 'lat' => 0, 'lon' => 0 ) );
173
		}
174 6
	}
175
176
	/**
177
	 * @see SMWDataValue::getShortWikiText
178
	 * 
179
	 * @since 0.6
180
	 */
181 1
	public function getShortWikiText( $linked = null ) {
182 1
		if ( $this->isValid() ) {
183 1
			if ( $this->m_caption === false ) {
184 1
				return $this->getFormattedCoord( $this->m_dataitem );
185
			}
186
			else {
187
				return $this->m_caption; 
188
			}
189
		}
190
		else {
191
			return $this->getErrorText();
192
		}
193
	}
194
	
195
	/**
196
	 * @see SMWDataValue::getShortHTMLText
197
	 * 
198
	 * @since 0.6
199
	 */
200
	public function getShortHTMLText( $linker = null ) {
201
		return $this->getShortWikiText( $linker );
202
	}
203
	
204
	/**
205
	 * @see SMWDataValue::getLongWikiText
206
	 * 
207
	 * @since 0.6
208
	 */
209
	public function getLongWikiText( $linked = null ) {
210
		if ( $this->isValid() ) {
211
			SMWOutputs::requireHeadItem( SMW_HEADER_TOOLTIP );
212
213
			// TODO: fix lang keys so they include the space and coordinates.
214
			$coordinateSet = $this->m_dataitem->getCoordinateSet();
215
			
216
			$text = $this->getFormattedCoord( $this->m_dataitem );
217
218
			$lines = array(
219
				wfMessage( 'semanticmaps-latitude', $coordinateSet['lat'] )->inContentLanguage()->escaped(),
220
				wfMessage( 'semanticmaps-longitude', $coordinateSet['lon'] )->inContentLanguage()->escaped(),
221
			);
222
			
223
			if ( array_key_exists( 'alt', $coordinateSet ) ) {
224
				$lines[] = wfMessage( 'semanticmaps-altitude', $coordinateSet['alt'] )->inContentLanguage()->escaped();
225
			}
226
			
227
			return 	'<span class="smwttinline">' . htmlspecialchars( $text ) . '<span class="smwttcontent">' .
228
		        	 	implode( '<br />', $lines ) .
229
		        	'</span></span>';
230
		} else {
231
			return $this->getErrorText();
232
		}		
233
	}
234
235
	/**
236
	 * @see SMWDataValue::getLongHTMLText
237
	 * 
238
	 * @since 0.6
239
	 */
240
	public function getLongHTMLText( $linker = null ) {
241
		return $this->getLongWikiText( $linker );
242
	}
243
244
	/**
245
	 * @see SMWDataValue::getWikiValue
246
	 * 
247
	 * @since 0.6
248
	 */
249
	public function getWikiValue() {
250
		return $this->wikiValue;
251
	}
252
253
	/**
254
	 * Create links to mapping services based on a wiki-editable message. The parameters
255
	 * available to the message are:
256
	 * 
257
	 * $1: The location in non-directional float notation.
258
	 * $2: The location in directional DMS notation.
259
	 * $3: The latitude in non-directional float notation.
260
	 * $4 The longitude in non-directional float notation.
261
	 * 
262
	 * @since 0.6.4
263
	 * 
264
	 * @return array
265
	 */
266
	protected function getServiceLinkParams() {
267
		$coordinateSet = $this->m_dataitem->getCoordinateSet();
268
		return array(
269
			$this->getFormattedCoord( $this->m_dataitem, 'float' ), // TODO
270
			$this->getFormattedCoord( $this->m_dataitem, 'dms' ), // TODO
271
			$coordinateSet['lat'],
272
			$coordinateSet['lon']
273
		);
274
	}
275
276
}
277