Completed
Push — master ( 21f028...112b84 )
by Jeroen De
03:13
created

Presentation/WikitextParsers/LocationParser.php (2 issues)

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
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 Maps\MapsFunctions;
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 85
	public function __construct( $enableLegacyCrud = true ) {
32 85
		if ( $enableLegacyCrud ) {
33 55
			$this->geocoder = MapsFactory::newDefault()->newGeocoder();
34 55
			$this->useAddressAsTitle = false;
35
		}
36 85
	}
37
38 30
	public static function newInstance( Geocoder $geocoder, bool $useAddressAsTitle = false ): self {
39 30
		$instance = new self( false );
40 30
		$instance->geocoder = $geocoder;
41 30
		$instance->useAddressAsTitle = $useAddressAsTitle;
42 30
		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 80
	public function parse( $value ) {
56 80
		$separator = '~';
57
58 80
		$metaData = explode( $separator, $value );
59
60 80
		$coordinatesOrAddress = array_shift( $metaData );
61 80
		$coordinates = $this->geocoder->geocode( $coordinatesOrAddress );
62
63 80
		if ( $coordinates === null ) {
64 1
			throw new ParseException( 'Location is not a parsable coordinate and not a geocodable address' );
65
		}
66
67 79
		$location = new Location( $coordinates );
68
69 79
		if ( $metaData !== [] ) {
70 11
			$this->setTitleOrLink( $location, array_shift( $metaData ) );
71
		} else {
72 68
			if ( $this->useAddressAsTitle && $this->isAddress( $coordinatesOrAddress ) ) {
73 1
				$location->setTitle( $coordinatesOrAddress );
74
			}
75
		}
76
77 79
		if ( $metaData !== [] ) {
78 2
			$location->setText( array_shift( $metaData ) );
79
		}
80
81 79
		if ( $metaData !== [] ) {
82
			// FIXME: global access
83 1
			$location->setIcon( MapsFunctions::getFileUrl( array_shift( $metaData ) ) );
0 ignored issues
show
Deprecated Code introduced by
The method Maps\MapsFunctions::getFileUrl() has been deprecated.

This method has been deprecated.

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

This method has been deprecated.

Loading history...
97
		}
98
99 79
		return $location;
100
	}
101
102 11
	private function setTitleOrLink( Location $location, $titleOrLink ) {
103 11
		if ( $this->isLink( $titleOrLink ) ) {
104 2
			$this->setLink( $location, $titleOrLink );
105
		} else {
106 9
			$location->setTitle( $titleOrLink );
107
		}
108 11
	}
109
110 11
	private function isLink( $value ) {
111 11
		return strpos( $value, 'link:' ) === 0;
112
	}
113
114 2
	private function setLink( Location $location, $link ) {
115 2
		$link = substr( $link, 5 );
116 2
		$location->setLink( $this->getExpandedLink( $link ) );
117 2
	}
118
119 2
	private function getExpandedLink( $link ) {
120 2
		if ( filter_var( $link, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED ) ) {
121 2
			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 2
	private function isAddress( string $coordsOrAddress ): bool {
134 2
		$coordinateParser = new LatLongParser();
135
136
		try {
137 2
			$coordinateParser->parse( $coordsOrAddress );
138
		}
139 1
		catch ( ParseException $parseException ) {
140 1
			return true;
141
		}
142
143 1
		return false;
144
	}
145
146
}
147