Passed
Push — develop ( 7115f3...4811e5 )
by Michael
01:32
created

Zapier   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Test Coverage

Coverage 77.27%

Importance

Changes 0
Metric Value
wmc 10
dl 0
loc 112
ccs 34
cts 44
cp 0.7727
rs 10
c 0
b 0
f 0

3 Methods

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