dolibarr 20.0.0
emailcollector_card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2018 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
4 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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
26// Load Dolibarr environment
27require '../main.inc.php';
28require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
29require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
31
32include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
33include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
34include_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollector.class.php';
35include_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollectorfilter.class.php';
36include_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollectoraction.class.php';
37include_once DOL_DOCUMENT_ROOT.'/emailcollector/lib/emailcollector.lib.php';
38
39use Webklex\PHPIMAP\ClientManager;
40use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
41
42
43use OAuth\Common\Storage\DoliStorage;
44use OAuth\Common\Consumer\Credentials;
45
46if (!$user->admin) {
48}
49if (!isModEnabled('emailcollector')) {
51}
52
53// Load traductions files required by page
54$langs->loadLangs(array("admin", "mails", "other"));
55
56// Get parameters
57$id = GETPOSTINT('id');
58$ref = GETPOST('ref', 'alpha');
59$action = GETPOST('action', 'aZ09');
60$confirm = GETPOST('confirm', 'alpha');
61$cancel = GETPOST('cancel', 'aZ09');
62$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'emailcollectorcard'; // To manage different context of search
63$backtopage = GETPOST('backtopage', 'alpha');
64
65$operationid = GETPOSTINT('operationid');
66
67// Initialize technical objects
68$object = new EmailCollector($db);
69$extrafields = new ExtraFields($db);
70$diroutputmassaction = $conf->emailcollector->dir_output.'/temp/massgeneration/'.$user->id;
71$hookmanager->initHooks(array('emailcollectorcard')); // Note that conf->hooks_modules contains array
72
73// Fetch optionals attributes and labels
74$extrafields->fetch_name_optionals_label($object->table_element);
75
76$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
77
78// Initialize array of search criteria
79$search_all = GETPOST("search_all", 'alpha');
80$search = array();
81foreach ($object->fields as $key => $val) {
82 if (GETPOST('search_'.$key, 'alpha')) {
83 $search[$key] = GETPOST('search_'.$key, 'alpha');
84 }
85}
86
87if (GETPOST('saveoperation2')) {
88 $action = 'updateoperation';
89}
90if (empty($action) && empty($id) && empty($ref)) {
91 $action = 'view';
92}
93
94// Load object
95include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once.
96
97// Security check - Protection if external user
98//if ($user->socid > 0) accessforbidden();
99//if ($user->socid > 0) $socid = $user->socid;
100//$isdraft = (($object->statut == MyObject::STATUS_DRAFT) ? 1 : 0);
101//$result = restrictedArea($user, 'mymodule', $object->id, '', '', 'fk_soc', 'rowid', $isdraft);
102
103$permissionnote = $user->admin; // Used by the include of actions_setnotes.inc.php
104$permissiondellink = $user->admin; // Used by the include of actions_dellink.inc.php
105$permissiontoadd = $user->admin; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
106
107$debuginfo = '';
108$error = 0;
109
110
111/*
112 * Actions
113 */
114
115$parameters = array();
116$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
117
118if ($reshook < 0) {
119 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
120}
121
122if (empty($reshook)) {
123 $permissiontoadd = 1;
124 $permissiontodelete = 1;
125 if (empty($backtopage)) {
126 $backtopage = DOL_URL_ROOT.'/admin/emailcollector_card.php?id='.($id > 0 ? $id : '__ID__');
127 }
128 $backurlforlist = DOL_URL_ROOT.'/admin/emailcollector_list.php';
129
130 // Actions cancel, add, update, delete or clone
131 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
132
133 // Actions when linking object each other
134 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
135
136 // Actions when printing a doc from card
137 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
138}
139
140if (GETPOST('addfilter', 'alpha')) {
141 $emailcollectorfilter = new EmailCollectorFilter($db);
142 $emailcollectorfilter->type = GETPOST('filtertype', 'aZ09');
143 $emailcollectorfilter->rulevalue = GETPOST('rulevalue', 'alpha');
144 $emailcollectorfilter->fk_emailcollector = $object->id;
145 $emailcollectorfilter->status = 1;
146
147 $result = $emailcollectorfilter->create($user);
148
149 if ($result > 0) {
150 $object->fetchFilters();
151 } else {
152 setEventMessages($emailcollectorfilter->error, $emailcollectorfilter->errors, 'errors');
153 }
154}
155
156if ($action == 'deletefilter') {
157 $emailcollectorfilter = new EmailCollectorFilter($db);
158 $emailcollectorfilter->fetch(GETPOSTINT('filterid'));
159 if ($emailcollectorfilter->id > 0) {
160 $result = $emailcollectorfilter->delete($user);
161 if ($result > 0) {
162 $object->fetchFilters();
163 } else {
164 setEventMessages($emailcollectorfilter->error, $emailcollectorfilter->errors, 'errors');
165 }
166 }
167}
168
169if (GETPOST('addoperation', 'alpha')) {
170 $emailcollectoroperation = new EmailCollectorAction($db);
171 $emailcollectoroperation->type = GETPOST('operationtype', 'aZ09');
172 $emailcollectoroperation->actionparam = GETPOST('operationparam', 'restricthtml');
173 $emailcollectoroperation->fk_emailcollector = $object->id;
174 $emailcollectoroperation->status = 1;
175 $emailcollectoroperation->position = 50;
176
177 if ($emailcollectoroperation->type == '-1') {
178 $error++;
179 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Operation")), null, 'errors');
180 }
181
182 if (in_array($emailcollectoroperation->type, array('loadthirdparty', 'loadandcreatethirdparty'))
183 && empty($emailcollectoroperation->actionparam)) {
184 $error++;
185 setEventMessages($langs->trans("ErrorAParameterIsRequiredForThisOperation"), null, 'errors');
186 }
187
188 if (!$error) {
189 $result = $emailcollectoroperation->create($user);
190
191 if ($result > 0) {
192 $object->fetchActions();
193 } else {
194 $error++;
195 setEventMessages($emailcollectoroperation->error, $emailcollectoroperation->errors, 'errors');
196 }
197 }
198}
199
200if ($action == 'updateoperation') {
201 $emailcollectoroperation = new EmailCollectorAction($db);
202 $emailcollectoroperation->fetch(GETPOSTINT('rowidoperation2'));
203
204 $emailcollectoroperation->actionparam = GETPOST('operationparam2', 'alphawithlgt');
205
206 if (in_array($emailcollectoroperation->type, array('loadthirdparty', 'loadandcreatethirdparty'))
207 && empty($emailcollectoroperation->actionparam)) {
208 $error++;
209 setEventMessages($langs->trans("ErrorAParameterIsRequiredForThisOperation"), null, 'errors');
210 }
211
212 if (!$error) {
213 $result = $emailcollectoroperation->update($user);
214
215 if ($result > 0) {
216 $object->fetchActions();
217 } else {
218 $error++;
219 setEventMessages($emailcollectoroperation->error, $emailcollectoroperation->errors, 'errors');
220 }
221 }
222}
223if ($action == 'deleteoperation') {
224 $emailcollectoroperation = new EmailCollectorAction($db);
225 $emailcollectoroperation->fetch(GETPOSTINT('operationid'));
226 if ($emailcollectoroperation->id > 0) {
227 $result = $emailcollectoroperation->delete($user);
228 if ($result > 0) {
229 $object->fetchActions();
230 } else {
231 setEventMessages($emailcollectoroperation->error, $emailcollectoroperation->errors, 'errors');
232 }
233 }
234}
235
236if ($action == 'collecttest') {
237 dol_include_once('/emailcollector/class/emailcollector.class.php');
238
239 $res = $object->doCollectOneCollector(1);
240 if ($res > 0) {
241 $debuginfo = $object->debuginfo;
242 setEventMessages($object->lastresult, null, 'mesgs');
243 } else {
244 $debuginfo = $object->debuginfo;
245 setEventMessages($object->error, $object->errors, 'errors');
246 }
247
248 $action = '';
249}
250
251if ($action == 'confirm_collect') {
252 dol_include_once('/emailcollector/class/emailcollector.class.php');
253
254 $res = $object->doCollectOneCollector(0);
255 if ($res > 0) {
256 $debuginfo = $object->debuginfo;
257 setEventMessages($object->lastresult, null, 'mesgs');
258 } else {
259 $debuginfo = $object->debuginfo;
260 setEventMessages($object->error, $object->errors, 'errors');
261 }
262
263 $action = '';
264}
265
266
267
268/*
269 * View
270 */
271
272$form = new Form($db);
273$formfile = new FormFile($db);
274
275$help_url = "EN:Module_EMail_Collector|FR:Module_Collecteur_de_courrier_électronique|ES:Module_EMail_Collector";
276
277llxHeader('', 'EmailCollector', $help_url, '', 0, 0, '', '', '', 'mod-admin page-emailcollector_card');
278
279// Part to create
280if ($action == 'create') {
281 print load_fiche_titre($langs->trans("NewEmailCollector", $langs->transnoentitiesnoconv("EmailCollector")));
282
283 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
284 print '<input type="hidden" name="token" value="'.newToken().'">';
285 print '<input type="hidden" name="action" value="add">';
286 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
287
288 print dol_get_fiche_head(array(), '');
289
290 print '<table class="border centpercent tableforfield">'."\n";
291
292 //unset($fields[]);
293
294 // Common attributes
295 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
296
297 // Other attributes
298 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
299
300 print '</table>'."\n";
301
302 print dol_get_fiche_end();
303
304 print $form->buttonsSaveCancel("Create");
305
306 print '</form>';
307}
308
309// Part to edit record
310if (($id || $ref) && $action == 'edit') {
311 print load_fiche_titre($langs->trans("EmailCollector"));
312
313 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
314 print '<input type="hidden" name="token" value="'.newToken().'">';
315 print '<input type="hidden" name="action" value="update">';
316 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
317 print '<input type="hidden" name="id" value="'.$object->id.'">';
318
319 print dol_get_fiche_head();
320
321 print '<table class="border centpercent tableforfield">'."\n";
322
323 // Common attributes
324 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
325
326 // Other attributes
327 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
328
329 print '</table>';
330
331 print dol_get_fiche_end();
332
333 print $form->buttonsSaveCancel();
334
335 print '</form>';
336}
337
338// Part to show record
339if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
340 $res = $object->fetch_optionals();
341
342 $object->fetchFilters();
343 $object->fetchActions();
344
345 $head = emailcollectorPrepareHead($object);
346 print dol_get_fiche_head($head, 'card', $langs->trans("EmailCollector"), -1, 'email');
347
348 $formconfirm = '';
349
350 // Confirmation to delete
351 if ($action == 'delete') {
352 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteEmailCollector'), $langs->trans('ConfirmDeleteEmailCollector'), 'confirm_delete', '', 0, 1);
353 }
354
355 // Clone confirmation
356 if ($action == 'clone') {
357 // Create an array for form
358 $formquestion = array();
359 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneEmailCollector', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
360 }
361
362 // Confirmation of action process
363 if ($action == 'collect') {
364 $formquestion = array();
365 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('EmailCollectorConfirmCollectTitle'), $langs->trans('EmailCollectorConfirmCollect'), 'confirm_collect', $formquestion, 0, 1, 220);
366 }
367
368 // Call Hook formConfirm
369 $parameters = array('formConfirm' => $formconfirm);
370 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
371 if (empty($reshook)) {
372 $formconfirm .= $hookmanager->resPrint;
373 } elseif ($reshook > 0) {
374 $formconfirm = $hookmanager->resPrint;
375 }
376
377 // Print form confirm
378 print $formconfirm;
379
380 // Object card
381 // ------------------------------------------------------------
382 $linkback = '<a href="'.DOL_URL_ROOT.'/admin/emailcollector_list.php?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
383
384 $morehtmlref = '<div class="refidno">';
385 $morehtmlref .= '</div>';
386
387 $morehtml = '';
388
389 $sourcedir = $object->source_directory;
390 $targetdir = ($object->target_directory ? $object->target_directory : ''); // Can be '[Gmail]/Trash' or 'mytag'
391
392 $connection = null;
393 $connectstringserver = $object->getConnectStringIMAP(); // Note: $object->host has been loaded by the fetch
394 $connectstringsource = '';
395 $connectstringtarget = '';
396
397
398 if ($action == 'scan') {
399 if (getDolGlobalString('MAIN_IMAP_USE_PHPIMAP')) {
400 require_once DOL_DOCUMENT_ROOT.'/includes/webklex/php-imap/vendor/autoload.php';
401
402 if ($object->acces_type == 1) {
403 dol_syslog("Scan IMAP with authentication mode = OAUTH2");
404
405 // Mode OAUth2 with PHP-IMAP
406 require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php';
407
408 $supportedoauth2array = getSupportedOauth2Array();
409
410 $keyforsupportedoauth2array = $object->oauth_service;
411 if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
412 $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
413 } else {
414 $keyforprovider = '';
415 }
416 $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
417 $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
418
419 $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
420
421 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
422 //$debugtext = "Host: ".$this->host."<br>Port: ".$this->port."<br>Login: ".$this->login."<br>Password: ".$this->password."<br>access type: ".$this->acces_type."<br>oauth service: ".$this->oauth_service."<br>Max email per collect: ".$this->maxemailpercollect;
423 //dol_syslog($debugtext);
424
425 $token = '';
426
427 $storage = new DoliStorage($db, $conf, $keyforprovider);
428
429 try {
430 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
431
432 $expire = true;
433 // Is token expired or will token expire in the next 30 seconds
434 // if (is_object($tokenobj)) {
435 // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30));
436 // }
437 // Token expired so we refresh it
438 if (is_object($tokenobj) && $expire) {
439 $credentials = new Credentials(
440 getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'),
441 getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'),
442 getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE')
443 );
444 $serviceFactory = new \OAuth\ServiceFactory();
445 $oauthname = explode('-', $OAUTH_SERVICENAME);
446
447 // ex service is Google-Emails we need only the first part Google
448 $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array());
449
450 // We have to save the token because Google give it only once
451 $refreshtoken = $tokenobj->getRefreshToken();
452
453 //var_dump($tokenobj);
454 try {
455 $tokenobj = $apiService->refreshAccessToken($tokenobj);
456 } catch (Exception $e) {
457 throw new Exception("Failed to refresh access token: ".$e->getMessage());
458 }
459
460 $tokenobj->setRefreshToken($refreshtoken);
461 $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj);
462 }
463
464 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
465 if (is_object($tokenobj)) {
466 $token = $tokenobj->getAccessToken();
467 } else {
468 $error++;
469 $morehtml .= "Token not found";
470 }
471 } catch (Exception $e) {
472 $error++;
473 $morehtml .= $e->getMessage();
474 }
475
476 if (empty($object->login)) {
477 $error++;
478 $morehtml .= 'Error: Login is empty. Must be email owner when using MAIN_IMAP_USE_PHPIMAP and OAuth.';
479 }
480
481 $cm = new ClientManager();
482 $client = $cm->make([
483 'host' => $object->host,
484 'port' => $object->port,
485 'encryption' => 'ssl',
486 'validate_cert' => true,
487 'protocol' => 'imap',
488 'username' => $object->login,
489 'password' => $token,
490 'authentication' => "oauth",
491 ]);
492 } else {
493 dol_syslog("Scan IMAP with authentication mode = PASS");
494
495 // Mode login/pass with PHP-IMAP
496 $cm = new ClientManager();
497 $client = $cm->make([
498 'host' => $object->host,
499 'port' => $object->port,
500 'encryption' => 'ssl',
501 'validate_cert' => true,
502 'protocol' => 'imap',
503 'username' => $object->login,
504 'password' => $object->password,
505 'authentication' => "login",
506 ]);
507 }
508
509 if (!$error) {
510 try {
511 // To emulate the command connect, you can run
512 // openssl s_client -crlf -connect outlook.office365.com:993
513 // TAG1 AUTHENTICATE XOAUTH2 dXN...
514 // TO Get debug log, you can set protected $debug = true; in Protocol.php file
515 //
516 // A MS bug make this not working !
517 // See https://github.com/MicrosoftDocs/office-developer-exchange-docs/issues/100
518 // See github.com/MicrosoftDocs/office-developer-exchange-docs/issues/87
519 // See github.com/Webklex/php-imap/issues/81
520 $client->connect();
521
522 // Uncomment this to output debug info
523 //$client->getConnection()->enableDebug(); // Add debug
524
525 $f = $client->getFolders(false, $object->source_directory);
526 if ($f) { // $f is Webklex\PHPIMAP\Support\FolderCollection
527 $folder = $f[0];
528 if ($folder instanceof Webklex\PHPIMAP\Folder) {
529 $nbemail = $folder->examine()["exists"];
530 } else {
531 $nbemail = 0;
532 }
533 } else {
534 $nbemail = 0;
535 }
536 $morehtml .= $nbemail;
537 } catch (ConnectionFailedException $e) {
538 $morehtml .= 'ConnectionFailedException '.$e->getMessage();
539 }
540 }
541 } else {
542 if (function_exists('imap_open')) {
543 try {
544 if ($sourcedir) {
545 //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir);
546 $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir);
547 }
548 if ($targetdir) {
549 //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir);
550 $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir);
551 }
552
553 $timeoutconnect = getDolGlobalInt('MAIN_USE_CONNECT_TIMEOUT', 5);
554 $timeoutread = getDolGlobalInt('MAIN_USE_RESPONSE_TIMEOUT', 20);
555
556 dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread);
557
558 $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect
559 $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread);
560 $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5);
561 $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5);
562
563 dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4);
564
565 $connection = imap_open($connectstringsource, $object->login, $object->password);
566
567 //dol_syslog("end imap_open connection=".var_export($connection, true));
568 } catch (Exception $e) {
569 $morehtml .= $e->getMessage();
570 }
571
572 if (!$connection) {
573 $morehtml .= 'Failed to open IMAP connection '.$connectstringsource;
574 if (function_exists('imap_last_error')) {
575 $morehtml .= '<br>'.imap_last_error();
576 }
577 dol_syslog("Error ".$morehtml, LOG_WARNING);
578 //var_dump(imap_errors())
579 } else {
580 dol_syslog("Imap connected. Now we call imap_num_msg()");
581 $morehtml .= imap_num_msg($connection);
582 }
583
584 if ($connection) {
585 dol_syslog("Imap close");
586 imap_close($connection);
587 }
588 } else {
589 $morehtml .= 'IMAP functions not available on your PHP. ';
590 }
591 }
592 }
593
594 $morehtml = $form->textwithpicto($langs->trans("NbOfEmailsInInbox"), 'Connect string = '.$connectstringserver.'<br>Option MAIN_IMAP_USE_PHPIMAP = '.getDolGlobalInt('MAIN_IMAP_USE_PHPIMAP')).': '.($morehtml !== '' ? $morehtml : '?');
595 $morehtml .= '<a class="flat paddingleft marginleftonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=scan&token='.newToken().'">'.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").'</a>';
596
597 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'<div class="refidno">'.$morehtml.'</div>', '', 0, '', '', 0, '');
598
599 print '<div class="fichecenter">';
600 print '<div class="fichehalfleft">';
601 print '<div class="underbanner clearboth"></div>';
602 print '<table class="border centpercent tableforfield">'."\n";
603
604 // Clean info (in view mode only)
605 if ($object->acces_type == 0) {
606 // If authent is using LOGIN and not OAUTHTOKEN, we don't need to show the OAUTH token
607 unset($object->fields['oauth_service']);
608 }
609 if ($object->acces_type == 1) {
610 // If authent is using OAUTHTOKEN, we don't need to show the password
611 unset($object->fields['password']);
612 }
613
614 // Common attributes
615 //$keyforbreak='fieldkeytoswithonsecondcolumn';
616 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
617
618 // Other attributes
619 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
620
621 print '</table>';
622
623
624 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
625 print '<input type="hidden" name="token" value="'.newToken().'">';
626 print '<input type="hidden" name="action" value="updatefiltersactions">';
627 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
628 print '<input type="hidden" name="id" value="'.$object->id.'">';
629
630 // Filters
631 print '<div class="div-table-responsive-no-min">';
632 print '<table id="tablelineoffilters" class="noborder nobordertop noshadow">';
633 print '<tr class="liste_titre nodrag nodrop">';
634 print '<td>'.img_picto('', 'filter', 'class="pictofixedwidth opacitymedium"').$form->textwithpicto($langs->trans("Filters"), $langs->trans("EmailCollectorFilterDesc")).'</td><td></td><td></td>';
635 print '</tr>';
636 // Add filter
637 print '<tr class="oddeven nodrag nodrop">';
638 print '<td>';
639 $arrayoftypes = array(
640 'from' => array('label' => 'MailFrom', 'data-placeholder' => $langs->trans('SearchString')),
641 'to' => array('label' => 'MailTo', 'data-placeholder' => $langs->trans('SearchString')),
642 'cc' => array('label' => 'Cc', 'data-placeholder' => $langs->trans('SearchString')),
643 'bcc' => array('label' => 'Bcc', 'data-placeholder' => $langs->trans('SearchString')),
644 'replyto' => array('label' => 'ReplyTo', 'data-placeholder' => $langs->trans('SearchString')),
645 'subject' => array('label' => 'Subject', 'data-placeholder' => $langs->trans('SearchString')),
646 'body' => array('label' => 'Body', 'data-placeholder' => $langs->trans('SearchString')),
647 // disabled because PHP imap_search is not compatible IMAPv4, only IMAPv2
648 //'header'=>array('label'=>'Header', 'data-placeholder'=>'HeaderKey SearchString'), // HEADER key value
649 //'X1'=>'---',
650 'X2' => '---',
651 'seen' => array('label' => 'AlreadyRead', 'data-noparam' => 1),
652 'unseen' => array('label' => 'NotRead', 'data-noparam' => 1),
653 'unanswered' => array('label' => 'Unanswered', 'data-noparam' => 1),
654 'answered' => array('label' => 'Answered', 'data-noparam' => 1),
655 'smaller' => array('label' => $langs->trans("Size").' ('.$langs->trans("SmallerThan").")", 'data-placeholder' => $langs->trans('NumberOfBytes')),
656 'larger' => array('label' => $langs->trans("Size").' ('.$langs->trans("LargerThan").")", 'data-placeholder' => $langs->trans('NumberOfBytes')),
657 'X3' => '---',
658 'withtrackingid' => array('label' => 'WithDolTrackingID', 'data-noparam' => 1),
659 'withouttrackingid' => array('label' => 'WithoutDolTrackingID', 'data-noparam' => 1),
660 'withtrackingidinmsgid' => array('label' => 'WithDolTrackingIDInMsgId', 'data-noparam' => 1),
661 'withouttrackingidinmsgid' => array('label' => 'WithoutDolTrackingIDInMsgId', 'data-noparam' => 1),
662 'X4' => '---',
663 'isnotanswer' => array('label' => 'IsNotAnAnswer', 'data-noparam' => 1),
664 'isanswer' => array('label' => 'IsAnAnswer', 'data-noparam' => 1)
665 );
666 print $form->selectarray('filtertype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'maxwidth300', 1, '', 2);
667
668 print "\n";
669 print '<script>';
670 print 'jQuery("#filtertype").change(function() {
671 console.log("We change a filter");
672 if (jQuery("#filtertype option:selected").attr("data-noparam")) {
673 jQuery("#rulevalue").attr("placeholder", "");
674 jQuery("#rulevalue").text("");
675 jQuery("#rulevalue").prop("disabled", true);
676 jQuery("#rulevaluehelp").addClass("unvisible");
677 } else {
678 jQuery("#rulevalue").prop("disabled", false);
679 jQuery("#rulevaluehelp").removeClass("unvisible");
680 }
681 jQuery("#rulevalue").attr("placeholder", (jQuery("#filtertype option:selected").attr("data-placeholder")));
682 ';
683 /*$noparam = array();
684 foreach ($arrayoftypes as $key => $value)
685 {
686 if ($value['noparam']) $noparam[] = $key;
687 }*/
688 print '})';
689 print '</script>'."\n";
690
691 print '</td><td class="nowraponall">';
692 print '<div class="nowraponall">';
693 print '<input type="text" name="rulevalue" id="rulevalue" class="inline-block valignmiddle">';
694 print '<div class="inline-block valignmiddle unvisible" id="rulevaluehelp">';
695 print img_warning($langs->trans("FilterSearchImapHelp"), '', 'pictowarning classfortooltip');
696 print '</div>';
697 print '</div>';
698 print '</td>';
699 print '<td class="right"><input type="submit" name="addfilter" id="addfilter" class="flat button smallpaddingimp" value="'.$langs->trans("Add").'"></td>';
700 print '</tr>';
701 // List filters
702 foreach ($object->filters as $rulefilter) {
703 $rulefilterobj = new EmailCollectorFilter($db);
704 $rulefilterobj->fetch($rulefilter['id']);
705
706 print '<tr class="oddeven">';
707 print '<td title="'.dol_escape_htmltag($langs->trans("Filter").': '.$rulefilter['type']).'">';
708 print $langs->trans($arrayoftypes[$rulefilter['type']]['label']);
709 print '</td>';
710 print '<td>'.$rulefilter['rulevalue'].'</td>';
711 print '<td class="right">';
712 print ' <a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletefilter&token='.urlencode(newToken()).'&filterid='.$rulefilter['id'].'">'.img_delete().'</a>';
713 print '</td>';
714 print '</tr>';
715 }
716
717 print '</tr>';
718 print '</table>';
719 print '</div>';
720
721 print '<div class="clearboth"></div><br><br>';
722
723 // Operations
724 print '<div class="div-table-responsive-no-min">';
725 print '<table id="tablelines" class="noborder noshadow">';
726 print '<tr class="liste_titre nodrag nodrop">';
727 print '<td>'.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).'</td>';
728 print '<td>';
729 $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc");
730 print $form->textwithpicto($langs->trans("Parameters"), $htmltext, 1, 'help', '', 0, 2, 'operationparamtt');
731 print '</td>';
732 print '<td></td>';
733 print '<td></td>';
734 print '</tr>';
735
736 $arrayoftypes = array(
737 'loadthirdparty' => $langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")),
738 'loadandcreatethirdparty' => $langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")),
739 'recordjoinpiece' => 'AttachJoinedDocumentsToObject',
740 'recordevent' => 'RecordEvent'
741 );
742 $arrayoftypesnocondition = $arrayoftypes;
743 if (isModEnabled('project')) {
744 $arrayoftypes['project'] = 'CreateLeadAndThirdParty';
745 }
746 $arrayoftypesnocondition['project'] = 'CreateLeadAndThirdParty';
747 if (isModEnabled('ticket')) {
748 $arrayoftypes['ticket'] = 'CreateTicketAndThirdParty';
749 }
750 $arrayoftypesnocondition['ticket'] = 'CreateTicketAndThirdParty';
751 if (isModEnabled('recruitment')) {
752 $arrayoftypes['candidature'] = 'CreateCandidature';
753 }
754 $arrayoftypesnocondition['candidature'] = 'CreateCandidature';
755
756 // support hook for add action
757 $parameters = array('arrayoftypes' => $arrayoftypes);
758 $res = $hookmanager->executeHooks('addMoreActionsEmailCollector', $parameters, $object, $action);
759
760 if ($res) {
761 $arrayoftypes = $hookmanager->resArray;
762 } else {
763 foreach ($hookmanager->resArray as $k => $desc) {
764 $arrayoftypes[$k] = $desc;
765 }
766 }
767
768 // Add operation
769 print '<tr class="oddeven nodrag nodrop">';
770 print '<td>';
771 print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'minwidth150 maxwidth250', 1);
772 print '</td><td>';
773 print '<textarea class="centpercent" name="operationparam" rows="3"></textarea>';
774 print '</td>';
775 print '<td>';
776 print '</td>';
777 print '<td class="right"><input type="submit" name="addoperation" id="addoperation" class="flat button smallpaddingimp" value="'.$langs->trans("Add").'"></td>';
778 print '</tr>';
779 // List operations
780 $nboflines = count($object->actions);
781 $table_element_line = 'emailcollector_emailcollectoraction';
782 $fk_element = 'position';
783 $i = 0;
784 foreach ($object->actions as $ruleaction) {
785 $ruleactionobj = new EmailCollectorAction($db);
786 $ruleactionobj->fetch($ruleaction['id']);
787
788 print '<tr class="drag drop oddeven" id="row-'.$ruleaction['id'].'">';
789 print '<td title="'.dol_escape_htmltag($langs->trans("Operation").': '.$ruleaction['type']).'">';
790 print '<!-- type of action: '.$ruleaction['type'].' -->';
791 if (array_key_exists($ruleaction['type'], $arrayoftypes)) {
792 print $langs->trans($arrayoftypes[$ruleaction['type']]);
793 } else {
794 if (array_key_exists($ruleaction['type'], $arrayoftypesnocondition)) {
795 print '<span class="opacitymedium">'.$langs->trans($arrayoftypesnocondition[$ruleaction['type']]).' - '.$langs->trans("Disabled").'</span>';
796 }
797 }
798
799 if (in_array($ruleaction['type'], array('recordevent'))) {
800 print $form->textwithpicto('', $langs->transnoentitiesnoconv('IfTrackingIDFoundEventWillBeLinked'));
801 } elseif (in_array($ruleaction['type'], array('loadthirdparty', 'loadandcreatethirdparty'))) {
802 print $form->textwithpicto('', $langs->transnoentitiesnoconv('EmailCollectorLoadThirdPartyHelp'));
803 }
804 print '</td>';
805 print '<td class="wordbreak minwidth300 small">';
806 if ($action == 'editoperation' && $ruleaction['id'] == $operationid) {
807 //print '<input type="text" class="quatrevingtquinzepercent" name="operationparam2" value="'.dol_escape_htmltag($ruleaction['actionparam']).'"><br>';
808 print '<textarea class="centpercent" name="operationparam2" rows="3">';
809 print dol_escape_htmltag($ruleaction['actionparam'], 0, 1);
810 print '</textarea>';
811 print '<input type="hidden" name="rowidoperation2" value="'.$ruleaction['id'].'">';
812 print '<input type="submit" class="button small button-save" name="saveoperation2" value="'.$langs->trans("Save").'">';
813 print '<input type="submit" class="button small button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
814 } else {
815 print dol_nl2br(dol_escape_htmltag($ruleaction['actionparam'], 0, 1));
816 }
817 print '</td>';
818 // Move up/down
819 print '<td class="center linecolmove tdlineupdown">';
820 if ($i > 0) {
821 print '<a class="lineupdown" href="'.$_SERVER['PHP_SELF'].'?action=up&amp;rowid='.$ruleaction['id'].'">'.img_up('default', 0, 'imgupforline').'</a>';
822 }
823 if ($i < count($object->actions) - 1) {
824 print '<a class="lineupdown" href="'.$_SERVER['PHP_SELF'].'?action=down&amp;rowid='.$ruleaction['id'].'">'.img_down('default', 0, 'imgdownforline').'</a>';
825 }
826 print '</td>';
827 // Delete
828 print '<td class="right nowraponall">';
829 print '<a class="editfielda marginrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editoperation&token='.newToken().'&operationid='.$ruleaction['id'].'">'.img_edit().'</a>';
830 print ' <a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteoperation&token='.newToken().'&operationid='.$ruleaction['id'].'">'.img_delete().'</a>';
831 print '</td>';
832 print '</tr>';
833 $i++;
834 }
835
836 print '</tr>';
837 print '</table>';
838 print '</div>';
839
840 if (!empty($conf->use_javascript_ajax)) {
841 $urltorefreshaftermove = DOL_URL_ROOT.'/admin/emailcollector_card.php?id='.$id;
842 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
843 }
844
845 print '</form>';
846
847 print '</div>';
848 print '</div>'; // End <div class="fichecenter">
849
850
851 print '<div class="clearboth"></div><br>';
852
853 print dol_get_fiche_end();
854
855 // Buttons for actions
856 if ($action != 'presend' && $action != 'editline') {
857 print '<div class="tabsAction">'."\n";
858 $parameters = array();
859 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
860 if ($reshook < 0) {
861 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
862 }
863
864 if (empty($reshook)) {
865 // Edit
866 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Edit").'</a></div>';
867
868 // Clone
869 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&token='.newToken().'&object=order">'.$langs->trans("ToClone").'</a></div>';
870
871 // Collect now
872 print '<div class="inline-block divButAction"><a class="butAction reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=collecttest&token='.newToken().'">'.$langs->trans("TestCollectNow").'</a></div>';
873
874 if (count($object->actions) > 0) {
875 print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=collect&token='.newToken().'">'.$langs->trans("CollectNow").'</a></div>';
876 } else {
877 print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoOperations")).'">'.$langs->trans("CollectNow").'</a></div>';
878 }
879
880 print '<div class="inline-block divButAction"><a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.urlencode(newToken()).'">'.$langs->trans('Delete').'</a></div>';
881 }
882 print '</div>'."\n";
883 }
884
885 if (!empty($debuginfo)) {
886 print info_admin($debuginfo);
887 }
888}
889
890// End of page
891llxFooter();
892$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
Class for EmailCollectorAction.
Class for EmailCollectorFilter.
Class for EmailCollector.
Class to manage standard extra fields.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
emailcollectorPrepareHead($object)
Prepare array of tabs for EmailCollector.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
img_down($titlealt='default', $selected=0, $moreclass='')
Show down arrow logo.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
img_up($titlealt='default', $selected=0, $moreclass='')
Show top arrow logo.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getSupportedOauth2Array()
Return array of tabs to used on pages to setup cron module.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.