1<?php
2
3namespace geoPHP\Adapter;
4
5/**
6 * Class GpxTypes
7 * Defines the available GPX types and their allowed elements following the GPX specification
8 *
9 * @see http://www.topografix.com/gpx/1/1/
10 * @package geoPHP\Adapter
11 */
12class GpxTypes
13{
14
15    // TODO: convert these static properties to constants once HHVM fixes this bug: https://github.com/facebook/hhvm/issues/4277
16
17    /**
18     * @var array Allowed elements in <gpx>
19     * @see http://www.topografix.com/gpx/1/1/#type_gpxType
20     */
21    public static $gpxTypeElements = [
22        'metadata', 'wpt', 'rte', 'trk'
23    ];
24
25    /**
26     * @var array Allowed elements in <trk>
27     * @see http://www.topografix.com/gpx/1/1/#type_trkType
28     */
29    public static $trkTypeElements = [
30        'name', 'cmt', 'desc', 'src', 'link', 'number', 'type'
31    ];
32
33    /**
34     * same as trkTypeElements
35     * @var array Allowed elements in <rte>
36     * @see http://www.topografix.com/gpx/1/1/#type_rteType
37     */
38    public static $rteTypeElements = [
39        'name', 'cmt', 'desc', 'src', 'link', 'number', 'type'
40    ];
41
42    /**
43     * @var array Allowed elements in <wpt>
44     * @see http://www.topografix.com/gpx/1/1/#type_wptType
45     */
46    public static $wptTypeElements = [
47        'ele', 'time', 'magvar', 'geoidheight', 'name', 'cmt', 'desc', 'src', 'link', 'sym', 'type',
48        'fix', 'sat', 'hdop', 'vdop', 'pdop', 'ageofdgpsdata', 'dgpsid'
49    ];
50
51    /**
52     * @var array Same as wptType
53     */
54    public static $trkptTypeElements = [    // same as wptTypeElements
55        'ele', 'time', 'magvar', 'geoidheight', 'name', 'cmt', 'desc', 'src', 'link', 'sym', 'type',
56        'fix', 'sat', 'hdop', 'vdop', 'pdop', 'ageofdgpsdata', 'dgpsid'
57    ];
58
59    /**
60     * @var array Same as wptType
61     */
62    public static $rteptTypeElements = [    // same as wptTypeElements
63        'ele', 'time', 'magvar', 'geoidheight', 'name', 'cmt', 'desc', 'src', 'link', 'sym', 'type',
64        'fix', 'sat', 'hdop', 'vdop', 'pdop', 'ageofdgpsdata', 'dgpsid'
65    ];
66
67    /**
68     * @var array Allowed elements in <metadata>
69     * @see http://www.topografix.com/gpx/1/1/#type_metadataType
70     */
71    public static $metadataTypeElements = [
72        'name', 'desc', 'author', 'copyright', 'link', 'time', 'keywords', 'bounds'
73    ];
74
75    protected $allowedGpxTypeElements;
76
77    protected $allowedTrkTypeElements;
78
79    protected $allowedRteTypeElements;
80
81    protected $allowedWptTypeElements;
82
83    protected $allowedTrkptTypeElements;
84
85    protected $allowedRteptTypeElements;
86
87    protected $allowedMetadataTypeElements;
88
89    /**
90     * GpxTypes constructor.
91     *
92     * @param array|null $allowedElements Which elements can be used in each GPX type
93     *                   If not specified, every element defined in the GPX specification can be used
94     *                   Can be overwritten with an associative array, with type name in keys.
95     *                   eg.: ['wptType' => ['ele', 'name'], 'trkptType' => ['ele'], 'metadataType' => null]
96     */
97    public function __construct($allowedElements = null)
98    {
99        $this->allowedGpxTypeElements = self::$gpxTypeElements;
100        $this->allowedTrkTypeElements = self::$trkTypeElements;
101        $this->allowedRteTypeElements = self::$rteTypeElements;
102        $this->allowedWptTypeElements = self::$wptTypeElements;
103        $this->allowedTrkptTypeElements = self::$trkTypeElements;
104        $this->allowedRteptTypeElements = self::$rteptTypeElements;
105        $this->allowedMetadataTypeElements = self::$metadataTypeElements;
106
107        if (is_array($allowedElements)) {
108            foreach ($allowedElements as $type => $elements) {
109                $elements = is_array($elements) ? $elements : [$elements];
110                $this->{'allowed' . ucfirst($type) . 'Elements'} = [];
111                foreach ($this::${$type . 'Elements'} as $availableType) {
112                    if (in_array($availableType, $elements)) {
113                        $this->{'allowed' . ucfirst($type) . 'Elements'}[] = $availableType;
114                    }
115                }
116            }
117        }
118    }
119
120    /**
121     * Returns an array of allowed elements for the given GPX type
122     * eg. "gpxType" returns ['metadata', 'wpt', 'rte', 'trk']
123     *
124     * @param string $type One of the following GPX types: gpxType, trkType, rteType, wptType, trkptType, rteptType, metadataType
125     * @return string[]
126     */
127    public function get($type)
128    {
129        $propertyName = 'allowed' . ucfirst($type) . 'Elements';
130        if (isset($this->{$propertyName})) {
131            return $this->{$propertyName};
132        }
133        return [];
134    }
135}
136