diff --git a/COPYRIGHT b/COPYRIGHT index 45b3047a375..83d054d63be 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -52,7 +52,7 @@ Ace 1.4.14 BSD Yes ChartJS 3.7.1 MIT License Yes JS library for graph CKEditor 4.18 LGPL-2.1+ Yes Editor WYSIWYG jQuery 3.6.0 MIT License Yes JS library -jQuery UI 1.13.1 GPL and MIT License Yes JS library plugin UI +jQuery UI 1.13.2 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.13 GPL and Apache License Yes JS library plugin for sexier multiselect. Warning: 4.0.6+ create troubles without patching css jQuery blockUI 2.70.0 GPL and MIT License Yes JS library plugin blockUI (to use ajax popups) jQuery Colorpicker 1.1 MIT License Yes JS library for color picker for a defined list of colors diff --git a/ChangeLog b/ChangeLog index bc38c9e6847..fcf5af4aef6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -27,7 +27,9 @@ Following changes may create regressions for some external modules, but were nec For users: --------------- -NEW: PHP 8.1 compatibility +NEW: PHP 8.1 compatibility. + Warning: Application works correctly with PHP8 and 8.1 but you may experience a lot of PHP warning into the PHP server log files (depending + on the PHP setup). Removal of all PHP warnings on server side is planned for v17. NEW: Support for recurring purchase invoices. NEW: #20292 Include German public holidays NEW: Can show ZATCA QR-Code on PDFs diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index 99ae0bd845b..bd48c205dae 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -49,7 +49,7 @@ if (empty($user->rights->accounting->mouvements->lire)) { if (empty($conf->comptabilite->enabled) && empty($conf->accounting->enabled) && empty($conf->asset->enabled) && empty($conf->intracommreport->enabled)) { accessforbidden(); } -if (empty($user->rights->compta->resultat->lire) && empty($user->rights->accounting->comptarapport->lire) && empty($user->rights->accounting->mouvements->lire) && empty($user->rights->asset->read) && empty($user->rights->intracommreport->read)) { +if (empty($user->hasRight('compta', 'resultat', 'lire')) && empty($user->hasRight('accounting', 'comptarapport', 'lire')) && empty($user->hasRight('accounting', 'mouvements', 'lire')) && empty($user->hasRight('asset', 'read')) && empty($user->hasRight('intracommreport', 'read'))) { accessforbidden(); } diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 2e04a29b69f..f7b900feaa4 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -40,6 +40,7 @@ require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; @@ -311,8 +312,8 @@ if (empty($reshook)) { //$object->twitter = trim(GETPOST("twitter", 'alpha')); //$object->facebook = trim(GETPOST("facebook", 'alpha')); //$object->linkedin = trim(GETPOST("linkedin", 'alpha')); - $object->birth = $birthdate; - + $object->birth = $birthdate; + $object->default_lang = GETPOST('default_lang', 'alpha'); $object->typeid = GETPOST("typeid", 'int'); //$object->note = trim(GETPOST("comment","alpha")); $object->morphy = GETPOST("morphy", 'alpha'); @@ -457,6 +458,7 @@ if (empty($reshook)) { $userid = GETPOST("userid", 'int'); $socid = GETPOST("socid", 'int'); + $default_lang = GETPOST('default_lang', 'alpha'); $object->civility_id = $civility_id; $object->firstname = $firstname; @@ -498,7 +500,7 @@ if (empty($reshook)) { $object->user_id = $userid; $object->socid = $socid; $object->public = $public; - + $object->default_lang = $default_lang; // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object); if ($ret < 0) { @@ -621,6 +623,11 @@ if (empty($reshook)) { } } $action = ($result < 0 || !$error) ? '' : 'create'; + + if (!$error && $backtopage) { + header("Location: ".$backtopage); + exit; + } } if ($user->rights->adherent->supprimer && $action == 'confirm_delete' && $confirm == 'yes') { @@ -894,6 +901,7 @@ if (empty($reshook)) { $form = new Form($db); $formfile = new FormFile($db); +$formadmin = new FormAdmin($db); $formcompany = new FormCompany($db); $title = $langs->trans("Member")." - ".$langs->trans("Card"); @@ -1358,6 +1366,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print $form->selectDate(($object->birth ? $object->birth : -1), 'birth', '', '', 1, 'formsoc'); print "\n"; + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print img_picto('', 'language').$formadmin->select_language($object->default_lang, 'default_lang', 0, 0, 1); + print ''; + print ''; + } + // Public profil print "".$langs->trans("Public")."\n"; print $form->selectyesno("public", (GETPOSTISSET("public") ? GETPOST("public", 'alphanohtml', 2) : $object->public), 1); @@ -1798,6 +1814,19 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // Birth Date print ''.$langs->trans("DateOfBirth").''.dol_print_date($object->birth, 'day').''; + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + print ''.$langs->trans("DefaultLang").''; + //$s=picto_from_langcode($object->default_lang); + //print ($s?$s.' ':''); + $langs->load("languages"); + $labellang = ($object->default_lang ? $langs->trans('Language_'.$object->default_lang) : ''); + print picto_from_langcode($object->default_lang, 'class="paddingrightonly saturatemedium opacitylow"'); + print $labellang; + print ''; + } + // Public print ''.$langs->trans("Public").''.yn($object->public).''; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index dec7584b68e..318dc4ac794 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -215,6 +215,12 @@ class Adherent extends CommonObject */ public $public; + /** + * Default language code of member (en_US, ...) + * @var string + */ + public $default_lang; + /** * @var string photo of member */ @@ -328,6 +334,7 @@ class Adherent extends CommonObject 'photo' => array('type' => 'varchar(255)', 'label' => 'Photo', 'enabled' => 1, 'visible' => -1, 'position' => 135), 'public' => array('type' => 'smallint(6)', 'label' => 'Public', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 145), 'datefin' => array('type' => 'datetime', 'label' => 'DateEnd', 'enabled' => 1, 'visible' => -1, 'position' => 150), + 'default_lang' =>array('type'=>'varchar(6)', 'label'=>'Default lang', 'enabled'=>1, 'visible'=>-1, 'position'=> 153), 'note_private' => array('type' => 'text', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 155), 'note_public' => array('type' => 'text', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 160), 'datevalid' => array('type' => 'datetime', 'label' => 'DateValidation', 'enabled' => 1, 'visible' => -1, 'position' => 165), @@ -710,9 +717,11 @@ class Adherent extends CommonObject $sql .= ", photo = ".($this->photo ? "'".$this->db->escape($this->photo)."'" : "null"); $sql .= ", public = '".$this->db->escape($this->public)."'"; $sql .= ", statut = ".$this->db->escape($this->statut); + $sql .= ", default_lang = ".(!empty($this->default_lang) ? "'".$this->db->escape($this->default_lang)."'" : "null"); $sql .= ", fk_adherent_type = ".$this->db->escape($this->typeid); $sql .= ", morphy = '".$this->db->escape($this->morphy)."'"; $sql .= ", birth = ".($this->birth ? "'".$this->db->idate($this->birth)."'" : "null"); + if ($this->datefin) { $sql .= ", datefin = '".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription } @@ -833,6 +842,8 @@ class Adherent extends CommonObject $luser->office_phone = $this->phone; $luser->user_mobile = $this->phone_mobile; + $luser->lang = $this->default_lang; + $luser->fk_member = $this->id; $result = $luser->update($user, 0, 1, 1); // Use nosync to 1 to avoid cyclic updates @@ -868,6 +879,7 @@ class Adherent extends CommonObject $lthirdparty->state_id = $this->state_id; $lthirdparty->country_id = $this->country_id; //$lthirdparty->phone_mobile=$this->phone_mobile; + $lthirdparty->default_lang = $this->default_lang; $result = $lthirdparty->update($this->fk_soc, $user, 0, 1, 1, 'update'); // Use sync to 0 to avoid cyclic updates @@ -1314,7 +1326,7 @@ class Adherent extends CommonObject $sql .= " d.photo, d.fk_adherent_type, d.morphy, d.entity,"; $sql .= " d.datec as datec,"; $sql .= " d.tms as datem,"; - $sql .= " d.datefin as datefin,"; + $sql .= " d.datefin as datefin, d.default_lang,"; $sql .= " d.birth as birthday,"; $sql .= " d.datevalid as datev,"; $sql .= " d.country,"; @@ -1407,6 +1419,8 @@ class Adherent extends CommonObject $this->date_validation = $this->db->jdate($obj->datev); $this->birth = $this->db->jdate($obj->birthday); + $this->default_lang = $obj->default_lang; + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->morphy = $obj->morphy; @@ -2556,6 +2570,7 @@ class Adherent extends CommonObject $this->datefin = $now; $this->datevalid = $now; + $this->default_lang = ''; $this->typeid = 1; // Id type adherent $this->type = 'Type adherent'; // Libelle type adherent diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index ddc9a1470c0..f3d5f96a78a 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -5,7 +5,7 @@ * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2013 Florian Henry * Copyright (C) 2015 Alexandre Spangaro - * Copyright (C) 2019 Thibault Foucart + * Copyright (C) 2019-2022 Thibault Foucart * Copyright (C) 2020 Josep Lluís Amador * Copyright (C) 2021 Waël Almoman * @@ -141,6 +141,7 @@ if ($action == 'add' && $user->rights->adherent->configurer) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); } else { $sql = "SELECT libelle FROM ".MAIN_DB_PREFIX."adherent_type WHERE libelle='".$db->escape($object->label)."'"; + $sql .= " WHERE entity IN (".getEntity('member_type').")"; $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index fa5d6deae97..3cba1a333ca 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -622,34 +622,33 @@ $sourceList = array(); if ($id == 11) { $elementList = array( '' => '', - 'societe' => $langs->trans('ThirdParty'), + 'agenda' => img_picto('', 'action', 'class="pictofixedwidth"').$langs->trans('Agenda'), + 'dolresource' => img_picto('', 'resource', 'class="pictofixedwidth"').$langs->trans('Resource'), + 'societe' => img_picto('', 'company', 'class="pictofixedwidth"').$langs->trans('ThirdParty'), // 'proposal' => $langs->trans('Proposal'), // 'order' => $langs->trans('Order'), // 'invoice' => $langs->trans('Bill'), - 'supplier_proposal' => $langs->trans('SupplierProposal'), - 'order_supplier' => $langs->trans('SupplierOrder'), - 'invoice_supplier' => $langs->trans('SupplierBill'), // 'intervention' => $langs->trans('InterventionCard'), // 'contract' => $langs->trans('Contract'), - 'project' => $langs->trans('Project'), - 'project_task' => $langs->trans('Task'), - 'ticket' => $langs->trans('Ticket'), - 'agenda' => $langs->trans('Agenda'), - 'dolresource' => $langs->trans('Resource'), - // old deprecated - 'propal' => $langs->trans('Proposal'), - 'commande' => $langs->trans('Order'), - 'facture' => $langs->trans('Bill'), - 'fichinter' => $langs->trans('InterventionCard'), - 'contrat' => $langs->trans('Contract'), + 'project' => img_picto('', 'project', 'class="pictofixedwidth"').$langs->trans('Project'), + 'project_task' => img_picto('', 'projecttask', 'class="pictofixedwidth"').$langs->trans('Task'), + 'propal' => img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans('Proposal'), + 'commande' => img_picto('', 'order', 'class="pictofixedwidth"').$langs->trans('Order'), + 'facture' => img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans('Bill'), + 'fichinter' => img_picto('', 'intervention', 'class="pictofixedwidth"').$langs->trans('InterventionCard'), + 'contrat' => img_picto('', 'contract', 'class="pictofixedwidth"').$langs->trans('Contract'), + 'ticket' => img_picto('', 'ticket', 'class="pictofixedwidth"').$langs->trans('Ticket'), + 'supplier_proposal' => img_picto('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans('SupplierProposal'), + 'order_supplier' => img_picto('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans('SupplierOrder'), + 'invoice_supplier' => img_picto('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans('SupplierBill'), ); - if (!empty($conf->global->MAIN_SUPPORT_SHARED_CONTACT_BETWEEN_THIRDPARTIES)) { - $elementList["societe"] = $langs->trans('ThirdParty'); + if (!empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { + $elementList['conferenceorbooth'] = img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'); } complete_elementList_with_modules($elementList); - asort($elementList); + //asort($elementList); $sourceList = array( 'internal' => $langs->trans('Internal'), 'external' => $langs->trans('External') @@ -1202,7 +1201,6 @@ if (GETPOST('from')) { if ($action == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'rowid='.urlencode($rowid).'&code='.urlencode($code).$paramwithsearch, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); } -//var_dump($elementList); /* @@ -1222,14 +1220,16 @@ if ($id > 0) { $sql .= natural_search("code_iso", $search_code); } elseif ($search_code != '' && $id == 28) { $sql .= natural_search("h.code", $search_code); - } elseif ($search_code != '' && $id == 32) { + } elseif ($search_code != '' && ($id == 7 || $id == 32)) { $sql .= natural_search("a.code", $search_code); } elseif ($search_code != '' && $id == 3) { $sql .= natural_search("r.code_region", $search_code); - } elseif ($search_code != '' && $id == 7) { - $sql .= natural_search("a.code", $search_code); - } elseif ($search_code != '' && $id == 10) { + } elseif ($search_code != '' && ($id == 8 || $id == 10)) { $sql .= natural_search("t.code", $search_code); + } elseif ($search_code != '' && $id == 1) { + $sql .= natural_search("f.code", $search_code); + } elseif ($search_code != '' && $id == 2) { + $sql .= natural_search("d.code_departement", $search_code); } elseif ($search_code != '' && $id != 9) { $sql .= natural_search("code", $search_code); } @@ -1960,7 +1960,7 @@ if ($id > 0) { $valuetoshow = price($valuetoshow); } if ($value == 'private') { - $valuetoshow = yn($elementList[$valuetoshow]); + $valuetoshow = yn($valuetoshow); } elseif ($value == 'libelle_facture') { $langs->load("bills"); $key = $langs->trans("PaymentCondition".strtoupper($obj->code)); @@ -2375,9 +2375,15 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') print ''; print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'lang'); print ''; - } elseif (in_array($value, array('element', 'source'))) { //Example: the type and source of the element (for contact types) + } elseif (in_array($value, array('element', 'source'))) { // Example: the type and source of the element (for contact types) + $tmparray = array(); + if ($value == 'element') { + $tmparray = $elementList; + } else { + $tmparray = $sourceList; + } print ''; - print $form->selectarray($value, $elementList, (!empty($obj->{$value}) ? $obj->{$value}:'')); + print $form->selectarray($value, $tmparray, (!empty($obj->{$value}) ? $obj->{$value}:''), 0, 0, 0, '', 0, 0, 0, '', 'maxwidth250'); print ''; } elseif (in_array($value, array('public', 'use_default'))) { // Fields 0/1 with a combo select Yes/No diff --git a/htdocs/admin/emailcollector_card.php b/htdocs/admin/emailcollector_card.php index ab4f0c7def0..bc8267f9ef9 100644 --- a/htdocs/admin/emailcollector_card.php +++ b/htdocs/admin/emailcollector_card.php @@ -378,33 +378,54 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $connectstringserver = $object->getConnectStringIMAP($usessl); - try { - if ($sourcedir) { - //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); - $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir); - } - if ($targetdir) { - //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); - $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); + if ($action == 'scan') { + try { + if ($sourcedir) { + //$connectstringsource = $connectstringserver.imap_utf7_encode($sourcedir); + $connectstringsource = $connectstringserver.$object->getEncodedUtf7($sourcedir); + } + if ($targetdir) { + //$connectstringtarget = $connectstringserver.imap_utf7_encode($targetdir); + $connectstringtarget = $connectstringserver.$object->getEncodedUtf7($targetdir); + } + + $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; + $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 20 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; + + dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread); + + $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect + $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread); + $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5); + $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5); + + dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4); + + $connection = imap_open($connectstringsource, $object->login, $object->password); + + //dol_syslog("end imap_open connection=".var_export($connection, true)); + } catch (Exception $e) { + print $e->getMessage(); } - $timeoutconnect = empty($conf->global->MAIN_USE_CONNECT_TIMEOUT) ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT; - $timeoutread = empty($conf->global->MAIN_USE_RESPONSE_TIMEOUT) ? 20 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT; + if (!$connection) { + $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; + if (function_exists('imap_last_error')) { + $morehtml .= '
'.imap_last_error(); + } + dol_syslog("Error ".$morehtml, LOG_WARNING); + //var_dump(imap_errors()) + } else { + dol_syslog("Imap connected. Now we call imap_num_msg()"); + $morehtml .= imap_num_msg($connection); + } - dol_syslog("imap_open connectstring=".$connectstringsource." login=".$object->login." password=".$object->password." timeoutconnect=".$timeoutconnect." timeoutread=".$timeoutread); - - $result1 = imap_timeout(IMAP_OPENTIMEOUT, $timeoutconnect); // timeout seems ignored with ssl connect - $result2 = imap_timeout(IMAP_READTIMEOUT, $timeoutread); - $result3 = imap_timeout(IMAP_WRITETIMEOUT, 5); - $result4 = imap_timeout(IMAP_CLOSETIMEOUT, 5); - - dol_syslog("result1=".$result1." result2=".$result2." result3=".$result3." result4=".$result4); - - $connection = imap_open($connectstringsource, $object->login, $object->password); - - //dol_syslog("end imap_open connection=".var_export($connection, true)); - } catch (Exception $e) { - print $e->getMessage(); + if ($connection) { + dol_syslog("Imap close"); + imap_close($connection); + } + } else { + $morehtml .= ''.img_picto('', 'refresh', 'class="paddingrightonly"').$langs->trans("Refresh").''; } $morehtml .= $form->textwithpicto('', 'connect string '.$connectstringserver); @@ -412,23 +433,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtml .= 'IMAP functions not available on your PHP. '; } - if (!$connection) { - $morehtml .= 'Failed to open IMAP connection '.$connectstringsource; - if (function_exists('imap_last_error')) { - $morehtml .= '
'.imap_last_error(); - } - dol_syslog("Error ".$morehtml, LOG_WARNING); - //var_dump(imap_errors()) - } else { - dol_syslog("Imap connected. Now we call imap_num_msg()"); - $morehtml .= imap_num_msg($connection); - } - - if ($connection) { - dol_syslog("Imap close"); - imap_close($connection); - } - dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref.'
'.$morehtml.'
', '', 0, '', '', 0, ''); print '
'; @@ -580,11 +584,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print $form->selectarray('operationtype', $arrayoftypes, '', 1, 0, 0, '', 1, 0, 0, '', 'maxwidth300', 1); print ''; - print ''; + //print ''; + $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); + print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); print ''; print ''; - $htmltext = $langs->transnoentitiesnoconv("OperationParamDesc"); - print $form->textwithpicto('', $htmltext, 1, 'help', '', 0, 2, 'operationparamtt'); print ''; print ''; print ''; diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 67bf775bdd9..0504315075d 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -88,7 +88,15 @@ if ($action == 'update' && !$cancel) { dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT", 'int'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER", 'alphanohtml'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID", 'alphanohtml'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW", 'none'), 'chaine', 0, '', $conf->entity); + if (GETPOSTISSET("MAIN_MAIL_SMTPS_PW")) { + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW", 'none'), 'chaine', 0, '', $conf->entity); + } + if (GETPOSTISSET("MAIN_MAIL_SMTPS_AUTH_TYPE")) { + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_AUTH_TYPE", GETPOST("MAIN_MAIL_SMTPS_AUTH_TYPE", 'chaine'), 'chaine', 0, '', $conf->entity); + } + if (GETPOSTISSET("MAIN_MAIL_SMTPS_OAUTH_SERVICE")) { + dolibarr_set_const($db, "MAIN_MAIL_SMTPS_OAUTH_SERVICE", GETPOST("MAIN_MAIL_SMTPS_OAUTH_SERVICE", 'chaine'), 'chaine', 0, '', $conf->entity); + } dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS", 'int'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS", 'int'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED", GETPOST("MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED", 'int'), 'chaine', 0, '', $conf->entity); @@ -171,6 +179,24 @@ if (version_compare(phpversion(), '7.0', '>=')) { $listofmethods['swiftmailer'] = 'Swift Mailer socket library'; } +// List of oauth services +$oauthservices = array(); + +foreach ($conf->global as $key => $val) { + if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { + $key = preg_replace('/^OAUTH_/', '', $key); + $key = preg_replace('/_ID$/', '', $key); + if (preg_match('/^.*-/', $key)) { + $name = preg_replace('/^.*-/', '', $key); + } else { + $name = $langs->trans("NoName"); + } + $provider = preg_replace('/-.*$/', '', $key); + $provider = ucfirst(strtolower($provider)); + + $oauthservices[$key] = $name." (".$provider.")"; + } +} if ($action == 'edit') { if ($conf->use_javascript_ajax) { @@ -195,6 +221,7 @@ if ($action == 'edit') { jQuery("#MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY").prop("disabled", true); jQuery(".smtp_method").hide(); jQuery(".dkim").hide(); + jQuery(".smtp_auth_method").hide(); '; if ($linuxlike) { print ' @@ -237,6 +264,7 @@ if ($action == 'edit') { jQuery("#smtp_port_mess").hide(); jQuery(".smtp_method").show(); jQuery(".dkim").hide(); + jQuery(".smtp_auth_method").show(); } if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'swiftmailer\') { @@ -264,12 +292,34 @@ if ($action == 'edit') { jQuery("#smtp_port_mess").hide(); jQuery(".smtp_method").show(); jQuery(".dkim").show(); + jQuery(".smtp_auth_method").show(); } } + function change_smtp_auth_method() { + console.log(jQuery("#radio_pw").prop("checked")); + if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'smtps\' && jQuery("#radio_oauth").prop("checked")) { + jQuery(".smtp_oauth_service").show(); + jQuery(".smtp_pw").hide(); + } else if (jQuery("#MAIN_MAIL_SENDMODE").val()==\'swiftmailer\' && jQuery("#radio_oauth").prop("checked")) { + jQuery(".smtp_oauth_service").show(); + jQuery(".smtp_pw").hide(); + } else if(jQuery("#MAIN_MAIL_SENDMODE").val()==\'mail\'){ + jQuery(".smtp_oauth_service").hide(); + jQuery(".smtp_pw").hide(); + } else { + jQuery(".smtp_oauth_service").hide(); + jQuery(".smtp_pw").show(); + } + } initfields(); + change_smtp_auth_method(); jQuery("#MAIN_MAIL_SENDMODE").change(function() { initfields(); + change_smtp_auth_method(); }); + jQuery("#radio_pw, #radio_oauth").change(function() { + change_smtp_auth_method(); + }); jQuery("#MAIN_MAIL_EMAIL_TLS").change(function() { if (jQuery("#MAIN_MAIL_EMAIL_TLS").val() == 1) jQuery("#MAIN_MAIL_EMAIL_STARTTLS").val(0); @@ -413,10 +463,29 @@ if ($action == 'edit') { print ''; } + + // OAUTH + if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) { + print ''.$langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE").''; + if (empty($conf->multicompany->enabled) || ($user->admin && !$user->entity)) { + print ' '; + print ''; + print '            '; + print ' '; + print ''; + } else { + $value = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE', 'LOGIN'); + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE"), $htmltext, 1, 'superadmin'); + print ''; + } + print ''; + } + // PW if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) { $mainsmtppw = (!empty($conf->global->MAIN_MAIL_SMTPS_PW) ? $conf->global->MAIN_MAIL_SMTPS_PW : ''); - print ''; + print ''; print $form->textwithpicto($langs->trans("MAIN_MAIL_SMTPS_PW"), $langs->trans("WithGMailYouCanCreateADedicatedPassword")); print ''; // SuperAdministrator access only @@ -430,6 +499,24 @@ if ($action == 'edit') { print ''; } + // OAUTH service provider + if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) { + print ''.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").''; + + // SuperAdministrator access only + if ((empty($conf->global->MAIN_MODULE_MULTICOMPANY)) || ($user->admin && !$user->entity)) { + print $form->selectarray('MAIN_MAIL_SMTPS_OAUTH_SERVICE', $oauthservices, $conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE); + } else { + $text = $oauthservices[$conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE]; + if (empty($text)) { + $text = $langs->trans("Undefined"); + } + $htmltext = $langs->trans("ContactSuperAdminForChange"); + print $form->textwithpicto($text, $htmltext, 1, 'superadmin'); + print ''; + } + print ''; + } // TLS print ''.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; if (!empty($conf->use_javascript_ajax) || (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer')))) { @@ -595,29 +682,46 @@ if ($action == 'edit') { print ''; // Host server - if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail')) { + if ($linuxlike && (getDolGlobalString('MAIN_MAIL_SENDMODE') == 'mail')) { print ''.$langs->trans("MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike").''.$langs->trans("SeeLocalSendMailSetup").''; } else { print ''.$langs->trans("MAIN_MAIL_SMTP_SERVER", ini_get('SMTP') ?ini_get('SMTP') : $langs->transnoentities("Undefined")).''.(!empty($conf->global->MAIN_MAIL_SMTP_SERVER) ? $conf->global->MAIN_MAIL_SMTP_SERVER : '').''; } + // Port - if ($linuxlike && (isset($conf->global->MAIN_MAIL_SENDMODE) && $conf->global->MAIN_MAIL_SENDMODE == 'mail')) { + if ($linuxlike && (getDolGlobalString('MAIN_MAIL_SENDMODE') == 'mail')) { print ''.$langs->trans("MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike").''.$langs->trans("SeeLocalSendMailSetup").''; } else { print ''.$langs->trans("MAIN_MAIL_SMTP_PORT", ini_get('smtp_port') ?ini_get('smtp_port') : $langs->transnoentities("Undefined")).''.(!empty($conf->global->MAIN_MAIL_SMTP_PORT) ? $conf->global->MAIN_MAIL_SMTP_PORT : '').''; } // SMTPS ID - if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) { + if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer'))) { print ''.$langs->trans("MAIN_MAIL_SMTPS_ID").''.$conf->global->MAIN_MAIL_SMTPS_ID.''; } + // AUTH method + if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer'))) { + $authtype = getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE', 'LOGIN'); + $text = ($authtype === "LOGIN") ? $langs->trans("UsePassword") : ($authtype === "XOAUTH2" ? $langs->trans("UseOauth") : '') ; + print ''.$langs->trans("MAIN_MAIL_SMTPS_AUTH_TYPE").''.$text.''; + } + // SMTPS PW - if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) { + if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') != "XOAUTH2") { print ''.$langs->trans("MAIN_MAIL_SMTPS_PW").''.preg_replace('/./', '*', $conf->global->MAIN_MAIL_SMTPS_PW).''; } + // SMTPS oauth service + if (in_array(getDolGlobalString('MAIN_MAIL_SENDMODE'), array('smtps', 'swiftmailer')) && getDolGlobalString('MAIN_MAIL_SMTPS_AUTH_TYPE') === "XOAUTH2") { + $text = $oauthservices[$conf->global->MAIN_MAIL_SMTPS_OAUTH_SERVICE]; + if (empty($text)) { + $text = $langs->trans("Undefined").img_warning(); + } + print ''.$langs->trans("MAIN_MAIL_SMTPS_OAUTH_SERVICE").''.$text.''; + } + // TLS print ''.$langs->trans("MAIN_MAIL_EMAIL_TLS").''; if (isset($conf->global->MAIN_MAIL_SENDMODE) && in_array($conf->global->MAIN_MAIL_SENDMODE, array('smtps', 'swiftmailer'))) { diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index 8e31d0e6d62..db92c33a7fb 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -557,6 +557,7 @@ if (!empty($extrafields->attributes[$object->table_element]['computed']) && is_a // -------------------------------------------------------------------- $i = 0; $totalarray = array(); +$totalarray['nbfield'] = 0; while ($i < ($limit ? min($num, $limit) : $num)) { $obj = $db->fetch_object($resql); if (empty($obj)) { diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index 772055f0809..ade561c4ef1 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -62,7 +62,7 @@ if ($action == 'add') { // $provider is OAUTH_XXX setEventMessages($langs->trans("AOAuthEntryForThisProviderAndLabelAlreadyHasAKey"), null, 'errors'); $error++; } else { - dolibarr_set_const($db, $constname, 'ToComplete', 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, $constname, $langs->trans('ToComplete'), 'chaine', 0, '', $conf->entity); setEventMessages($langs->trans("OAuthProviderAdded"), null); } } @@ -78,6 +78,16 @@ if ($action == 'update') { if (!dolibarr_set_const($db, $constvalue.'_SECRET', GETPOST($constvalue.'_ID') ? GETPOST($constvalue.'_SECRET') : '', 'chaine', 0, '', $conf->entity)) { $error++; } + if (GETPOSTISSET($constvalue.'_URLAUTHORIZE')) { + if (!dolibarr_set_const($db, $constvalue.'_URLAUTHORIZE', GETPOST($constvalue.'_URLAUTHORIZE'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + } + if (GETPOSTISSET($constvalue.'_SCOPE')) { + if (!dolibarr_set_const($db, $constvalue.'_SCOPE', GETPOST($constvalue.'_SCOPE'), 'chaine', 0, '', $conf->entity)) { + $error++; + } + } } } @@ -147,11 +157,17 @@ print ''; $i = 0; -//var_dump($list); +// Define $listinsetup foreach ($conf->global as $key => $val) { if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { $provider = preg_replace('/_ID$/', '', $key); - $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider)); + $listinsetup[] = array( + $provider.'_NAME', + $provider.'_ID', + $provider.'_SECRET', + $provider.'_URLAUTHORIZE', // For custom oauth links + $provider.'_SCOPE' // For custom oauth links + ); } } @@ -178,12 +194,16 @@ foreach ($listinsetup as $key) { $i++; - print ''; // Api Name $label = $langs->trans($keyforsupportedoauth2array); + print ''; print ''; print ''; - print ''; + + if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') { + print ''; + print ''; + print ''; + } } else { print ''; print ''; @@ -213,14 +240,32 @@ foreach ($listinsetup as $key) { // Api Id print ''; print ''; - print ''; // Api Secret print ''; print ''; - print ''; + + // TODO Move this into token generation + if ($supported) { + if ($keyforsupportedoauth2array == 'OAUTH_OTHER_NAME') { + print ''; + print ''; + print ''; + } else { + print ''; + print ''; + print ''; + } + } } print '
'; print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); - print $label; + if ($label == $keyforsupportedoauth2array) { + print $supportedoauth2array[$keyforsupportedoauth2array]['name']; + } else { + print $label; + } if ($keyforprovider) { print ' ('.$keyforprovider.')'; } else { @@ -201,8 +221,15 @@ foreach ($listinsetup as $key) { $redirect_uri = $urlwithroot.'/core/modules/oauth/'.$supportedoauth2array[$keyforsupportedoauth2array]['callbackfile'].'_oauthcallback.php'; print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").''; + print ''; print '
'.$langs->trans("URLOfServiceForAuthorization").''; + print '
'.$langs->trans("UseTheFollowingUrlAsRedirectURI").'
'; + print ''; print '
'; + print ''; print '
'.$langs->trans("Scopes").''; + print ''; + print '
'.$langs->trans("Scopes").''; + //print ''; + print $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope']; + print '
'."\n"; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index b2830f95743..00daaf01e27 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -138,11 +138,17 @@ if (GETPOST('error')) { if ($mode == 'setup' && $user->admin) { print ''.$langs->trans("OAuthSetupForLogin")."

\n"; - //var_dump($list); + // Define $listinsetup foreach ($conf->global as $key => $val) { if (!empty($val) && preg_match('/^OAUTH_.*_ID$/', $key)) { $provider = preg_replace('/_ID$/', '', $key); - $listinsetup[] = array($provider.'_NAME', $provider.'_ID', $provider.'_SECRET', 'OAUTH Provider '.str_replace('OAUTH_', '', $provider)); + $listinsetup[] = array( + $provider.'_NAME', + $provider.'_ID', + $provider.'_SECRET', + $provider.'_URLAUTHORIZE', // For custom oauth links + $provider.'_SCOPE' // For custom oauth links + ); } } @@ -165,46 +171,39 @@ if ($mode == 'setup' && $user->admin) { $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); - // Define $shortscope, $urltorenew, $urltodelete, $urltocheckperms + $shortscope = $supportedoauth2array[$keyforsupportedoauth2array]['defaultscope']; + if (getDolGlobalString($key[4])) { + $shortscope = getDolGlobalString($key[4]); + } + $state = $shortscope; // TODO USe a better state + + // Define $urltorenew, $urltodelete, $urltocheckperms // TODO Use array $supportedoauth2array if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // We pass this param list in to 'state' because we need it before and after the redirect. - $shortscope = 'user,public_repo'; - // Note: github does not accept csrf key inside the state parameter (only know values) - $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + // Note: github does not accept csrf key inside the state parameter (only known values) + $urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.$shortscope.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://github.com/settings/applications/'; } elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') { // List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service). // List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes // We pass this key list into the param 'state' because we need it before and after the redirect. - $shortscope = 'userinfo_email,userinfo_profile'; - $shortscope .= ',openid,email,profile'; // For openid connect - if (!empty($conf->printing->enabled)) { - $shortscope .= ',cloud_print'; - } - if (!empty($conf->global->OAUTH_GOOGLE_GSUITE)) { - $shortscope .= ',admin_directory_user'; - } - if (!empty($conf->global->OAUTH_GOOGLE_GMAIL)) { - $shortscope.=',gmail_full'; - } - - $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.$shortscope.'&state='.$shortscope.'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms = 'https://security.google.com/settings/security/permissions'; } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_TEST_NAME') { - $shortscope = 'none'; - - $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/stripetest_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; } elseif ($keyforsupportedoauth2array == 'OAUTH_STRIPE_LIVE_NAME') { - $shortscope = 'none'; - - $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltorenew = $urlwithroot.'/core/modules/oauth/stripelive_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); + $urltodelete = ''; + $urltocheckperms = ''; + } elseif ($keyforsupportedoauth2array = 'OAUTH_OTHER_NAME') { + $urltorenew = $urlwithroot.'/core/modules/oauth/generic_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltodelete = ''; $urltocheckperms = ''; } else { @@ -212,7 +211,8 @@ if ($mode == 'setup' && $user->admin) { $urltodelete = ''; $urltocheckperms = ''; } - $urltorenew .= '&keyforprovider='.$keyforprovider; + + $urltorenew .= '&keyforprovider='.urlencode($keyforprovider); // Show value of token $tokenobj = null; @@ -246,7 +246,7 @@ if ($mode == 'setup' && $user->admin) { } elseif ($endoflife == $tokenobj::EOL_UNKNOWN) { $expiredat = $langs->trans("Unknown"); } else { - $expiredat = dol_print_date($endoflife, "dayhour"); + $expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel'); } } } @@ -260,10 +260,16 @@ if ($mode == 'setup' && $user->admin) { print '
'; print ''."\n"; + // Api Name + $label = $langs->trans($keyforsupportedoauth2array); print ''; print ''; +print ''; +print ''; +print ''; +print ''; + /* if (empty($conf->global->MAIN_APPLICATION_TITLE)) { $conf->global->MAIN_APPLICATION_TITLE = ""; diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index a23f3127ca8..2b25d7deb5a 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -643,7 +643,7 @@ print ''."\n"; print ''; print ''; print '"; print "\n"; diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index fae91d3ecb4..588cc5ed866 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -168,9 +168,10 @@ print ''; print ''; -print '
'; print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"'); - print $langs->trans($keyforsupportedoauth2array); + if ($label == $keyforsupportedoauth2array) { + print $supportedoauth2array[$keyforsupportedoauth2array]['name']; + } else { + print $label; + } if ($keyforprovider) { print ' ('.$keyforprovider.')'; } else { @@ -292,7 +298,8 @@ if ($mode == 'setup' && $user->admin) { print ''; print ''; if (is_object($tokenobj)) { - print $langs->trans("HasAccessToken"); + // TODO Read in database to get the date of creation of token + print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '); } else { print ''.$langs->trans("NoAccessToken").''; } @@ -305,7 +312,9 @@ if ($mode == 'setup' && $user->admin) { } // Request remote token if ($urltorenew) { - print ''.$langs->trans('RequestAccess').'
'; + print ''.$langs->trans('GetAccess').''; + print $form->textwithpicto('', $langs->trans('RequestAccess')); + print '
'; } // Check remote access if ($urltocheckperms) { @@ -378,8 +387,8 @@ if ($mode == 'setup' && $user->admin) { } } - print ''; + print '
'; } } diff --git a/htdocs/admin/security_other.php b/htdocs/admin/security_other.php index 79190725c16..090e2254541 100644 --- a/htdocs/admin/security_other.php +++ b/htdocs/admin/security_other.php @@ -61,14 +61,17 @@ if (preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) { dol_print_error($db); } } elseif ($action == 'updateform') { - $res1 = 1; $res2 = 1; + $res1 = 1; $res2 = 1; $res3 = 1; if (GETPOSTISSET('MAIN_APPLICATION_TITLE')) { $res1 = dolibarr_set_const($db, "MAIN_APPLICATION_TITLE", GETPOST("MAIN_APPLICATION_TITLE", 'alphanohtml'), 'chaine', 0, '', $conf->entity); } if (GETPOSTISSET('MAIN_SESSION_TIMEOUT')) { $res2 = dolibarr_set_const($db, "MAIN_SESSION_TIMEOUT", GETPOST("MAIN_SESSION_TIMEOUT", 'alphanohtml'), 'chaine', 0, '', $conf->entity); } - if ($res1 && $res2) { + if (GETPOSTISSET('MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT')) { + $res3 = dolibarr_set_const($db, "MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT", GETPOST("MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT", 'alphanohtml'), 'int', 0, '', $conf->entity); + } + if ($res1 && $res2 && $res3) { setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); } } @@ -174,6 +177,14 @@ print ''; print '
'.$langs->trans("MaxNumberOfImagesInGetPost").''; +print ''; +print ' '.strtolower($langs->trans("Images")); +print '
'.$langs->trans("MainDefaultWarehouse").''; -print $formproduct->selectWarehouses($conf->global->MAIN_DEFAULT_WAREHOUSE, 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition'); +print $formproduct->selectWarehouses(!empty($conf->global->MAIN_DEFAULT_WAREHOUSE) ? $conf->global->MAIN_DEFAULT_WAREHOUSE : -1, 'default_warehouse', '', 1, 0, 0, '', 0, 0, array(), 'left reposition'); print ''; print "
'; print $langs->trans("DatabaseName").' : '.$dolibarr_main_db_name.'
'; print '
'; +print '
'; print ''; + print ''; print ''; -print ''; -print ''; +print ''; +print '
'; @@ -195,27 +196,31 @@ print ''; print ''; print ''; +print '
'; + +print ''; print ''; print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -597,7 +598,8 @@ if ($type == Categorie::TYPE_CUSTOMER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddThirdParty"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/societe/card.php?action=create&client=3&custcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); print_barre_liste($langs->trans("Customers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'companies', 0, $newcardbutton, '', $limit); print ''."\n"; @@ -618,7 +620,7 @@ if ($type == Categorie::TYPE_CUSTOMER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -671,7 +673,8 @@ if ($type == Categorie::TYPE_SUPPLIER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($socs); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddSupplier"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/societe/card.php?action=create&fournisseur=1&suppcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); print_barre_liste($langs->trans("Suppliers"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'companies', 0, $newcardbutton, '', $limit); print ''."\n"; @@ -692,7 +695,7 @@ if ($type == Categorie::TYPE_SUPPLIER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -748,7 +751,8 @@ if ($type == Categorie::TYPE_MEMBER) { print ''; print '
'; - $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; $newcardbutton = ''; + $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($prods); $nbtotalofrecords = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddMember"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/adherents/card.php?action=create&memcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->adherent->creer); print_barre_liste($langs->trans("Member"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'members', 0, $newcardbutton, '', $limit); print "\n"; @@ -772,7 +776,7 @@ if ($type == Categorie::TYPE_MEMBER) { // Link to delete from category print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -788,7 +792,7 @@ if ($type == Categorie::TYPE_MEMBER) { } } -// Categorie contact +// List of contacts if ($type == Categorie::TYPE_CONTACT) { $permission = $user->rights->societe->creer; @@ -808,7 +812,7 @@ if ($type == Categorie::TYPE_CONTACT) { print ''; print ''; print ''; print ''; @@ -826,7 +830,7 @@ if ($type == Categorie::TYPE_CONTACT) { $param = '&limit='.$limit.'&id='.$id.'&type='.$type; $num = count($contacts); $nbtotalofrecords = ''; - $newcardbutton = ''; + $newcardbutton = dolGetButtonTitle($langs->trans("AddContact"), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/contact/card.php?action=create&contcats[]='.$object->id.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id), '', $user->rights->societe->creer); $objsoc = new Societe($db); print_barre_liste($langs->trans("Contact"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contact', 0, $newcardbutton, '', $limit); @@ -853,7 +857,7 @@ if ($type == Categorie::TYPE_CONTACT) { // Link to delete from category print '
'; - print $langs->trans("AddContactIntoCategory").'  '; + print $langs->trans("AssignCategoryTo").'  '; print $form->selectContacts('', '', 'elemid'); print '
'; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -931,7 +935,7 @@ if ($type == Categorie::TYPE_ACCOUNT) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1009,7 +1013,7 @@ if ($type == Categorie::TYPE_PROJECT) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1026,7 +1030,7 @@ if ($type == Categorie::TYPE_PROJECT) { } // List of users -if ($type == Categorie::TYPE_USER) { +if ($type == Categorie::TYPE_USER && $user->hasRight("user", "user", "read")) { require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; $users = $object->getObjectsInCateg($type); @@ -1081,7 +1085,7 @@ if ($type == Categorie::TYPE_USER) { // Link to delete from category print ''; if ($user->rights->user->user->creer) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1095,6 +1099,9 @@ if ($type == Categorie::TYPE_USER) { print ''."\n"; } +} else { + print_barre_liste($langs->trans("Users"), null, $_SERVER["PHP_SELF"], '', '', '', '', '', '', 'user'); + accessforbidden($langs->trans("NotEnoughPermissions"), 0, 0); } @@ -1140,7 +1147,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; @@ -1156,6 +1163,7 @@ if ($type == Categorie::TYPE_WAREHOUSE) { } } +// List of tickets if ($type == Categorie::TYPE_TICKET) { $permission = ($user->rights->categorie->creer || $user->rights->categorie->creer); @@ -1212,7 +1220,7 @@ if ($type == Categorie::TYPE_TICKET) { // Link to delete from category print ''; if ($permission) { - print ""; + print "id."'>"; print $langs->trans("DeleteFromCat"); print img_picto($langs->trans("DeleteFromCat"), 'unlink', '', false, 0, 0, '', 'paddingleft'); print ""; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index ed25d89db67..6f97b3f134d 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -538,7 +538,7 @@ if (empty($reshook) && $action == 'add') { $error++; } // End date - $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth", 'int') ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser'); + $repeateventlimitdate = dol_mktime('23', '59', '59', GETPOSTISSET("limitmonth") ? GETPOST("limitmonth", 'int') : 01, GETPOSTISSET("limitday", 'int') ? GETPOST("limitday", 'int') : 01, GETPOSTISSET("limityear", 'int') && GETPOST("limityear", 'int') < 2100 ? GETPOST("limityear", 'int') : 2100, $tzforfullday ? $tzforfullday : 'tzuser'); // Set date of end of event $deltatime = num_between_day($object->datep, $datep); $datef = dol_time_plus_duree($datef, $deltatime, 'd'); diff --git a/htdocs/comm/action/class/cactioncomm.class.php b/htdocs/comm/action/class/cactioncomm.class.php index d2b089491a7..db62dfe6a9f 100644 --- a/htdocs/comm/action/class/cactioncomm.class.php +++ b/htdocs/comm/action/class/cactioncomm.class.php @@ -216,6 +216,9 @@ class CActionComm if ($obj->module == 'shipping' && !empty($conf->expedition->enabled) && !empty($user->rights->expedition->lire)) { $qualified = 1; } + if (preg_split("/@/", $obj->module, -1)[1] == 'eventorganization' && !empty($conf->eventorganization->enabled)) { + $qualified = 1; + } // For the generic case with type = 'module...' and module = 'myobject@mymodule' $regs = array(); if (preg_match('/^module/', $obj->type)) { diff --git a/htdocs/comm/multiprix.php b/htdocs/comm/multiprix.php index 8da9a17ebb2..0e582946df9 100644 --- a/htdocs/comm/multiprix.php +++ b/htdocs/comm/multiprix.php @@ -75,7 +75,7 @@ if ($_socid > 0) { // We load data of thirdparty $objsoc = new Societe($db); $objsoc->id = $_socid; - $objsoc->fetch($_socid, $to); + $objsoc->fetch($_socid); $head = societe_prepare_head($objsoc); @@ -141,7 +141,6 @@ if ($_socid > 0) { $resql = $db->query($sql); if ($resql) { print ''; - $tag = !$tag; print ''; print ''; print ''; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 06c36ce517c..31e318f0c39 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -112,17 +112,17 @@ if ($id > 0 || !empty($ref)) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('propalcard', 'globalcard')); -$usercanread = $user->rights->propal->lire; -$usercancreate = $user->rights->propal->creer; -$usercandelete = $user->rights->propal->supprimer; +$usercanread = $user->hasRight("propal", "lire"); +$usercancreate = $user->hasRight("propal", "creer"); +$usercandelete = $user->hasRight("propal", "supprimer"); $usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->close))); $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->send))); -$usercancreateorder = $user->rights->commande->creer; -$usercancreateinvoice = $user->rights->facture->creer; -$usercancreatecontract = $user->rights->contrat->creer; +$usercancreateorder = $user->hasRight('commande', 'creer'); +$usercancreateinvoice = $user->hasRight('facture', 'creer'); +$usercancreatecontract = $user->hasRight('contrat', 'creer'); $usercancreateintervention = $user->hasRight('ficheinter', 'creer'); $usercancreatepurchaseorder = ($user->hasRight('fournisseur', 'commande', 'creer') || $user->hasRight('supplier_order', 'creer')); diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index aa26e7be794..43c49bdc8a2 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -108,9 +108,9 @@ $extrafields->fetch_name_optionals_label($object->table_element); // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once -$usercanread = $user->hasRight('commande', 'lire'); -$usercancreate = $user->hasRight('commande', 'creer'); -$usercandelete = $user->hasRight('commande', 'supprimer'); +$usercanread = $user->hasRight("commande", "lire"); +$usercancreate = $user->hasRight("commande", "creer"); +$usercandelete = $user->hasRight("commande", "supprimer"); // Advanced permissions $usercanclose = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($usercancreate)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->hasRight('commande', 'order_advance', 'close')))); diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 2751947c023..3dfe18a3581 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -846,6 +846,9 @@ if ($action == 'create') { $object = new Account($db); $object->fetch(GETPOST('id', 'int')); + $title = $object->ref." - ".$langs->trans("Card"); + llxHeader("", $title, $help_url); + print load_fiche_titre($langs->trans("EditFinancialAccount"), '', 'bank_account'); if ($conf->use_javascript_ajax) { @@ -1014,7 +1017,7 @@ if ($action == 'create') { $tdextra = ' class="fieldrequired titlefieldcreate"'; } - print ''.$langs->trans("AccountancyCode").''; + print ''.$langs->trans("AccountancyCode").''; print ''; + print ''; } // Alias if (!empty($arrayfields['s.name_alias']['checked'])) { @@ -2083,7 +2084,7 @@ if ($resql) { // Amount HT if (!empty($arrayfields['f.total_ht']['checked'])) { - print '\n"; + print '\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/compta/index.php b/htdocs/compta/index.php index e7cb0b1d4b5..55ee99f4cb6 100644 --- a/htdocs/compta/index.php +++ b/htdocs/compta/index.php @@ -102,19 +102,24 @@ print load_fiche_titre($langs->trans("AccountancyTreasuryArea"), '', 'bill'); print '
'; -print getNumberInvoicesPieChart('customers'); -print '
'; +if (isModEnabled('facture')) { + print getNumberInvoicesPieChart('customers'); + print '
'; +} -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getNumberInvoicesPieChart('fourn'); print '
'; } -print getCustomerInvoiceDraftTable($max, $socid); - -if (!empty($conf->fournisseur->enabled)) { +if (isModEnabled('facture')) { + print getCustomerInvoiceDraftTable($max, $socid); print '
'; +} + +if (isModEnabled('fournisseur') || isModEnabled('supplier_invoice')) { print getDraftSupplierTable($max, $socid); + print '
'; } print '
'; @@ -273,7 +278,7 @@ if (isModEnabled('facture') && !empty($user->rights->facture->lire)) { // Last modified supplier invoices -if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) { +if ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) { $langs->load("boxes"); $facstatic = new FactureFournisseur($db); @@ -400,7 +405,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU // Latest donations -if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { +if (isModEnabled('don') && !empty($user->rights->don->lire)) { include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; $langs->load("boxes"); @@ -490,7 +495,7 @@ if (!empty($conf->don->enabled) && !empty($user->rights->don->lire)) { /** * Social contributions to pay */ -if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { +if (isModEnabled('tax') && !empty($user->rights->tax->charges->lire)) { if (!$socid) { $chargestatic = new ChargeSociales($db); @@ -582,7 +587,7 @@ if (!empty($conf->tax->enabled) && !empty($user->rights->tax->charges->lire)) { /* * Customers orders to be billed */ -if (isModEnabled('facture') && !empty($conf->commande->enabled) && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { +if (isModEnabled('facture') && isModEnabled('commande') && $user->rights->commande->lire && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { $commandestatic = new Commande($db); $langs->load("orders"); diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index 8c859e6e689..f41ecd820ad 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -59,8 +59,15 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $offset = $limit * $page; $upload_dir = $conf->bank->multidir_output[$object->entity ? $object->entity : $conf->entity]."/checkdeposits"; - -$filterdate = dol_mktime(0, 0, 0, GETPOST('fdmonth'), GETPOST('fdday'), GETPOST('fdyear')); +// filter by dates from / to +$search_date_start_day = GETPOST('search_date_start_day', 'int'); +$search_date_start_month = GETPOST('search_date_start_month', 'int'); +$search_date_start_year = GETPOST('search_date_start_year', 'int'); +$search_date_end_day = GETPOST('search_date_end_day', 'int'); +$search_date_end_month = GETPOST('search_date_end_month', 'int'); +$search_date_end_year = GETPOST('search_date_end_year', 'int'); +$search_date_start = dol_mktime(0, 0, 0, $search_date_start_month, $search_date_start_day, $search_date_start_year); +$search_date_end = dol_mktime(23, 59, 59, $search_date_end_month, $search_date_end_day, $search_date_end_year); $filteraccountid = GETPOST('accountid', 'int'); // Security check @@ -265,7 +272,15 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) { */ if (GETPOST('removefilter')) { - $filterdate = ''; + // filter by dates from / to + $search_date_start_day = ''; + $search_date_start_month = ''; + $search_date_start_year = ''; + $search_date_end_day = ''; + $search_date_end_month = ''; + $search_date_end_year = ''; + $search_date_start = ''; + $search_date_end = ''; $filteraccountid = 0; } @@ -352,7 +367,13 @@ if ($action == 'new') { //print '
'; // Filter print ''; print ''; // Group @@ -324,12 +324,12 @@ class FormTicket if ($public) { $filter = 'public=1'; } - $this->selectGroupTickets((GETPOST('category_code') ? GETPOST('category_code') : $this->category_code), 'category_code', $filter, 2, 0, 0, 0, 'minwidth200'); + $this->selectGroupTickets((GETPOST('category_code') ? GETPOST('category_code') : $this->category_code), 'category_code', $filter, 2, 1, 0, 0, 'minwidth200'); print ''; // Severity print ''; // Subject @@ -341,10 +341,12 @@ class FormTicket print $langs->trans('SubjectAnswerToTicket').' '.$this->topic_title; print ''; } else { - if ($this->withreadid > 0) { + if (isset($this->withreadid) && $this->withreadid > 0) { $subject = $langs->trans('SubjectAnswerToTicket').' '.$this->withreadid.' : '.$this->topic_title.''; + } else { + $subject = GETPOST('subject', 'alpha'); } - print ''; + print ''; print ''; } } @@ -643,7 +645,7 @@ class FormTicket print '
'; - print $form->buttonsSaveCancel((($this->withreadid > 0) ? "SendResponse" : "CreateTicket"), ($this->withcancel ? "Cancel" : "")); + print $form->buttonsSaveCancel(((isset($this->withreadid) && $this->withreadid > 0) ? "SendResponse" : "CreateTicket"), ($this->withcancel ? "Cancel" : "")); /* print '
'; @@ -733,6 +735,7 @@ class FormTicket } print '>'; + $value = ' '; if ($format == 0) { $value = ($maxlength ? dol_trunc($arraytypes['label'], $maxlength) : $arraytypes['label']); @@ -744,7 +747,7 @@ class FormTicket $value = $arraytypes['code']; } - print $value; + print $value ? $value : ' '; print ''; } } @@ -839,6 +842,7 @@ class FormTicket print '>'; + $value = ''; if ($format == 0) { $value = ($maxlength ? dol_trunc($label, $maxlength) : $label); } @@ -1172,6 +1176,8 @@ class FormTicket } print '>'; + + $value = ''; if ($format == 0) { $value = ($maxlength ? dol_trunc($arrayseverities['label'], $maxlength) : $arrayseverities['label']); } diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 1f5a48a517d..06ada5c4911 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -68,6 +68,11 @@ class SMTPs */ private $_smtpsPW = null; + /** + * Token in case we use OAUTH2 + */ + private $_smtpsToken = null; + /** * Who sent the Message * This can be defined via a INI file or via a setter method @@ -565,13 +570,13 @@ class SMTPs } // Default authentication method is LOGIN - if (empty($conf->global->MAIL_SMTP_AUTH_TYPE)) { - $conf->global->MAIL_SMTP_AUTH_TYPE = 'LOGIN'; + if (empty($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE)) { + $conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE = 'LOGIN'; } // Send Authentication to Server // Check for errors along the way - switch ($conf->global->MAIL_SMTP_AUTH_TYPE) { + switch ($conf->global->MAIN_MAIL_SMTPS_AUTH_TYPE) { case 'NONE': // Do not send the 'AUTH type' message. For test purpose, if you don't need authentication, it is better to not enter login/pass into setup. $_retVal = true; @@ -583,9 +588,10 @@ class SMTPs break; case 'XOAUTH2': // "user=$email\1auth=Bearer $token\1\1" - $token = 'xxx'; - $xxxx = "user=".$this->_smtpsID."\1auth=Bearer ".$token."\1\1"; - $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($xxxx), '235'); + $user = $this->_smtpsID; + $token = $this->_smtpsToken; + $initRes = "user=".$user."\001auth=Bearer ".$token."\001\001"; + $_retVal = $this->socket_send_str('AUTH XOAUTH2 '.base64_encode($initRes), '235'); if (!$_retVal) { $this->_setErr(130, 'Error when asking for AUTH XOAUTH2'); } @@ -631,7 +637,7 @@ class SMTPs // Connect to Server if ($this->socket = $this->_server_connect()) { // If a User ID *and* a password is given, assume Authentication is desired - if (!empty($this->_smtpsID) && !empty($this->_smtpsPW)) { + if (!empty($this->_smtpsID) && (!empty($this->_smtpsPW) || !empty($this->_smtpsToken))) { // Send the RFC2554 specified EHLO. $_retVal = $this->_server_authenticate(); } else { @@ -923,6 +929,27 @@ class SMTPs return $this->_smtpsPW; } + /** + * User token for OAUTH2 + * + * @param string $_strToken User token + * @return void + */ + public function setToken($_strToken) + { + $this->_smtpsToken = $_strToken; + } + + /** + * Retrieves the User token for OAUTH2 + * + * @return string User token for OAUTH2 + */ + public function getToken() + { + return $this->_smtpsToken; + } + /** * Character set used for current message * Character set is defaulted to 'iso-8859-1'; @@ -1866,7 +1893,7 @@ class SMTPs } if (!(substr($server_response, 0, 3) == $response)) { - $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: $server_response"); + $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse:".$server_response); $_retVal = false; } diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index c11f94fa047..29db15e0a0b 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -637,7 +637,11 @@ class Translate ); if (strpos($key, 'Format') !== 0) { - $str = sprintf($str, $param1, $param2, $param3, $param4); // Replace %s and %d except for FormatXXX strings. + try { + $str = sprintf($str, $param1, $param2, $param3, $param4); // Replace %s and %d except for FormatXXX strings. + } catch (Exception $e) { + // No exception managed + } } // Crypt string into HTML diff --git a/htdocs/core/class/utils_diff.class.php b/htdocs/core/class/utils_diff.class.php index 9abc1d899fe..2925bffc3b6 100644 --- a/htdocs/core/class/utils_diff.class.php +++ b/htdocs/core/class/utils_diff.class.php @@ -247,6 +247,7 @@ class Diff $html = ''; // loop over the lines in the diff + $element = 'unknown'; foreach ($diff as $line) { // extend the HTML with the line switch ($line[1]) { @@ -260,10 +261,7 @@ class Diff $element = 'ins'; break; } - $html .= - '<'.$element.'>' - . htmlspecialchars($line[0]) - . ''; + $html .= '<'.$element.'>'.dol_escape_htmltag($line[0]).''; // extend the HTML with the separator $html .= $separator; @@ -286,6 +284,8 @@ class Diff // initialise the HTML $html = $indentation."
'.$langs->trans("Date").''.$langs->trans("PriceLevel").'
'; if (!empty($conf->accounting->enabled)) { print $formaccounting->select_account($object->account_number, 'account_number', 1, '', 1, 1); diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 2dbaaa07373..c08336841e2 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -387,6 +387,10 @@ if (empty($numref)) { * Show list of record into a bank statement */ + $title = $langs->trans("FinancialAccount").' - '.$langs->trans("AccountStatements"); + $helpurl = ""; + llxHeader('', $title, $helpurl); + // Onglets $head = account_statement_prepare_head($object, $numref); print dol_get_fiche_head($head, 'statement', $langs->trans("AccountStatement"), -1, 'account'); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 59345604d1d..61b0c4b6302 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -128,11 +128,11 @@ if ($id > 0 || !empty($ref)) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('invoicecard', 'globalcard')); -$usercanread = $user->rights->facture->lire; -$usercancreate = $user->rights->facture->creer; -$usercanissuepayment = $user->rights->facture->paiement; -$usercandelete = $user->rights->facture->supprimer; -$usercancreatecontract = $user->rights->contrat->creer; +$usercanread = $user->hasRight("facture", "lire"); +$usercancreate = $user->hasRight("facture", "creer"); +$usercanissuepayment = $user->hasRight("facture", "paiement"); +$usercandelete = $user->hasRight("facture", "supprimer"); +$usercancreatecontract = $user->hasRight("contrat", "creer"); $usercanvalidate = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->validate))); $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->send))); $usercanreopen = ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && $usercancreate) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->facture->invoice_advance->reopen))); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index bdc6a102147..23f53c3d405 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -363,11 +363,11 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $search_datelimit_start = ''; $search_datelimit_end = ''; $search_fac_rec_source_title = ''; - $option = ''; - $filter = ''; $toselect = array(); $search_array_options = array(); $search_categ_cus = 0; + $option = ''; + $socid = 0; } if (empty($reshook)) { @@ -919,7 +919,7 @@ if ($resql) { llxHeader('', $langs->trans('CustomersInvoices'), 'EN:Customers_Invoices|FR:Factures_Clients|ES:Facturas_a_clientes'); - if ($socid) { + if ($socid > 0) { $soc = new Societe($db); $soc->fetch($socid); if (empty($search_company)) { @@ -1151,8 +1151,9 @@ if ($resql) { print ''; print ''; print ''; + print ''; - print_barre_liste($langs->trans('BillsCustomers').' '.($socid ? ' '.$soc->name : ''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); + print_barre_liste($langs->trans('BillsCustomers').' '.($socid > 0 ? ' '.$soc->name : ''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bill', 0, $newcardbutton, '', $limit, 0, 0, 1); $topicmail = "SendBillRef"; $modelmail = "facture_send"; @@ -1329,7 +1330,7 @@ if ($resql) { } // Thirdparty if (!empty($arrayfields['s.nom']['checked'])) { - print ' 0 ? " disabled" : "").'>'.price($obj->total_ht)."'.price($obj->total_ht)."
'.$langs->trans('Date').''.dol_print_date($now,'day').'
'.$langs->trans("DateChequeReceived").''; - print $form->selectDate($filterdate, 'fd', 0, 0, 1, '', 1, 1); + // filter by dates from / to + print '
'; + print $form->selectDate($search_date_start, 'search_date_start_', 0, 0, 1, '', 1, 1, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
'; + print '
'; + print $form->selectDate($search_date_end, 'search_date_end_', 0, 0, 1, '', 1, 1, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
'; print '
'.$langs->trans("BankAccount").''; $form->select_comptes($filteraccountid, 'accountid', 0, 'courant <> 2', 1); @@ -363,7 +384,7 @@ if ($action == 'new') { print '
'; print ''; - if ($filterdate || $filteraccountid > 0) { + if ($search_date_start || $search_date_end || $filteraccountid > 0) { print '   '; print ''; } @@ -382,8 +403,11 @@ if ($action == 'new') { $sql .= " AND ba.entity IN (".getEntity('bank_account').")"; $sql .= " AND b.fk_bordereau = 0"; $sql .= " AND b.amount > 0"; - if ($filterdate) { - $sql .= " AND b.dateo = '".$db->idate($filterdate)."'"; + if ($search_date_start) { + $sql .= " AND b.dateo >= '".$db->idate($search_date_start)."'"; + } + if ($search_date_end) { + $sql .= " AND b.dateo <= '".$db->idate($search_date_end)."'"; } if ($filteraccountid > 0) { $sql .= " AND ba.rowid = ".((int) $filteraccountid); diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example index 487576ed058..b58ac33707e 100644 --- a/htdocs/conf/conf.php.example +++ b/htdocs/conf/conf.php.example @@ -185,7 +185,7 @@ $dolibarr_main_instance_unique_id='84b5bc91f83b56e458db71e0adac2b62'; // values using a ",". In this case, Dolibarr will check login/pass for each value in // order defined into value. However, note that this can't work with all values. // Examples: -// $dolibarr_main_authentication='dolibarr'; // Use the password defined into application on user record. +// $dolibarr_main_authentication='dolibarr'; // Use the password defined into application on user file (default). // $dolibarr_main_authentication='http'; // Use the HTTP Basic authentication // $dolibarr_main_authentication='ldap'; // Check the password into a LDAP server // $dolibarr_main_authentication='ldap,dolibarr'; // You can set several mode using a comma as a separator. diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 8d60b37611f..a0091061adb 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -207,16 +207,16 @@ foreach ($object->fields as $key => $val) { } // Add none object fields to fields for list -$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>22, 'checked'=>0); +$arrayfields['country.code_iso'] = array('label'=>"Country", 'position'=>66, 'checked'=>0); if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) { - $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>25, 'checked'=>1); + $arrayfields['s.nom'] = array('label'=>"ThirdParty", 'position'=>113, 'checked'=> 1); } $arrayfields['unsubscribed'] = array( 'label'=>'No_Email', 'checked'=>0, 'enabled'=>(!empty($conf->mailing->enabled)), - 'position'=>41); + 'position'=>111); if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index f0ef66eb78b..3749b403469 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -361,7 +361,7 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } $mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1, '', '', $trackid, '', $sendcontext); - if ($mailfile->error) { + if (!empty($mailfile->error) || !empty($mailfile->errors)) { setEventMessages($mailfile->error, $mailfile->errors, 'errors'); $action = 'presend'; } else { @@ -427,9 +427,14 @@ if (($action == 'send' || $action == 'relance') && !GETPOST('addfile') && !GETPO } else { $langs->load("other"); $mesg = '
'; - if ($mailfile->error) { + if (!empty($mailfile->error) || !empty($mailfile->errors)) { $mesg .= $langs->transnoentities('ErrorFailedToSendMail', dol_escape_htmltag($from), dol_escape_htmltag($sendto)); - $mesg .= '
'.$mailfile->error; + if (!empty($mailfile->error)) { + $mesg .= '
'.$mailfile->error; + } + if (!empty($mailfile->errors) && is_array($mailfile->errors)) { + $mesg .= '
'.implode('
', $mailfile->errors); + } } else { $mesg .= $langs->transnoentities('ErrorFailedToSendMail', dol_escape_htmltag($from), dol_escape_htmltag($sendto)); if (!empty($conf->global->MAIN_DISABLE_ALL_MAILS)) { diff --git a/htdocs/core/ajax/selectsearchbox.php b/htdocs/core/ajax/selectsearchbox.php index 090fc52cb4f..54e3e1e4470 100644 --- a/htdocs/core/ajax/selectsearchbox.php +++ b/htdocs/core/ajax/selectsearchbox.php @@ -64,11 +64,11 @@ $arrayresult = array(); // Define $searchform -if (isModEnabled('adherent') && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->rights->adherent->lire) { +if (isModEnabled('adherent') && empty($conf->global->MAIN_SEARCHFORM_ADHERENT_DISABLED) && $user->hasRight('adherent', 'lire')) { $arrayresult['searchintomember'] = array('position'=>8, 'shortcut'=>'M', 'img'=>'object_member', 'label'=>$langs->trans("SearchIntoMembers", $search_boxvalue), 'text'=>img_picto('', 'object_member', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoMembers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/adherents/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))) && empty($conf->global->MAIN_SEARCHFORM_SOCIETE_DISABLED) && $user->rights->societe->lire) { +if (((isModEnabled('societe') && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || isModEnabled('supplier_order') || isModEnabled('supplier_invoice'))) && empty($conf->global->MAIN_SEARCHFORM_SOCIETE_DISABLED) && $user->hasRight('societe', 'lire')) { $arrayresult['searchintothirdparty'] = array('position'=>10, 'shortcut'=>'T', 'img'=>'object_company', 'label'=>$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'text'=>img_picto('', 'object_company', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoThirdparties", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/societe/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } @@ -76,7 +76,7 @@ if (isModEnabled('societe') && empty($conf->global->MAIN_SEARCHFORM_CONTACT_DISA $arrayresult['searchintocontact'] = array('position'=>15, 'shortcut'=>'A', 'img'=>'object_contact', 'label'=>$langs->trans("SearchIntoContacts", $search_boxvalue), 'text'=>img_picto('', 'object_contact', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContacts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contact/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->product->enabled) && $user->hasRight('produit', 'lire')) || (!empty($conf->service->enabled) && $user->hasRight('service', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { +if (((isModEnabled('product') && $user->hasRight('produit', 'lire')) || (isModEnabled('service') && $user->hasRight('service', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_PRODUITSERVICE_DISABLED)) { $arrayresult['searchintoproduct'] = array('position'=>30, 'shortcut'=>'P', 'img'=>'object_product', 'label'=>$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'text'=>img_picto('', 'object_product', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoProductsOrServices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/product/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); // search on lot/serial numbers if (isModEnabled('productbatch')) { @@ -108,13 +108,13 @@ if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INV $arrayresult['searchintoinvoice'] = array('position'=>90, 'img'=>'object_bill', 'label'=>$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_bill', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoCustomerInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/compta/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->rights->supplier_proposal->lire) { +if (isModEnabled('supplier_proposal') && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_PROPAL_DISABLED) && $user->hasRight('supplier_proposal', 'lire')) { $arrayresult['searchintosupplierpropal'] = array('position'=>100, 'img'=>'object_supplier_proposal', 'label'=>$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_proposal', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierProposals", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/supplier_proposal/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (!empty($conf->supplier_order->enabled) && $user->rights->supplier_order->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'commande', 'lire')) || (isModEnabled('supplier_order') && $user->hasRight('supplier_order', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_ORDER_DISABLED)) { $arrayresult['searchintosupplierorder'] = array('position'=>110, 'img'=>'object_supplier_order', 'label'=>$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_order', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierOrders", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/commande/list.php'.($search_boxvalue ? '?search_all='.urlencode($search_boxvalue) : '')); } -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled('supplier_invoice') && $user->hasRight('supplier_invoice', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { $arrayresult['searchintosupplierinvoice'] = array('position'=>120, 'img'=>'object_supplier_invoice', 'label'=>$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'text'=>img_picto('', 'object_supplier_invoice', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoSupplierInvoices", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fourn/facture/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } @@ -129,7 +129,7 @@ if (isModEnabled('facture') && empty($conf->global->MAIN_SEARCHFORM_CUSTOMER_INV } // Vendor payments -if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (!empty($conf->supplier_invoice->enabled) && $user->rights->supplier_invoice->lire)) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { +if (((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight('fournisseur', 'facture', 'lire')) || (isModEnabled('supplier_invoice') && $user->hasRight('supplier_invoice', 'lire'))) && empty($conf->global->MAIN_SEARCHFORM_SUPPLIER_INVOICE_DISABLED)) { $arrayresult['searchintovendorpayments'] = array( 'position'=>175, 'img'=>'object_payment', @@ -139,7 +139,7 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S } // Miscellaneous payments -if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->rights->banque->lire) { +if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS_DISABLED) && $user->hasRight('banque', 'lire')) { $arrayresult['searchintomiscpayments'] = array( 'position'=>180, 'img'=>'object_payment', @@ -148,24 +148,24 @@ if (isModEnabled('banque') && empty($conf->global->MAIN_SEARCHFORM_MISC_PAYMENTS 'url'=>DOL_URL_ROOT.'/compta/bank/various_payment/list.php?leftmenu=tax_various'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('contrat') && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->rights->contrat->lire) { +if (isModEnabled('contrat') && empty($conf->global->MAIN_SEARCHFORM_CONTRACT_DISABLED) && $user->hasRight('contrat', 'lire')) { $arrayresult['searchintocontract'] = array('position'=>130, 'img'=>'object_contract', 'label'=>$langs->trans("SearchIntoContracts", $search_boxvalue), 'text'=>img_picto('', 'object_contract', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoContracts", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/contrat/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('ficheinter') && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->rights->ficheinter->lire) { +if (isModEnabled('ficheinter') && empty($conf->global->MAIN_SEARCHFORM_FICHINTER_DISABLED) && $user->hasRight('ficheinter', 'lire')) { $arrayresult['searchintointervention'] = array('position'=>140, 'img'=>'object_intervention', 'label'=>$langs->trans("SearchIntoInterventions", $search_boxvalue), 'text'=>img_picto('', 'object_intervention', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoInterventions", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/fichinter/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('ticket') && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->rights->ticket->read) { +if (isModEnabled('ticket') && empty($conf->global->MAIN_SEARCHFORM_TICKET_DISABLED) && $user->hasRight('ticket', 'read')) { $arrayresult['searchintotickets'] = array('position'=>145, 'img'=>'object_ticket', 'label'=>$langs->trans("SearchIntoTickets", $search_boxvalue), 'text'=>img_picto('', 'object_ticket', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoTickets", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/ticket/list.php?mainmenu=ticket'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } // HR -if (isModEnabled('user') && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->rights->user->user->lire) { +if (isModEnabled('user') && empty($conf->global->MAIN_SEARCHFORM_USER_DISABLED) && $user->hasRight('user', 'user', 'lire')) { $arrayresult['searchintouser'] = array('position'=>200, 'shortcut'=>'U', 'img'=>'object_user', 'label'=>$langs->trans("SearchIntoUsers", $search_boxvalue), 'text'=>img_picto('', 'object_user', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoUsers", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/user/list.php'.($search_boxvalue ? '?sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('expensereport') && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->rights->expensereport->lire) { +if (isModEnabled('expensereport') && empty($conf->global->MAIN_SEARCHFORM_EXPENSEREPORT_DISABLED) && $user->hasRight('expensereport', 'lire')) { $arrayresult['searchintoexpensereport'] = array('position'=>210, 'img'=>'object_trip', 'label'=>$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'text'=>img_picto('', 'object_trip', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoExpenseReports", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } -if (isModEnabled('holiday') && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->rights->holiday->read) { +if (isModEnabled('holiday') && empty($conf->global->MAIN_SEARCHFORM_HOLIDAY_DISABLED) && $user->hasRight('holiday', 'read')) { $arrayresult['searchintoleaves'] = array('position'=>220, 'img'=>'object_holiday', 'label'=>$langs->trans("SearchIntoLeaves", $search_boxvalue), 'text'=>img_picto('', 'object_holiday', 'class="pictofixedwidth"').' '.$langs->trans("SearchIntoLeaves", $search_boxvalue), 'url'=>DOL_URL_ROOT.'/holiday/list.php?mainmenu=hrm'.($search_boxvalue ? '&sall='.urlencode($search_boxvalue) : '')); } diff --git a/htdocs/core/boxes/box_birthdays.php b/htdocs/core/boxes/box_birthdays.php index 9462c810393..6aec6f4064a 100644 --- a/htdocs/core/boxes/box_birthdays.php +++ b/htdocs/core/boxes/box_birthdays.php @@ -85,13 +85,19 @@ class box_birthdays extends ModeleBoxes if ($user->rights->user->user->lire) { $tmparray = dol_getdate(dol_now(), true); - $sql = "SELECT u.rowid, u.firstname, u.lastname, u.birth, u.email, u.statut as status"; + $sql = "SELECT u.rowid, u.firstname, u.lastname, u.birth as datea, 'birth' as typea, u.email, u.statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE u.entity IN (".getEntity('user').")"; $sql .= " AND u.statut = 1"; $sql .= dolSqlDateFilter('u.birth', 0, $tmparray['mon'], 0); - $sql .= " ORDER BY DAY(u.birth) ASC"; - $sql .= $this->db->plimit($max, 0); + $sql .= ' UNION '; + $sql .= "SELECT u.rowid, u.firstname, u.lastname, u.dateemployment as datea, 'employment' as typea, u.email, u.statut as status"; + $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; + $sql .= " WHERE u.entity IN (".getEntity('user').")"; + $sql .= " AND u.statut = 1"; + $sql .= dolSqlDateFilter('u.dateemployment', 0, $tmparray['mon'], 0); + + $sql .= " ORDER BY DAY(datea) ASC"; dol_syslog(get_class($this)."::loadBox", LOG_DEBUG); $result = $this->db->query($sql); @@ -108,9 +114,13 @@ class box_birthdays extends ModeleBoxes $userstatic->email = $objp->email; $userstatic->statut = $objp->status; - $dateb = $this->db->jdate($objp->birth); + $dateb = $this->db->jdate($objp->datea); $age = date('Y', dol_now()) - date('Y', $dateb); + $picb = ''; + $pice = ''; + $typea = ($objp->typea == 'birth') ? $picb : $pice; + $this->info_box_contents[$line][] = array( 'td' => '', 'text' => $userstatic->getNomUrl(1), @@ -119,7 +129,18 @@ class box_birthdays extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => 'class="center nowraponall"', - 'text' => dol_print_date($dateb, "day", 'tzserver').' - '.$age.' '.$langs->trans('DurationYears') + 'text' => dol_print_date($dateb, "day", 'tzserver') + ); + + $this->info_box_contents[$line][] = array( + 'td' => 'class="right nowraponall"', + 'text' => $age.' '.$langs->trans('DurationYears') + ); + + $this->info_box_contents[$line][] = array( + 'td' => 'class="center nowraponall"', + 'text' => $typea, + 'asis' => 1 ); /*$this->info_box_contents[$line][] = array( diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 94fb05d5346..54573f92c7a 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -6,7 +6,7 @@ * Copyright (C) 2003 Jean-Louis Bergamo * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2022 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ * \brief File of class to send emails (with attachments or not) */ +use OAuth\Common\Storage\DoliStorage; /** * Class to send emails (with attachments or not) * Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext,$replyto); @@ -71,9 +72,29 @@ class CMailFile */ public $error = ''; + /** + * @var string[] Array of Error code (or message) + */ + public $errors = array(); + public $smtps; // Contains SMTPs object (if this method is used) public $phpmailer; // Contains PHPMailer object (if this method is used) + /** + * @var Swift_SmtpTransport + */ + public $transport; + + /** + * @var Swift_Mailer + */ + public $mailer; + + /** + * @var Swift_Plugins_Loggers_ArrayLogger + */ + public $logger; + /** * @var string CSS */ @@ -470,12 +491,12 @@ class CMailFile $emailMatchs = preg_match_all($regexp, $from, $adressEmailFrom); $adressEmailFrom = reset($adressEmailFrom); if ($emailMatchs !== false && filter_var($conf->global->MAIN_MAIL_SMTPS_ID, FILTER_VALIDATE_EMAIL) && $conf->global->MAIN_MAIL_SMTPS_ID !== $adressEmailFrom) { - $result = $this->message->setFrom($conf->global->MAIN_MAIL_SMTPS_ID); + $this->message->setFrom($conf->global->MAIN_MAIL_SMTPS_ID); } else { - $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); + $this->message->setFrom($this->getArrayAddress($this->addr_from)); } } else { - $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); + $this->message->setFrom($this->getArrayAddress($this->addr_from)); } } catch (Exception $e) { $this->errors[] = $e->getMessage(); @@ -485,7 +506,7 @@ class CMailFile // Set the To addresses with an associative array if (!empty($this->addr_to)) { try { - $result = $this->message->setTo($this->getArrayAddress($this->addr_to)); + $this->message->setTo($this->getArrayAddress($this->addr_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } @@ -493,14 +514,14 @@ class CMailFile if (!empty($this->reply_to)) { try { - $result = $this->message->SetReplyTo($this->getArrayAddress($this->reply_to)); + $this->message->SetReplyTo($this->getArrayAddress($this->reply_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } try { - $result = $this->message->setCharSet($conf->file->character_set_client); + $this->message->setCharSet($conf->file->character_set_client); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } @@ -547,14 +568,26 @@ class CMailFile } if (!empty($this->addr_cc)) { - $this->message->setCc($this->getArrayAddress($this->addr_cc)); + try { + $this->message->setCc($this->getArrayAddress($this->addr_cc)); + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + } } if (!empty($this->addr_bcc)) { - $this->message->setBcc($this->getArrayAddress($this->addr_bcc)); + try { + $this->message->setBcc($this->getArrayAddress($this->addr_bcc)); + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + } } //if (! empty($this->errors_to)) $this->message->setErrorsTo($this->getArrayAddress($this->errors_to)); if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) { - $this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from)); + try { + $this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from)); + } catch (Exception $e) { + $this->errors[] = $e->getMessage(); + } } } else { // Send mail method not correctly defined @@ -657,6 +690,8 @@ class CMailFile } $keyforsmtpserver = 'MAIN_MAIL_SMTP_SERVER'; + $keyforsmtpauthtype = "MAIN_MAIL_SMTPS_AUTH_TYPE"; + $keyforsmtpoauthservice = "MAIN_MAIL_SMTPS_OAUTH_SERVICE"; $keyforsmtpport = 'MAIN_MAIL_SMTP_PORT'; $keyforsmtpid = 'MAIN_MAIL_SMTPS_ID'; $keyforsmtppw = 'MAIN_MAIL_SMTPS_PW'; @@ -832,6 +867,36 @@ class CMailFile $this->smtps->setPW($loginpass); } + if (getDolGlobalString($keyforsmtpauthtype) === "XOAUTH2") { + require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array + $keyforsupportedoauth2array = $conf->global->$keyforsmtpoauthservice; + if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); + } else { + $keyforprovider = ''; + } + $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); + $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; + + $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); + + require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; + + $storage = new DoliStorage($db, $conf); + try { + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + if (is_object($tokenobj)) { + $this->smtps->setToken($tokenobj->getAccessToken()); + } else { + $this->error = "Token not found"; + } + } catch (Exception $e) { + // Return an error if token not found + $this->error = $e->getMessage(); + dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); + } + } + $res = true; $from = $this->smtps->getFrom('org'); if ($res && !$from) { @@ -852,7 +917,6 @@ class CMailFile } $result = $this->smtps->sendMsg(); - //print $result; if (!empty($conf->global->MAIN_MAIL_DEBUG)) { $this->dump_mail(); @@ -898,9 +962,39 @@ class CMailFile if (!empty($conf->global->$keyforsmtpid)) { $this->transport->setUsername($conf->global->$keyforsmtpid); } - if (!empty($conf->global->$keyforsmtppw)) { + if (!empty($conf->global->$keyforsmtppw) && getDolGlobalString($keyforsmtpauthtype) != "XOAUTH2") { $this->transport->setPassword($conf->global->$keyforsmtppw); } + if (getDolGlobalString($keyforsmtpauthtype) === "XOAUTH2") { + require_once DOL_DOCUMENT_ROOT.'/core/lib/oauth.lib.php'; // define $supportedoauth2array + $keyforsupportedoauth2array = getDolGlobalString($keyforsmtpoauthservice); + if (preg_match('/^.*-/', $keyforsupportedoauth2array)) { + $keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array); + } else { + $keyforprovider = ''; + } + $keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array); + $keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME'; + + $OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : '')); + + require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php'; + + $storage = new DoliStorage($db, $conf); + try { + $tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME); + if (is_object($tokenobj)) { + $this->transport->setAuthMode('XOAUTH2'); + $this->transport->setPassword($tokenobj->getAccessToken()); + } else { + $this->errors[] = "Token not found"; + } + } catch (Exception $e) { + // Return an error if token not found + $this->errors[] = $e->getMessage(); + dol_syslog("CMailFile::sendfile: mail end error=".$e->getMessage(), LOG_ERR); + } + } if (!empty($conf->global->$keyforsslseflsigned)) { $this->transport->setStreamOptions(array('ssl' => array('allow_self_signed' => true, 'verify_peer' => false))); } @@ -933,16 +1027,16 @@ class CMailFile try { $result = $this->mailer->send($this->message, $failedRecipients); } catch (Exception $e) { - $this->error = $e->getMessage(); + $this->errors[] = $e->getMessage(); } if (!empty($conf->global->MAIN_MAIL_DEBUG)) { $this->dump_mail(); } $res = true; - if (!empty($this->error) || !$result) { + if (!empty($this->error) || !empty($this->errors) || !$result) { if (!empty($failedRecipients)) { - $this->error = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".'; + $this->errors[] = 'Transport failed for the following addresses: "' . join('", "', $failedRecipients) . '".'; } dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); $res = false; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2d393ab9dc3..6d460dfadf0 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -744,6 +744,7 @@ abstract class CommonObject public function setUpperOrLowerCase() { global $conf; + if (!empty($conf->global->MAIN_FIRST_TO_UPPER)) { $this->lastname = dol_ucwords(dol_strtolower($this->lastname)); $this->firstname = dol_ucwords(dol_strtolower($this->firstname)); @@ -759,8 +760,12 @@ abstract class CommonObject $this->address = dol_strtoupper($this->address); $this->town = dol_strtoupper($this->town); } - $this->email = dol_strtolower($this->email); - $this->personal_email = dol_strtolower($this->personal_email); + if (isset($this->email)) { + $this->email = dol_strtolower($this->email); + } + if (isset($this->personal_email)) { + $this->personal_email = dol_strtolower($this->personal_email); + } } /** @@ -6019,7 +6024,7 @@ abstract class CommonObject // Test fetch_array ! is_int($key) because fetch_array result is a mix table with Key as alpha and Key as int (depend db engine) if ($key != 'rowid' && $key != 'tms' && $key != 'fk_member' && !is_int($key)) { // we can add this attribute to object - if (!empty($extrafields) && in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime'))) { + if (!empty($extrafields->attributes[$this->table_element]) && in_array($extrafields->attributes[$this->table_element]['type'][$key], array('date', 'datetime'))) { //var_dump($extrafields->attributes[$this->table_element]['type'][$key]); $this->array_options["options_".$key] = $this->db->jdate($value); } else { @@ -6032,7 +6037,7 @@ abstract class CommonObject // If field is a computed field, value must become result of compute foreach ($tab as $key => $value) { - if (!empty($extrafields) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { + if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { //var_dump($conf->disable_compute); if (empty($conf->disable_compute)) { $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, ''); @@ -7760,12 +7765,12 @@ abstract class CommonObject } else { $value = ''; } - } elseif (preg_match('/^(text|html)/', $type)) { - $value = dol_htmlentitiesbr($value); } elseif ($type == 'password') { $value = preg_replace('/./i', '*', $value); } elseif ($type == 'array') { $value = implode('
', $value); + } else { // text|html|varchar + $value = dol_htmlentitiesbr($value); } //print $type.'-'.$size.'-'.$value; @@ -8446,8 +8451,8 @@ abstract class CommonObject /** * Get buy price to use for margin calculation. This function is called when buy price is unknown. * Set buy price = sell price if ForceBuyingPriceIfNull configured, - * else if calculation MARGIN_TYPE = 'costprice' and costprice is defined, use costprice as buyprice - * else if calculation MARGIN_TYPE = 'pmp' and pmp is calculated, use pmp as buyprice + * elseif calculation MARGIN_TYPE = 'costprice' and costprice is defined, use costprice as buyprice + * elseif calculation MARGIN_TYPE = 'pmp' and pmp is calculated, use pmp as buyprice * else set min buy price as buy price * * @param float $unitPrice Product unit price @@ -8801,7 +8806,7 @@ abstract class CommonObject public function isInt($info) { if (is_array($info)) { - if (isset($info['type']) && ($info['type'] == 'int' || preg_match('/^integer/i', $info['type']))) { + if (isset($info['type']) && (preg_match('/(^int|int$)/i', $info['type']))) { return true; } else { return false; @@ -9060,6 +9065,8 @@ abstract class CommonObject return 'NULL'; } elseif (preg_match('/^(int|double|real|price)/i', $fieldsentry['type'])) { return price2num("$value"); + } elseif (preg_match('/int$/i', $fieldsentry['type'])) { + return (int) $value; } elseif ($fieldsentry['type'] == 'boolean') { if ($value) { return 'true'; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 82e73186233..17b8c50aff3 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5156,8 +5156,9 @@ class Form closeOnEscape: false, buttons: { "'.dol_escape_js($langs->transnoentities($labelbuttonyes)).'": function() { - var options = "&token='.urlencode(newToken()).'"; + var options = "token='.urlencode(newToken()).'"; var inputok = '.json_encode($inputok).'; /* List of fields into form */ + var page = "'.dol_escape_js(!empty($page) ? $page : '').'"; var pageyes = "'.dol_escape_js(!empty($pageyes) ? $pageyes : '').'"; if (inputok.length>0) { $.each(inputok, function(i, inputname) { @@ -5174,13 +5175,19 @@ class Form options += "&" + inputname + "=" + encodeURIComponent(inputvalue); }); } - var urljump = pageyes + (pageyes.indexOf("?") < 0 ? "?" : "") + options; - if (pageyes.length > 0) { location.href = urljump; } + if (pageyes.length > 0) { + var post = $.post( + pageyes, + options, + (data) => {$("body").html(data)} + ); + } $(this).dialog("close"); }, "'.dol_escape_js($langs->transnoentities($labelbuttonno)).'": function() { - var options = "&token='.urlencode(newToken()).'"; + var options = "token='.urlencode(newToken()).'"; var inputko = '.json_encode($inputko).'; /* List of fields into form */ + var page = "'.dol_escape_js(!empty($page) ? $page : '').'"; var pageno="'.dol_escape_js(!empty($pageno) ? $pageno : '').'"; if (inputko.length>0) { $.each(inputko, function(i, inputname) { @@ -5191,9 +5198,13 @@ class Form options += "&" + inputname + "=" + encodeURIComponent(inputvalue); }); } - var urljump=pageno + (pageno.indexOf("?") < 0 ? "?" : "") + options; - //alert(urljump); - if (pageno.length > 0) { location.href = urljump; } + if (pageno.length > 0) { + var post = $.post( + pageno, + options, + (data) => {$("body").html(data)} + ); + } $(this).dialog("close"); } } diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 4c77566eeed..61f62f28a54 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -4,7 +4,7 @@ * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2015-2017 Marcos García * Copyright (C) 2015-2017 Nicolas ZABOURI - * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018-2022 Frédéric France * Copyright (C) 2022 Charlene Benke * * This program is free software; you can redistribute it and/or modify @@ -85,7 +85,7 @@ class FormMail extends Form public $toid; /** - * @var string replyto name + * @var string Reply-to name */ public $replytoname; @@ -95,20 +95,25 @@ class FormMail extends Form public $replytomail; /** - * @var string to name + * @var string To name */ public $toname; /** - * @var string to email + * @var string To email */ public $tomail; /** - * @var string trackid + * @var string Track id */ public $trackid; + /** + * @var string If you know a MSGID of an email and want to send the email in reply to it. Will be added into header as In-Reply-To: <...> + */ + public $inreplyto; + public $withsubstit; // Show substitution array public $withfrom; @@ -396,7 +401,7 @@ class FormMail extends Form // Define output language $outputlangs = $langs; $newlang = ''; - if (!empty($conf->global->MAIN_MULTILANGS) && empty($newlang)) { + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($this->param['langsmodels'])) { $newlang = $this->param['langsmodels']; } if (!empty($newlang)) { @@ -423,7 +428,7 @@ class FormMail extends Form $keytoavoidconflict = empty($this->trackid) ? '' : '-'.$this->trackid; // this->trackid must be defined if (GETPOST('mode', 'alpha') == 'init' || (GETPOST('modelselected') && GETPOST('modelmailselected', 'alpha') && GETPOST('modelmailselected', 'alpha') != '-1')) { - if (!empty($arraydefaultmessage->joinfiles) && is_array($this->param['fileinit'])) { + if (!empty($arraydefaultmessage->joinfiles) && !empty($this->param['fileinit']) && is_array($this->param['fileinit'])) { foreach ($this->param['fileinit'] as $file) { $this->add_attached_files($file, basename($file), dol_mimetype($file)); } @@ -449,6 +454,7 @@ class FormMail extends Form $out .= ''; $out .= ''; $out .= ''; + $out .= ''; } if (!empty($this->withfrom)) { if (!empty($this->withfromreadonly)) { @@ -458,7 +464,7 @@ class FormMail extends Form } foreach ($this->param as $key => $value) { if (is_array($value)) { - $out .= "\n"; + $out .= "\n"; } else { $out .= ''."\n"; } @@ -598,7 +604,7 @@ class FormMail extends Form // Also add robot email if (!empty($this->fromalsorobot)) { - if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && $conf->global->MAIN_MAIL_EMAIL_FROM != $conf->global->MAIN_INFO_SOCIETE_MAIL) { + if (!empty($conf->global->MAIN_MAIL_EMAIL_FROM) && getDolGlobalString('MAIN_MAIL_EMAIL_FROM') != getDolGlobalString('MAIN_INFO_SOCIETE_MAIL')) { $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM; if ($this->frommail) { $liste['robot'] .= ' <'.$conf->global->MAIN_MAIL_EMAIL_FROM.'>'; @@ -1176,7 +1182,7 @@ class FormMail extends Form { global $conf, $langs; //if (! $this->errorstomail) $this->errorstomail=$this->frommail; - $errorstomail = (!empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : $this->errorstomail); + $errorstomail = getDolGlobalString('MAIN_MAIL_ERRORS_TO', (!empty($this->errorstomail) ? $this->errorstomail : '')); if ($this->witherrorstoreadonly) { $out = '
'.$langs->trans("MailErrorsTo").''; $out .= ''; diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 2dd729df91d..3ff36b356da 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -1093,6 +1093,7 @@ class FormSetupItem $out.= $this->langs->trans("NorProspectNorCustomer"); } } elseif ($this->type == 'product') { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $product = new Product($this->db); $resprod = $product->fetch($this->fieldValue); if ($resprod > 0) { diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index e13aaba4685..68cb3d1af84 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -119,7 +119,7 @@ class FormTicket $this->action = 'add'; - $this->withcompany = $conf->societe->enabled ? 1 : 0; + $this->withcompany = isModEnabled("societe"); $this->withfromsocid = 0; $this->withfromcontactid = 0; //$this->withreadid=0; @@ -169,7 +169,7 @@ class FormTicket print dol_get_fiche_head(null, 'card', '', 0, ''); } - print '
'; + print 'param["returnurl"] : "").'">'; print ''; print ''; foreach ($this->param as $key => $value) { @@ -315,7 +315,7 @@ class FormTicket // Type print '
'; - $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 0, 0, 0, 'minwidth200'); + $this->selectTypesTickets((GETPOST('type_code', 'alpha') ? GETPOST('type_code', 'alpha') : $this->type_code), 'type_code', '', 2, 1, 0, 0, 'minwidth200'); print '
'; - $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 0); + $this->selectSeveritiesTickets((GETPOST('severity_code') ? GETPOST('severity_code') : $this->severity_code), 'severity_code', '', 2, 1); print '
\n"; + $rightCell = $leftCell = ''; + // loop over the lines in the diff $index = 0; $nbdiff = count($diff); diff --git a/htdocs/core/filemanagerdol/browser/default/browser.php b/htdocs/core/filemanagerdol/browser/default/browser.php index b5bce100d39..0c1b29d12b2 100644 --- a/htdocs/core/filemanagerdol/browser/default/browser.php +++ b/htdocs/core/filemanagerdol/browser/default/browser.php @@ -21,10 +21,12 @@ //define('NOTOKENRENEWAL',1); // Disables token renewal //require '../../../../main.inc.php'; -require '../../connectors/php/config.php'; // This include the define('NOTOKENRENEWAL',1) and the require main.in.php +require '../../connectors/php/config.inc.php'; // This include the define('NOTOKENRENEWAL',1) and the require main.in.php global $Config; +top_httphead(); + ?> diff --git a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php index c66187ee433..949307c0624 100644 --- a/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php +++ b/htdocs/core/filemanagerdol/browser/default/frmactualfolder.php @@ -23,6 +23,8 @@ define('NOTOKENRENEWAL', 1); // Disables token renewal require '../../../../main.inc.php'; +top_httphead(); + ?> \n"; print ''; print '
'; } if (empty($conf->global->PROJECT_HIDE_TASKS)) { - print ' '; + print ' '; $htmltext = $langs->trans("ProjectFollowTasks"); print ''; print '
'; } if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_BILL_TIME_SPENT)) { - print ' '; + print ' '; $htmltext = $langs->trans("ProjectBillTimeDescription"); print ''; print '
'; } if (!empty($conf->eventorganization->enabled)) { - print ' '; + print ' '; $htmltext = $langs->trans("EventOrganizationDescriptionLong"); print ''; } @@ -735,7 +739,7 @@ if ($action == 'create' && $user->rights->projet->creer) { print ''; - // Change probability from status + // Change probability from status or role of project print ''; print '
'; diff --git a/htdocs/public/eventorganization/attendee_new.php b/htdocs/public/eventorganization/attendee_new.php index 661ae6accfe..8bb85022b2e 100644 --- a/htdocs/public/eventorganization/attendee_new.php +++ b/htdocs/public/eventorganization/attendee_new.php @@ -60,6 +60,7 @@ global $dolibarr_main_url_root; // Init vars $errmsg = ''; +$errors = array(); $error = 0; $backtopage = GETPOST('backtopage', 'alpha'); $action = GETPOST('action', 'aZ09'); @@ -90,6 +91,7 @@ if ($type == 'conf') { if ($resultproject < 0) { $error++; $errmsg .= $project->error; + $errors = array_merge($errors, $project->errors); } } @@ -99,6 +101,7 @@ if ($type == 'global') { if ($resultproject < 0) { $error++; $errmsg .= $project->error; + $errors = array_merge($errors, $project->errors); } else { $sql = "SELECT COUNT(*) as nb FROM ".MAIN_DB_PREFIX."projet"; $sql .= " WHERE ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee = ".((int) $project->id); @@ -279,6 +282,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen if ($resultconfattendee < 0) { $error++; $errmsg .= $confattendee->error; + $errors = array_merge($errors, $confattendee->errors); } } @@ -403,6 +407,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen // If an error was found $error++; $errmsg .= $thirdparty->error; + $errors = array_merge($errors, $thirdparty->errors); } elseif ($resultfetchthirdparty == 0) { // No thirdparty found + a payment is expected // Creation of a new thirdparty if (!empty($societe)) { @@ -441,6 +446,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen if ($readythirdparty < 0) { $error++; $errmsg .= $thirdparty->error; + $errors = array_merge($errors, $thirdparty->errors); } else { $thirdparty->country_code = getCountry($thirdparty->country_id, 2, $db, $langs); $thirdparty->country = getCountry($thirdparty->country_code, 0, $db, $langs); @@ -472,6 +478,7 @@ if (empty($reshook) && $action == 'add' && (!empty($conference->id) && $conferen if ($resultprod < 0) { $error++; $errmsg .= $productforinvoicerow->error; + $errors = array_merge($errors, $productforinvoicerow->errors); } else { $facture = new Facture($db); if (empty($confattendee->fk_invoice)) { @@ -668,7 +675,7 @@ if ($maxattendees && $currentnbofattendees >= $maxattendees) { print '
'; -dol_htmloutput_errors($errmsg); +dol_htmloutput_errors($errmsg, $errors); if ((!empty($conference->id) && $conference->status == ConferenceOrBooth::STATUS_CONFIRMED) || (!empty($project->id) && $project->status == Project::STATUS_VALIDATED)) { if (empty($maxattendees) || $currentnbofattendees < $maxattendees) { diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 992e7ab403d..fbeba92516f 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -369,6 +369,7 @@ if ($ispaymentok) { } if (empty($user->rights->facture)) { $user->rights->facture = new stdClass(); + $user->rights->facture->invoice_advance = new stdClass(); } if (empty($user->rights->adherent)) { $user->rights->adherent = new stdClass(); @@ -376,6 +377,7 @@ if ($ispaymentok) { } $user->rights->societe->creer = 1; $user->rights->facture->creer = 1; + $user->rights->facture->invoice_advance->validate = 1; $user->rights->adherent->cotisation->creer = 1; if (array_key_exists('MEM', $tmptag) && $tmptag['MEM'] > 0) { diff --git a/htdocs/public/project/suggestbooth.php b/htdocs/public/project/suggestbooth.php index cb1b1089b0c..52193e4fcd4 100644 --- a/htdocs/public/project/suggestbooth.php +++ b/htdocs/public/project/suggestbooth.php @@ -101,7 +101,7 @@ $extrafields = new ExtraFields($db); $user->loadDefaultValues(); $cactioncomm = new CActionComm($db); -$arrayofeventtype = $cactioncomm->liste_array('', 'id', '', 0, "module='booth@eventorganization'"); +$arrayofconfboothtype = $cactioncomm->liste_array('', 'id', '', 0, "module='booth@eventorganization'"); // Security check if (empty($conf->eventorganization->enabled)) { @@ -612,8 +612,8 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { print ''; } // Type of event -print ''."\n"; -print ''; +print ''."\n"; +print ''; // Label print ''."\n"; print ''."\n"; diff --git a/htdocs/public/project/suggestconference.php b/htdocs/public/project/suggestconference.php index 22589c941d2..05cc8e61a82 100644 --- a/htdocs/public/project/suggestconference.php +++ b/htdocs/public/project/suggestconference.php @@ -102,7 +102,7 @@ $extrafields = new ExtraFields($db); $user->loadDefaultValues(); $cactioncomm = new CActionComm($db); -$arrayofeventtype = $cactioncomm->liste_array('', 'id', '', 0, "module='conference@eventorganization'"); +$arrayofconfboothtype = $cactioncomm->liste_array('', 'id', '', 0, "module='conference@eventorganization'"); // Security check if (empty($conf->eventorganization->enabled)) { @@ -463,8 +463,7 @@ print '
'; print '
'; print '
'; - -dol_htmloutput_errors($errmsg); +dol_htmloutput_errors($errmsg, $errors); // Print form print '
'."\n"; @@ -547,8 +546,8 @@ if (empty($conf->global->SOCIETE_DISABLE_STATE)) { print ''; } // Type of event -print '
'."\n"; -print ''; +print ''."\n"; +print ''; // Label print ''."\n"; print ''."\n"; diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index b0a8e9e52a0..c42d6d10ff1 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -114,20 +114,21 @@ class RecruitmentCandidature extends CommonObject 'fk_recruitmentjobposition' => array('type'=>'integer:RecruitmentJobPosition:recruitment/class/recruitmentjobposition.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>15, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'picto'=>'recruitmentjobposition', 'css'=>'minwidth300 maxwidth500 widthcentpercentminusx', 'csslist'=>'minwidth125 tdoverflowmax200'), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), - 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>1,), - 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2,), 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>'1', 'position'=>510, 'notnull'=>1, 'visible'=>-2, 'foreignkey'=>'user.rowid',), 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>'1', 'position'=>511, 'notnull'=>-1, 'visible'=>-2,), - 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1,), - 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), + 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1, 'csslist'=>'tdoverflowmax150'), + 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1, 'csslist'=>'tdoverflowmax150'), 'email' => array('type'=>'email', 'label'=>'EMail', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'picto'=>'email', 'csslist'=>'tdoverflowmax200'), 'phone' => array('type'=>'phone', 'label'=>'Phone', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>1, 'picto'=>'phone', 'csslist'=>'tdoverflowmax150'), 'date_birth' => array('type'=>'date', 'label'=>'DateOfBirth', 'enabled'=>'1', 'position'=>70, 'visible'=>-1,), 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'), + 'email_date' => array('type'=>'datetime', 'label'=>'EmailDate', 'visible'=>-2, 'enabled'=>1, 'position'=>541), //'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1), 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>80, 'notnull'=>0, 'visible'=>-1,), 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>81, 'notnull'=>0, 'visible'=>-1,), - 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>500, 'notnull'=>0, 'visible'=>3, 'cssview'=>'wordbreak'), + 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>300, 'notnull'=>0, 'visible'=>3, 'cssview'=>'wordbreak'), + 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>1, 'csslist'=>'nowraponall'), + 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>'1', 'position'=>501, 'notnull'=>0, 'visible'=>-2, 'csslist'=>'nowraponall'), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'default'=>0, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Received', '3'=>'ContractProposed', '5'=>'ContractSigned', '8'=>'Refused', '9'=>'Canceled')), @@ -149,6 +150,7 @@ class RecruitmentCandidature extends CommonObject public $phone; public $date_birth; public $email_msgid; + public $email_date; public $remuneration_requested; public $remuneration_proposed; public $fk_recruitment_origin; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php index 8d187807700..ba35cb0ba3f 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php @@ -4,7 +4,7 @@ * Copyright (C) 2014 Marcos García * Copyright (C) 2016 Charlie Benke * Copyright (C) 2018-2021 Philippe Grand - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2022 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,12 +22,12 @@ */ /** - * \file htdocs/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php + * \file htdocs/recruitment/core/modules/recruitment/doc/doc_generic_recruitmentjobposition_odt.modules.php * \ingroup recruitment * \brief File of class to build ODT documents for recruitmentjobpositions */ -dol_include_once('/recruitment/core/modules/recruitment/modules_recruitmentjobposition.php'); +require_once DOL_DOCUMENT_ROOT.'/recruitment/core/modules/recruitment/modules_recruitmentjobposition.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -234,7 +234,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi $outputlangs->loadLangs(array("main", "dict", "companies", "bills")); - if ($conf->commande->dir_output) { + if ($conf->recruitment->dir_output) { // If $object is id instead of object if (!is_object($object)) { $id = $object; @@ -246,7 +246,7 @@ class doc_generic_recruitmentjobposition_odt extends ModelePDFRecruitmentJobPosi } } - $dir = $conf->commande->multidir_output[isset($object->entity) ? $object->entity : 1]; + $dir = $conf->recruitment->multidir_output[isset($object->entity) ? $object->entity : 1].'/recruitmentjobposition/'; $objectref = dol_sanitizeFileName($object->ref); if (!preg_match('/specimen/i', $objectref)) { $dir .= "/".$objectref; diff --git a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php index 000c045a03f..8772e97bf77 100644 --- a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php +++ b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php @@ -104,7 +104,7 @@ class mod_recruitmentcandidature_advanced extends ModeleNumRefRecruitmentCandida $old_code_type = $mysoc->typent_code; $mysoc->code_client = 'CCCCCCCCCC'; $mysoc->typent_code = 'TTTTTTTTTT'; - $numExample = $this->getNextValue($mysoc, ''); + $numExample = $this->getNextValue($mysoc); $mysoc->code_client = $old_code_client; $mysoc->typent_code = $old_code_type; diff --git a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php index c7253f182bf..c280153f9c8 100644 --- a/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php +++ b/htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php @@ -104,7 +104,7 @@ class mod_recruitmentjobposition_advanced extends ModeleNumRefRecruitmentJobPosi $old_code_type = $mysoc->typent_code; $mysoc->code_client = 'CCCCCCCCCC'; $mysoc->typent_code = 'TTTTTTTTTT'; - $numExample = $this->getNextValue($mysoc, ''); + $numExample = $this->getNextValue($mysoc); $mysoc->code_client = $old_code_client; $mysoc->typent_code = $old_code_type; diff --git a/htdocs/recruitment/recruitmentcandidature_card.php b/htdocs/recruitment/recruitmentcandidature_card.php index c1a4ca94045..721ed4c4a2a 100644 --- a/htdocs/recruitment/recruitmentcandidature_card.php +++ b/htdocs/recruitment/recruitmentcandidature_card.php @@ -477,6 +477,23 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } } }*/ + // Author + if (!empty($object->email_msgid)) { + $morehtmlref .= $langs->trans("CreatedBy").' : '; + + if ($object->fk_user_creat > 0) { + $fuser = new User($db); + $fuser->fetch($object->fk_user_creat); + $morehtmlref .= $fuser->getNomUrl(-1); + } + if (!empty($object->email_msgid)) { + $morehtmlref .= ' ('.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $langs->trans("EmailMsgID").': '.$object->email_msgid).')'; + } + } /* elseif (!empty($object->origin_email)) { + $morehtmlref .= $langs->trans("CreatedBy").' : '; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("CreatedByPublicPortal").')'; + } */ $morehtmlref .= ''; @@ -652,6 +669,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $defaulttopic = 'InformationMessage'; $diroutput = $conf->recruitment->dir_output; $trackid = 'recruitmentcandidature'.$object->id; + $inreplyto = $object->email_msgid; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } diff --git a/htdocs/recruitment/recruitmentcandidature_document.php b/htdocs/recruitment/recruitmentcandidature_document.php index 25cdb80aa3e..cd3da93b9e0 100644 --- a/htdocs/recruitment/recruitmentcandidature_document.php +++ b/htdocs/recruitment/recruitmentcandidature_document.php @@ -48,7 +48,7 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$offset = $liste_limit * $page; +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (!$sortorder) { diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index ed1b1b54711..996868a791e 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -21,41 +21,21 @@ * \brief Page to create/edit/view recruitmentjobposition */ -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN",'1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. -//if (! defined('NOIPCHECK')) define('NOIPCHECK','1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip -//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value -//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler -//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message -//if (! defined("FORCECSP")) define('FORCECSP','none'); // Disable all Content Security Policies - - // Load Dolibarr environment require_once '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -dol_include_once('/recruitment/class/recruitmentjobposition.class.php'); -dol_include_once('/recruitment/lib/recruitment_recruitmentjobposition.lib.php'); +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/lib/recruitment_recruitmentjobposition.lib.php'; // Load translation files required by the page $langs->loadLangs(array("recruitment", "other")); // Get parameters $id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); +$ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); $cancel = GETPOST('cancel', 'aZ09'); diff --git a/htdocs/recruitment/recruitmentjobposition_document.php b/htdocs/recruitment/recruitmentjobposition_document.php index 3845a53a4e3..d05ed9ab5d6 100644 --- a/htdocs/recruitment/recruitmentjobposition_document.php +++ b/htdocs/recruitment/recruitmentjobposition_document.php @@ -28,8 +28,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -dol_include_once('/recruitment/class/recruitmentjobposition.class.php'); -dol_include_once('/recruitment/lib/recruitment_recruitmentjobposition.lib.php'); +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/lib/recruitment_recruitmentjobposition.lib.php'; // Load translation files required by the page $langs->loadLangs(array("recruitment", "companies", "other", "mails")); @@ -48,7 +48,7 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$offset = $liste_limit * $page; +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (!$sortorder) { diff --git a/htdocs/recruitment/recruitmentjobposition_list.php b/htdocs/recruitment/recruitmentjobposition_list.php index ef9a882bd8e..54f244efc5b 100644 --- a/htdocs/recruitment/recruitmentjobposition_list.php +++ b/htdocs/recruitment/recruitmentjobposition_list.php @@ -216,7 +216,7 @@ $now = dol_now(); //$help_url="EN:Module_RecruitmentJobPosition|FR:Module_RecruitmentJobPosition_FR|ES:Módulo_RecruitmentJobPosition"; $help_url = ''; -$title = $langs->trans('ListOfPositionsToBeFilled'); +$title = $langs->trans('PositionsToBeFilled'); $morejs = array(); $morecss = array(); diff --git a/htdocs/societe/class/companybankaccount.class.php b/htdocs/societe/class/companybankaccount.class.php index 717398c92d4..4ddbd1c613f 100644 --- a/htdocs/societe/class/companybankaccount.class.php +++ b/htdocs/societe/class/companybankaccount.class.php @@ -127,7 +127,7 @@ class CompanyBankAccount extends Account // End call triggers if (!$error) { - return 1; + return $this->id; } else { return 0; } @@ -136,7 +136,7 @@ class CompanyBankAccount extends Account } } } else { - print $this->db->error(); + $this->error = $this->db->lasterror(); return 0; } } @@ -150,7 +150,7 @@ class CompanyBankAccount extends Account */ public function update(User $user = null, $notrigger = 0) { - global $conf; + global $conf, $langs; $error = 0; @@ -207,7 +207,11 @@ class CompanyBankAccount extends Account return 1; } } else { - $this->error = $this->db->lasterror(); + if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->error = $langs->trans('ErrorDuplicateField'); + } else { + $this->error = $this->db->lasterror(); + } return -1; } } diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 0f41ce6a56b..9e4c0e91137 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1722,10 +1722,10 @@ if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) { print '
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Format").'*'.Form::selectarray('eventtype', $arrayofconfboothtype, $eventtype, 1).'
'.$langs->trans("LabelOfBooth").'*
'.$langs->trans("EventType").'*'.FORM::selectarray('eventtype', $arrayofeventtype, $eventtype).'
'.$langs->trans("Format").'*'.Form::selectarray('eventtype', $arrayofconfboothtype, $eventtype, 1).'
'.$langs->trans("LabelOfconference").'*
'; print ''; - print ''; + print ''; print ''; - print ''; + print ''; // Show fields of bank account foreach ($companybankaccount->getFieldsToShow(1) as $val) { @@ -1818,7 +1818,7 @@ if ($socid && $action == 'create' && $permissiontoaddupdatepaymentinformation) { print dol_get_fiche_end(); - dol_set_focus('#label'); + dol_set_focus('#bank'); print $form->buttonsSaveCancel("Add"); } diff --git a/htdocs/stripe/charge.php b/htdocs/stripe/charge.php index 2cd61bfe5d0..7f17d51800d 100644 --- a/htdocs/stripe/charge.php +++ b/htdocs/stripe/charge.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2018-2022 Thibault FOUCART * Copyright (C) 2019 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -251,16 +251,15 @@ if (!$rowid) { $object = new Commande($db); $object->fetch($charge->metadata->dol_id); if ($object->id > 0) { - print "".img_picto('', 'object_order')." ".$object->ref.""; + print "".img_picto('', 'order')." ".$object->ref.""; } else { print $FULLTAG; } } elseif ($charge->metadata->dol_type == "invoice" || $charge->metadata->dol_type == "facture") { - print $charge->metadata->dol_type.' '.$charge->metadata->dol_id.' - '; $object = new Facture($db); $object->fetch($charge->metadata->dol_id); if ($object->id > 0) { - print "".img_picto('', 'object_invoice')." ".$object->ref.""; + print "".img_picto('', 'bill')." ".$object->ref.""; } else { print $FULLTAG; } diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 00d3c4a0d94..5ec149ba07f 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -643,9 +643,6 @@ class Stripe extends CommonObject if (!empty($conf->global->STRIPE_BANCONTACT)) { $paymentmethodtypes[] = "bancontact"; } - if (!empty($conf->global->STRIPE_KLARNA)) { - $paymentmethodtypes[] = "klarna"; - } if (!empty($conf->global->STRIPE_IDEAL)) { $paymentmethodtypes[] = "ideal"; } diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index 64ce74b6022..0bfe4ebd080 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -70,6 +70,8 @@ $terminaltouse = $terminal; if (GETPOST('action', 'alpha') == 'set') { $db->begin(); + $res = dolibarr_set_const($db, "TAKEPOS_TERMINAL_NAME_".$terminaltouse, (!empty(GETPOST('terminalname'.$terminaltouse, 'restricthtml')) ? GETPOST('terminalname'.$terminaltouse, 'restricthtml') : $langs->trans("TerminalName", $terminaltouse)), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "CASHDESK_ID_THIRDPARTY".$terminaltouse, (GETPOST('socid', 'int') > 0 ? GETPOST('socid', 'int') : ''), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "CASHDESK_ID_BANKACCOUNT_CASH".$terminaltouse, (GETPOST('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_BANKACCOUNT_CASH'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity); @@ -148,6 +150,11 @@ print ''; print ''; print "\n"; +print ''; +print ''; + print ''; print ''; + // Origin + /* + if ($object->email_msgid) { + $texttoshow = $langs->trans("CreatedByEmailCollector"); + } elseif ($object->origin_email) { + $texttoshow = $langs->trans("FromPublicEmail"); + } + if ($texttoshow) { + print ''; + print ''; + } + */ + // Read date print '
'.$langs->trans("LabelRIB").'
'.$langs->trans("Bank").'
'.$langs->trans("Parameters").''.$langs->trans("Value").'
'.$langs->trans("TerminalNameDesc").''; +print 'trans("TerminalName", $terminal)).'" >'; +print '
'.$langs->trans("CashDeskThirdPartyForSell").''; print $form->select_company($conf->global->{'CASHDESK_ID_THIRDPARTY'.$terminaltouse}, 'socid', '(s.client IN (1, 3) AND s.status = 1)', 1, 0, 0, array(), 0); diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index ee6a6c85d80..e9717e7c992 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -955,14 +955,9 @@ if (empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) { - trans("Terminal"); ?> + trans("TerminalName", $_SESSION["takeposterminal"])); ?> - - '.dol_print_date(dol_now(), "day").''; ?> @@ -1019,11 +1014,11 @@ if (empty($conf->global->TAKEPOS_HIDE_HEAD_BAR)) {

trans("TerminalSelect"); ?>

diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index e3f4a106c67..3657ca7f4b6 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -562,13 +562,20 @@ if (empty($reshook)) { $invoice->fetch_thirdparty(); $array_options = array(); + $line = array('description' => $prod->description, 'price' => $price, 'tva_tx' => $tva_tx, 'locatax1_tx' => $localtax1_tx, 'locatax2_tx' => $localtax2_tx, 'remise_percent' => $customer->remise_percent, 'price_ttc' => $price_ttc, 'array_options' => $array_options); + // complete line by hook - $parameters = array('prod' => $prod); - $reshook=$hookmanager->executeHooks('completeTakePosAddLine', $parameters, $invoice, $action); + $parameters = array('prod' => $prod, 'line' => $line); + $reshook=$hookmanager->executeHooks('completeTakePosAddLine', $parameters, $invoice, $action); // Note that $action and $line may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + if (empty($reshook)) { - $idoflineadded = $invoice->addline($prod->description, $price, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, (!empty($parent_line)) ? $parent_line : '', null, '', '', $array_options, 100, '', null, 0); + if (!empty($hookmanager->resArray)) { + $line = $hookmanager->resArray; + } + + $idoflineadded = $invoice->addline($line['description'], $line['price'], $qty, $line['tva_tx'], $line['localtax1_tx'], $line['localtax2_tx'], $idproduct, $line['remise_percent'], '', 0, 0, 0, '', $price_base_type, $line['price_ttc'], $prod->type, -1, 0, '', 0, (!empty($parent_line)) ? $parent_line : '', null, '', '', $line['array_options'], 100, '', null, 0); } if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) { diff --git a/htdocs/takepos/pay.php b/htdocs/takepos/pay.php index f487862e895..24ca8cc782b 100644 --- a/htdocs/takepos/pay.php +++ b/htdocs/takepos/pay.php @@ -655,6 +655,10 @@ if ($conf->global->TAKEPOS_ENABLE_SUMUP) { } } +$parameters = array(); +$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $invoice, $action); // Note that $action and $object may have been modified by hook +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); + $class = ($i == 3) ? "calcbutton3" : "calcbutton2"; foreach ($action_buttons as $button) { $newclass = $class.($button["class"] ? " ".$button["class"] : ""); diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 3886651e8d5..078d485a5c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -543,6 +543,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6e423228df1..ca485fb0d5f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -725,6 +725,7 @@ fieldset { border: 1px solid #AAAAAA !important; padding-inline-start: 2em; padding-inline-end: 2em; + min-inline-size: auto; } .legendforfieldsetstep { padding-bottom: 10px; } input#onlinepaymenturl, input#directdownloadlink { diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index e7fc3abba34..20c5d45dd3b 100755 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -56,6 +56,7 @@ $projectid = GETPOST('projectid', 'int'); $cancel = GETPOST('cancel', 'alpha'); $action = GETPOST('action', 'aZ09'); $backtopage = GETPOST('$backtopage', 'alpha'); +$contactid = GETPOST('contactid', 'int'); $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha'); @@ -171,7 +172,19 @@ if (empty($reshook)) { if (GETPOST('save', 'alpha') && !empty($user->rights->ticket->write)) { $error = 0; - if (!GETPOST("subject", 'alphanohtml')) { + if (!GETPOST("type_code", 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketTypeRequest")), null, 'errors'); + $action = 'create'; + } elseif (!GETPOST("category_code", 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketCategory")), null, 'errors'); + $action = 'create'; + } elseif (!GETPOST("severity_code", 'alpha')) { + $error++; + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketSeverity")), null, 'errors'); + $action = 'create'; + } elseif (!GETPOST("subject", 'alphanohtml')) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")), null, 'errors'); $action = 'create'; @@ -924,15 +937,17 @@ if ($action == 'create' || $action == 'presend') { if ($object->fk_user_create > 0) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $langs->load("users"); $fuser = new User($db); $fuser->fetch($object->fk_user_create); $morehtmlref .= $fuser->getNomUrl(-1); - } - if (!empty($object->origin_email)) { + } elseif (!empty($object->email_msgid)) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); - $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("TicketEmailOriginIssuer").')'; + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $langs->trans("EmailMsgID").': '.$object->email_msgid).')'; + } elseif (!empty($object->origin_email)) { + $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("CreatedByPublicPortal").')'; } // Thirdparty @@ -1018,6 +1033,23 @@ if ($action == 'create' || $action == 'presend') { print ' - '.$langs->trans("TimeElapsedSince").': '.convertSecondToTime(roundUpToNextMultiple($now - $object->datec, 60)).''; print '
'; + print $langs->trans("Origin"); + print ''; + print $texttoshow; + print '
'.$langs->trans("TicketReadOn").''; if (!empty($object->date_read)) { @@ -1038,7 +1070,7 @@ if ($action == 'create' || $action == 'presend') { print '
'; print '
'; print $langs->trans("AssignedTo"); - if ($object->fk_status < $object::STATUS_CLOSED && GETPOST('set', 'alpha') != "assign_ticket" && $user->rights->ticket->manage) { + if (isset($object->fk_status) && $object->fk_status < $object::STATUS_CLOSED && GETPOST('set', 'alpha') != "assign_ticket" && $user->rights->ticket->manage) { print ''.img_edit($langs->trans('Modify'), '').''; } print '
'; @@ -1066,7 +1098,7 @@ if ($action == 'create' || $action == 'presend') { print ''; - if ($action != 'progression' && $object->fk_status < $object::STATUS_CLOSED && !$user->socid) { + if ($action != 'progression' && isset($object->fk_status) && $object->fk_status < $object::STATUS_CLOSED && !$user->socid) { print ''; } print '
'; print $langs->trans('Progression').''; print ''.img_edit($langs->trans('Modify')).'
'; @@ -1117,6 +1149,7 @@ if ($action == 'create' || $action == 'presend') { // Fin colonne gauche et début colonne droite print '
'; + print ''; print ''; print ''; @@ -1126,13 +1159,10 @@ if ($action == 'create' || $action == 'presend') { // Categories if (isModEnabled('categorie')) { - print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table - - print ''; - + print '
'; print ''; print '
'; - print ''; } elseif ($key == 'fk_user_assign' || $key == 'fk_user_create') { print ''; } elseif ($key == 'fk_statut') { $arrayofstatus = array(); @@ -1005,7 +1005,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { } elseif ($key == 'subject') { $s = $obj->subject; print ''; - print $s; + print dol_escape_htmltag($s); print ''; } elseif ($key == 'type_code') { $s = $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code); diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index 4b887691f01..df829a010ec 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -157,14 +157,17 @@ $morehtmlref .= $object->subject; if ($object->fk_user_create > 0) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $langs->load("users"); $fuser = new User($db); $fuser->fetch($object->fk_user_create); $morehtmlref .= $fuser->getNomUrl(-1); -} -if (!empty($object->origin_email)) { +} elseif (!empty($object->email_msgid)) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $morehtmlref .= $object->origin_email.' ('.$langs->trans("TicketEmailOriginIssuer").')'; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $langs->trans("EmailMsgID").': '.$object->email_msgid).')'; +} elseif (!empty($object->origin_email)) { + $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("CreatedByPublicPortal").')'; } // Thirdparty diff --git a/htdocs/ticket/stats/index.php b/htdocs/ticket/stats/index.php index 37273ee4d1d..463526ba711 100644 --- a/htdocs/ticket/stats/index.php +++ b/htdocs/ticket/stats/index.php @@ -284,7 +284,7 @@ foreach ($data as $val) { print ''; print ''; print ''; - print ''; + print ''; //print ''; //print ''; //print ''; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 5f8a4be0446..988f508550b 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -76,15 +76,15 @@ $dateendvalidity = dol_mktime(0, 0, 0, GETPOST('dateendvaliditymonth', 'int'), G $dateofbirth = dol_mktime(0, 0, 0, GETPOST('dateofbirthmonth', 'int'), GETPOST('dateofbirthday', 'int'), GETPOST('dateofbirthyear', 'int')); // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } $childids = $user->getAllChildIds(1); // For later, test on salary visibility @@ -92,8 +92,8 @@ $childids = $user->getAllChildIds(1); // For later, test on salary visibility // Define value to know what current user can do on properties of edited user if ($id > 0) { // $user is the current logged user, $id is the user we want to edit - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) || (($user->id != $id) && $user->rights->user->user->creer)); - $caneditpassword = ((($user->id == $id) && $user->rights->user->self->password) || (($user->id != $id) && $user->rights->user->user->password)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) || (($user->id != $id) && $user->hasRight("user", "user", "write"))); + $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password"))); } // Security check @@ -712,7 +712,7 @@ if (empty($reshook)) { // Actions to build doc $upload_dir = $conf->user->dir_output; - $permissiontoadd = $user->rights->user->user->creer; + $permissiontoadd = $user->hasRight("user", "user", "write"); include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -1165,7 +1165,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print ''; - if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($id, $childids)) - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + if ((!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "read")) && in_array($id, $childids)) + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // THM @@ -1365,7 +1365,7 @@ if ($action == 'create' || $action == 'adduserldap') { $title = $langs->trans("User"); $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } } @@ -1417,7 +1417,7 @@ if ($action == 'create' || $action == 'adduserldap') { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; @@ -1541,8 +1541,8 @@ if ($action == 'create' || $action == 'adduserldap') { // Sensitive salary/value information if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // Salary @@ -1625,7 +1625,7 @@ if ($action == 'create' || $action == 'adduserldap') { } // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print '
'; print ''; } @@ -1804,7 +1805,7 @@ if ($action == 'create' || $action == 'adduserldap') { print ''."\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->hasRight("api", "apikey", "generate"))) { print ''; print '\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->rights->api->apikey->generate)) { + if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->hasRight("api", "apikey", "generate"))) { print ''; print ''; // Categories - if (!empty($conf->categorie->enabled) && !empty($user->rights->categorie->lire)) { + if (!empty($conf->categorie->enabled) && !empty($user->hasRight("categorie", "read"))) { print ''; print '
'; + print ''; @@ -1169,11 +1199,8 @@ if ($action == 'create' || $action == 'presend') { } print '
'; print $langs->trans("Categories"); if ($action != 'categories' && !$user->socid) { print ''.img_edit($langs->trans('Modify')).'
'; - - print ''; } - // View Original message $actionobject->viewTicketOriginalMessage($user, $action, $object); @@ -1189,7 +1216,7 @@ if ($action == 'create' || $action == 'presend') { print ''; } else { // Button to edit Properties - if ($object->fk_status < $object::STATUS_NEED_MORE_INFO && $user->rights->ticket->write) { + if (isset($object->fk_status) && $object->fk_status < $object::STATUS_NEED_MORE_INFO && $user->rights->ticket->write) { print ' '.img_edit($langs->trans('Modify')).''; } } @@ -1248,7 +1275,7 @@ if ($action == 'create' || $action == 'presend') { // Display navbar with links to change ticket status print ''; - if (!$user->socid && $user->rights->ticket->write && $object->fk_status < $object::STATUS_CLOSED && GETPOST('set') !== 'properties') { + if (!$user->socid && $user->rights->ticket->write && isset($object->fk_status) && $object->fk_status < $object::STATUS_CLOSED && GETPOST('set') !== 'properties') { $actionobject->viewStatusActions($object); } @@ -1384,16 +1411,16 @@ if ($action == 'create' || $action == 'presend') { if (empty($reshook)) { // Show link to add a message (if read and not closed) - if ($object->fk_status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") { + if (isset($object->fk_status) && $object->fk_status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") { print dolGetButtonAction('', $langs->trans('TicketAddMessage'), 'default', $_SERVER["PHP_SELF"].'?action=presend_addmessage&mode=init&token='.newToken().'&track_id='.$object->track_id, ''); } // Link to create an intervention // socid is needed otherwise fichinter ask it and forgot origin after form submit :\ - if (!$object->fk_soc && $user->rights->ficheinter->creer) { + if (!$object->fk_soc && $user->hasRight("ficheinter", "creer")) { print dolGetButtonAction($langs->trans('UnableToCreateInterIfNoSocid'), $langs->trans('TicketAddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false); } - if ($object->fk_soc > 0 && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ficheinter->creer) { + if ($object->fk_soc > 0 && isset($object->fk_status) && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ficheinter->creer) { print dolGetButtonAction('', $langs->trans('TicketAddIntervention'), 'default', DOL_URL_ROOT.'/fichinter/card.php?action=create&token='.newToken().'&socid='. $object->fk_soc.'&origin=ticket_ticket&originid='. $object->id, ''); } @@ -1404,17 +1431,17 @@ if ($action == 'create' || $action == 'presend') { */ // Close ticket if statut is read - if ($object->fk_status > 0 && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) { + if (isset($object->fk_status) && $object->fk_status > 0 && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) { print dolGetButtonAction('', $langs->trans('CloseTicket'), 'default', $_SERVER["PHP_SELF"].'?action=close&token='.newToken().'&track_id='.$object->track_id, ''); } // Abadon ticket if statut is read - if ($object->fk_status > 0 && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) { + if (isset($object->fk_status) && $object->fk_status > 0 && $object->fk_status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) { print dolGetButtonAction('', $langs->trans('AbandonTicket'), 'default', $_SERVER["PHP_SELF"].'?action=abandon&token='.newToken().'&track_id='.$object->track_id, ''); } // Re-open ticket - if (!$user->socid && ($object->fk_status == Ticket::STATUS_CLOSED || $object->fk_status == Ticket::STATUS_CANCELED) && !$user->socid) { + if (!$user->socid && (isset($object->fk_status) && ($object->fk_status == Ticket::STATUS_CLOSED || $object->fk_status == Ticket::STATUS_CANCELED)) && !$user->socid) { print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&track_id='.$object->track_id, ''); } diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index 3151f75877b..2fd77693984 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -187,10 +187,14 @@ class Tickets extends DolibarrApi if (is_array($this->ticket->cache_logs_ticket) && count($this->ticket->cache_logs_ticket) > 0) { $num = count($this->ticket->cache_logs_ticket); $i = 0; + $user_action = new User($this->db); + while ($i < $num) { + $userstring = ''; if ($this->ticket->cache_logs_ticket[$i]['fk_user_create'] > 0) { - $user_action = new User($this->db); $user_action->fetch($this->ticket->cache_logs_ticket[$i]['fk_user_create']); + + $userstring = dolGetFirstLastname($user_action->firstname, $user_action->lastname); } // Now define messages @@ -198,7 +202,7 @@ class Tickets extends DolibarrApi 'id' => $this->ticket->cache_logs_ticket[$i]['id'], 'fk_user_author' => $this->ticket->cache_msgs_ticket[$i]['fk_user_author'], 'fk_user_action' => $this->ticket->cache_logs_ticket[$i]['fk_user_create'], - 'fk_user_action_string' => dolGetFirstLastname($user_action->firstname, $user_action->lastname), + 'fk_user_action_string' => $userstring, 'message' => $this->ticket->cache_logs_ticket[$i]['message'], 'datec' => $this->ticket->cache_logs_ticket[$i]['datec'], ); @@ -243,6 +247,7 @@ class Tickets extends DolibarrApi } // If the internal user must only see his customers, force searching by him + $search_sale = 0; if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) { $search_sale = DolibarrApiAccess::$user->id; } diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 5fae77938e8..496e6607bf7 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -203,16 +203,23 @@ class Ticket extends CommonObject public $notify_tiers_at_create; /** - * @var string msgid + * @var string Email MSGID */ public $email_msgid; + /** + * @var string Email Date + */ + public $email_date; + + public $lines; + /** * @var string Regex pour les images */ - public $regeximgext = '\.jpg|\.jpeg|\.bmp|\.gif|\.png|\.tiff'; + public $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into images.lib.php /** * Status @@ -259,24 +266,25 @@ class Ticket extends CommonObject 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>5, 'notnull'=>1, 'index'=>1), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'visible'=>1, 'enabled'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'css'=>'', 'showoncombobox'=>1), 'track_id' => array('type'=>'varchar(255)', 'label'=>'TicketTrackId', 'visible'=>-2, 'enabled'=>1, 'position'=>11, 'notnull'=>-1, 'searchall'=>1, 'help'=>"Help text"), - 'fk_user_create' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Author', 'visible'=>1, 'enabled'=>1, 'position'=>15, 'notnull'=>1, 'css'=>'tdoverflowmax125 maxwidth150onsmartphone'), - 'origin_email' => array('type'=>'mail', 'label'=>'OriginEmail', 'visible'=>-2, 'enabled'=>1, 'position'=>16, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'css'=>'tdoverflowmax150'), + 'fk_user_create' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Author', 'visible'=>1, 'enabled'=>1, 'position'=>15, 'notnull'=>1, 'csslist'=>'tdoverflowmax100 maxwidth150onsmartphone'), + 'origin_email' => array('type'=>'mail', 'label'=>'OriginEmail', 'visible'=>-2, 'enabled'=>1, 'position'=>16, 'notnull'=>1, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'csslist'=>'tdoverflowmax150'), 'subject' => array('type'=>'varchar(255)', 'label'=>'Subject', 'visible'=>1, 'enabled'=>1, 'position'=>18, 'notnull'=>-1, 'searchall'=>1, 'help'=>"", 'css'=>'maxwidth200 tdoverflowmax200', 'autofocusoncreate'=>1), - 'type_code' => array('type'=>'varchar(32)', 'label'=>'Type', 'visible'=>1, 'enabled'=>1, 'position'=>20, 'notnull'=>-1, 'help'=>"", 'css'=>'maxwidth125 tdoverflowmax50'), + 'type_code' => array('type'=>'varchar(32)', 'label'=>'Type', 'visible'=>1, 'enabled'=>1, 'position'=>20, 'notnull'=>-1, 'help'=>"", 'csslist'=>'maxwidth125 tdoverflowmax50'), 'category_code' => array('type'=>'varchar(32)', 'label'=>'TicketCategory', 'visible'=>-1, 'enabled'=>1, 'position'=>21, 'notnull'=>-1, 'help'=>"", 'css'=>'maxwidth100 tdoverflowmax200'), 'severity_code' => array('type'=>'varchar(32)', 'label'=>'Severity', 'visible'=>1, 'enabled'=>1, 'position'=>22, 'notnull'=>-1, 'help'=>"", 'css'=>'maxwidth100'), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'searchall'=>1, 'help'=>"LinkToThirparty", 'css'=>'tdoverflowmax150 maxwidth150onsmartphone'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=>1, 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'searchall'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'css'=>'tdoverflowmax150 maxwidth150onsmartphone'), 'notify_tiers_at_create' => array('type'=>'integer', 'label'=>'NotifyThirdparty', 'visible'=>-1, 'enabled'=>0, 'position'=>51, 'notnull'=>1, 'index'=>1), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php', 'label'=>'Project', 'visible'=>-1, 'enabled'=>'$conf->project->enabled', 'position'=>52, 'notnull'=>-1, 'index'=>1, 'help'=>"LinkToProject"), //'timing' => array('type'=>'varchar(20)', 'label'=>'Timing', 'visible'=>-1, 'enabled'=>1, 'position'=>42, 'notnull'=>-1, 'help'=>""), // what is this ? - 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>1, 'enabled'=>1, 'position'=>500, 'notnull'=>1), + 'datec' => array('type'=>'datetime', 'label'=>'DateCreation', 'visible'=>1, 'enabled'=>1, 'position'=>500, 'notnull'=>1, 'csslist'=>'nowraponall'), 'date_read' => array('type'=>'datetime', 'label'=>'TicketReadOn', 'visible'=>-1, 'enabled'=>1, 'position'=>501, 'notnull'=>1), 'date_last_msg_sent' => array('type'=>'datetime', 'label'=>'TicketLastMessageDate', 'visible'=>0, 'enabled'=>1, 'position'=>502, 'notnull'=>-1), - 'fk_user_assign' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'AssignedTo', 'visible'=>1, 'enabled'=>1, 'position'=>505, 'notnull'=>1, 'css'=>'tdoverflowmax125'), + 'fk_user_assign' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'AssignedTo', 'visible'=>1, 'enabled'=>1, 'position'=>505, 'notnull'=>1, 'csslist'=>'tdoverflowmax100 maxwidth150onsmartphone'), 'date_close' => array('type'=>'datetime', 'label'=>'TicketCloseOn', 'visible'=>-1, 'enabled'=>1, 'position'=>510, 'notnull'=>1), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'visible'=>-1, 'enabled'=>1, 'position'=>520, 'notnull'=>1), 'message' => array('type'=>'text', 'label'=>'Message', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1,), 'email_msgid' => array('type'=>'varchar(255)', 'label'=>'EmailMsgID', 'visible'=>-2, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'help'=>'EmailMsgIDDesc'), + 'email_date' => array('type'=>'datetime', 'label'=>'EmailDate', 'visible'=>-2, 'enabled'=>1, 'position'=>541), 'progress' => array('type'=>'integer', 'label'=>'Progression', 'visible'=>-1, 'enabled'=>1, 'position'=>540, 'notnull'=>-1, 'css'=>'right', 'help'=>"", 'isameasure'=>2, 'csslist'=>'width50'), 'resolution' => array('type'=>'integer', 'label'=>'Resolution', 'visible'=>-1, 'enabled'=>'$conf->global->TICKET_ENABLE_RESOLUTION', 'position'=>550, 'notnull'=>1), 'fk_statut' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>600, 'notnull'=>1, 'index'=>1, 'arrayofkeyval'=>array(0 => 'Unread', 1 => 'Read', 3 => 'Answered', 4 => 'Assigned', 5 => 'InProgress', 6 => 'Waiting', 8 => 'SolvedClosed', 9 => 'Deleted')), @@ -437,6 +445,7 @@ class Ticket extends CommonObject $sql .= "fk_user_create,"; $sql .= "fk_user_assign,"; $sql .= "email_msgid,"; + $sql .= "email_date,"; $sql .= "subject,"; $sql .= "message,"; $sql .= "fk_statut,"; @@ -460,6 +469,7 @@ class Ticket extends CommonObject $sql .= " ".($this->fk_user_create > 0 ? $this->fk_user_create : ($user->id > 0 ? $user->id : 'NULL')).","; $sql .= " ".($this->fk_user_assign > 0 ? $this->fk_user_assign : 'NULL').","; $sql .= " ".(empty($this->email_msgid) ? 'NULL' : "'".$this->db->escape($this->email_msgid)."'").","; + $sql .= " ".(empty($this->email_date) ? 'NULL' : "'".$this->db->idate($this->email_date)."'").","; $sql .= " ".(!isset($this->subject) ? 'NULL' : "'".$this->db->escape($this->subject)."'").","; $sql .= " ".(!isset($this->message) ? 'NULL' : "'".$this->db->escape($this->message)."'").","; $sql .= " ".(!isset($this->fk_statut) ? '0' : "'".$this->db->escape($this->fk_statut)."'").","; @@ -570,6 +580,7 @@ class Ticket extends CommonObject $sql .= " t.fk_user_create,"; $sql .= " t.fk_user_assign,"; $sql .= " t.email_msgid,"; + $sql .= " t.email_date,"; $sql .= " t.subject,"; $sql .= " t.message,"; $sql .= " t.fk_statut as status,"; @@ -620,6 +631,7 @@ class Ticket extends CommonObject $this->fk_user_create = $obj->fk_user_create; $this->fk_user_assign = $obj->fk_user_assign; $this->email_msgid = $obj->email_msgid; + $this->email_date = $this->db->jdate($obj->email_date); $this->subject = $obj->subject; $this->message = $obj->message; @@ -1572,28 +1584,28 @@ class Ticket extends CommonObject // foreach contact send email with notification message if (count($contacts) > 0) { foreach ($contacts as $key => $info_sendto) { - $message = ''; + $tmpmessage = ''; $subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNotificationEmailSubject', $this->track_id); - $message .= $langs->transnoentities('TicketNotificationEmailBody', $this->track_id)."\n\n"; - $message .= $langs->transnoentities('Title').' : '.$this->subject."\n"; + $tmpmessage .= $langs->transnoentities('TicketNotificationEmailBody', $this->track_id)."\n\n"; + $tmpmessage .= $langs->transnoentities('Title').' : '.$this->subject."\n"; $recipient_name = dolGetFirstLastname($info_sendto['firstname'], $info_sendto['lastname'], '-1'); $recipient = (!empty($recipient_name) ? $recipient_name : $info_sendto['email']).' ('.strtolower($info_sendto['libelle']).')'; - $message .= $langs->transnoentities('TicketNotificationRecipient').' : '.$recipient."\n"; - $message .= "\n"; - $message .= '* '.$langs->transnoentities('TicketNotificationLogMessage').' *'."\n"; - $message .= dol_html_entity_decode($log_message, ENT_QUOTES | ENT_HTML5)."\n"; + $tmpmessage .= $langs->transnoentities('TicketNotificationRecipient').' : '.$recipient."\n"; + $tmpmessage .= "\n"; + $tmpmessage .= '* '.$langs->transnoentities('TicketNotificationLogMessage').' *'."\n"; + $tmpmessage .= dol_html_entity_decode($message, ENT_QUOTES | ENT_HTML5)."\n"; if ($info_sendto['source'] == 'internal') { $url_internal_ticket = dol_buildpath('/ticket/card.php', 2).'?track_id='.$this->track_id; - $message .= "\n".$langs->transnoentities('TicketNotificationEmailBodyInfosTrackUrlinternal').' : '.$this->track_id.''."\n"; + $tmpmessage .= "\n".$langs->transnoentities('TicketNotificationEmailBodyInfosTrackUrlinternal').' : '.$this->track_id.''."\n"; } else { $url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$this->track_id; - $message .= "\n".$langs->transnoentities('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$this->track_id.''."\n"; + $tmpmessage .= "\n".$langs->transnoentities('TicketNewEmailBodyInfosTrackUrlCustomer').' : '.$this->track_id.''."\n"; } - $message .= "\n"; - $message .= $langs->transnoentities('TicketEmailPleaseDoNotReplyToThisEmail')."\n"; + $tmpmessage .= "\n"; + $tmpmessage .= $langs->transnoentities('TicketEmailPleaseDoNotReplyToThisEmail')."\n"; $from = $conf->global->MAIN_INFO_SOCIETE_NOM.'<'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>'; $replyto = $from; @@ -1603,7 +1615,7 @@ class Ticket extends CommonObject $filename = array(); $mimetype = array(); - $message = dol_nl2br($message); + $tmpmessage = dol_nl2br($tmpmessage); if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; @@ -1612,7 +1624,7 @@ class Ticket extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; $sendtocc = ''; $deliveryreceipt = 0; - $mailfile = new CMailFile($subject, $info_sendto['email'], $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, 0); + $mailfile = new CMailFile($subject, $info_sendto['email'], $from, $tmpmessage, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, 0); if ($mailfile->error || $mailfile->errors) { setEventMessages($mailfile->error, $mailfile->errors, 'errors'); } else { @@ -2119,12 +2131,13 @@ class Ticket extends CommonObject { $array_contact = array(); - $array_contact = $this->getIdTicketInternalContact($exclude_self); + $array_contact = $this->getIdTicketInternalContact(); - $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact($exclude_self)); + $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact()); - $array_contact = array_merge($array_contact, $this->getIdTicketInternalInvolvedContact($exclude_self)); - $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact($exclude_self)); + $array_contact = array_merge($array_contact, $this->getIdTicketInternalInvolvedContact()); + + $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact()); return $array_contact; } @@ -2138,8 +2151,9 @@ class Ticket extends CommonObject { $array_contact = array(); - $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact($exclude_self)); - $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact($exclude_self)); + $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact()); + + $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact()); return $array_contact; } @@ -2813,11 +2827,14 @@ class Ticket extends CommonObject $filename = $mimefilename_list; $mimetype = $mimetype_list; - // Envoi du mail + // Send email + + $old_MAIN_MAIL_AUTOCOPY_TO = getDolGlobalString('MAIN_MAIL_AUTOCOPY_TO'); + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { - $old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO; $conf->global->MAIN_MAIL_AUTOCOPY_TO = ''; } + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; $trackid = "tic".$this->id; $mailfile = new CMailFile($subject, $receiver, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', $trackid, '', 'ticket'); @@ -2838,6 +2855,7 @@ class Ticket extends CommonObject } } } + if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) { $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO; } diff --git a/htdocs/ticket/contact.php b/htdocs/ticket/contact.php index 5b1b73799f2..d32ab88eb1c 100644 --- a/htdocs/ticket/contact.php +++ b/htdocs/ticket/contact.php @@ -196,14 +196,17 @@ if ($id > 0 || !empty($track_id) || !empty($ref)) { if ($object->fk_user_create > 0) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $langs->load("users"); $fuser = new User($db); $fuser->fetch($object->fk_user_create); $morehtmlref .= $fuser->getNomUrl(-1); - } - if (!empty($object->origin_email)) { + } elseif (!empty($object->email_msgid)) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $morehtmlref .= $object->origin_email.' ('.$langs->trans("TicketEmailOriginIssuer").')'; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $langs->trans("EmailMsgID").': '.$object->email_msgid).')'; + } elseif (!empty($object->origin_email)) { + $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("CreatedByPublicPortal").')'; } // Thirdparty diff --git a/htdocs/ticket/document.php b/htdocs/ticket/document.php index bf2b1c51fc4..234c5e92918 100644 --- a/htdocs/ticket/document.php +++ b/htdocs/ticket/document.php @@ -129,16 +129,19 @@ if ($object->id) { $morehtmlref .= $object->subject; // Author if ($object->fk_user_create > 0) { - $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; + $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $langs->load("users"); $fuser = new User($db); $fuser->fetch($object->fk_user_create); $morehtmlref .= $fuser->getNomUrl(-1); - } - if (!empty($object->origin_email)) { + } elseif (!empty($object->email_msgid)) { $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; - $morehtmlref .= $object->origin_email.' ('.$langs->trans("TicketEmailOriginIssuer").')'; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $langs->trans("EmailMsgID").': '.$object->email_msgid).')'; + } elseif (!empty($object->origin_email)) { + $morehtmlref .= '
'.$langs->trans("CreatedBy").' : '; + $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"'); + $morehtmlref .= dol_escape_htmltag($object->origin_email).' ('.$langs->trans("CreatedByPublicPortal").')'; } // Thirdparty diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index f09388fa0ac..693a40fbb5f 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -824,7 +824,7 @@ foreach ($object->fields as $key => $val) { print '
'; - print $form->select_dolusers((empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, 1, null, 0, '', '', '0', 0, 0, '', 0, '', ($val['css'] ? $val['css'] : 'maxwidth125')); + print $form->select_dolusers((empty($search[$key]) ? '' : $search[$key]), 'search_'.$key, 1, null, 0, '', '', '0', 0, 0, '', 0, '', ($val['css'] ? $val['css'] : 'maxwidth100')); print '
0 ? '&userid='.$userid : '').'">'.$year.''.$val['nb'].''.round($val['nb_diff']).''.round(isset($val['nb_diff']) ? $val['nb_diff'] : 0).''.price(price2num($val['total'], 'MT'), 1).''.round($val['total_diff']).''.price(price2num($val['avg'], 'MT'), 1).'
'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).''; $cate_arbo = $form->select_all_categories('user', null, 'parent', null, null, 1); print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('usercats', $cate_arbo, GETPOST('usercats', 'array'), 0, 0, 'maxwdith300 widthcentpercentminusx', 0, '90%'); @@ -1234,9 +1234,9 @@ if ($action == 'create' || $action == 'adduserldap') { print ''; print '
'.$langs->trans("Categories").''; print $form->showCategories($object->id, Categorie::TYPE_USER, 1); @@ -1642,6 +1642,7 @@ if ($action == 'create' || $action == 'adduserldap') { //$s=picto_from_langcode($object->default_lang); //print ($s?$s.' ':''); $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : ''); + print picto_from_langcode($object->lang, 'class="paddingrightonly saturatemedium opacitylow"'); print $labellang; print '
'.$langs->trans("ApiKey").''; if (!empty($object->api_key)) { @@ -2369,7 +2370,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
'.$langs->trans("ApiKey").''; print ''; @@ -2566,7 +2567,7 @@ if ($action == 'create' || $action == 'adduserldap') { print '
'.$form->editfieldkey('Categories', 'usercats', '', $object, 0).''; print img_picto('', 'category', 'class="pictofixedwidth"'); @@ -2711,8 +2712,8 @@ if ($action == 'create' || $action == 'adduserldap') { // Sensitive salary/value information if ((empty($user->socid) && in_array($id, $childids)) // A user can always see salary/value information for its subordinates - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $langs->load("salaries"); // Salary @@ -2803,8 +2804,8 @@ if ($action == 'create' || $action == 'adduserldap') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output."/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->user->user->lire; - $delallowed = $user->rights->user->user->creer; + $genallowed = $user->hasRight("user", "user", "read"); + $delallowed = $user->hasRight("user", "user", "write"); print $formfile->showdocuments('user', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', empty($soc->default_lang) ? '' : $soc->default_lang); $somethingshown = $formfile->numoffiles; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 6fca728ee8b..008aaae5007 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -775,16 +775,16 @@ class User extends CommonObject // For backward compatibility with old permissions called "lire", "creer", "create", "supprimer" // instead of "read", "write", "delete" if ($permlevel2 == 'read' && !empty($this->rights->$rightsPath->$permlevel1->lire)) { - return $this->rights->$rightsPath->lire; + return $this->rights->$rightsPath->$permlevel1->lire; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->creer)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->creer; } if ($permlevel2 == 'write' && !empty($this->rights->$rightsPath->$permlevel1->create)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->$permlevel1->create; } if ($permlevel2 == 'delete' && !empty($this->rights->$rightsPath->$permlevel1->supprimer)) { - return $this->rights->$rightsPath->supprimer; + return $this->rights->$rightsPath->$permlevel1->supprimer; } } } else { @@ -797,7 +797,7 @@ class User extends CommonObject return $this->rights->$rightsPath->lire; } if ($permlevel1 == 'write' && !empty($this->rights->$rightsPath->creer)) { - return $this->rights->$rightsPath->create; + return $this->rights->$rightsPath->creer; } if ($permlevel1 == 'write' && !empty($this->rights->$rightsPath->create)) { return $this->rights->$rightsPath->create; @@ -2073,6 +2073,8 @@ class User extends CommonObject $adh->phone = $this->office_phone; $adh->phone_mobile = $this->user_mobile; + $adh->default_lang = $this->lang; + $adh->user_id = $this->id; $adh->user_login = $this->login; @@ -2117,6 +2119,8 @@ class User extends CommonObject $tmpobj->phone_mobile = $this->user_mobile; $tmpobj->fax = $this->office_fax; + $tmpobj->default_lang = $this->lang; + $tmpobj->address = $this->address; $tmpobj->town = $this->town; $tmpobj->zip = $this->zip; diff --git a/htdocs/user/document.php b/htdocs/user/document.php index ed1fe30df4e..31ec618a795 100644 --- a/htdocs/user/document.php +++ b/htdocs/user/document.php @@ -41,23 +41,23 @@ $ref = GETPOST('ref', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'userdoc'; // To manage different context of search // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } // Define value to know what current user can do on properties of edited user if ($id) { // $user est le user qui edite, $id est l'id de l'utilisateur edite - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) - || (($user->id != $id) && $user->rights->user->user->creer)); - $caneditpassword = ((($user->id == $id) && $user->rights->user->self->password) - || (($user->id != $id) && $user->rights->user->user->password)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) + || (($user->id != $id) && $user->hasRight("user", "user", "write"))); + $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) + || (($user->id != $id) && $user->hasRight("user", "user", "passsword"))); } $permissiontoadd = $caneditfield; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles @@ -147,7 +147,7 @@ if ($object->id) { print dol_get_fiche_head($head, 'document', $langs->trans("User"), -1, 'user'); $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -155,7 +155,7 @@ if ($object->id) { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; print '
'; diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 92d309e554b..9b6e9e1c317 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -32,16 +32,16 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Defini si peux lire/modifier utilisateurs et permisssions -$canreadperms = ($user->admin || $user->rights->user->user->lire); -$caneditperms = ($user->admin || $user->rights->user->user->creer); -$candisableperms = ($user->admin || $user->rights->user->user->supprimer); +$canreadperms = ($user->admin || $user->hasRight("user", "user", "read")); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); +$candisableperms = ($user->admin || $user->hasRight("user", "user", "delete")); $feature2 = 'user'; // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadperms = ($user->admin || $user->rights->user->group_advance->read); - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); - $candisableperms = ($user->admin || $user->rights->user->group_advance->delete); + $canreadperms = ($user->admin || $user->hasRight("user", "group_advance", "read")); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); + $candisableperms = ($user->admin || $user->hasRight("user", "group_advance", "delete")); $feature2 = 'group_advance'; } @@ -238,7 +238,7 @@ if (empty($reshook)) { // Actions to build doc $upload_dir = $conf->user->dir_output.'/usergroups'; - $permissiontoadd = $user->rights->user->user->creer; + $permissiontoadd = $user->hasRight("user", "user", "write"); include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; } @@ -250,7 +250,7 @@ $title = $object->name.' - '.$langs->trans("Card"); if ($action == 'create') { $title = $langs->trans("NewGroup"); } - +$help_url = ""; llxHeader('', $title, $help_url); @@ -329,7 +329,7 @@ if ($action == 'create') { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; print '
'; @@ -485,8 +485,8 @@ if ($action == 'create') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->user->dir_output."/usergroups/".dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->user->user->creer; - $delallowed = $user->rights->user->user->supprimer; + $genallowed = $user->hasRight("user", "user", "write"); + $delallowed = $user->hasRight("user", "user", "delete"); $somethingshown = $formfile->showdocuments('usergroup', $filename, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', 0, '', $mysoc->default_lang); diff --git a/htdocs/user/group/list.php b/htdocs/user/group/list.php index bb130b33e75..8f7f907eb7b 100644 --- a/htdocs/user/group/list.php +++ b/htdocs/user/group/list.php @@ -38,10 +38,10 @@ $massaction = GETPOST('massaction', 'alpha'); // The bulk action (combo box choi $contextpage = GETPOST('optioncss', 'aZ09'); // Defini si peux lire/modifier utilisateurs et permisssions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); } // Load variable for pagination @@ -70,7 +70,7 @@ $fieldstosearchall = array( ); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - if (!$user->rights->user->group_advance->read && !$user->admin) { + if (!$user->hasRight("user", "group_advance", "read") && !$user->admin) { accessforbidden(); } } @@ -80,7 +80,7 @@ if (!empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global-> accessforbidden(); } -if (!$user->rights->user->user->lire && !$user->admin) { +if (!$user->hasRight("user", "user", "read") && !$user->admin) { accessforbidden(); } @@ -121,6 +121,7 @@ if (empty($reshook)) { * View */ $title = $langs->trans("ListOfGroups"); +$help_url=""; llxHeader('', $title, $help_url); $sql = "SELECT g.rowid, g.nom as name, g.note, g.entity, g.datec, g.tms as datem, COUNT(DISTINCT ugu.fk_user) as nb, COUNT(DISTINCT ugr.fk_id) as nbpermissions"; diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php index edf20d0884c..15fcc2a319f 100644 --- a/htdocs/user/group/perms.php +++ b/htdocs/user/group/perms.php @@ -50,15 +50,15 @@ if (!isset($id) || empty($id)) { } // Define if user can read permissions -$canreadperms = ($user->admin || $user->rights->user->user->lire); +$canreadperms = ($user->admin || $user->hasRight("user", "user", "read")); // Define if user can modify group permissions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions $advancedpermsactive = false; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { $advancedpermsactive = true; - $canreadperms = ($user->admin || ($user->rights->user->group_advance->read && $user->rights->user->group_advance->readperms)); - $caneditperms = ($user->admin || $user->rights->user->group_advance->write); + $canreadperms = ($user->admin || ($user->hasRight("user", "group_advance", "read") && $user->hasRight("user", "group_advance", "readperms"))); + $caneditperms = ($user->admin || $user->hasRight("user", "group_advance", "write")); } // Security check @@ -206,7 +206,7 @@ if ($object->id > 0) { $linkback = ''.$langs->trans("BackToList").''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; print '
'; diff --git a/htdocs/user/hierarchy.php b/htdocs/user/hierarchy.php index 92d0490f1c6..3f8326d3b7b 100644 --- a/htdocs/user/hierarchy.php +++ b/htdocs/user/hierarchy.php @@ -60,9 +60,9 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', $userstatic = new User($db); // Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->rights->user->user->creer); +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); -if (!$user->rights->user->user->lire && !$user->admin) { +if (!$user->hasRight("user", "user", "read") && !$user->admin) { accessforbidden(); } diff --git a/htdocs/user/ldap.php b/htdocs/user/ldap.php index 8a8ca28092e..01be4fdcbae 100644 --- a/htdocs/user/ldap.php +++ b/htdocs/user/ldap.php @@ -97,7 +97,7 @@ llxHeader('', $title, $help_url); $head = user_prepare_head($object); $title = $langs->trans("User"); -print dol_get_fiche_head($head, 'ldap', $title, 0, 'user'); +print dol_get_fiche_head($head, 'ldap', $title, -1, 'user'); $linkback = ''; @@ -110,7 +110,7 @@ dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $use print '
'; print '
'; -print ''; +print '
'; // Login print ''; diff --git a/htdocs/user/list.php b/htdocs/user/list.php index a47fa7a51c2..f0196789e25 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -131,7 +131,7 @@ $arrayfields = array( 'u.email'=>array('label'=>"EMail", 'checked'=>1, 'position'=>35), 'u.api_key'=>array('label'=>"ApiKey", 'checked'=>0, 'position'=>40, "enabled"=>(!empty($conf->api->enabled) && $user->admin)), 'u.fk_soc'=>array('label'=>"Company", 'checked'=>($contextpage == 'employeelist' ? 0 : 1), 'position'=>45), - 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall))), + 'u.salary'=>array('label'=>"Salary", 'checked'=>1, 'position'=>80, 'enabled'=>(!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall")))), 'u.datelastlogin'=>array('label'=>"LastConnexion", 'checked'=>1, 'position'=>100), 'u.datepreviouslogin'=>array('label'=>"PreviousConnexion", 'checked'=>0, 'position'=>110), 'u.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), @@ -174,26 +174,26 @@ if ($mode == 'employee' && !GETPOSTISSET('search_employee')) { } // Define value to know what current user can do on users -$permissiontoadd = (!empty($user->admin) || $user->rights->user->user->creer); -$canreaduser = (!empty($user->admin) || $user->rights->user->user->lire); -$canedituser = (!empty($user->admin) || $user->rights->user->user->creer); -$candisableuser = (!empty($user->admin) || $user->rights->user->user->supprimer); +$permissiontoadd = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); $canreadgroup = $canreaduser; $caneditgroup = $canedituser; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->rights->user->group_advance->read); - $caneditgroup = (!empty($user->admin) || $user->rights->user->group_advance->write); + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); } $error = 0; // Permission to list if ($mode == 'employee') { - if (empty($user->rights->salaries->read)) { + if (empty($user->hasRight("salaries", "read"))) { accessforbidden(); } } else { - if (empty($user->rights->user->user->lire) && empty($user->admin)) { + if (empty($user->hasRight("user", "user", "read")) && empty($user->admin)) { accessforbidden(); } } @@ -441,7 +441,7 @@ if ($search_categ == -2) { if ($search_warehouse > 0) { $sql .= " AND u.fk_warehouse = ".((int) $search_warehouse); } -if ($mode == 'employee' && empty($user->rights->salaries->readall)) { +if ($mode == 'employee' && empty($user->hasRight("salaries", "readall"))) { $sql .= " AND u.rowid IN (".$db->sanitize(join(',', $childids)).")"; } // Add where from extra fields @@ -658,7 +658,7 @@ $moreforfilter = ''; $moreforfilter.= '';*/ // Filter on categories -if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { +if (!empty($conf->categorie->enabled) && $user->hasRight("categorie", "read")) { $moreforfilter .= '
'; $tmptitle = $langs->trans('Category'); $moreforfilter .= img_picto($langs->trans("Category"), 'category', 'class="pictofixedwidth"').$formother->select_categories(Categorie::TYPE_USER, $search_categ, 'search_categ', 1, $tmptitle); @@ -939,9 +939,9 @@ while ($i < $imaxinloop) { $li = $object->getNomUrl(-1, '', 0, 0, 24, 1, 'login', '', 1); $canreadhrmdata = 0; - if ((!empty($conf->salaries->enabled) && !empty($user->rights->salaries->read) && in_array($obj->rowid, $childids)) - || (!empty($conf->salaries->enabled) && !empty($user->rights->salaries->readall)) - || (!empty($conf->hrm->enabled) && !empty($user->rights->hrm->employee->read))) { + if ((!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "read")) && in_array($obj->rowid, $childids)) + || (!empty($conf->salaries->enabled) && !empty($user->hasRight("salaries", "readall"))) + || (!empty($conf->hrm->enabled) && !empty($user->hasRight("hrm", "employee", "read")))) { $canreadhrmdata = 1; } $canreadsecretapi = 0; diff --git a/htdocs/user/logout.php b/htdocs/user/logout.php index 57a653a01d1..661995bb729 100644 --- a/htdocs/user/logout.php +++ b/htdocs/user/logout.php @@ -33,6 +33,11 @@ if (!defined('NOREQUIREHTML')) { if (!defined('NOREQUIREAJAX')) { define('NOREQUIREAJAX', '1'); } +/* We do now force CSRF check so we can logout using logout.php page (required for DoliDroid for example) +if (!defined('CSRFCHECK_WITH_TOKEN')) { + define('CSRFCHECK_WITH_TOKEN', '1'); +} +*/ //if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // We need company to get correct logo onto home page if (!defined('EVEN_IF_ONLY_LOGIN_ALLOWED')) { define('EVEN_IF_ONLY_LOGIN_ALLOWED', '1'); diff --git a/htdocs/user/note.php b/htdocs/user/note.php index 2aeb496c20f..2b1e02b1376 100644 --- a/htdocs/user/note.php +++ b/htdocs/user/note.php @@ -39,7 +39,7 @@ $object->fetch($id, '', '', 1); $object->getrights(); // If user is not user read and no permission to read other users, we stop -if (($object->id != $user->id) && (!$user->rights->user->user->lire)) { +if (($object->id != $user->id) && (!$user->hasRight("user", "user", "read"))) { accessforbidden(); } @@ -48,7 +48,7 @@ $socid = 0; if ($user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); $result = restrictedArea($user, 'user', $id, 'user&user', $feature2); @@ -67,7 +67,7 @@ if ($reshook < 0) { } if (empty($reshook)) { - if ($action == 'update' && $user->rights->user->user->creer && !GETPOST("cancel")) { + if ($action == 'update' && $user->hasRight("user", "user", "write") && !GETPOST("cancel")) { $db->begin(); $res = $object->update_note(dol_html_entity_decode(GETPOST('note_private', 'restricthtml'), ENT_QUOTES | ENT_HTML5)); @@ -99,7 +99,7 @@ if ($id) { $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -107,7 +107,7 @@ if ($id) { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; @@ -138,7 +138,7 @@ if ($id) { } print '
'; - $editenabled = (($action == 'edit') && !empty($user->rights->user->user->creer)); + $editenabled = (($action == 'edit') && !empty($user->hasRight("user", "user", "write"))); // Note print ''; @@ -171,7 +171,7 @@ if ($id) { print '
'; - if ($user->rights->user->user->creer && $action != 'edit') { + if ($user->hasRight("user", "user", "write") && $action != 'edit') { print ''.$langs->trans('Modify').""; } diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 4c138bfde6e..6a5eea96490 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; $langs->loadLangs(array('companies', 'products', 'admin', 'users', 'languages', 'projects', 'members')); // Defini si peux lire/modifier permisssions -$canreaduser = ($user->admin || $user->rights->user->user->lire); +$canreaduser = ($user->admin || $user->hasRight("user", "user", "read")); $id = GETPOST('id', 'int'); $action = GETPOST('action', 'aZ09'); @@ -40,8 +40,8 @@ $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'use if ($id) { // $user est le user qui edite, $id est l'id de l'utilisateur edite - $caneditfield = ((($user->id == $id) && $user->rights->user->self->creer) - || (($user->id != $id) && $user->rights->user->user->creer)); + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) + || (($user->id != $id) && $user->hasRight("user", "user", "write"))); } // Security check @@ -49,7 +49,7 @@ $socid = 0; if ($user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); $result = restrictedArea($user, 'user', $id, 'user&user', $feature2); if ($user->id <> $id && !$canreaduser) { @@ -231,11 +231,11 @@ if ($action == 'edit') { $linkback = ''; - if ($user->rights->user->user->lire || $user->admin) { + if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin); print '
'; @@ -346,7 +346,7 @@ if ($action == 'edit') { $morehtmlref .= img_picto($langs->trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; - dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); + dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/user/perms.php b/htdocs/user/perms.php index 47d68703d69..bfc234abce1 100644 --- a/htdocs/user/perms.php +++ b/htdocs/user/perms.php @@ -50,13 +50,13 @@ if (!isset($id) || empty($id)) { } // Define if user can read permissions -$canreaduser = ($user->admin || $user->rights->user->user->lire); +$canreaduser = ($user->admin || $user->hasRight("user", "user", "read")); // Define if user can modify other users and permissions -$caneditperms = ($user->admin || $user->rights->user->user->creer); +$caneditperms = ($user->admin || $user->hasRight("user", "user", "write")); // Advanced permissions if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreaduser = ($user->admin || ($user->rights->user->user->lire && $user->rights->user->user_advance->readperms)); - $caneditselfperms = ($user->id == $id && $user->rights->user->self_advance->writeperms); + $canreaduser = ($user->admin || ($user->hasRight("user", "user", "read") && $user->hasRight("user", "user_advance", "readperms"))); + $caneditselfperms = ($user->id == $id && $user->hasRight("user", "self_advance", "writeperms")); $caneditperms = (($caneditperms || $caneditselfperms) ? 1 : 0); } @@ -65,9 +65,9 @@ $socid = 0; if (isset($user->socid) && $user->socid > 0) { $socid = $user->socid; } -$feature2 = (($socid && $user->rights->user->self->creer) ? '' : 'user'); +$feature2 = (($socid && $user->hasRight("user", "self", "write")) ? '' : 'user'); // A user can always read its own card if not advanced perms enabled, or if he has advanced perms, except for admin -if ($user->id == $id && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->user->self_advance->readperms) && empty($user->admin))) { +if ($user->id == $id && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->hasRight("user", "self_advance", "readperms")) && empty($user->admin))) { accessforbidden(); } @@ -249,7 +249,7 @@ if ($result) { $linkback = ''; -if ($user->rights->user->user->lire || $user->admin) { +if ($user->hasRight("user", "user", "read") || $user->admin) { $linkback = ''.$langs->trans("BackToList").''; } @@ -257,7 +257,7 @@ $morehtmlref = 'trans("Download").' '.$langs->trans("VCard"), 'vcard.png', 'class="valignmiddle marginleftonly paddingrightonly"'); $morehtmlref .= ''; -dol_banner_tab($object, 'id', $linkback, $user->rights->user->user->lire || $user->admin, 'rowid', 'ref', $morehtmlref); +dol_banner_tab($object, 'id', $linkback, $user->hasRight("user", "user", "read") || $user->admin, 'rowid', 'ref', $morehtmlref); print '
'; diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 0e062b038a0..aa405861e6a 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1059,29 +1059,35 @@ class Website extends CommonObject $line .= "'".$this->db->escape($objectpageold->grabbed_from)."', "; $line .= "'".$this->db->escape($objectpageold->type_container)."', "; + // Make substitution with a generic path into htmlheader content $stringtoexport = $objectpageold->htmlheader; $stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport); $stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport); + $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport); $line .= "'".$this->db->escape(str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport))."', "; // Replace \r \n to have record on 1 line + // Make substitution with a generic path into page content $stringtoexport = $objectpageold->content; $stringtoexport = str_replace(array("\r\n", "\r", "\n"), "__N__", $stringtoexport); $stringtoexport = str_replace('file=image/'.$website->ref.'/', "file=image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('file=js/'.$website->ref.'/', "file=js/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/image/'.$website->ref.'/', "medias/image/__WEBSITE_KEY__/", $stringtoexport); $stringtoexport = str_replace('medias/js/'.$website->ref.'/', "medias/js/__WEBSITE_KEY__/", $stringtoexport); + $stringtoexport = str_replace('"image/'.$website->ref.'/', '"image/__WEBSITE_KEY__/', $stringtoexport); // When we have a link src="image/websiteref/file.png" into html content + $stringtoexport = str_replace('"/image/'.$website->ref.'/', '"/image/__WEBSITE_KEY__/', $stringtoexport); // When we have a link src="/image/websiteref/file.png" into html content + $stringtoexport = str_replace('"js/'.$website->ref.'/', '"js/__WEBSITE_KEY__/', $stringtoexport); + $stringtoexport = str_replace('"/js/'.$website->ref.'/', '"/js/__WEBSITE_KEY__/', $stringtoexport); + $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_small, "file=logos%2Fthumbs%2F__LOGO_SMALL_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo_mini, "file=logos%2Fthumbs%2F__LOGO_MINI_KEY__", $stringtoexport); $stringtoexport = str_replace('file=logos%2Fthumbs%2F'.$mysoc->logo, "file=logos%2Fthumbs%2F__LOGO_KEY__", $stringtoexport); - // When we have a link src="image/websiteref/file.png" into html content - $stringtoexport = str_replace('="image/'.$website->ref.'/', '="image/__WEBSITE_KEY__/', $stringtoexport); $line .= "'".$this->db->escape($stringtoexport)."', "; // Replace \r \n to have record on 1 line $line .= "'".$this->db->escape($objectpageold->author_alias)."', "; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 90277e59594..5020ad00626 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2741,8 +2741,12 @@ if (!GETPOST('hide_websitemenu')) { print ''; - //print ''; - print ''; + // Delete website + if ($website->status == $website::STATUS_VALIDATED) { + print ''; + } else { + print ''; + } // Regenerate all pages print 'ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("RegenerateWebsiteContent")).'">'; diff --git a/htdocs/workstation/workstation_document.php b/htdocs/workstation/workstation_document.php index 50331b4b231..92cf4dfde15 100644 --- a/htdocs/workstation/workstation_document.php +++ b/htdocs/workstation/workstation_document.php @@ -48,7 +48,7 @@ $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("pa if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 -$offset = $liste_limit * $page; +$offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (!$sortorder) { diff --git a/test/phpunit/LangTest.php b/test/phpunit/LangTest.php index c9c332b311e..e0eaded97de 100644 --- a/test/phpunit/LangTest.php +++ b/test/phpunit/LangTest.php @@ -226,6 +226,14 @@ class LangTest extends PHPUnit\Framework\TestCase $result=strpos($filecontent, '%'); // A special % char we don't want. We want the common one. //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; $this->assertTrue($result === false, 'Found a bad percent char % instead of % into file '.$code.'/'.$file); + + $result=preg_match('/%n/m', $filecontent); // A sequence of char we don't want + //print __METHOD__." Result for checking we don't have bad percent char = ".$result."\n"; + $this->assertTrue($result == 0, 'Found a sequence %n into the translation file '.$code.'/'.$file.'. We probably want %s'); + + $result=preg_match('/<<<<assertTrue($result == 0, 'Found a sequence <<<<< into the translation file '.$code.'/'.$file.'. Probably a bad merge of code were done.'); } } diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 4f7a78790f1..cc43d6c3a31 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -382,6 +382,9 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_POST["param13b"]='n n > < " XSS'; $_POST["param14"]="Text with ' encoded with the numeric html entity converted into text entity ' (like when submited by CKEditor)"; $_POST["param15"]=" src=>0xbeefed"; + $_POST["param16"]='abc'; + $_POST["param17"]='abc'; + $_POST["param18"]='abc'; //$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)'; //$_POST["param14"]='javascripT&javascript#x3a alert(1)'; @@ -554,6 +557,18 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals('0xbeefed', $result, 'Test 15b'); + $result=GETPOST('param16', 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('abc', $result, 'Test tag a with forbidden attribute z-index'); + + $result=GETPOST('param17', 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('abc', $result, 'Test anytag with a forbidden value for attribute'); + + $result=GETPOST('param18', 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('abc', $result, 'Test anytag with a forbidden value for attribute'); + unset($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES); @@ -589,6 +604,13 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals('x3aalert(1)', $result, 'Test for backtopage param'); + + $conf->global->MAIN_SECURITY_MAX_IMG_IN_HTML_CONTENT = 3; + $_POST["pagecontentwithlinks"]=''; + $result=GETPOST("pagecontentwithlinks", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('TooManyLinksIntoHTMLString', $result, 'Test on limit on GETPOST fails'); + return $result; }
'.$langs->trans("Login").'
'.$langs->trans("Note").'