Completed
Push — develop ( 005f78...818c3c )
by Armando
11s
created

DateCommand::getFormattedDate()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 17
rs 8.8571
cc 5
eloc 9
nc 3
nop 1
1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot\Commands\UserCommands;
12
13
use DateTime;
14
use DateTimeZone;
15
use GuzzleHttp\Client;
16
use GuzzleHttp\Exception\RequestException;
17
use Longman\TelegramBot\Commands\UserCommand;
18
use Longman\TelegramBot\Request;
19
use Longman\TelegramBot\TelegramLog;
20
21
/**
22
 * User "/date" command
23
 */
24
class DateCommand extends UserCommand
25
{
26
    /**
27
     * @var string
28
     */
29
    protected $name = 'date';
30
31
    /**
32
     * @var string
33
     */
34
    protected $description = 'Show date/time by location';
35
36
    /**
37
     * @var string
38
     */
39
    protected $usage = '/date <location>';
40
41
    /**
42
     * @var string
43
     */
44
    protected $version = '1.4.0';
45
46
    /**
47
     * Guzzle Client object
48
     *
49
     * @var \GuzzleHttp\Client
50
     */
51
    private $client;
52
53
    /**
54
     * Base URI for Google Maps API
55
     *
56
     * @var string
57
     */
58
    private $google_api_base_uri = 'https://maps.googleapis.com/maps/api/';
59
60
    /**
61
     * The Google API Key from the command config
62
     *
63
     * @var string
64
     */
65
    private $google_api_key;
66
67
    /**
68
     * Date format
69
     *
70
     * @var string
71
     */
72
    private $date_format = 'd-m-Y H:i:s';
73
74
    /**
75
     * Get coordinates
76
     *
77
     * @param string $location
78
     *
79
     * @return array
80
     */
81
    private function getCoordinates($location)
82
    {
83
        $path  = 'geocode/json';
84
        $query = ['address' => urlencode($location)];
85
86
        if ($this->google_api_key !== null) {
87
            $query['key'] = $this->google_api_key;
88
        }
89
90
        try {
91
            $response = $this->client->get($path, ['query' => $query]);
92
        } catch (RequestException $e) {
93
            TelegramLog::error($e->getMessage());
94
95
            return [];
96
        }
97
98
        if (!($data = $this->validateResponseData($response->getBody()))) {
99
            return [];
100
        }
101
102
        $result = $data['results'][0];
103
        $lat    = $result['geometry']['location']['lat'];
104
        $lng    = $result['geometry']['location']['lng'];
105
        $acc    = $result['geometry']['location_type'];
106
        $types  = $result['types'];
107
108
        return [$lat, $lng, $acc, $types];
109
    }
110
111
    /**
112
     * Get date
113
     *
114
     * @param string $lat
115
     * @param string $lng
116
     *
117
     * @return array
118
     */
119
    private function getDate($lat, $lng)
120
    {
121
        $path = 'timezone/json';
122
123
        $date_utc  = new \DateTime(null, new \DateTimeZone('UTC'));
124
        $timestamp = $date_utc->format('U');
125
126
        $query = [
127
            'location'  => urlencode($lat) . ',' . urlencode($lng),
128
            'timestamp' => urlencode($timestamp),
129
        ];
130
131
        if ($this->google_api_key !== null) {
132
            $query['key'] = $this->google_api_key;
133
        }
134
135
        try {
136
            $response = $this->client->get($path, ['query' => $query]);
137
        } catch (RequestException $e) {
138
            TelegramLog::error($e->getMessage());
139
140
            return [];
141
        }
142
143
        if (!($data = $this->validateResponseData($response->getBody()))) {
144
            return [];
145
        }
146
147
        $local_time = $timestamp + $data['rawOffset'] + $data['dstOffset'];
148
149
        return [$local_time, $data['timeZoneId']];
150
    }
151
152
    /**
153
     * Evaluate the response data and see if the request was successful
154
     *
155
     * @param string $data
156
     *
157
     * @return array
158
     */
159
    private function validateResponseData($data)
160
    {
161
        if (empty($data)) {
162
            return [];
163
        }
164
165
        $data = json_decode($data, true);
166
        if (empty($data)) {
167
            return [];
168
        }
169
170
        if (isset($data['status']) && $data['status'] !== 'OK') {
171
            return [];
172
        }
173
174
        return $data;
175
    }
176
177
    /**
178
     * Get formatted date at the passed location
179
     *
180
     * @param string $location
181
     *
182
     * @return string
183
     * @throws \Longman\TelegramBot\Exception\TelegramException
184
     */
185
    private function getFormattedDate($location)
186
    {
187
        if ($location === null || $location === '') {
188
            return 'The time in nowhere is never';
189
        }
190
191
        list($lat, $lng) = $this->getCoordinates($location);
192
        if (empty($lat) || empty($lng)) {
193
            return 'It seems that in "' . $location . '" they do not have a concept of time.';
194
        }
195
196
        list($local_time, $timezone_id) = $this->getDate($lat, $lng);
197
198
        $date_utc = new DateTime(gmdate('Y-m-d H:i:s', $local_time), new DateTimeZone($timezone_id));
199
200
        return 'The local time in ' . $timezone_id . ' is: ' . $date_utc->format($this->date_format);
201
    }
202
203
    /**
204
     * Command execute method
205
     *
206
     * @return mixed
207
     * @throws \Longman\TelegramBot\Exception\TelegramException
208
     */
209
    public function execute()
210
    {
211
        //First we set up the necessary member variables.
212
        $this->client = new Client(['base_uri' => $this->google_api_base_uri]);
213
        if (($this->google_api_key = trim($this->getConfig('google_api_key'))) === '') {
214
            $this->google_api_key = null;
215
        }
216
217
        $message = $this->getMessage();
218
219
        $chat_id  = $message->getChat()->getId();
220
        $location = $message->getText(true);
221
222
        $text = 'You must specify location in format: /date <city>';
223
224
        if ($location !== '') {
225
            $text = $this->getFormattedDate($location);
226
        }
227
228
        $data = [
229
            'chat_id' => $chat_id,
230
            'text'    => $text,
231
        ];
232
233
        return Request::sendMessage($data);
234
    }
235
}
236