Completed
Push — nophpunit ( 9a5068 )
by Jeroen De
05:11
created

LocationParser::setLink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 4
ccs 4
cts 4
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Maps;
4
5
use DataValues\Geo\Parsers\LatLongParser;
6
use Jeroen\SimpleGeocoder\Geocoder;
7
use Maps\Elements\Location;
8
use Title;
9
use ValueParsers\ParseException;
10
use ValueParsers\StringValueParser;
11
use ValueParsers\ValueParser;
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 implements ValueParser {
22
23
	private $geocoder;
24
	private $useAddressAsTitle;
25
26
	/**
27
	 * @deprecated Use newInstance instead
28
	 */
29
	public function __construct( $enableLegacyCrud = true ) {
30
		if ( $enableLegacyCrud ) {
31
			$this->geocoder = MapsFactory::newDefault()->newGeocoder();
32
			$this->useAddressAsTitle = false;
33
		}
34
	}
35
36 10
	public static function newInstance( Geocoder $geocoder, bool $useAddressAsTitle = false ): self {
37 10
		$instance = new self( false );
38 10
		$instance->geocoder = $geocoder;
39 10
		$instance->useAddressAsTitle = $useAddressAsTitle;
40 10
		return $instance;
41
	}
42
43
	/**
44
	 * @see StringValueParser::stringParse
45
	 *
46
	 * @since 3.0
47
	 *
48
	 * @param string $value
49
	 *
50
	 * @return Location
51
	 * @throws ParseException
52
	 */
53 10
	public function parse( $value ) {
54 10
		$separator = '~';
55
56 10
		$metaData = explode( $separator, $value );
57
58 10
		$coordinatesOrAddress = array_shift( $metaData );
59 10
		$coordinates = $this->geocoder->geocode( $coordinatesOrAddress );
60
61 10
		if ( $coordinates === null ) {
62
			throw new ParseException( 'Location is not a parsable coordinate and not a geocodable address' );
63
		}
64
65 10
		$location = new Location( $coordinates );
66
67 10
		if ( $metaData !== [] ) {
68 8
			$this->setTitleOrLink( $location, array_shift( $metaData ) );
69
		} else {
70 2
			if ( $this->useAddressAsTitle && $this->isAddress( $coordinatesOrAddress ) ) {
71 1
				$location->setTitle( $coordinatesOrAddress );
72
			}
73
		}
74
75 10
		if ( $metaData !== [] ) {
76
			$location->setText( array_shift( $metaData ) );
77
		}
78
79 10
		if ( $metaData !== [] ) {
80
			$location->setIcon( array_shift( $metaData ) );
81
		}
82
83 10
		if ( $metaData !== [] ) {
84
			$location->setGroup( array_shift( $metaData ) );
85
		}
86
87 10
		if ( $metaData !== [] ) {
88
			$location->setInlineLabel( array_shift( $metaData ) );
89
		}
90
91 10
		return $location;
92
	}
93
94 8
	private function setTitleOrLink( Location $location, $titleOrLink ) {
95 8
		if ( $this->isLink( $titleOrLink ) ) {
96 2
			$this->setLink( $location, $titleOrLink );
97
		} else {
98 6
			$location->setTitle( $titleOrLink );
99
		}
100 8
	}
101
102 8
	private function isLink( $value ) {
103 8
		return strpos( $value, 'link:' ) === 0;
104
	}
105
106 2
	private function setLink( Location $location, $link ) {
107 2
		$link = substr( $link, 5 );
108 2
		$location->setLink( $this->getExpandedLink( $link ) );
109 2
	}
110
111 2
	private function getExpandedLink( $link ) {
112 2
		if ( filter_var( $link, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED ) ) {
113 2
			return $link;
114
		}
115
116
		$title = Title::newFromText( $link );
117
118
		if ( $title === null ) {
119
			return '';
120
		}
121
122
		return $title->getFullURL();
123
	}
124
125
	/**
126
	 * @param string $coordsOrAddress
127
	 *
128
	 * @return boolean
129
	 */
130 2
	private function isAddress( $coordsOrAddress ) {
131 2
		$coordinateParser = new LatLongParser();
132
133
		try {
134 2
			$coordinateParser->parse( $coordsOrAddress );
135
		}
136 1
		catch ( ParseException $parseException ) {
137 1
			return true;
138
		}
139
140 1
		return false;
141
	}
142
143
}
144