Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
CoordFormatter
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
4 / 4
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 convertCoord
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 format
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 formatParsoidSpan
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Kartographer;
4
5use Language;
6use Wikimedia\Parsoid\DOM\DocumentFragment;
7use Wikimedia\Parsoid\Ext\ParsoidExtensionAPI;
8
9/**
10 * Formats coordinates into human-readable strings
11 *
12 * @license MIT
13 */
14class CoordFormatter {
15
16    /** @var int[] */
17    private array $lat;
18    /** @var int[] */
19    private array $lon;
20    private string $msgKey;
21
22    public function __construct( ?float $lat, ?float $lon ) {
23        [ $plusMinusLat, $this->lat ] = $this->convertCoord( $lat );
24        [ $plusMinusLon, $this->lon ] = $this->convertCoord( $lon );
25        // Messages used here:
26        // * kartographer-coord-lat-pos-lon-pos
27        // * kartographer-coord-lat-pos-lon-neg
28        // * kartographer-coord-lat-neg-lon-pos
29        // * kartographer-coord-lat-neg-lon-neg
30        $this->msgKey = "kartographer-coord-lat-$plusMinusLat-lon-$plusMinusLon";
31    }
32
33    /**
34     * Convert coordinates to degrees, minutes, seconds
35     *
36     * @param float|null $coord
37     * @return array{string,int[]}
38     */
39    private function convertCoord( ?float $coord ): array {
40        $val = round( (float)$coord * 3600 );
41        $sign = $val < 0 ? 'neg' : 'pos';
42        $val = abs( $val );
43        $degrees = floor( $val / 3600 );
44        $minutes = floor( ( $val - $degrees * 3600 ) / 60 );
45        $seconds = $val - $degrees * 3600 - $minutes * 60;
46
47        return [ $sign, [ (int)$degrees, (int)$minutes, (int)$seconds ] ];
48    }
49
50    /**
51     * Formats coordinates
52     * @param Language|string $language
53     *
54     * @return string
55     */
56    public function format( $language ): string {
57        return wfMessage( $this->msgKey )
58            ->numParams( ...$this->lat, ...$this->lon )
59            ->inLanguage( $language )
60            ->plain();
61    }
62
63    /**
64     * Formats coordinates as a Parsoid i18n span. This method should not be used to generate
65     * content that is added to a tag attribute.
66     * @param ParsoidExtensionAPI $extAPI
67     * @param string|null $language
68     * @return DocumentFragment
69     */
70    public function formatParsoidSpan( ParsoidExtensionAPI $extAPI, ?string $language ): DocumentFragment {
71        $params = [ ...$this->lat, ...$this->lon ];
72        return ParsoidUtils::createLangFragment( $this->msgKey, $params, $extAPI, $language );
73    }
74
75}