Webhooks::run()   A
last analyzed

Complexity

Conditions 3
Paths 5

Size

Total Lines 34
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 8
Bugs 1 Features 4
Metric Value
cc 3
eloc 12
c 8
b 1
f 4
nc 5
nop 3
dl 0
loc 34
rs 9.8666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Canvas;
6
7
use function Canvas\Core\isJson;
8
use Canvas\Models\SystemModules;
9
use Canvas\Models\UserWebhooks;
10
use GuzzleHttp\Client;
0 ignored issues
show
Bug introduced by
The type GuzzleHttp\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use Phalcon\Di;
12
use Phalcon\Http\Response;
0 ignored issues
show
Bug introduced by
The type Phalcon\Http\Response was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Throwable;
14
15
/**
16
 * Class Validation.
17
 *
18
 * @package Canvas
19
 */
20
class Webhooks
21
{
22
    /**
23
     * Given the webhook id, we run a test for it.
24
     *
25
     * @param int $id
26
     * @param mixed $data
27
     *
28
     * @return Response
29
     */
30
    public static function run(int $id, array $data, array $headers = [])
31
    {
32
        /**
33
         * 1- verify it s correct url
34
         * 2- verify the method
35
         * 3- get the entity info from one entity of this app and company
36
         * 4- guzzle the request with the info
37
         * 5- verify you got a 200
38
         * 6- return the response from the webhook.
39
         *
40
         * later - add job for all system module to execute a queue when CRUD action are run, maybe the middleware would do this?
41
         *
42
         */
43
        $userWebhook = UserWebhooks::getById($id);
44
45
        $client = new Client();
46
47
        try {
48
            /**
49
             * @todo move the guzzle request to Async for faster performance
50
             */
51
            $clientRequest = $client->request(
52
                $userWebhook->method,
53
                $userWebhook->url,
54
                self::formatData($userWebhook->method, $data, $headers)
55
            );
56
57
            $responseContent = $clientRequest->getBody()->getContents();
58
            $response = isJson($responseContent) ? json_decode($responseContent, true) : $responseContent;
59
        } catch (Throwable $error) {
60
            $response = $error->getMessage();
61
        }
62
63
        return $response;
64
    }
65
66
    /**
67
     * Execute the the webhook for the given app company providing the system module
68
     * for the SDK
69
     *  - pass the system module classname or classname\namespace
70
     *  - pass the action you are doing from the CRUD
71
     *  - get all the hooks from the user that match this action
72
     *  - pass the data you are sending
73
     *  - then we send it over to the URl.
74
     *
75
     * @param string $model
76
     * @param mixed $data
77
     * @param string $action
78
     *
79
     * @throws Exception
80
     *
81
     * @return bool
82
     */
83
    public static function process(string $module, array $data, string $action, array $headers = []) : array
84
    {
85
        $appId = Di::getDefault()->getApp()->getId();
86
        $company = Di::getDefault()->getUserData()->getDefaultCompany();
87
88
        $systemModule = SystemModules::getByName($module);
89
90
        $webhooks = UserWebhooks::find([
91
            'conditions' => 'apps_id = ?0 AND companies_id = ?1 
92
                            AND webhooks_id in 
93
                                (SELECT Canvas\Models\Webhooks.id FROM Canvas\Models\Webhooks 
94
                                    WHERE Canvas\Models\Webhooks.apps_id = ?0 
95
                                    AND Canvas\Models\Webhooks.system_modules_id = ?2 
96
                                    AND Canvas\Models\Webhooks.action = ?3
97
                                )',
98
            'bind' => [
99
                $appId,
100
                $company->getId(),
101
                $systemModule->getId(),
102
                $action
103
            ]
104
        ]);
105
106
        $results = [];
107
108
        if ($webhooks->count()) {
109
            foreach ($webhooks as $userWebhook) {
110
                $results[$userWebhook->webhook->name][$action][] = [
111
                    $userWebhook->url => [
112
                        'results' => self::run($userWebhook->getId(), $data, $headers),
113
                    ]
114
                ];
115
            }
116
117
            return $results;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $results returns the type array which is incompatible with the documented return type boolean.
Loading history...
118
        }
119
120
        return [
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('message' =...a, 'action' => $action) returns the type array<string,array|string> which is incompatible with the documented return type boolean.
Loading history...
121
            'message' => 'No user configure webhooks found for : ',
122
            'module' => $module,
123
            'data' => $data,
124
            'action' => $action
125
        ];
126
    }
127
128
    /**
129
     * Format the data for guzzle correct usage.
130
     *
131
     * @return array
132
     */
133
    public static function formatData(string $method, array $data, array $headers = []) : array
134
    {
135
        switch (ucwords($method)) {
136
            case 'GET':
137
                $updateDataFormat = [
138
                    'query' => $data
139
                ];
140
                break;
141
142
            case 'PUT':
143
            case 'POST':
144
                    $updateDataFormat = [
145
                        'json' => $data,
146
                        'form_params' => $data
147
                    ];
148
                break;
149
            default:
150
                $updateDataFormat = [];
151
                break;
152
        }
153
154
        if (!empty($headers)) {
155
            $updateDataFormat['headers'] = $headers;
156
        }
157
158
        return $updateDataFormat;
159
    }
160
}
161