dolibarr 24.0.0-beta
api_webhook.class.php
1<?php
2/* Copyright (C) 2024 Florian Charlaix <fcharlaix@easya.solutions>
3 * Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
4 * Copyright (C) 2025 Frédéric France <frederic.france@free.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20use Luracast\Restler\RestException;
21
28class Webhook extends DolibarrApi
29{
33 public static $FIELDS = array(
34 'url',
35 'trigger_codes'
36 );
37
41 public $target;
42
46 public function __construct()
47 {
48 global $db;
49 $this->db = $db;
50
51 require_once DOL_DOCUMENT_ROOT.'/webhook/class/target.class.php';
52
53 $this->target = new Target($this->db);
54 }
55
66 public function get($id)
67 {
68 return $this->_fetch($id);
69 }
70
87 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '', $properties = '', $pagination_data = false)
88 {
89 $obj_ret = array();
90
91 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'read')) {
92 throw new RestException(403);
93 }
94
95 $sql = "SELECT t.rowid";
96 $sql .= " FROM ".MAIN_DB_PREFIX."webhook_target as t";
97
98 // Add sql filters
99 if ($sqlfilters) {
100 $errormessage = '';
101 $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
102 if ($errormessage) {
103 throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
104 }
105 }
106
107 //this query will return total target with the filters given
108 $sqlTotals = str_replace('SELECT t.rowid', 'SELECT count(t.rowid) as total', $sql);
109
110 $sql .= $this->db->order($sortfield, $sortorder);
111 if ($limit) {
112 if ($page < 0) {
113 $page = 0;
114 }
115 $offset = $limit * $page;
116
117 $sql .= $this->db->plimit($limit + 1, $offset);
118 }
119
120 $result = $this->db->query($sql);
121 if ($result) {
122 $num = $this->db->num_rows($result);
123 $min = min($num, ($limit <= 0 ? $num : $limit));
124 $i = 0;
125 while ($i < $min) {
126 $obj = $this->db->fetch_object($result);
127 $target_static = new Target($this->db);
128 if ($target_static->fetch($obj->rowid)) {
129 $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($target_static), $properties);
130 }
131 $i++;
132 }
133 } else {
134 throw new RestException(503, 'Error when retrieve targets : '.$this->db->lasterror());
135 }
136 if (!count($obj_ret)) {
137 throw new RestException(404, 'Targets not found');
138 }
139
140 //if $pagination_data is true the response will contain element data with all values and element pagination with pagination data(total,page,limit)
141 if ($pagination_data) {
142 $totalsResult = $this->db->query($sqlTotals);
143 $total = $this->db->fetch_object($totalsResult)->total;
144
145 $tmp = $obj_ret;
146 $obj_ret = [];
147
148 $obj_ret['data'] = $tmp;
149 $obj_ret['pagination'] = [
150 'total' => (int) $total,
151 'page' => $page, //count starts from 0
152 'page_count' => ceil((int) $total / $limit),
153 'limit' => $limit
154 ];
155 }
156
157 return $obj_ret;
158 }
159
168 public function post($request_data = null)
169 {
170 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'write')) {
171 throw new RestException(403);
172 }
173
174 if (!is_array($request_data)) {
175 $request_data = array();
176 }
177
178 // Check mandatory fields (not using output, only possible exception is important)
179 $this->_validate($request_data);
180
181 foreach ($request_data as $field => $value) {
182 $this->target->$field = $this->_checkValForAPI($field, $value, $this->target);
183 }
184
185 if (!array_key_exists('status', $request_data)) {
186 $this->target->status = 1;
187 }
188
189 if ($this->target->create(DolibarrApiAccess::$user) < 0) {
190 throw new RestException(500, 'Error creating target', array_merge(array($this->target->error), $this->target->errors));
191 }
192
193 return $this->target->id;
194 }
195
209 public function put($id, $request_data = null)
210 {
211 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'write')) {
212 throw new RestException(403);
213 }
214
215 $result = $this->target->fetch($id);
216 if (!$result) {
217 throw new RestException(404, 'Target not found');
218 }
219
220 foreach ($request_data as $field => $value) {
221 if ($field == 'id') {
222 continue;
223 }
224 $this->target->$field = $this->_checkValForAPI($field, $value, $this->target);
225 }
226
227 if ($this->target->update(DolibarrApiAccess::$user, 1) > 0) {
228 return $this->get($id);
229 } else {
230 throw new RestException(500, $this->target->error);
231 }
232 }
233
242 public function delete($id)
243 {
244 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'delete')) {
245 throw new RestException(403);
246 }
247
248 $result = $this->target->fetch($id);
249 if (!$result) {
250 throw new RestException(404, 'Target not found');
251 }
252
253 $res = $this->target->delete(DolibarrApiAccess::$user);
254 if ($res < 0) {
255 throw new RestException(500, "Can't delete target, error occurs");
256 }
257
258 return array(
259 'success' => array(
260 'code' => 200,
261 'message' => 'Target deleted'
262 )
263 );
264 }
265
275 public function listOfTriggers()
276 {
277 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'read')) {
278 throw new RestException(403);
279 }
280
281 $triggers = array();
282
283 $sql = "SELECT c.code, c.label FROM ".MAIN_DB_PREFIX."c_action_trigger as c ORDER BY c.rang ASC";
284 $resql = $this->db->query($sql);
285 if ($resql) {
286 $num = $this->db->num_rows($resql);
287 $i = 0;
288 while ($i < $num) {
289 $obj = $this->db->fetch_object($resql);
290 $triggers[$obj->code] = $obj->label;
291 $i++;
292 }
293 } else {
294 throw new RestException(500, "Can't get list of triggers");
295 }
296
297 return $triggers;
298 }
299
308 private function _validate($data)
309 {
310 if ($data === null) {
311 $data = array();
312 }
313 $target = array();
314 foreach (self::$FIELDS as $field) {
315 if (!isset($data[$field])) {
316 throw new RestException(400, "$field field missing");
317 }
318 $target[$field] = $data[$field];
319 }
320 return $target;
321 }
322
323 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
333 protected function _cleanObjectDatas($object)
334 {
335 // phpcs:enable
336 $object = parent::_cleanObjectDatas($object);
337
338 unset($object->rowid);
339 unset($object->array_options);
340 unset($object->array_languages);
341 unset($object->contacts_ids);
342 unset($object->linkedObjectsIds);
343 unset($object->canvas);
344 unset($object->fk_project);
345 unset($object->contact_id);
346 unset($object->user);
347 unset($object->origin_type);
348 unset($object->origin_id);
349 unset($object->ref_ext);
350 unset($object->statut);
351 unset($object->country_id);
352 unset($object->country_code);
353 unset($object->state_id);
354 unset($object->region_id);
355 unset($object->barcode_type);
356 unset($object->barcode_type_coder);
357 unset($object->mode_reglement_id);
358 unset($object->cond_reglement_id);
359 unset($object->demand_reason_id);
360 unset($object->transport_mode_id);
361 unset($object->shipping_method_id);
362 unset($object->shipping_method);
363 unset($object->fk_multicurrency);
364 unset($object->multicurrency_code);
365 unset($object->multicurrency_tx);
366 unset($object->multicurrency_total_ht);
367 unset($object->multicurrency_total_tva);
368 unset($object->multicurrency_total_ttc);
369 unset($object->multicurrency_total_localtax1);
370 unset($object->multicurrency_total_localtax2);
371 unset($object->last_main_doc);
372 unset($object->fk_account);
373 unset($object->total_ht);
374 unset($object->total_tva);
375 unset($object->total_localtax1);
376 unset($object->total_localtax2);
377 unset($object->total_ttc);
378 unset($object->lines);
379 unset($object->actiontypecode);
380 unset($object->name);
381 unset($object->lastname);
382 unset($object->firstname);
383 unset($object->civility_id);
384 unset($object->date_validation);
385 unset($object->date_modification);
386 unset($object->date_cloture);
387 unset($object->user_creation_id);
388 unset($object->user_validation_id);
389 unset($object->user_closing_id);
390 unset($object->user_modification_id);
391 unset($object->specimen);
392 unset($object->extraparams);
393 unset($object->product);
394 unset($object->cond_reglement_supplier_id);
395 unset($object->deposit_percent);
396 unset($object->retained_warranty_fk_cond_reglement);
397 unset($object->warehouse_id);
398 unset($object->module);
399
400 return $object;
401 }
402
414 private function _fetch($rowid, $ref = '')
415 {
416 if (!DolibarrApiAccess::$user->hasRight('webhook', 'webhook_target', 'read')) {
417 throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login.'. No read permission on target.');
418 }
419
420 if ($rowid === 0) {
421 $result = $this->target->initAsSpecimen();
422 } else {
423 $result = $this->target->fetch($rowid, $ref);
424 }
425
426 if (!$result) {
427 throw new RestException(404, 'Target not found');
428 }
429
430 return $this->_cleanObjectDatas($this->target);
431 }
432}
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
Class for API REST v1.
Definition api.class.php:35
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Class for Target.
_fetch($rowid, $ref='')
Fetch properties of a target object.
listOfTriggers()
Get the list of all available triggers.
put($id, $request_data=null)
Update target.
post($request_data=null)
Create target object.
_validate($data)
Validate fields before create or update object.
__construct()
Constructor.
_cleanObjectDatas($object)
Clean sensible object datas @phpstan-template T.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $sqlfilters='', $properties='', $pagination_data=false)
List targets.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.