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