dolibarr  17.0.4
interface_95_modZapier_ZapierTriggers.class.php
1 <?php
2 /* Copyright (C) 2017-2020 Frédéric France <frederic.france@netlogic.fr>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
24 require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
25 
26 
31 {
37  public function __construct($db)
38  {
39  $this->db = $db;
40 
41  $this->name = preg_replace('/^Interface/i', '', get_class($this));
42  $this->family = "technic";
43  $this->description = "Zapier triggers.";
44  // 'development', 'experimental', 'dolibarr' or version
45  $this->version = self::VERSION_DEVELOPMENT;
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 mouvement
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 }
411 function 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 
441 function 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->statuts);
474  unset($toclean->statuts_short);
475  unset($toclean->statuts_logo);
476  unset($toclean->statuts_long);
477 
478  unset($toclean->element);
479  unset($toclean->fk_element);
480  unset($toclean->table_element);
481  unset($toclean->table_element_line);
482  unset($toclean->picto);
483 
484  unset($toclean->skip_update_total);
485  unset($toclean->context);
486 
487  // Remove the $oldcopy property because it is not supported by the JSON
488  // encoder. The following error is generated when trying to serialize
489  // it: "Error encoding/decoding JSON: Type is not supported"
490  // Note: Event if this property was correctly handled by the JSON
491  // encoder, it should be ignored because keeping it would let the API
492  // have a very strange behavior: calling PUT and then GET on the same
493  // resource would give different results:
494  // PUT /objects/{id} -> returns object with oldcopy = previous version of the object
495  // GET /objects/{id} -> returns object with oldcopy empty
496  unset($toclean->oldcopy);
497 
498  // If object has lines, remove $db property
499  if (isset($toclean->lines) && count($toclean->lines) > 0) {
500  $nboflines = count($toclean->lines);
501  for ($i = 0; $i < $nboflines; $i++) {
502  cleanObjectDatas($toclean->lines[$i]);
503  }
504  }
505 
506  // If object has linked objects, remove $db property
507  /*
508  if(isset($toclean->linkedObjects) && count($toclean->linkedObjects) > 0) {
509  foreach($toclean->linkedObjects as $type_object => $linked_object) {
510  foreach($linked_object as $toclean2clean) {
511  $this->cleanObjectDatas($toclean2clean);
512  }
513  }
514  }*/
515 
516  return $toclean;
517 }
518 
525 function cleanAgendaEventsDatas($toclean)
526 {
527  unset($toclean->usermod);
528  unset($toclean->libelle);
529  //unset($toclean->array_options);
530  unset($toclean->context);
531  unset($toclean->canvas);
532  unset($toclean->contact);
533  unset($toclean->contact_id);
534  unset($toclean->thirdparty);
535  unset($toclean->user);
536  unset($toclean->origin);
537  unset($toclean->origin_id);
538  unset($toclean->ref_ext);
539  unset($toclean->statut);
540  unset($toclean->country);
541  unset($toclean->country_id);
542  unset($toclean->country_code);
543  unset($toclean->barcode_type);
544  unset($toclean->barcode_type_code);
545  unset($toclean->barcode_type_label);
546  unset($toclean->barcode_type_coder);
547  unset($toclean->mode_reglement_id);
548  unset($toclean->cond_reglement_id);
549  unset($toclean->cond_reglement);
550  unset($toclean->fk_delivery_address);
551  unset($toclean->shipping_method_id);
552  unset($toclean->fk_account);
553  unset($toclean->total_ht);
554  unset($toclean->total_tva);
555  unset($toclean->total_localtax1);
556  unset($toclean->total_localtax2);
557  unset($toclean->total_ttc);
558  unset($toclean->fk_incoterms);
559  unset($toclean->libelle_incoterms);
560  unset($toclean->location_incoterms);
561  unset($toclean->name);
562  unset($toclean->lastname);
563  unset($toclean->firstname);
564  unset($toclean->civility_id);
565  unset($toclean->contact);
566  unset($toclean->societe);
567 
568  return $toclean;
569 }
Class to stock current configuration.
Definition: conf.class.php:34
Class that all the triggers must extend.
runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
Function called when a Dolibarrr business event is done.
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:47
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:745
print *****$script_file(".$version.") pid 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).
Definition: geturl.lib.php:41
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:122
$conf db
API class for accounts.
Definition: inc.php:41