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