1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Ridvanbaluyos\Mmda; |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Metro Manila Development Authority - Traffic Data |
7
|
|
|
* http://mmdatraffic.interaksyon.com/livefeed/ |
8
|
|
|
* |
9
|
|
|
* @package MMDA Traffic Data |
10
|
|
|
* @author Ridvan Baluyos <[email protected]> |
11
|
|
|
* @link https://github.com/ridvanbaluyos/mmda |
12
|
|
|
* @license MIT |
13
|
|
|
*/ |
14
|
|
|
class MMDA |
15
|
|
|
{ |
16
|
|
|
const FEED_URL = 'http://mmdatraffic.interaksyon.com'; |
17
|
|
|
|
18
|
|
|
private $trafficData; |
19
|
|
|
private $channel; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* MMDA constructor. |
23
|
|
|
*/ |
24
|
|
|
public function __construct() |
25
|
|
|
{ |
26
|
|
|
$metroManilaFeedUrl = self::FEED_URL . '/livefeed/'; |
27
|
|
|
$nlexFeedUrl = self::FEED_URL . '/nlex/livefeed/'; |
28
|
|
|
|
29
|
|
|
$metroManilaTrafficData = $this->getTrafficData($metroManilaFeedUrl); |
30
|
|
|
$nlexTrafficData = $this->getTrafficData($nlexFeedUrl); |
31
|
|
|
|
32
|
|
|
$this->trafficData = array_merge($metroManilaTrafficData, $nlexTrafficData); |
33
|
|
|
} |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* This function retrieves the traffic data. |
37
|
|
|
* @return array |
38
|
|
|
*/ |
39
|
|
|
public function traffic() |
40
|
|
|
{ |
41
|
|
|
$traffic = $this->trafficData; |
42
|
|
|
|
43
|
|
|
return $traffic; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* This function returns the list of highways. |
48
|
|
|
* |
49
|
|
|
* @return array|null |
50
|
|
|
*/ |
51
|
|
|
public function highways() |
52
|
|
|
{ |
53
|
|
|
if ($this->trafficData) { |
|
|
|
|
54
|
|
|
return array_keys($this->trafficData); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
return null; |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* This function returns the list of segments in a given highway. |
62
|
|
|
* |
63
|
|
|
* @param $highway |
64
|
|
|
* @return array|null |
65
|
|
|
*/ |
66
|
|
|
public function segments($highway = NULL) |
67
|
|
|
{ |
68
|
|
|
if ($highway && isset($this->trafficData[$highway]['segments'])) { |
69
|
|
|
return array_keys($this->trafficData[$highway]['segments']); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
return null; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* This function retrieves the traffic data from the MMDA Traffic API. |
77
|
|
|
* |
78
|
|
|
* @return array |
79
|
|
|
*/ |
80
|
|
|
final private function getTrafficData($feedUrl) |
81
|
|
|
{ |
82
|
|
|
$ch = curl_init(); |
83
|
|
|
curl_setopt($ch, CURLOPT_URL, $feedUrl); |
|
|
|
|
84
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
85
|
|
|
$response = curl_exec($ch); |
|
|
|
|
86
|
|
|
curl_close($ch); |
|
|
|
|
87
|
|
|
|
88
|
|
|
$xml = simplexml_load_string($response); |
89
|
|
|
|
90
|
|
|
return $this->sanitizeTrafficData($this->parseTrafficData($xml)); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* This function parses the XML response from the MMDA Traffic API into JSON. |
95
|
|
|
* |
96
|
|
|
* @param $xml |
97
|
|
|
* @return array |
98
|
|
|
*/ |
99
|
|
|
final private function parseTrafficData($xml) |
100
|
|
|
{ |
101
|
|
|
$traffic = []; |
102
|
|
|
|
103
|
|
|
foreach ($xml->channel->item as $item) { |
104
|
|
|
$item = get_object_vars($item); |
105
|
|
|
$title = $item['title']; |
106
|
|
|
$description = $item['description']; |
107
|
|
|
$pubDate = $item['pubDate']; |
108
|
|
|
|
109
|
|
|
$highway = explode('-', $title, 2)[0]; |
110
|
|
|
$segment = substr(explode('-', $title, 2)[1], 0, -3); |
111
|
|
|
$direction = substr(explode('-', $title, 2)[1], -2); |
112
|
|
|
|
113
|
|
|
if (empty($traffic[$highway])) $traffic[$highway] = []; |
114
|
|
|
if (empty($traffic[$highway][$segment])) $traffic[$highway][$segment] = []; |
115
|
|
|
|
116
|
|
|
$traffic[$highway][$segment][$direction] = $description; |
117
|
|
|
$traffic[$highway][$segment]['pubDate'] = $pubDate; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
return $traffic; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* This function sanitizes the traffic data and organizes them into an envelope |
125
|
|
|
* |
126
|
|
|
* @param array $trafficData |
127
|
|
|
* @return array |
128
|
|
|
*/ |
129
|
|
|
final private function sanitizeTrafficData(Array $trafficData) |
130
|
|
|
{ |
131
|
|
|
$traffic = []; |
132
|
|
|
foreach ($trafficData as $highway=>$segments) { |
133
|
|
|
$traffic[$highway] = [ |
134
|
|
|
'name' => $highway, |
135
|
|
|
'label' => $this->convertToTitle($highway), |
136
|
|
|
]; |
137
|
|
|
$traffic[$highway]['segments'] = []; |
138
|
|
|
$dataSegments = []; |
139
|
|
|
|
140
|
|
|
foreach ($segments as $segment=>$status) { |
141
|
|
|
$dataSegments[$segment] = [ |
142
|
|
|
'name' => $segment, |
143
|
|
|
'label' => $this->convertToTitle($segment), |
144
|
|
|
'status' => $this->convertToStatus($status), |
145
|
|
|
|
146
|
|
|
]; |
147
|
|
|
$traffic[$highway]['segments'] = $dataSegments; |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
return $traffic; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* This function converts traffic data status to readable format. |
156
|
|
|
* |
157
|
|
|
* @param array $data |
158
|
|
|
* @return array |
159
|
|
|
*/ |
160
|
|
|
final private function convertToStatus(Array $data) |
161
|
|
|
{ |
162
|
|
|
$statusMatrix = [ |
163
|
|
|
'-' => 'No data', |
164
|
|
|
'L' => 'Light', |
165
|
|
|
'ML' => 'Light to Moderate', |
166
|
|
|
'M' => 'Moderate', |
167
|
|
|
'MH' => 'Moderate to Heavy', |
168
|
|
|
'H' => 'Heavy' |
169
|
|
|
]; |
170
|
|
|
|
171
|
|
|
$northBound = ($data['SB']) ?? '-'; |
172
|
|
|
$southBound = ($data['SB']) ?? '-'; |
173
|
|
|
|
174
|
|
|
$status = [ |
175
|
|
|
'NB' => [ |
176
|
|
|
'name' => $northBound, |
177
|
|
|
'label' => $statusMatrix[$northBound] . ' Traffic', |
178
|
|
|
'last_updated' => $data['pubDate'] |
179
|
|
|
], |
180
|
|
|
'SB' => [ |
181
|
|
|
'name' => $southBound, |
182
|
|
|
'label' => $statusMatrix[$southBound] . ' Traffic', |
183
|
|
|
'last_updated' => $data['pubDate'] |
184
|
|
|
] |
185
|
|
|
]; |
186
|
|
|
|
187
|
|
|
return $status; |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* This function sanitizes certain abbreviations into readable format. |
192
|
|
|
* |
193
|
|
|
* @param $string |
194
|
|
|
* @return string |
195
|
|
|
*/ |
196
|
|
|
final private function convertToTitle($string) |
197
|
|
|
{ |
198
|
|
|
$string2 = []; |
199
|
|
|
$string = str_replace(['_', 'AVE.', 'BLVD.'], [' ', 'AVENUE', 'BOULEVARD'], $string); |
200
|
|
|
$words = explode(' ', $string); |
201
|
|
|
|
202
|
|
|
foreach ($words as $word) { |
203
|
|
|
if (!in_array($word, ['EDSA', 'U.N.'])) { |
204
|
|
|
$word = ucwords(mb_strtolower($word)); |
205
|
|
|
} |
206
|
|
|
array_push($string2, $word); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
return implode(' ', $string2); |
210
|
|
|
} |
211
|
|
|
} |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.