1<?php
2
3namespace dokuwiki\plugin\swarmwebhook\webhooks;
4
5use dokuwiki\plugin\struct\meta\Schema;
6
7class Zapier extends AbstractWebhook
8{
9    public function run($json)
10    {
11        global $conf, $INPUT;
12
13        if ($conf['allowdebug']) {
14            dbglog($_SERVER);
15        }
16
17        /** @var null|\helper_plugin_swarmwebhook $helper */
18        $helper = plugin_load('helper', 'swarmwebhook');
19        if (!$helper) {
20            http_status(422, 'swarmwebhook plugin not active at this server');
21            return;
22        }
23        if ($helper->getConf('service') !== 'Zapier') {
24            http_status(422, 'This service is deactivated in the plugin configuration.');
25            return;
26        }
27        /*
28        @FIXME unfotunately Zapier fails to send the respective header, even when configured correctly
29        @FIXME until this is resolved by Zapier, this security check is useless ��
30        $storedSecret = $helper->getConf('hook_secret');
31        if (!empty($storedSecret)) {
32            $requestSecret = $INPUT->server->str('X_HOOK_SECRET');
33            if (empty($requestSecret)) {
34                http_status(401, 'Header X_HOOK_SECRET missing!');
35                return;
36            }
37
38            if ($requestSecret !== $storedSecret) {
39                http_status(403, 'Header X_HOOK_SECRET not identical with configured secret!');
40                return;
41            }
42        }
43        */
44
45        $ok = $this->handleWebhookPayload($json);
46
47        if ($ok) {
48            http_status(202);
49        }
50    }
51
52    /**
53     * Stores the webhook's payload to the struct table
54     *
55     * FIXME: don't set http status here
56     *
57     * @param string $json the original webhooks payload as json
58     *
59     * @return bool false if there was an error, http status has already been set, true if everything was ok
60     */
61    protected function handleWebhookPayload($json)
62    {
63        /** @var null|\helper_plugin_struct $struct */
64        $struct = plugin_load('helper', 'struct');
65        if (!$struct) {
66            http_status(422, 'struct plugin not active at this server');
67            return false;
68        }
69
70        /** @var \helper_plugin_swarmwebhook $helper */
71        $helper = plugin_load('helper', 'swarmwebhook');
72
73        $lookupData = $this->extractDataFromPayload(json_decode($json, true));
74        $lookupData['json'] = $json;
75
76        try {
77            $schemas = Schema::getAll('lookup');
78            if (!in_array('swarm', $schemas)) {
79                $helper->createNewSwarmSchema();
80            }
81
82            $helper->deleteCheckinFromLookup($lookupData['checkinid']);
83            $helper->saveDataToLookup($lookupData);
84        } catch (\Exception $e) { // FIXME: catch more specific exceptions!
85            $errorMessage = $e->getMessage();
86            dbglog($errorMessage);
87            http_status(500, $errorMessage);
88            return false;
89        }
90
91        return true;
92    }
93
94
95
96    /**
97     * Extract the data to be saved from the payload
98     *
99     * @param array $data
100     *
101     * @return array
102     */
103    protected function extractDataFromPayload(array $data)
104    {
105        $checkinID = $data['id'];
106        $locationName = $data['venue']['name'];
107
108        /** @var \helper_plugin_swarmwebhook $helper */
109        $helper = plugin_load('helper', 'swarmwebhook');
110        $dateTime = $helper->getDateTimeInstance($data['createdAt'], $data['timeZoneOffset']);
111
112        $lookupData = [
113            'date' => $dateTime->format('Y-m-d'),
114            'time' => $dateTime->format(\DateTime::ATOM),
115            'checkinid' => $checkinID,
116            'locname' => $locationName,
117            'service' => 'Zapier',
118        ];
119        if (!empty($data['shout'])) {
120            $lookupData['shout'] = $data['shout'];
121        }
122        return $lookupData;
123    }
124}
125