From b93a3ceb297b7722229ecfbfe6d0eedb16c2f5cc Mon Sep 17 00:00:00 2001 From: "jove@bisquerra.com" Date: Fri, 8 May 2020 17:25:48 +0200 Subject: [PATCH 01/12] TakePOS Auto Order improvements --- htdocs/takepos/css/phone.css | 28 +++++ htdocs/takepos/genimg/qr.php | 7 +- htdocs/takepos/invoice.php | 20 ++-- htdocs/takepos/phone.php | 162 ++++++++++++++++++++++----- htdocs/takepos/public/auto_order.php | 7 +- 5 files changed, 185 insertions(+), 39 deletions(-) diff --git a/htdocs/takepos/css/phone.css b/htdocs/takepos/css/phone.css index 49d833ade17..0f3606071f0 100644 --- a/htdocs/takepos/css/phone.css +++ b/htdocs/takepos/css/phone.css @@ -79,3 +79,31 @@ button.phonebutton { height:90%; font-weight: bold; } + +button.publicphonebutton { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ + width:33%; + height:90%; + font-weight: bold; +} + +button.publicphonebutton2 { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ + width:33%; + font-weight: bold; + padding: 8px 16px; +} diff --git a/htdocs/takepos/genimg/qr.php b/htdocs/takepos/genimg/qr.php index c73e874a465..553f5165a0d 100644 --- a/htdocs/takepos/genimg/qr.php +++ b/htdocs/takepos/genimg/qr.php @@ -29,5 +29,8 @@ require '../../core/modules/barcode/doc/tcpdfbarcode.modules.php'; $key = GETPOST('key'); -$module = new modTcpdfbarcode($db); -$result = $module->buildBarCode("http://www.takepos.com", 'QRCODE', 'Y'); +$urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); +$urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + +$module = new modtcpdfbarcode($db); +$result = $module->buildBarCode($urlwithroot."/takepos/auto_order.php?key=".dol_encode($key), 'QRCODE', 'Y'); diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index b1641072829..236b302406d 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -32,7 +32,7 @@ if (!defined('NOREQUIREMENU')) { define('NOREQUIREMENU', '1'); } if (!defined('NOREQUIREHTML')) { define('NOREQUIREHTML', '1'); } if (!defined('NOREQUIREAJAX')) { define('NOREQUIREAJAX', '1'); } -require '../main.inc.php'; +if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; @@ -47,16 +47,11 @@ $idproduct = GETPOST('idproduct', 'int'); $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Bar or Restaurant $placeid = 0; // $placeid is ID of invoice -if ($_SESSION["publicterminal"]) { - $_SESSION["takeposterminal"] = 1; // Use Terminal 1 for public customers -} -elseif (empty($user->rights->takepos->run)) { +if (empty($user->rights->takepos->run) && !defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { accessforbidden(); } - - -if (($conf->global->TAKEPOS_PHONE_BASIC_LAYOUT == 1 && $conf->browser->layout == 'phone') || $_SESSION["publicterminal"]) +if (($conf->global->TAKEPOS_PHONE_BASIC_LAYOUT == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { // DIRECT LINK TO THIS PAGE FROM MOBILE AND NO TERMINAL SELECTED if ($_SESSION["takeposterminal"] == "") @@ -629,6 +624,12 @@ $(document).ready(function() { if (selectedline==this.id) return; // If is already selected else selectedline=this.id; selectedtext=$('#'+selectedline).find("td:first").html(); + }); /* Autoselect the line */ @@ -913,7 +914,7 @@ if ($_SESSION["basiclayout"] == 1) $htmlforlines .= '" onclick="AddProduct(\''.$place.'\', '.$row->id.')">'; $htmlforlines .= ''; $htmlforlines .= $row->label; - $htmlforlines .= ''; + $htmlforlines .= '
'.price($row->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).'
'; $htmlforlines .= ''."\n"; } $htmlforlines .= ''; @@ -990,6 +991,7 @@ if ($placeid > 0) } $htmlforlines .= '" id="'.$line->id.'">'; $htmlforlines .= ''; + if ($_SESSION["basiclayout"] == 1) $htmlforlines .= $line->qty." x "; //if ($line->product_label) $htmlforlines.= ''.$line->product_label.''; if (isset($line->product_type)) { diff --git a/htdocs/takepos/phone.php b/htdocs/takepos/phone.php index eac1f40bfd1..6e912d988dc 100644 --- a/htdocs/takepos/phone.php +++ b/htdocs/takepos/phone.php @@ -31,7 +31,7 @@ if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); -if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) require '../main.inc.php'; +if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE') && isset($_GET['key'])) require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -45,6 +45,7 @@ if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { else $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Ba or Restaurant $action = GETPOST('action', 'alpha'); $setterminal = GETPOST('setterminal', 'int'); +$idproduct = GETPOST('idproduct', 'int'); if ($setterminal > 0) { @@ -53,14 +54,10 @@ if ($setterminal > 0) $langs->loadLangs(array("bills", "orders", "commercial", "cashdesk", "receiptprinter")); -if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { - $_SESSION["takeposterminal"] = 1; // Use Terminal 1 for public customers -} -elseif (empty($user->rights->takepos->run)) { +if (empty($user->rights->takepos->run) && !defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { accessforbidden(); } - /* * View */ @@ -75,7 +72,42 @@ $head = ' top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); ?> - + +fetch($idproduct); + print "".$prod->label."
"; + print ''; + print "
".$prod->description; + print "
".price($prod->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).""; + print '
'; + print ''; +} +elseif ($action=="editline"){ + $placeid = GETPOST('placeid', 'int'); + $selectedline = GETPOST('selectedline', 'int'); + $invoice = new Facture($db); + $invoice->fetch($placeid); + foreach ($invoice->lines as $line) + { + if ($line->id == $selectedline) + { + $prod = new Product($db); + $prod->fetch($line->fk_product); + print "".$prod->label."
"; + print ''; + print "
".$prod->description; + print "
".price($prod->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).""; + print '
'; + print ''; + print ''; + print ''; + } + } +} +else { +?> -global->TAKEPOS_NUM_TERMINALS != "1" && $_SESSION["takeposterminal"] == "") print '
'.$langs->trans('TerminalSelect').'
'; -?> + global->TAKEPOS_NUM_TERMINALS != "1" && $_SESSION["takeposterminal"] == "") print '
'.$langs->trans('TerminalSelect').'
'; + ?>
global->TAKEPOS_NUM_TERMINALS != "1" && $_SESSION["takeposterminal"]
- Date: Fri, 8 May 2020 18:04:38 +0200 Subject: [PATCH 03/12] Fix URLs --- htdocs/takepos/phone.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/takepos/phone.php b/htdocs/takepos/phone.php index 7e454a734a3..8714173e45f 100644 --- a/htdocs/takepos/phone.php +++ b/htdocs/takepos/phone.php @@ -31,7 +31,7 @@ if (!defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); if (!defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); if (!defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); -if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE') && isset($_GET['key'])) require '../main.inc.php'; +if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; @@ -71,14 +71,13 @@ $head = ' '; top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); -?> - -'; + if ($action=="productinfo"){ $prod = new Product($db); $prod->fetch($idproduct); print "".$prod->label."
"; - print ''; + print ''; print "
".$prod->description; print "
".price($prod->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).""; print '
'; From b89b6d7679546811e13826e74262fa67cd10be75 Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Fri, 8 May 2020 18:51:49 +0200 Subject: [PATCH 04/12] Name fix --- htdocs/takepos/genimg/qr.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/genimg/qr.php b/htdocs/takepos/genimg/qr.php index 553f5165a0d..99f7fced1d0 100644 --- a/htdocs/takepos/genimg/qr.php +++ b/htdocs/takepos/genimg/qr.php @@ -32,5 +32,5 @@ $key = GETPOST('key'); $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file -$module = new modtcpdfbarcode($db); +$module = new modTcpdfbarcode($db); $result = $module->buildBarCode($urlwithroot."/takepos/auto_order.php?key=".dol_encode($key), 'QRCODE', 'Y'); From 8bd1179b8207671f4d33d8f6d156c453b7bf8239 Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Tue, 12 May 2020 17:03:24 +0200 Subject: [PATCH 05/12] Update qr.php --- htdocs/takepos/genimg/qr.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/takepos/genimg/qr.php b/htdocs/takepos/genimg/qr.php index 99f7fced1d0..3f27464f5ca 100644 --- a/htdocs/takepos/genimg/qr.php +++ b/htdocs/takepos/genimg/qr.php @@ -33,4 +33,4 @@ $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', t $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file $module = new modTcpdfbarcode($db); -$result = $module->buildBarCode($urlwithroot."/takepos/auto_order.php?key=".dol_encode($key), 'QRCODE', 'Y'); +$result = $module->buildBarCode($urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($key), 'QRCODE', 'Y'); From 366ae2f116cfaaed73e07a4b06d0a596ded92582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 12 May 2020 18:44:26 +0200 Subject: [PATCH 06/12] Update dolistore.class.php --- .../admin/dolistore/class/dolistore.class.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/htdocs/admin/dolistore/class/dolistore.class.php b/htdocs/admin/dolistore/class/dolistore.class.php index 230c588f7e4..a229f3c985d 100644 --- a/htdocs/admin/dolistore/class/dolistore.class.php +++ b/htdocs/admin/dolistore/class/dolistore.class.php @@ -248,11 +248,8 @@ class Dolistore // phpcs:enable global $langs, $conf; $html = ""; - $parity = "pair"; $last_month = time() - (30 * 24 * 60 * 60); foreach ($this->products as $product) { - $parity = ($parity == "impair") ? 'pair' : 'impair'; - // check new product ? $newapp = ''; if ($last_month < strtotime($product->date_add)) { @@ -267,7 +264,7 @@ class Dolistore // add image or default ? if ($product->id_default_image != '') { $image_url = DOL_URL_ROOT.'/admin/dolistore/ajax/image.php?id_product='.$product->id.'&id_image='.$product->id_default_image; - $images = ''; + $images = ''; $images .= ''; } else { $images = ''; @@ -306,16 +303,16 @@ class Dolistore //.'
'.$langs->trans("SeeInMarkerPlace").' //output template - $html .= ' + $html .= '
'.$newapp.$images.'

'.$product->name->language[$this->lang - 1] .'
'.$version.'

- '.dol_print_date(dol_stringtotime($product->date_upd), 'dayhour').' - '.$langs->trans('Ref').': '.$product->reference.' - '.$langs->trans('Id').': '.$product->id.'

'.$product->description_short->language[$this->lang - 1].' - '.$product->description->language[$this->lang - 1].' - '.$price.' - - '.$download_link.' - '; + '.dol_print_date(dol_stringtotime($product->date_upd), 'dayhour').' - '.$langs->trans('Ref').': '.$product->reference.' - '.$langs->trans('Id').': '.$product->id.'

'.$product->description_short->language[$this->lang - 1].''; + // do not load if display none + //$html .= ''.$product->description->language[$this->lang - 1].''; + $html .= ''.$price.''; + $html .= ''.$download_link.''; + $html .= ''; } return $html; } From 9785e0b852bbbb9562942e3f84c748ef3ba3f0f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 May 2020 12:30:59 +0200 Subject: [PATCH 07/12] Trans --- htdocs/langs/en_US/modulebuilder.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index b815cf997cc..135ac1ae9ec 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -83,7 +83,7 @@ ListOfDictionariesEntries=List of dictionaries entries ListOfPermissionsDefined=List of defined permissions SeeExamples=See examples here EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) -VisibleDesc=Is the field visible ? (Examples: 0=Never visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create), 5=Visible on list end view form only (not create, not update). Using a negative value means field is not shown by default on list but can be selected for viewing). It can be an expression, for example:
preg_match('/public/', $_SERVER['PHP_SELF'])?0:1
($user->rights->holiday->define_holiday ? 1 : 0) +VisibleDesc=Is the field visible ? (Examples: 0=Never visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create), 5=Visible on list end view form only (not create, not update).

Using a negative value means field is not shown by default on list but can be selected for viewing).

It can be an expression, for example:
preg_match('/public/', $_SERVER['PHP_SELF'])?0:1
($user->rights->holiday->define_holiday ? 1 : 0) DisplayOnPdfDesc=Display this field on compatible PDF documents, you can manage position with "Position" field.
Currently, known compatibles PDF models are : eratosthene (order), espadon (ship), sponge (invoices), cyan (propal/quotation), cornas (supplier order)

For document :
0 = not displayed
1 = display
2 = display only if not empty

For document lines :
0 = not displayed
1 = displayed in a column
3 = display in line description column after the description
4 = display in description column after the description only if not empty DisplayOnPdf=Display on PDF IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Examples: 1 or 0) From 8e6efba0be33b762f6fdf58321f6d1b69433be3d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 May 2020 12:49:53 +0200 Subject: [PATCH 08/12] CSS --- htdocs/theme/eldy/global.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index ef39d38a568..60c7ee43bb0 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1611,7 +1611,7 @@ div.nopadding { } td.nobordernopadding.widthpictotitle.col-picto { - color: var(--colortexttitlenotab); + color: #bbb; opacity: 0.85; } .table-list-of-attached-files .col-picto, .table-list-of-links .col-picto { From 3b87b7c359a61bcfce64ec6f8366aeb5904fed0d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 13 May 2020 13:29:50 +0200 Subject: [PATCH 09/12] CSS --- htdocs/core/tpl/extrafields_view.tpl.php | 21 ++++++++++++++++++--- htdocs/theme/eldy/global.inc.php | 2 +- htdocs/theme/md/style.css.php | 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index e6cbad245d9..198a3910747 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -52,8 +52,12 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] { $lastseparatorkeyfound = ''; $extrafields_collapse_num = ''; + $extrafields_collapse_num_old = ''; + $i = 0; foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $label) { + $i++; + // Discard if extrafield is a hidden field on form $enabled = 1; @@ -65,6 +69,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] { $enabled = dol_eval($extrafields->attributes[$object->table_element]['list'][$key], 1); } + $perms = 1; if ($perms && isset($extrafields->attributes[$object->table_element]['perms'][$key])) { @@ -87,6 +92,8 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] $value = $object->array_options["options_".$key]; //var_dump($key.' - '.$value); } + + // Print line tr of extra field if ($extrafields->attributes[$object->table_element]['type'][$key] == 'separate') { $extrafields_collapse_num = ''; @@ -109,13 +116,20 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] } else { - print ''; + print ''; + $extrafields_collapse_num_old = $extrafields_collapse_num; print ''; print ''; print ''; - print ''; print ''; print ''; @@ -643,7 +643,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; // Delete print ''; print ''; diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 4f3930a4588..3fc3151030a 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -308,7 +308,7 @@ class Translate continue; } else { - // Convert some strings: Parse and render carriage returns. Also, change '\\s' int '\s' because transifex sync pull the string '\s' into string '\\s' + // Convert some strings: Parse and render carriage returns. Also, change '\\s' into '\s' because transifex sync pull the string '\s' into string '\\s' $this->tab_translate[$key] = str_replace(array('\\n', '\\\\s'), array("\n", '\s'), $value); if ($usecachekey) { $tabtranslatedomain[$key] = $value; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 20094da216c..31716dc3f3c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5794,7 +5794,8 @@ function dolGetFirstLineOfText($text, $nboflines = 1, $charset = 'UTF-8') /** - * Replace CRLF in string with a HTML BR tag + * Replace CRLF in string with a HTML BR tag. + * WARNING: The content after operation contains some HTML tags (the
) so be sure to also have encode the special chars of stringtoencode into HTML before. * * @param string $stringtoencode String to encode * @param int $nl2brmode 0=Adding br before \n, 1=Replacing \n by br @@ -6048,7 +6049,7 @@ function dol_textishtml($msg, $option = 0) * * @param string $text1 Text 1 * @param string $text2 Text 2 - * @param bool $forxml false=Use
instead of \n if html content detected, true=Use
instead of \n if html content detected + * @param bool $forxml true=Use
instead of
if we have to add a br tag * @param bool $invert invert order of description lines (we often use config MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION in this parameter) * @return string Text 1 + new line + Text2 * @see dol_textishtml() @@ -6063,9 +6064,9 @@ function dol_concatdesc($text1, $text2, $forxml = false, $invert = false) } $ret = ''; - $ret .= (!dol_textishtml($text1) && dol_textishtml($text2)) ?dol_nl2br($text1, 0, $forxml) : $text1; + $ret .= (!dol_textishtml($text1) && dol_textishtml($text2)) ? dol_nl2br(dol_escape_htmltag($text1, 0, 1, '', 1), 0, $forxml) : $text1; $ret .= (!empty($text1) && !empty($text2)) ? ((dol_textishtml($text1) || dol_textishtml($text2)) ? ($forxml ? "
\n" : "
\n") : "\n") : ""; - $ret .= (dol_textishtml($text1) && !dol_textishtml($text2)) ?dol_nl2br($text2, 0, $forxml) : $text2; + $ret .= (dol_textishtml($text1) && !dol_textishtml($text2)) ? dol_nl2br(dol_escape_htmltag($text2, 0, 1, '', 1), 0, $forxml) : $text2; return $ret; } diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 969b83cac5a..2bc6d6db962 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -937,8 +937,8 @@ class EmailCollector extends CommonObject } imap_errors(); // Clear stack of errors. - // $conf->global->MAIL_PREFIX_FOR_EMAIL_ID must be defined $host = dol_getprefix('email'); + //$host = '123456'; // Define the IMAP search string // See https://tools.ietf.org/html/rfc3501#section-6.4.4 for IMAPv4 (PHP not yet compatible) @@ -1081,6 +1081,7 @@ class EmailCollector extends CommonObject dol_syslog("Start of loop on email", LOG_INFO, 1); + $i = 0; foreach ($arrayofemail as $imapemail) { if ($nbemailprocessed > 1000) @@ -1088,6 +1089,8 @@ class EmailCollector extends CommonObject break; // Do not process more than 1000 email per launch (this is a different protection than maxnbcollectedpercollect } + $i++; + $header = imap_fetchheader($connection, $imapemail, 0); $header = preg_replace('/\r\n\s+/m', ' ', $header); // When a header line is on several lines, merge lines $matches = array(); @@ -1095,6 +1098,8 @@ class EmailCollector extends CommonObject $headers = array_combine($matches[1], $matches[2]); //var_dump($headers); + dol_syslog("** Process email ".$i." References: ".$headers['References']); + // If there is a filter on trackid if ($searchfilterdoltrackid > 0) { @@ -1130,7 +1135,7 @@ class EmailCollector extends CommonObject // GET Email meta datas $overview = imap_fetch_overview($connection, $imapemail, 0); - dol_syslog("** Process email - msgid=".$overview[0]->message_id." date=".dol_print_date($overview[0]->udate, 'dayrfc', 'gmt')." subject=".$overview[0]->subject); + dol_syslog("msgid=".$overview[0]->message_id." date=".dol_print_date($overview[0]->udate, 'dayrfc', 'gmt')." subject=".$overview[0]->subject); // Decode $overview[0]->subject according to RFC2047 // Can use also imap_mime_header_decode($str) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 5ce79a12231..6c139a0f10c 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -1939,7 +1939,7 @@ WithoutDolTrackingID=Dolibarr Reference not found in Message ID FormatZip=Zip MainMenuCode=Menu entry code (mainmenu) ECMAutoTree=Show automatic ECM tree -OperationParamDesc=Define values to use for action, or how to extract values. For example:
objproperty1=SET:abc
objproperty1=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:abc
objproperty4=EXTRACT:HEADER:X-Myheaderkey.*[^\s]+(.*)
options_myextrafield=EXTRACT:SUBJECT:([^\s]*)
object.objproperty5=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. +OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
objproperty1=SET:the value to set
objproperty2=SET:a value with replacement of __objproperty1__
objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
objproperty4=EXTRACT:HEADER:X-Myheaderkey:\s*([^\s]*)
options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
object.objproperty5=EXTRACT:BODY:My company name is\s([^\s]*)

Use a ; char as separator to extract or set several properties. OpeningHours=Opening hours OpeningHoursDesc=Enter here the regular opening hours of your company. ResourceSetup=Configuration of Resource module From 4a65b629ee3c93266226208d24806aee8243e168 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 14 May 2020 14:29:14 +0200 Subject: [PATCH 12/12] Position of fields --- htdocs/index.php | 4 ++-- htdocs/theme/eldy/global.inc.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 36aae1f25b8..7f6e462839b 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -142,11 +142,11 @@ if (empty($user->socid) && empty($conf->global->MAIN_DISABLE_GLOBAL_BOXSTATS)) 'orders', 'invoices', 'donations', - 'contracts', - 'interventions', 'supplier_proposals', 'supplier_orders', 'supplier_invoices', + 'contracts', + 'interventions', 'ticket' ); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 2f5e10c1459..afb154408c5 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -3643,7 +3643,7 @@ ul.noborder li:nth-child(even):not(.liste_titre) { box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.20); } span.boxstatstext { - opacity: 0.7; + opacity: 0.5; line-height: 18px; color: var(--colortext); }
attributes[$object->table_element]['required'][$key])) print ' fieldrequired'; print '">'; if (!empty($extrafields->attributes[$object->table_element]['help'][$key])) print $form->textwithpicto($langs->trans($label), $langs->trans($extrafields->attributes[$object->table_element]['help'][$key])); @@ -161,6 +175,7 @@ if (empty($reshook) && is_array($extrafields->attributes[$object->table_element] //print 'x'.$object->array_options['options_' . $key].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); $value = isset($_POST["options_".$key]) ? dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]) : $datenotinstring; } + //TODO Improve element and rights detection if ($action == 'edit_extras' && $permok && GETPOST('attribute', 'none') == $key) { diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 60c7ee43bb0..2f5e10c1459 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1751,7 +1751,7 @@ img.photorefnoborder { border-bottom: px solid rgb(); /* border-bottom: 2px solid var(--colorbackhmenu1); */ } -.trextrafieldseparator td { +.trextrafieldseparator td, .trextrafields_collapse_last td { /* border-bottom: 2px solid var(--colorbackhmenu1) !important; */ border-bottom: 2px solid rgb() !important; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c7ce5709efd..da2df5eb788 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1799,7 +1799,7 @@ img.photorefnoborder { border-bottom: px solid rgb(); } -.trextrafieldseparator td { +.trextrafieldseparator td, .trextrafields_collapse_last td { border-bottom: 1px solid rgb() !important; } .tdhrthin { From 1bd00b0e8c635db1a8348c97d3933699b92d88db Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 14 May 2020 12:28:17 +0200 Subject: [PATCH 10/12] Fix to solve feedbacks of https://www.dolibarr.fr/forum/t/email-collector-avec-office-365-bug-et-contournement/32726 --- .../class/emailcollector.class.php | 20 +++++++++++++++---- .../install/mysql/migration/11.0.0-12.0.0.sql | 2 ++ .../llx_emailcollector_emailcollector.sql | 3 ++- htdocs/langs/en_US/admin.lang | 1 + 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/htdocs/emailcollector/class/emailcollector.class.php b/htdocs/emailcollector/class/emailcollector.class.php index 11cf2477720..969b83cac5a 100644 --- a/htdocs/emailcollector/class/emailcollector.class.php +++ b/htdocs/emailcollector/class/emailcollector.class.php @@ -100,8 +100,9 @@ class EmailCollector extends CommonObject 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'help'=>'Example: MyCollector1'), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'visible'=>1, 'enabled'=>1, 'position'=>30, 'notnull'=>-1, 'searchall'=>1, 'help'=>'Example: My Email collector'), 'description' => array('type'=>'text', 'label'=>'Description', 'visible'=>-1, 'enabled'=>1, 'position'=>60, 'notnull'=>-1), - 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>100, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com'), - 'login' => array('type'=>'varchar(128)', 'label'=>'Login', 'visible'=>1, 'enabled'=>1, 'position'=>101, 'notnull'=>-1, 'index'=>1, 'comment'=>"IMAP login", 'help'=>'Example: myaccount@gmail.com'), + 'host' => array('type'=>'varchar(255)', 'label'=>'EMailHost', 'visible'=>1, 'enabled'=>1, 'position'=>90, 'notnull'=>1, 'searchall'=>1, 'comment'=>"IMAP server", 'help'=>'Example: imap.gmail.com'), + 'hostcharset' => array('type'=>'varchar(16)', 'label'=>'HostCharset', 'visible'=>-1, 'enabled'=>1, 'position'=>91, 'notnull'=>0, 'searchall'=>0, 'comment'=>"IMAP server charset", 'help'=>'Example: "UTF-8" (May be "US-ASCII" with some Office365)'), + 'login' => array('type'=>'varchar(128)', 'label'=>'Login', 'visible'=>1, 'enabled'=>1, 'position'=>101, 'notnull'=>-1, 'index'=>1, 'comment'=>"IMAP login", 'help'=>'Example: myaccount@gmail.com'), 'password' => array('type'=>'password', 'label'=>'Password', 'visible'=>-1, 'enabled'=>1, 'position'=>102, 'notnull'=>-1, 'comment'=>"IMAP password", 'help'=>'WithGMailYouCanCreateADedicatedPassword'), 'source_directory' => array('type'=>'varchar(255)', 'label'=>'MailboxSourceDirectory', 'visible'=>-1, 'enabled'=>1, 'position'=>103, 'notnull'=>1, 'default' => 'Inbox', 'help'=>'Example: INBOX'), //'filter' => array('type'=>'text', 'label'=>'Filter', 'visible'=>1, 'enabled'=>1, 'position'=>105), @@ -173,6 +174,7 @@ class EmailCollector extends CommonObject public $host; + public $hostcharset; public $login; public $password; public $source_directory; @@ -985,9 +987,10 @@ class EmailCollector extends CommonObject $nbemailprocessed = 0; $nbemailok = 0; $nbactiondone = 0; + $charset = ($this->hostcharset ? $this->hostcharset : "UTF-8"); // Scan IMAP inbox - $arrayofemail = imap_search($connection, $search, null, "UTF-8"); + $arrayofemail = imap_search($connection, $search, null, $charset); if ($arrayofemail === false) { // Nothing found or search string not understood @@ -1086,6 +1089,7 @@ class EmailCollector extends CommonObject } $header = imap_fetchheader($connection, $imapemail, 0); + $header = preg_replace('/\r\n\s+/m', ' ', $header); // When a header line is on several lines, merge lines $matches = array(); preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)\r\n/m', $header, $matches); $headers = array_combine($matches[1], $matches[2]); @@ -1132,7 +1136,10 @@ class EmailCollector extends CommonObject // Can use also imap_mime_header_decode($str) // Can use also mb_decode_mimeheader($str) // Can use also iconv_mime_decode($str, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8') - if (function_exists('imap_mime_header_decode')) { + if (function_exists('iconv_mime_decode')) { + $overview[0]->subject = iconv_mime_decode($overview[0]->subject, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8'); + } + elseif (function_exists('imap_mime_header_decode')) { $elements = imap_mime_header_decode($overview[0]->subject); $newstring = ''; if (!empty($elements)) { @@ -1146,6 +1153,8 @@ class EmailCollector extends CommonObject elseif (function_exists('mb_decode_mimeheader')) { $overview[0]->subject = mb_decode_mimeheader($overview[0]->subject); } + // Removed emojis + $overview[0]->subject = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $overview[0]->subject); // Parse IMAP email structure global $htmlmsg, $plainmsg, $charset, $attachments; @@ -1153,6 +1162,9 @@ class EmailCollector extends CommonObject //$htmlmsg,$plainmsg,$charset,$attachments $messagetext = $plainmsg ? $plainmsg : dol_string_nohtmltag($htmlmsg, 0); + // Removed emojis + $messagetext = preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $messagetext); + /*var_dump($plainmsg); var_dump($htmlmsg); var_dump($messagetext);*/ diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 8a68e763160..7daf41a05d3 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -285,3 +285,5 @@ ALTER TABLE llx_prelevement_facture ADD COLUMN fk_facture_fourn INTEGER NULL; ALTER TABLE llx_menu MODIFY COLUMN module varchar(255); UPDATE llx_actioncomm SET fk_action = 50 where fk_action = 40 AND code = 'TICKET_MSG'; + +ALTER TABLE llx_emailcollector_emailcollector ADD COLUMN hostcharset varchar(16) DEFAULT 'UTF-8'; diff --git a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql index 10f3e4f8b9b..87581f418e8 100644 --- a/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql +++ b/htdocs/install/mysql/tables/llx_emailcollector_emailcollector.sql @@ -21,7 +21,8 @@ CREATE TABLE llx_emailcollector_emailcollector( ref varchar(128) NOT NULL, label varchar(255), description text, - host varchar(255), + host varchar(255), + hostcharset varchar(16) DEFAULT 'UTF-8', login varchar(128), password varchar(128), source_directory varchar(255) NOT NULL, diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 1bd7f3d0297..5ce79a12231 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -40,6 +40,7 @@ WebUserGroup=Web server user/group NoSessionFound=Your PHP configuration seems to not allow listing of active sessions. The directory used to save sessions (%s) may be protected (for example by OS permissions or by PHP directive open_basedir). DBStoringCharset=Database charset to store data DBSortingCharset=Database charset to sort data +HostCharset=Host charset ClientCharset=Client charset ClientSortingCharset=Client collation WarningModuleNotActive=Module %s must be enabled From bcaa83eeeca16486d5d3d511ea7290b25146aba5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 14 May 2020 14:10:04 +0200 Subject: [PATCH 11/12] FIX dol_concatdesc to escape < Better help --- htdocs/admin/emailcollector_card.php | 4 ++-- htdocs/core/class/translate.class.php | 2 +- htdocs/core/lib/functions.lib.php | 9 +++++---- htdocs/emailcollector/class/emailcollector.class.php | 9 +++++++-- htdocs/langs/en_US/admin.lang | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index 74592ff777a..80161eaadc6 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -592,7 +592,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); //var_dump($htmltext); - print $form->textwithpicto('', $htmltext); + print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); print ''; - print ''.img_edit().''; + print ''.img_edit().''; print ' '.img_delete().''; print '