Completed
Push — address-as-title ( 9b6eeb )
by Jeroen De
10:20
created

LocationParser::isAddress()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 12
rs 9.4285
1
<?php
2
3
namespace Maps;
4
5
use DataValues\Geo\Parsers\GeoCoordinateParser;
6
use DataValues\Geo\Values\LatLongValue;
7
use Maps\Elements\Location;
8
use MWException;
9
use Title;
10
use ValueParsers\ParseException;
11
use ValueParsers\StringValueParser;
12
13
/**
14
 * ValueParser that parses the string representation of a location.
15
 *
16
 * @since 3.0
17
 *
18
 * @licence GNU GPL v2+
19
 * @author Jeroen De Dauw < [email protected] >
20
 */
21
class LocationParser extends StringValueParser {
22
23
	/**
24
	 * @see StringValueParser::stringParse
25
	 *
26
	 * @since 3.0
27
	 *
28
	 * @param string $value
29
	 *
30
	 * @return Location
31
	 * @throws MWException
32
	 */
33
	public function stringParse( $value ) {
34
		$separator = '~';
35
36
		$metaData = explode( $separator, $value );
37
38
		$coordinatesOrAddress = array_shift( $metaData );
39
		$coordinates = $this->stringToLatLongValue( $coordinatesOrAddress );
40
41
		$location = new Location( $coordinates );
42
43
		if ( $metaData !== [] ) {
44
			$this->setTitleOrLink( $location, array_shift( $metaData ) );
45
		}
46
		else if ( $this->isAddress( $coordinatesOrAddress ) ) {
47
			$location->setTitle( $coordinatesOrAddress );
48
		}
49
50
		if ( $metaData !== [] ) {
51
			$location->setText( array_shift( $metaData ) );
52
		}
53
54
		if ( $metaData !== [] ) {
55
			$location->setIcon( array_shift( $metaData ) );
56
		}
57
58
		if ( $metaData !== [] ) {
59
			$location->setGroup( array_shift( $metaData ) );
60
		}
61
62
		if ( $metaData !== [] ) {
63
			$location->setInlineLabel( array_shift( $metaData ) );
64
		}
65
66
		return $location;
67
	}
68
69
	private function setTitleOrLink( Location $location, $titleOrLink ) {
70
		if ( $this->isLink( $titleOrLink ) ) {
71
			$this->setLink( $location, $titleOrLink );
72
		}
73
		else {
74
			$location->setTitle( $titleOrLink );
75
		}
76
	}
77
78
	private function isLink( $value ) {
79
		return strpos( $value , 'link:' ) === 0;
80
	}
81
82
	private function setLink( Location $location, $link ) {
83
		$link = substr( $link, 5 );
84
		$location->setLink( $this->getExpandedLink( $link ) );
85
	}
86
87
	private function getExpandedLink( $link ) {
88
		if ( filter_var( $link , FILTER_VALIDATE_URL , FILTER_FLAG_SCHEME_REQUIRED ) ) {
89
			return $link;
90
		}
91
92
		$title = Title::newFromText( $link );
93
94
		if ( $title === null ) {
95
			return '';
96
		}
97
98
		return $title->getFullUrl();
99
	}
100
101
	/**
102
	 * @param string $location
103
	 *
104
	 * @return LatLongValue
105
	 * @throws ParseException
106
	 */
107
	private function stringToLatLongValue( $location ) {
108
		if ( Geocoders::canGeocode() ) {
109
			$latLongValue = Geocoders::attemptToGeocode( $location );
110
111
			if ( $latLongValue === false ) {
112
				throw new ParseException( 'Failed to parse or geocode' );
113
			}
114
115
			assert( $latLongValue instanceof LatLongValue );
116
			return $latLongValue;
117
		}
118
119
		$parser = new GeoCoordinateParser( new \ValueParsers\ParserOptions() );
120
		return $parser->parse( $location );
121
	}
122
123
	/**
124
	 * @param string $coordsOrAddress
125
	 *
126
	 * @return boolean
127
	 */
128
	private function isAddress( $coordsOrAddress ) {
129
		$coordinateParser = new GeoCoordinateParser( new \ValueParsers\ParserOptions() );
130
131
		try {
132
			$coordinateParser->parse( $coordsOrAddress );
133
		}
134
		catch ( ParseException $parseException ) {
135
			return false;
136
		}
137
138
		return true;
139
	}
140
141
}
142