dolibarr 21.0.0-alpha
interface_95_modZapier_ZapierTriggers.class.php
1<?php
2/* Copyright (C) 2017-2020 Frédéric France <frederic.france@netlogic.fr>
3 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
25require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
26
27
32{
38 public function __construct($db)
39 {
40 $this->db = $db;
41
42 $this->name = preg_replace('/^Interface/i', '', get_class($this));
43 $this->family = "technic";
44 $this->description = "Zapier triggers.";
45 $this->version = self::VERSIONS['dev'];
46 $this->picto = 'zapier';
47 }
48
61 public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
62 {
63 if (empty($conf->zapier) || empty($conf->zapier->enabled)) {
64 // Module not active, we do nothing
65 return 0;
66 }
67
68 $logtriggeraction = false;
69 $sql = '';
70 if ($action != '') {
71 $actions = explode('_', $action);
72 $sql = 'SELECT rowid, url FROM '.MAIN_DB_PREFIX.'zapier_hook';
73 $sql .= ' WHERE module="'.$this->db->escape(strtolower($actions[0])).'" AND action="'.$this->db->escape(strtolower($actions[1])).'"';
74 //setEventMessages($sql, null);
75 }
76
77 switch ($action) {
78 // Users
79 case 'USER_CREATE':
80 $resql = $this->db->query($sql);
81 // TODO voir comment regrouper les webhooks en un post
82 while ($resql && $obj = $this->db->fetch_array($resql)) {
83 $cleaned = cleanObjectDatas(dol_clone($object));
84 $json = json_encode($cleaned);
85 // call the zapierPostWebhook() function
86 zapierPostWebhook($obj['url'], $json);
87 }
88 $logtriggeraction = true;
89 break;
90 case 'USER_MODIFY':
91 $resql = $this->db->query($sql);
92 // TODO voir comment regrouper les webhooks en un post
93 while ($resql && $obj = $this->db->fetch_array($resql)) {
94 $cleaned = cleanObjectDatas(dol_clone($object));
95 $json = json_encode($cleaned);
96 // call the zapierPostWebhook() function
97 zapierPostWebhook($obj['url'], $json);
98 }
99 $logtriggeraction = true;
100 break;
101 //case 'USER_NEW_PASSWORD':
102 //case 'USER_ENABLEDISABLE':
103 //case 'USER_DELETE':
104 //case 'USER_LOGIN':
105 //case 'USER_LOGIN_FAILED':
106 //case 'USER_LOGOUT':
107
108 // Actions
109 case 'ACTION_MODIFY':
110 //$logtriggeraction = true;
111 break;
112 case 'ACTION_CREATE':
113 $resql = $this->db->query($sql);
114 // TODO voir comment regrouper les webhooks en un post
115 while ($resql && $obj = $this->db->fetch_array($resql)) {
116 $cleaned = cleanObjectDatas(dol_clone($object));
117 $cleaned = cleanAgendaEventsDatas($cleaned);
118 $json = json_encode($cleaned);
119 // call the zapierPostWebhook() function
120 zapierPostWebhook($obj['url'], $json);
121 //setEventMessages($obj['url'], null);
122 }
123 $logtriggeraction = true;
124 break;
125 case 'ACTION_DELETE':
126 //$logtriggeraction = true;
127 break;
128
129 // Groups
130 //case 'USERGROUP_CREATE':
131 //case 'USERGROUP_MODIFY':
132 //case 'USERGROUP_DELETE':
133
134 // Categories
135 // case 'CATEGORY_CREATE':
136 // case 'CATEGORY_MODIFY':
137 // case 'CATEGORY_DELETE':
138 // case 'CATEGORY_SET_MULTILANGS':
139
140 // Companies
141 case 'COMPANY_CREATE':
142 $resql = $this->db->query($sql);
143 while ($resql && $obj = $this->db->fetch_array($resql)) {
144 $cleaned = cleanObjectDatas(dol_clone($object));
145 $json = json_encode($cleaned);
146 // call the zapierPostWebhook() function
147 zapierPostWebhook($obj['url'], $json);
148 }
149 $logtriggeraction = true;
150 break;
151 case 'COMPANY_MODIFY':
152 $resql = $this->db->query($sql);
153 while ($resql && $obj = $this->db->fetch_array($resql)) {
154 $cleaned = cleanObjectDatas(dol_clone($object));
155 $json = json_encode($cleaned);
156 // call the zapierPostWebhook() function
157 zapierPostWebhook($obj['url'], $json);
158 }
159 $logtriggeraction = true;
160 break;
161 case 'COMPANY_DELETE':
162 //$logtriggeraction = true;
163 break;
164
165 // Contacts
166 case 'CONTACT_CREATE':
167 $resql = $this->db->query($sql);
168 while ($resql && $obj = $this->db->fetch_array($resql)) {
169 $cleaned = cleanObjectDatas(dol_clone($object));
170 $json = json_encode($cleaned);
171 // call the zapierPostWebhook() function
172 zapierPostWebhook($obj['url'], $json);
173 }
174 $logtriggeraction = true;
175 break;
176 case 'CONTACT_MODIFY':
177 $resql = $this->db->query($sql);
178 while ($resql && $obj = $this->db->fetch_array($resql)) {
179 $cleaned = cleanObjectDatas(dol_clone($object));
180 $json = json_encode($cleaned);
181 // call the zapierPostWebhook() function
182 zapierPostWebhook($obj['url'], $json);
183 }
184 $logtriggeraction = true;
185 break;
186 case 'CONTACT_DELETE':
187 break;
188 case 'CONTACT_ENABLEDISABLE':
189 break;
190 // Products
191 // case 'PRODUCT_CREATE':
192 // case 'PRODUCT_MODIFY':
193 // case 'PRODUCT_DELETE':
194 // case 'PRODUCT_PRICE_MODIFY':
195 // case 'PRODUCT_SET_MULTILANGS':
196 // case 'PRODUCT_DEL_MULTILANGS':
197
198 //Stock movement
199 // case 'STOCK_MOVEMENT':
200
201 //MYECMDIR
202 // case 'MYECMDIR_DELETE':
203 // case 'MYECMDIR_CREATE':
204 // case 'MYECMDIR_MODIFY':
205
206 // Sales orders
207 case 'ORDER_CREATE':
208 $resql = $this->db->query($sql);
209 while ($resql && $obj = $this->db->fetch_array($resql)) {
210 $cleaned = cleanObjectDatas(dol_clone($object));
211 $json = json_encode($cleaned);
212 // call the zapierPostWebhook() function
213 zapierPostWebhook($obj['url'], $json);
214 }
215 $logtriggeraction = true;
216 break;
217 case 'ORDER_CLONE':
218 break;
219 case 'ORDER_VALIDATE':
220 break;
221 case 'ORDER_DELETE':
222 case 'ORDER_CANCEL':
223 case 'ORDER_SENTBYMAIL':
224 case 'ORDER_CLASSIFY_BILLED':
225 case 'ORDER_SETDRAFT':
226 case 'LINEORDER_INSERT':
227 case 'LINEORDER_UPDATE':
228 case 'LINEORDER_DELETE':
229 break;
230 // Supplier orders
231 // case 'ORDER_SUPPLIER_CREATE':
232 // case 'ORDER_SUPPLIER_CLONE':
233 // case 'ORDER_SUPPLIER_VALIDATE':
234 // case 'ORDER_SUPPLIER_DELETE':
235 // case 'ORDER_SUPPLIER_APPROVE':
236 // case 'ORDER_SUPPLIER_REFUSE':
237 // case 'ORDER_SUPPLIER_CANCEL':
238 // case 'ORDER_SUPPLIER_SENTBYMAIL':
239 // case 'ORDER_SUPPLIER_RECEIVE':
240 // case 'LINEORDER_SUPPLIER_DISPATCH':
241 // case 'LINEORDER_SUPPLIER_CREATE':
242 // case 'LINEORDER_SUPPLIER_UPDATE':
243
244 // Proposals
245 // case 'PROPAL_CREATE':
246 // case 'PROPAL_CLONE':
247 // case 'PROPAL_MODIFY':
248 // case 'PROPAL_VALIDATE':
249 // case 'PROPAL_SENTBYMAIL':
250 // case 'PROPAL_CLOSE_SIGNED':
251 // case 'PROPAL_CLOSE_REFUSED':
252 // case 'PROPAL_DELETE':
253 // case 'LINEPROPAL_INSERT':
254 // case 'LINEPROPAL_UPDATE':
255 // case 'LINEPROPAL_DELETE':
256
257 // SupplierProposal
258 // case 'SUPPLIER_PROPOSAL_CREATE':
259 // case 'SUPPLIER_PROPOSAL_CLONE':
260 // case 'SUPPLIER_PROPOSAL_MODIFY':
261 // case 'SUPPLIER_PROPOSAL_VALIDATE':
262 // case 'SUPPLIER_PROPOSAL_SENTBYMAIL':
263 // case 'SUPPLIER_PROPOSAL_CLOSE_SIGNED':
264 // case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED':
265 // case 'SUPPLIER_PROPOSAL_DELETE':
266 // case 'LINESUPPLIER_PROPOSAL_INSERT':
267 // case 'LINESUPPLIER_PROPOSAL_UPDATE':
268 // case 'LINESUPPLIER_PROPOSAL_DELETE':
269
270 // Contracts
271 // case 'CONTRACT_CREATE':
272 // case 'CONTRACT_ACTIVATE':
273 // case 'CONTRACT_CANCEL':
274 // case 'CONTRACT_CLOSE':
275 // case 'CONTRACT_DELETE':
276 // case 'LINECONTRACT_INSERT':
277 // case 'LINECONTRACT_UPDATE':
278 // case 'LINECONTRACT_DELETE':
279
280 // Bills
281 // case 'BILL_CREATE':
282 // case 'BILL_CLONE':
283 // case 'BILL_MODIFY':
284 // case 'BILL_VALIDATE':
285 // case 'BILL_UNVALIDATE':
286 // case 'BILL_SENTBYMAIL':
287 // case 'BILL_CANCEL':
288 // case 'BILL_DELETE':
289 // case 'BILL_PAYED':
290 // case 'LINEBILL_INSERT':
291 // case 'LINEBILL_UPDATE':
292 // case 'LINEBILL_DELETE':
293
294 //Supplier Bill
295 // case 'BILL_SUPPLIER_CREATE':
296 // case 'BILL_SUPPLIER_UPDATE':
297 // case 'BILL_SUPPLIER_DELETE':
298 // case 'BILL_SUPPLIER_PAYED':
299 // case 'BILL_SUPPLIER_UNPAYED':
300 // case 'BILL_SUPPLIER_VALIDATE':
301 // case 'BILL_SUPPLIER_UNVALIDATE':
302 // case 'LINEBILL_SUPPLIER_CREATE':
303 // case 'LINEBILL_SUPPLIER_UPDATE':
304 // case 'LINEBILL_SUPPLIER_DELETE':
305
306 // Payments
307 // case 'PAYMENT_CUSTOMER_CREATE':
308 // case 'PAYMENT_SUPPLIER_CREATE':
309 // case 'PAYMENT_ADD_TO_BANK':
310 // case 'PAYMENT_DELETE':
311
312 // Online
313 // case 'PAYMENT_PAYBOX_OK':
314 // case 'PAYMENT_PAYPAL_OK':
315 // case 'PAYMENT_STRIPE_OK':
316
317 // Donation
318 // case 'DON_CREATE':
319 // case 'DON_UPDATE':
320 // case 'DON_DELETE':
321
322 // Interventions
323 // case 'FICHINTER_CREATE':
324 // case 'FICHINTER_MODIFY':
325 // case 'FICHINTER_VALIDATE':
326 // case 'FICHINTER_DELETE':
327 // case 'LINEFICHINTER_CREATE':
328 // case 'LINEFICHINTER_UPDATE':
329 // case 'LINEFICHINTER_DELETE':
330
331 // Members
332 case 'MEMBER_CREATE':
333 $resql = $this->db->query($sql);
334 while ($resql && $obj = $this->db->fetch_array($resql)) {
335 $cleaned = cleanObjectDatas(dol_clone($object));
336 $json = json_encode($cleaned);
337 // call the zapierPostWebhook() function
338 zapierPostWebhook($obj['url'], $json);
339 }
340 $logtriggeraction = true;
341 break;
342 case 'MEMBER_MODIFY':
343 $resql = $this->db->query($sql);
344 while ($resql && $obj = $this->db->fetch_array($resql)) {
345 $cleaned = cleanObjectDatas(dol_clone($object));
346 $json = json_encode($cleaned);
347 // call the zapierPostWebhook() function
348 zapierPostWebhook($obj['url'], $json);
349 }
350 $logtriggeraction = true;
351 break;
352 // case 'MEMBER_VALIDATE':
353 // case 'MEMBER_SUBSCRIPTION':
354 // case 'MEMBER_NEW_PASSWORD':
355 // case 'MEMBER_RESILIATE':
356 // case 'MEMBER_DELETE':
357
358 // Projects
359 // case 'PROJECT_CREATE':
360 // case 'PROJECT_MODIFY':
361 // case 'PROJECT_DELETE':
362
363 // Project tasks
364 // case 'TASK_CREATE':
365 // case 'TASK_MODIFY':
366 // case 'TASK_DELETE':
367
368 // Task time spent
369 // case 'TASK_TIMESPENT_CREATE':
370 // case 'TASK_TIMESPENT_MODIFY':
371 // case 'TASK_TIMESPENT_DELETE':
372 case 'TICKET_CREATE':
373 $resql = $this->db->query($sql);
374 // TODO voir comment regrouper les webhooks en un post
375 while ($resql && $obj = $this->db->fetch_array($resql)) {
376 $cleaned = cleanObjectDatas(dol_clone($object));
377 $json = json_encode($cleaned);
378 // call the zapierPostWebhook() function
379 zapierPostWebhook($obj['url'], $json);
380 }
381 $logtriggeraction = true;
382 break;
383 // case 'TICKET_MODIFY':
384 // break;
385 // case 'TICKET_DELETE':
386 // break;
387
388 // Shipping
389 // case 'SHIPPING_CREATE':
390 // case 'SHIPPING_MODIFY':
391 // case 'SHIPPING_VALIDATE':
392 // case 'SHIPPING_SENTBYMAIL':
393 // case 'SHIPPING_BILLED':
394 // case 'SHIPPING_CLOSED':
395 // case 'SHIPPING_REOPEN':
396 // case 'SHIPPING_DELETE':
397 }
398 if ($logtriggeraction) {
399 dol_syslog("Trigger '".$this->name."' for action '".$action."' launched by ".__FILE__." id=".$object->id);
400 }
401 return 0;
402 }
403}
411function zapierPostWebhook($url, $json)
412{
413 $headers = array('Accept: application/json', 'Content-Type: application/json');
414
415 // TODO disable wekhook if error ?
416
417 dol_syslog("Send message to Zapier with json size=".dol_strlen($json), LOG_DEBUG);
418 getURLContent($url, 'POSTALREADYFORMATED', $json, 1, $headers, array('http', 'https'), 0);
419
420 /*
421 $ch = curl_init();
422 curl_setopt($ch, CURLOPT_URL, $url);
423 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
424 curl_setopt($ch, CURLOPT_TIMEOUT, 10);
425 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
426 curl_setopt($ch, CURLOPT_POST, 1);
427 curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
428 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
429
430 $output = curl_exec($ch);
431 curl_close($ch);
432 */
433}
434
441function cleanObjectDatas($toclean)
442{
443 // Remove $db object property for object
444 unset($toclean->db);
445
446 // Remove linkedObjects. We should already have linkedObjectsIds that avoid huge responses
447 unset($toclean->linkedObjects);
448
449 unset($toclean->lines); // should be ->lines
450
451 unset($toclean->fields);
452
453 unset($toclean->oldline);
454
455 unset($toclean->error);
456 unset($toclean->errors);
457
458 unset($toclean->ref_previous);
459 unset($toclean->ref_next);
460
461 unset($toclean->projet); // Should be fk_project
462 unset($toclean->project); // Should be fk_project
463 unset($toclean->author); // Should be fk_user_author
464 unset($toclean->timespent_old_duration);
465 unset($toclean->timespent_id);
466 unset($toclean->timespent_duration);
467 unset($toclean->timespent_date);
468 unset($toclean->timespent_datehour);
469 unset($toclean->timespent_withhour);
470 unset($toclean->timespent_fk_user);
471 unset($toclean->timespent_note);
472
473 unset($toclean->labelStatus);
474 unset($toclean->labelStatusShort);
475
476 unset($toclean->element);
477 unset($toclean->fk_element);
478 unset($toclean->table_element);
479 unset($toclean->table_element_line);
480 unset($toclean->picto);
481
482 unset($toclean->skip_update_total);
483 unset($toclean->context);
484
485 // Remove the $oldcopy property because it is not supported by the JSON
486 // encoder. The following error is generated when trying to serialize
487 // it: "Error encoding/decoding JSON: Type is not supported"
488 // Note: Event if this property was correctly handled by the JSON
489 // encoder, it should be ignored because keeping it would let the API
490 // have a very strange behavior: calling PUT and then GET on the same
491 // resource would give different results:
492 // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
493 // GET /objects/{id} -> returns object with oldcopy empty
494 unset($toclean->oldcopy);
495
496 // If object has lines, remove $db property
497 if (isset($toclean->lines) && count($toclean->lines) > 0) {
498 $nboflines = count($toclean->lines);
499 for ($i = 0; $i < $nboflines; $i++) {
500 cleanObjectDatas($toclean->lines[$i]);
501 }
502 }
503
504 // If object has linked objects, remove $db property
505 /*
506 if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) {
507 foreach($toclean->linkedObjects as $type_object => $linked_object) {
508 foreach($linked_object as $toclean2clean) {
509 $this->cleanObjectDatas($toclean2clean);
510 }
511 }
512 }*/
513
514 return $toclean;
515}
516
523function cleanAgendaEventsDatas($toclean)
524{
525 unset($toclean->usermod);
526 unset($toclean->libelle);
527 //unset($toclean->array_options);
528 unset($toclean->context);
529 unset($toclean->canvas);
530 unset($toclean->contact);
531 unset($toclean->contact_id);
532 unset($toclean->thirdparty);
533 unset($toclean->user);
534 unset($toclean->origin);
535 unset($toclean->origin_id);
536 unset($toclean->ref_ext);
537 unset($toclean->statut);
538 unset($toclean->country);
539 unset($toclean->country_id);
540 unset($toclean->country_code);
541 unset($toclean->barcode_type);
542 unset($toclean->barcode_type_code);
543 unset($toclean->barcode_type_label);
544 unset($toclean->barcode_type_coder);
545 unset($toclean->mode_reglement_id);
546 unset($toclean->cond_reglement_id);
547 unset($toclean->cond_reglement);
548 unset($toclean->fk_delivery_address);
549 unset($toclean->shipping_method_id);
550 unset($toclean->fk_account);
551 unset($toclean->total_ht);
552 unset($toclean->total_tva);
553 unset($toclean->total_localtax1);
554 unset($toclean->total_localtax2);
555 unset($toclean->total_ttc);
556 unset($toclean->fk_incoterms);
557 unset($toclean->libelle_incoterms);
558 unset($toclean->location_incoterms);
559 unset($toclean->name);
560 unset($toclean->lastname);
561 unset($toclean->firstname);
562 unset($toclean->civility_id);
563 unset($toclean->contact);
564 unset($toclean->societe);
565
566 return $toclean;
567}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
Class to stock current configuration.
Class that all triggers must inherit.
runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
Function called when a Dolibarr business event is done.
Class to manage translations.
Class to manage Dolibarr users.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getURLContent($url, $postorget='GET', $param='', $followlocation=1, $addheaders=array(), $allowedschemes=array('http', 'https'), $localurl=0, $ssl_verifypeer=-1)
Function to get a content from an URL (use proxy if proxy defined).
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140