Completed
Push — move ( b63aae...04f5b5 )
by Jeroen De
16:21 queued 06:23
created

LocationParser   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 6
dl 0
loc 124
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A newInstance() 0 6 1
B parse() 0 46 10
A setTitleOrLink() 0 7 2
A isLink() 0 3 1
A setLink() 0 4 1
A getExpandedLink() 0 13 3
A isAddress() 0 12 2
1
<?php
2
3
namespace Maps\Presentation\WikitextParsers;
4
5
use DataValues\Geo\Parsers\LatLongParser;
6
use Jeroen\SimpleGeocoder\Geocoder;
7
use Maps\Elements\Location;
8
use Maps\MapsFactory;
9
use MapsMapper;
10
use Title;
11
use ValueParsers\ParseException;
12
use ValueParsers\StringValueParser;
13
use ValueParsers\ValueParser;
14
15
/**
16
 * ValueParser that parses the string representation of a location.
17
 *
18
 * @since 3.0
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Jeroen De Dauw < [email protected] >
22
 */
23
class LocationParser implements ValueParser {
24
25
	private $geocoder;
26
	private $useAddressAsTitle;
27
28
	/**
29
	 * @deprecated Use newInstance instead
30
	 */
31
	public function __construct( $enableLegacyCrud = true ) {
32
		if ( $enableLegacyCrud ) {
33
			$this->geocoder = MapsFactory::newDefault()->newGeocoder();
34
			$this->useAddressAsTitle = false;
35
		}
36
	}
37
38
	public static function newInstance( Geocoder $geocoder, bool $useAddressAsTitle = false ): self {
39
		$instance = new self( false );
40
		$instance->geocoder = $geocoder;
41
		$instance->useAddressAsTitle = $useAddressAsTitle;
42
		return $instance;
43
	}
44
45
	/**
46
	 * @see StringValueParser::stringParse
47
	 *
48
	 * @since 3.0
49
	 *
50
	 * @param string $value
51
	 *
52
	 * @return Location
53
	 * @throws ParseException
54
	 */
55
	public function parse( $value ) {
56
		$separator = '~';
57
58
		$metaData = explode( $separator, $value );
59
60
		$coordinatesOrAddress = array_shift( $metaData );
61
		$coordinates = $this->geocoder->geocode( $coordinatesOrAddress );
62
63
		if ( $coordinates === null ) {
64
			throw new ParseException( 'Location is not a parsable coordinate and not a geocodable address' );
65
		}
66
67
		$location = new Location( $coordinates );
68
69
		if ( $metaData !== [] ) {
70
			$this->setTitleOrLink( $location, array_shift( $metaData ) );
71
		} else {
72
			if ( $this->useAddressAsTitle && $this->isAddress( $coordinatesOrAddress ) ) {
73
				$location->setTitle( $coordinatesOrAddress );
74
			}
75
		}
76
77
		if ( $metaData !== [] ) {
78
			$location->setText( array_shift( $metaData ) );
79
		}
80
81
		if ( $metaData !== [] ) {
82
			// FIXME: global access
83
			$location->setIcon( MapsMapper::getFileUrl( array_shift( $metaData ) ) );
0 ignored issues
show
Deprecated Code introduced by
The method MapsMapper::getFileUrl() has been deprecated.

This method has been deprecated.

Loading history...
84
		}
85
86
		if ( $metaData !== [] ) {
87
			$location->setGroup( array_shift( $metaData ) );
88
		}
89
90
		if ( $metaData !== [] ) {
91
			$location->setInlineLabel( array_shift( $metaData ) );
92
		}
93
94
		if ( $metaData !== [] ) {
95
			// FIXME: global access
96
			$location->setVisitedIcon( MapsMapper::getFileUrl( array_shift( $metaData ) ) ) ;
0 ignored issues
show
Deprecated Code introduced by
The method MapsMapper::getFileUrl() has been deprecated.

This method has been deprecated.

Loading history...
97
		}
98
99
		return $location;
100
	}
101
102
	private function setTitleOrLink( Location $location, $titleOrLink ) {
103
		if ( $this->isLink( $titleOrLink ) ) {
104
			$this->setLink( $location, $titleOrLink );
105
		} else {
106
			$location->setTitle( $titleOrLink );
107
		}
108
	}
109
110
	private function isLink( $value ) {
111
		return strpos( $value, 'link:' ) === 0;
112
	}
113
114
	private function setLink( Location $location, $link ) {
115
		$link = substr( $link, 5 );
116
		$location->setLink( $this->getExpandedLink( $link ) );
117
	}
118
119
	private function getExpandedLink( $link ) {
120
		if ( filter_var( $link, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED ) ) {
121
			return $link;
122
		}
123
124
		$title = Title::newFromText( $link );
125
126
		if ( $title === null ) {
127
			return '';
128
		}
129
130
		return $title->getFullURL();
131
	}
132
133
	private function isAddress( string $coordsOrAddress ): bool {
134
		$coordinateParser = new LatLongParser();
135
136
		try {
137
			$coordinateParser->parse( $coordsOrAddress );
138
		}
139
		catch ( ParseException $parseException ) {
140
			return true;
141
		}
142
143
		return false;
144
	}
145
146
}
147