dolibarr 20.0.2
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('/-.*$/', '', strtoupper($keyforsupportedoauth2array));
417 $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
418
419 if (!empty($supportedoauth2array)) {
420 $nameofservice = ucfirst(strtolower(empty($supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']));
421 $nameofservice .= ($keyforprovider ? '-'.$keyforprovider : '');
422 $OAUTH_SERVICENAME = $nameofservice;
423 } else {
424 $OAUTH_SERVICENAME = 'Unknown';
425 }
426
427 $keyforparamtenant = 'OAUTH_'.strtoupper(empty($supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['callbackfile']).($keyforprovider ? '-'.$keyforprovider : '').'_TENANT';
428
429 require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
430 //$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;
431 //dol_syslog($debugtext);
432
433 $token = '';
434
435 $storage = new DoliStorage($db, $conf, $keyforprovider, getDolGlobalString($keyforparamtenant));
436
437 try {
438 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
439
440 $expire = true;
441 // Is token expired or will token expire in the next 30 seconds
442 // if (is_object($tokenobj)) {
443 // $expire = ($tokenobj->getEndOfLife() !== -9002 && $tokenobj->getEndOfLife() !== -9001 && time() > ($tokenobj->getEndOfLife() - 30));
444 // }
445 // Token expired so we refresh it
446 if (is_object($tokenobj) && $expire) {
447 $credentials = new Credentials(
448 getDolGlobalString('OAUTH_'.$object->oauth_service.'_ID'),
449 getDolGlobalString('OAUTH_'.$object->oauth_service.'_SECRET'),
450 getDolGlobalString('OAUTH_'.$object->oauth_service.'_URLAUTHORIZE')
451 );
452 $serviceFactory = new \OAuth\ServiceFactory();
453 $oauthname = explode('-', $OAUTH_SERVICENAME);
454
455 // ex service is Google-Emails we need only the first part Google
456 $apiService = $serviceFactory->createService($oauthname[0], $credentials, $storage, array());
457
458 // We have to save the token because Google give it only once
459 $refreshtoken = $tokenobj->getRefreshToken();
460
461 //var_dump($tokenobj);
462 try {
463 $tokenobj = $apiService->refreshAccessToken($tokenobj);
464 } catch (Exception $e) {
465 throw new Exception("Failed to refresh access token: ".$e->getMessage());
466 }
467
468 $tokenobj->setRefreshToken($refreshtoken);
469 $storage->storeAccessToken($OAUTH_SERVICENAME, $tokenobj);
470 }
471
472 $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
473 if (is_object($tokenobj)) {
474 $token = $tokenobj->getAccessToken();
475 } else {
476 $error++;
477 $morehtml .= "Token not found";
478 }
479 } catch (Exception $e) {
480 $error++;
481 $morehtml .= $e->getMessage();
482 }
483
484 if (empty($object->login)) {
485 $error++;
486 $morehtml .= 'Error: Login is empty. Must be email owner when using MAIN_IMAP_USE_PHPIMAP and OAuth.';
487 }
488
489 $cm = new ClientManager();
490 $client = $cm->make([
491 'host' => $object->host,
492 'port' => $object->port,
493 'encryption' => 'ssl',
494 'validate_cert' => true,
495 'protocol' => 'imap',
496 'username' => $object->login,
497 'password' => $token,
498 'authentication' => "oauth",
499 ]);
500 } else {
501 dol_syslog("Scan IMAP with authentication mode = PASS");
502
503 // Mode login/pass with PHP-IMAP
504 $cm = new ClientManager();
505 $client = $cm->make([
506 'host' => $object->host,
507 'port' => $object->port,
508 'encryption' => 'ssl',
509 'validate_cert' => true,
510 'protocol' => 'imap',
511 'username' => $object->login,
512 'password' => $object->password,
513 'authentication' => "login",
514 ]);
515 }
516
517 if (!$error) {
518 try {
519 // To emulate the command connect, you can run
520 // openssl s_client -crlf -connect outlook.office365.com:993
521 // TAG1 AUTHENTICATE XOAUTH2 dXN...
522 // TO Get debug log, you can set protected $debug = true; in Protocol.php file
523 //
524 // A MS bug make this not working !
525 // See https://github.com/MicrosoftDocs/office-developer-exchange-docs/issues/100
526 // See github.com/MicrosoftDocs/office-developer-exchange-docs/issues/87
527 // See github.com/Webklex/php-imap/issues/81
528 $client->connect();
529
530 // Uncomment this to output debug info
531 //$client->getConnection()->enableDebug(); // Add debug
532
533 $f = $client->getFolders(false, $object->source_directory);
534 if ($f) { // $f is Webklex\PHPIMAP\Support\FolderCollection
535 $folder = $f[0];
536 if ($folder instanceof Webklex\PHPIMAP\Folder) {
537 $nbemail = $folder->examine()["exists"];
538 } else {
539 $nbemail = 0;
540 }
541 } else {
542 $nbemail = 0;
543 }
544 $morehtml .= $nbemail;
545 } catch (ConnectionFailedException $e) {
546 $morehtml .= 'ConnectionFailedException '.$e->getMessage();
547 }
548 }
549 } else {
550 if (function_exists('imap_open')) {
551 try {
552 if ($sourcedir) {
553 //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir);
554 $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir);
555 }
556 if ($targetdir) {
557 //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir);
558 $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir);
559 }
560
561 $timeoutconnect = getDolGlobalInt('MAIN_USE_CONNECT_TIMEOUT', 5);
562 $timeoutread = getDolGlobalInt('MAIN_USE_RESPONSE_TIMEOUT', 20);
563
564 dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread);
565
566 $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect
567 $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread);
568 $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5);
569 $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5);
570
571 dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4);
572
573 $connection = imap_open($connectstringsource, $object->login, $object->password);
574
575 //dol_syslog("end imap_open connection=".var_export($connection, true));
576 } catch (Exception $e) {
577 $morehtml .= $e->getMessage();
578 }
579
580 if (!$connection) {
581 $morehtml .= 'Failed to open IMAP connection '.$connectstringsource;
582 if (function_exists('imap_last_error')) {
583 $morehtml .= '<br>'.imap_last_error();
584 }
585 dol_syslog("Error ".$morehtml, LOG_WARNING);
586 //var_dump(imap_errors())
587 } else {
588 dol_syslog("Imap connected. Now we call imap_num_msg()");
589 $morehtml .= imap_num_msg($connection);
590 }
591
592 if ($connection) {
593 dol_syslog("Imap close");
594 imap_close($connection);
595 }
596 } else {
597 $morehtml .= 'IMAP functions not available on your PHP. ';
598 }
599 }
600 }
601
602 $morehtml = $form->textwithpicto($langs->trans("NbOfEmailsInInbox"), 'Connect string = '.$connectstringserver.'<br>Option MAIN_IMAP_USE_PHPIMAP = '.getDolGlobalInt('MAIN_IMAP_USE_PHPIMAP')).': '.($morehtml !== '' ? $morehtml : '?');
603 $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>';
604
605 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'<div class="refidno">'.$morehtml.'</div>', '', 0, '', '', 0, '');
606
607 print '<div class="fichecenter">';
608 print '<div class="fichehalfleft">';
609 print '<div class="underbanner clearboth"></div>';
610 print '<table class="border centpercent tableforfield">'."\n";
611
612 // Clean info (in view mode only)
613 if ($object->acces_type == 0) {
614 // If authent is using LOGIN and not OAUTHTOKEN, we don't need to show the OAUTH token
615 unset($object->fields['oauth_service']);
616 }
617 if ($object->acces_type == 1) {
618 // If authent is using OAUTHTOKEN, we don't need to show the password
619 unset($object->fields['password']);
620 }
621
622 // Common attributes
623 //$keyforbreak='fieldkeytoswithonsecondcolumn';
624 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
625
626 // Other attributes
627 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
628
629 print '</table>';
630
631
632 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
633 print '<input type="hidden" name="token" value="'.newToken().'">';
634 print '<input type="hidden" name="action" value="updatefiltersactions">';
635 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
636 print '<input type="hidden" name="id" value="'.$object->id.'">';
637
638 // Filters
639 print '<div class="div-table-responsive-no-min">';
640 print '<table id="tablelineoffilters" class="noborder nobordertop noshadow">';
641 print '<tr class="liste_titre nodrag nodrop">';
642 print '<td>'.img_picto('', 'filter', 'class="pictofixedwidth opacitymedium"').$form->textwithpicto($langs->trans("Filters"), $langs->trans("EmailCollectorFilterDesc")).'</td><td></td><td></td>';
643 print '</tr>';
644 // Add filter
645 print '<tr class="oddeven nodrag nodrop">';
646 print '<td>';
647 $arrayoftypes = array(
648 'from' => array('label' => 'MailFrom', 'data-placeholder' => $langs->trans('SearchString')),
649 'to' => array('label' => 'MailTo', 'data-placeholder' => $langs->trans('SearchString')),
650 'cc' => array('label' => 'Cc', 'data-placeholder' => $langs->trans('SearchString')),
651 'bcc' => array('label' => 'Bcc', 'data-placeholder' => $langs->trans('SearchString')),
652 'replyto' => array('label' => 'ReplyTo', 'data-placeholder' => $langs->trans('SearchString')),
653 'subject' => array('label' => 'Subject', 'data-placeholder' => $langs->trans('SearchString')),
654 'body' => array('label' => 'Body', 'data-placeholder' => $langs->trans('SearchString')),
655 // disabled because PHP imap_search is not compatible IMAPv4, only IMAPv2
656 //'header'=>array('label'=>'Header', 'data-placeholder'=>'HeaderKey SearchString'), // HEADER key value
657 //'X1'=>'---',
658 'X2' => '---',
659 'seen' => array('label' => 'AlreadyRead', 'data-noparam' => 1),
660 'unseen' => array('label' => 'NotRead', 'data-noparam' => 1),
661 'unanswered' => array('label' => 'Unanswered', 'data-noparam' => 1),
662 'answered' => array('label' => 'Answered', 'data-noparam' => 1),
663 'smaller' => array('label' => $langs->trans("Size").' ('.$langs->trans("SmallerThan").")", 'data-placeholder' => $langs->trans('NumberOfBytes')),
664 'larger' => array('label' => $langs->trans("Size").' ('.$langs->trans("LargerThan").")", 'data-placeholder' => $langs->trans('NumberOfBytes')),
665 'X3' => '---',
666 'withtrackingid' => array('label' => 'WithDolTrackingID', 'data-noparam' => 1),
667 'withouttrackingid' => array('label' => 'WithoutDolTrackingID', 'data-noparam' => 1),
668 'withtrackingidinmsgid' => array('label' => 'WithDolTrackingIDInMsgId', 'data-noparam' => 1),
669 'withouttrackingidinmsgid' => array('label' => 'WithoutDolTrackingIDInMsgId', 'data-noparam' => 1),
670 'X4' => '---',
671 'isnotanswer' => array('label' => 'IsNotAnAnswer', 'data-noparam' => 1),
672 'isanswer' => array('label' => 'IsAnAnswer', 'data-noparam' => 1)
673 );
674 print $form->selectarray('filtertype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'maxwidth300', 1, '', 2);
675
676 print "\n";
677 print '<script>';
678 print 'jQuery("#filtertype").change(function() {
679 console.log("We change a filter");
680 if (jQuery("#filtertype option:selected").attr("data-noparam")) {
681 jQuery("#rulevalue").attr("placeholder", "");
682 jQuery("#rulevalue").text("");
683 jQuery("#rulevalue").prop("disabled", true);
684 jQuery("#rulevaluehelp").addClass("unvisible");
685 } else {
686 jQuery("#rulevalue").prop("disabled", false);
687 jQuery("#rulevaluehelp").removeClass("unvisible");
688 }
689 jQuery("#rulevalue").attr("placeholder", (jQuery("#filtertype option:selected").attr("data-placeholder")));
690 ';
691 /*$noparam = array();
692 foreach ($arrayoftypes as $key => $value)
693 {
694 if ($value['noparam']) $noparam[] = $key;
695 }*/
696 print '})';
697 print '</script>'."\n";
698
699 print '</td><td class="nowraponall">';
700 print '<div class="nowraponall">';
701 print '<input type="text" name="rulevalue" id="rulevalue" class="inline-block valignmiddle">';
702 print '<div class="inline-block valignmiddle unvisible" id="rulevaluehelp">';
703 print img_warning($langs->trans("FilterSearchImapHelp"), '', 'pictowarning classfortooltip');
704 print '</div>';
705 print '</div>';
706 print '</td>';
707 print '<td class="right"><input type="submit" name="addfilter" id="addfilter" class="flat button smallpaddingimp" value="'.$langs->trans("Add").'"></td>';
708 print '</tr>';
709 // List filters
710 foreach ($object->filters as $rulefilter) {
711 $rulefilterobj = new EmailCollectorFilter($db);
712 $rulefilterobj->fetch($rulefilter['id']);
713
714 print '<tr class="oddeven">';
715 print '<td title="'.dol_escape_htmltag($langs->trans("Filter").': '.$rulefilter['type']).'">';
716 print $langs->trans($arrayoftypes[$rulefilter['type']]['label']);
717 print '</td>';
718 print '<td>'.$rulefilter['rulevalue'].'</td>';
719 print '<td class="right">';
720 print ' <a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deletefilter&token='.urlencode(newToken()).'&filterid='.$rulefilter['id'].'">'.img_delete().'</a>';
721 print '</td>';
722 print '</tr>';
723 }
724
725 print '</tr>';
726 print '</table>';
727 print '</div>';
728
729 print '<div class="clearboth"></div><br><br>';
730
731 // Operations
732 print '<div class="div-table-responsive-no-min">';
733 print '<table id="tablelines" class="noborder noshadow">';
734 print '<tr class="liste_titre nodrag nodrop">';
735 print '<td>'.img_picto('', 'technic', 'class="pictofixedwidth"').$form->textwithpicto($langs->trans("EmailcollectorOperations"), $langs->trans("EmailcollectorOperationsDesc")).'</td>';
736 print '<td>';
737 $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc");
738 print $form->textwithpicto($langs->trans("Parameters"), $htmltext, 1, 'help', '', 0, 2, 'operationparamtt');
739 print '</td>';
740 print '<td></td>';
741 print '<td></td>';
742 print '</tr>';
743
744 $arrayoftypes = array(
745 'loadthirdparty' => $langs->trans('LoadThirdPartyFromName', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")),
746 'loadandcreatethirdparty' => $langs->trans('LoadThirdPartyFromNameOrCreate', $langs->transnoentities("ThirdPartyName").'/'.$langs->transnoentities("AliasNameShort").'/'.$langs->transnoentities("Email").'/'.$langs->transnoentities("ID")),
747 'recordjoinpiece' => 'AttachJoinedDocumentsToObject',
748 'recordevent' => 'RecordEvent'
749 );
750 $arrayoftypesnocondition = $arrayoftypes;
751 if (isModEnabled('project')) {
752 $arrayoftypes['project'] = 'CreateLeadAndThirdParty';
753 }
754 $arrayoftypesnocondition['project'] = 'CreateLeadAndThirdParty';
755 if (isModEnabled('ticket')) {
756 $arrayoftypes['ticket'] = 'CreateTicketAndThirdParty';
757 }
758 $arrayoftypesnocondition['ticket'] = 'CreateTicketAndThirdParty';
759 if (isModEnabled('recruitment')) {
760 $arrayoftypes['candidature'] = 'CreateCandidature';
761 }
762 $arrayoftypesnocondition['candidature'] = 'CreateCandidature';
763
764 // support hook for add action
765 $parameters = array('arrayoftypes' => $arrayoftypes);
766 $res = $hookmanager->executeHooks('addMoreActionsEmailCollector', $parameters, $object, $action);
767
768 if ($res) {
769 $arrayoftypes = $hookmanager->resArray;
770 } else {
771 foreach ($hookmanager->resArray as $k => $desc) {
772 $arrayoftypes[$k] = $desc;
773 }
774 }
775
776 // Add operation
777 print '<tr class="oddeven nodrag nodrop">';
778 print '<td>';
779 print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'minwidth150 maxwidth250', 1);
780 print '</td><td>';
781 print '<textarea class="centpercent" name="operationparam" rows="3"></textarea>';
782 print '</td>';
783 print '<td>';
784 print '</td>';
785 print '<td class="right"><input type="submit" name="addoperation" id="addoperation" class="flat button smallpaddingimp" value="'.$langs->trans("Add").'"></td>';
786 print '</tr>';
787 // List operations
788 $nboflines = count($object->actions);
789 $table_element_line = 'emailcollector_emailcollectoraction';
790 $fk_element = 'position';
791 $i = 0;
792 foreach ($object->actions as $ruleaction) {
793 $ruleactionobj = new EmailCollectorAction($db);
794 $ruleactionobj->fetch($ruleaction['id']);
795
796 print '<tr class="drag drop oddeven" id="row-'.$ruleaction['id'].'">';
797 print '<td title="'.dol_escape_htmltag($langs->trans("Operation").': '.$ruleaction['type']).'">';
798 print '<!-- type of action: '.$ruleaction['type'].' -->';
799 if (array_key_exists($ruleaction['type'], $arrayoftypes)) {
800 print $langs->trans($arrayoftypes[$ruleaction['type']]);
801 } else {
802 if (array_key_exists($ruleaction['type'], $arrayoftypesnocondition)) {
803 print '<span class="opacitymedium">'.$langs->trans($arrayoftypesnocondition[$ruleaction['type']]).' - '.$langs->trans("Disabled").'</span>';
804 }
805 }
806
807 if (in_array($ruleaction['type'], array('recordevent'))) {
808 print $form->textwithpicto('', $langs->transnoentitiesnoconv('IfTrackingIDFoundEventWillBeLinked'));
809 } elseif (in_array($ruleaction['type'], array('loadthirdparty', 'loadandcreatethirdparty'))) {
810 print $form->textwithpicto('', $langs->transnoentitiesnoconv('EmailCollectorLoadThirdPartyHelp'));
811 }
812 print '</td>';
813 print '<td class="wordbreak minwidth300 small">';
814 if ($action == 'editoperation' && $ruleaction['id'] == $operationid) {
815 //print '<input type="text" class="quatrevingtquinzepercent" name="operationparam2" value="'.dol_escape_htmltag($ruleaction['actionparam']).'"><br>';
816 print '<textarea class="centpercent" name="operationparam2" rows="3">';
817 print dol_escape_htmltag($ruleaction['actionparam'], 0, 1);
818 print '</textarea>';
819 print '<input type="hidden" name="rowidoperation2" value="'.$ruleaction['id'].'">';
820 print '<input type="submit" class="button small button-save" name="saveoperation2" value="'.$langs->trans("Save").'">';
821 print '<input type="submit" class="button small button-cancel" name="cancel" value="'.$langs->trans("Cancel").'">';
822 } else {
823 print dol_nl2br(dol_escape_htmltag($ruleaction['actionparam'], 0, 1));
824 }
825 print '</td>';
826 // Move up/down
827 print '<td class="center linecolmove tdlineupdown">';
828 if ($i > 0) {
829 print '<a class="lineupdown" href="'.$_SERVER['PHP_SELF'].'?action=up&amp;rowid='.$ruleaction['id'].'">'.img_up('default', 0, 'imgupforline').'</a>';
830 }
831 if ($i < count($object->actions) - 1) {
832 print '<a class="lineupdown" href="'.$_SERVER['PHP_SELF'].'?action=down&amp;rowid='.$ruleaction['id'].'">'.img_down('default', 0, 'imgdownforline').'</a>';
833 }
834 print '</td>';
835 // Delete
836 print '<td class="right nowraponall">';
837 print '<a class="editfielda marginrightonly" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editoperation&token='.newToken().'&operationid='.$ruleaction['id'].'">'.img_edit().'</a>';
838 print ' <a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=deleteoperation&token='.newToken().'&operationid='.$ruleaction['id'].'">'.img_delete().'</a>';
839 print '</td>';
840 print '</tr>';
841 $i++;
842 }
843
844 print '</tr>';
845 print '</table>';
846 print '</div>';
847
848 if (!empty($conf->use_javascript_ajax)) {
849 $urltorefreshaftermove = DOL_URL_ROOT.'/admin/emailcollector_card.php?id='.$id;
850 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
851 }
852
853 print '</form>';
854
855 print '</div>';
856 print '</div>'; // End <div class="fichecenter">
857
858
859 print '<div class="clearboth"></div><br>';
860
861 print dol_get_fiche_end();
862
863 // Buttons for actions
864 if ($action != 'presend' && $action != 'editline') {
865 print '<div class="tabsAction">'."\n";
866 $parameters = array();
867 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
868 if ($reshook < 0) {
869 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
870 }
871
872 if (empty($reshook)) {
873 // Edit
874 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>';
875
876 // Clone
877 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>';
878
879 // Collect now
880 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>';
881
882 if (count($object->actions) > 0) {
883 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>';
884 } else {
885 print '<div class="inline-block divButAction"><a class="butActionRefused" href="#" title="'.dol_escape_htmltag($langs->trans("NoOperations")).'">'.$langs->trans("CollectNow").'</a></div>';
886 }
887
888 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>';
889 }
890 print '</div>'."\n";
891 }
892
893 if (!empty($debuginfo)) {
894 print info_admin($debuginfo);
895 }
896}
897
898// End of page
899llxFooter();
900$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.