diff --git a/dev/examples/zapier/package.json b/dev/examples/zapier/package.json index 4266a6f00b1..cc0768a27ef 100644 --- a/dev/examples/zapier/package.json +++ b/dev/examples/zapier/package.json @@ -15,7 +15,7 @@ "npm": ">=5.6.0" }, "dependencies": { - "zapier-platform-core": "10.1.2" + "zapier-platform-core": "11.0.0" }, "devDependencies": { "mocha": "^5.2.0", diff --git a/dev/resources/iso-normes/address_format.txt b/dev/resources/iso-normes/address_format.txt index cc3b23285c8..d87e90e79b5 100644 --- a/dev/resources/iso-normes/address_format.txt +++ b/dev/resources/iso-normes/address_format.txt @@ -1 +1,4 @@ -http://bitboost.com/ref/international-address-formats.html#Formats \ No newline at end of file +https://bitboost.com/ref/international-address-formats.html#Formats + +https://www.upu.int/en/Postal-Solutions/Programmes-Services/Addressing-Solutions + diff --git a/dev/resources/iso-normes/code_nace.txt b/dev/resources/iso-normes/code_nace.txt index 0c490bd4bf1..a07e3a76b31 100644 --- a/dev/resources/iso-normes/code_nace.txt +++ b/dev/resources/iso-normes/code_nace.txt @@ -1 +1,5 @@ -http://ec.europa.eu/eurostat/ramon/nomenclatures/index.cfm?TargetUrl=LST_CLS_DLD&StrNom=NACE_REV2&StrLanguageCode=FR&StrLayoutCode=# \ No newline at end of file +NACE + +https://ec.europa.eu/eurostat/ramon/nomenclatures/index.cfm?TargetUrl=LST_CLS_DLD&StrNom=NACE_REV2&StrLanguageCode=EN&StrLayoutCode= + +https://en.wikipedia.org/wiki/Statistical_Classification_of_Economic_Activities_in_the_European_Community diff --git a/dev/resources/iso-normes/countries_iso-3166_en.txt b/dev/resources/iso-normes/countries_iso-3166_en.txt index b953435d1c9..d6624026963 100644 --- a/dev/resources/iso-normes/countries_iso-3166_en.txt +++ b/dev/resources/iso-normes/countries_iso-3166_en.txt @@ -3,11 +3,12 @@ # The list is updated whenever a change to the official code list in ISO 3166-1 is effected by the ISO 3166/MA. # It lists 240 official short names and code elements. One line of text contains one entry. # A country name and its code element are separated by a semicolon (;). -# http://www.iso.org/iso/fr/iso3166_en_code_lists.txt +# https://www.iso.org/iso-3166-country-codes.html -# ISO-3166: http://en.wikipedia.org/wiki/ISO_3166-1 -# ISO-3166 alpha 2: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 -# ISO-3166 alpha 3: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 +# https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes +# ISO-3166: https://en.wikipedia.org/wiki/ISO_3166-1 +# ISO-3166 alpha 2: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 +# ISO-3166 alpha 3: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 AFGHANISTAN;AF ÅLAND ISLANDS;AX @@ -254,4 +255,4 @@ WALLIS AND FUTUNA;WF WESTERN SAHARA;EH YEMEN;YE ZAMBIA;ZM -ZIMBABWE;ZW \ No newline at end of file +ZIMBABWE;ZW diff --git a/dev/resources/iso-normes/countries_iso-3166_fr.txt b/dev/resources/iso-normes/countries_iso-3166_fr.txt index 578c0f0effe..532b73ef47e 100644 --- a/dev/resources/iso-normes/countries_iso-3166_fr.txt +++ b/dev/resources/iso-normes/countries_iso-3166_fr.txt @@ -3,11 +3,12 @@ # The list is updated whenever a change to the official code list in ISO 3166-1 is effected by the ISO 3166/MA. # It lists 240 official short names and code elements. One line of text contains one entry. # A country name and its code element are separated by a semicolon (;). -# http://www.iso.org/iso/fr/iso3166_fr_code_lists.txt +# https://www.iso.org/fr/iso-3166-country-codes.html -# ISO-3166: http://en.wikipedia.org/wiki/ISO_3166-1 -# ISO-3166 alpha 2: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 -# ISO-3166 alpha 3: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 +# https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes +# ISO-3166: https://fr.wikipedia.org/wiki/ISO_3166-1 +# ISO-3166 alpha 2: https://fr.wikipedia.org/wiki/ISO_3166-1_alpha-2 +# ISO-3166 alpha 3: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3 AFGHANISTAN;AF AFRIQUE DU SUD;ZA @@ -254,4 +255,4 @@ VIET NAM;VN WALLIS ET FUTUNA;WF YÉMEN;YE ZAMBIE;ZM -ZIMBABWE;ZW \ No newline at end of file +ZIMBABWE;ZW diff --git a/dev/resources/iso-normes/locales.txt b/dev/resources/iso-normes/locales.txt index cb39e45ec0d..67ea5280342 100644 --- a/dev/resources/iso-normes/locales.txt +++ b/dev/resources/iso-normes/locales.txt @@ -1,9 +1,9 @@ For languages: -http://demo.icu-project.org/icu-bin/locexp?d_=fr +https://icu4c-demos.unicode.org/icu-bin/icudemos - Locale Explorer -> Error 404 For format number: -http://en.wikipedia.org/wiki/Decimal_mark +https://en.wikipedia.org/wiki/Decimal_mark For date format: -http://en.wikipedia.org/wiki/Date_format_by_country \ No newline at end of file +https://en.wikipedia.org/wiki/Date_format_by_country diff --git a/dev/resources/iso-normes/vat_number_names.txt b/dev/resources/iso-normes/vat_number_names.txt index 23fce59ed3b..b1e8d469ec8 100644 --- a/dev/resources/iso-normes/vat_number_names.txt +++ b/dev/resources/iso-normes/vat_number_names.txt @@ -1 +1,7 @@ -http://en.wikipedia.org/wiki/VAT_identification_number \ No newline at end of file +https://en.wikipedia.org/wiki/VAT_identification_number + +terms +(en) VAT = Value Added Tax +(fr) TVA = Taxe sur la Valeur Ajouté +(es) NIF / CIF +(de) USt / MwSt diff --git a/dev/resources/iso-normes/world_tax_rates.txt b/dev/resources/iso-normes/world_tax_rates.txt index 740062288dc..c007474e5fd 100644 --- a/dev/resources/iso-normes/world_tax_rates.txt +++ b/dev/resources/iso-normes/world_tax_rates.txt @@ -1,4 +1,5 @@ http://www.taxrates.cc/index.html +https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates For India: VAT=IGST/CGST=Localtax1/SGST=Localtax2: https://cleartax.in/s/what-is-sgst-cgst-igst diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index dbcfeded5a4..dfa55834e58 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,3 +1,7 @@ +https://en.wikipedia.org/wiki/Single_Euro_Payments_Area +https://www.ecb.europa.eu/paym/integration/retail/sepa/html/index.en.html +https://www.europeanpaymentscouncil.eu/about-sepa + Spec for credit transfer: https://docs.oracle.com/cd/E39124_01/doc.91/e60210/fields_sepa_pay_file_appx.htm#EOAEL00515 diff --git a/htdocs/adherents/document.php b/htdocs/adherents/document.php index 5150bea861e..f2a7c6f3f55 100644 --- a/htdocs/adherents/document.php +++ b/htdocs/adherents/document.php @@ -93,6 +93,8 @@ if ($id) { $caneditfieldmember = $user->rights->adherent->creer; } +$permissiontoadd = $canaddmember; + // Security check $result = restrictedArea($user, 'adherent', $object->id, '', '', 'socid', 'rowid', 0); diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index f8a782a54e5..d03574d473b 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -871,8 +871,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { if ($value == 'price' || preg_match('/^amount/i', $value)) { $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($value == 'taux' || $value == 'localtax1' || $value == 'localtax2') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); + } elseif ($value == 'taux' || $value == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z } elseif ($value == 'entity') { $_POST[$keycode] = getEntity($tabname[$id]); } @@ -940,8 +940,8 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) { if ($field == 'price' || preg_match('/^amount/i', $field)) { $_POST[$keycode] = price2num(GETPOST($keycode), 'MU'); - } elseif ($field == 'taux' || $field == 'localtax1' || $field == 'localtax2') { - $_POST[$keycode] = price2num(GETPOST($keycode), 8); + } elseif ($field == 'taux' || $field == 'localtax1') { + $_POST[$keycode] = price2num(GETPOST($keycode), 8); // Note that localtax2 can be a list of rates separated by coma like X:Y:Z } elseif ($field == 'entity') { $_POST[$keycode] = getEntity($tabname[$id]); } @@ -1254,13 +1254,13 @@ if ($id) { $valuetoshow = $langs->trans("UseLocalTax")." 2"; $class = "center"; $sortable = 0; } if ($value == 'localtax1') { - $valuetoshow = $langs->trans("Rate")." 2"; $class = "center"; + $valuetoshow = $langs->trans("RateOfTaxN", '2'); $class = "center"; } if ($value == 'localtax2_type') { $valuetoshow = $langs->trans("UseLocalTax")." 3"; $class = "center"; $sortable = 0; } if ($value == 'localtax2') { - $valuetoshow = $langs->trans("Rate")." 3"; $class = "center"; + $valuetoshow = $langs->trans("RateOfTaxN", '3'); $class = "center"; } if ($value == 'organization') { $valuetoshow = $langs->trans("Organization"); @@ -1598,17 +1598,18 @@ if ($id) { } $cssprefix = 'center '; } + if ($value == 'localtax1_type') { $valuetoshow = $langs->trans("UseLocalTax")." 2"; $cssprefix = "center "; $sortable = 0; } if ($value == 'localtax1') { - $valuetoshow = $langs->trans("Rate")." 2"; $cssprefix = "center "; $sortable = 0; + $valuetoshow = $langs->trans("RateOfTaxN", '2'); $cssprefix = "center "; $sortable = 0; } if ($value == 'localtax2_type') { $valuetoshow = $langs->trans("UseLocalTax")." 3"; $cssprefix = "center "; $sortable = 0; } if ($value == 'localtax2') { - $valuetoshow = $langs->trans("Rate")." 3"; $cssprefix = "center "; $sortable = 0; + $valuetoshow = $langs->trans("RateOfTaxN", '3'); $cssprefix = "center "; $sortable = 0; } if ($value == 'organization') { $valuetoshow = $langs->trans("Organization"); diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index 8fcbc898844..2d3133c9fce 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -48,7 +48,7 @@ $substitutionarrayfortest = array( '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, '__ID__' => 'RecipientIdRecord', //'__EMAIL__' => 'RecipientEMail', // Done into actions_sendmails - '__CHECK_READ__' => (is_object($object) && !empty($object->thirdparty) && is_object($object->thirdparty)) ? '' : '', + '__CHECK_READ__' => (!empty($object) && is_object($object) && is_object($object->thirdparty)) ? '' : '', '__USER_SIGNATURE__' => (($user->signature && empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN)) ? $usersignature : ''), // Done into actions_sendmails '__LOGIN__' => 'RecipientLogin', '__LASTNAME__' => 'RecipientLastname', @@ -737,14 +737,14 @@ if ($action == 'edit') { print ''.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').''; print ''; - if (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) && $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'robot') { + if (getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE') === 'robot') { print $langs->trans('RobotEmail'); - } elseif (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) && $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'user') { + } elseif (getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE') === 'user') { print $langs->trans('UserEmail'); - } elseif (!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) && $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'company') { + } elseif (getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE') === 'company') { print $langs->trans('CompanyEmail').' '.dol_escape_htmltag('<'.$mysoc->email.'>'); } else { - $id = preg_replace('/senderprofile_/', '', !empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE) ? $conf->global->MAIN_MAIL_DEFAULT_FROMTYPE : ''); + $id = preg_replace('/senderprofile_/', '', getDolGlobalString('MAIN_MAIL_DEFAULT_FROMTYPE')); if ($id > 0) { include_once DOL_DOCUMENT_ROOT.'/core/class/emailsenderprofile.class.php'; $emailsenderprofile = new EmailSenderProfile($db); @@ -756,7 +756,7 @@ if ($action == 'edit') { // Errors To print ''.$langs->trans("MAIN_MAIL_ERRORS_TO").''; - print ''.(!empty($conf->global->MAIN_MAIL_ERRORS_TO) ? $conf->global->MAIN_MAIL_ERRORS_TO : ''); + print ''.(getDolGlobalString('MAIN_MAIL_ERRORS_TO')); if (!empty($conf->global->MAIN_MAIL_ERRORS_TO) && !isValidEmail($conf->global->MAIN_MAIL_ERRORS_TO)) { print img_warning($langs->trans("ErrorBadEMail")); } diff --git a/htdocs/admin/security_file.php b/htdocs/admin/security_file.php index 2b6a4e81fb4..12c90cf3c21 100644 --- a/htdocs/admin/security_file.php +++ b/htdocs/admin/security_file.php @@ -66,7 +66,7 @@ if ($action == 'updateform') { } elseif ($action == 'delete') { // Delete file $langs->load("other"); - $file = $conf->admin->dir_temp.'/'.GETPOST('urlfile', 'alpha'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). + $file = $conf->admin->dir_temp.'/'.GETPOST('urlfile', 'alpha'); $ret = dol_delete_file($file); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile', 'alpha')), null, 'mesgs'); diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 530860dee71..50b27b30964 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -53,8 +53,8 @@ print ''.$langs->trans("FileCheckDesc").'
print '
'; print ''; print ''."\n"; -print ''."\n"; -print ''."\n"; +print ''."\n"; +print ''."\n"; print '
'.$langs->trans("Version").''.$langs->trans("Value").'
'.$langs->trans("VersionLastInstall").''.$conf->global->MAIN_VERSION_LAST_INSTALL.'
'.$langs->trans("VersionLastUpgrade").''.$conf->global->MAIN_VERSION_LAST_UPGRADE.'
'.$langs->trans("VersionLastInstall").''.getDolGlobalString('MAIN_VERSION_LAST_INSTALL').'
'.$langs->trans("VersionLastUpgrade").''.getDolGlobalString('MAIN_VERSION_LAST_UPGRADE').'
'.$langs->trans("VersionProgram").''.DOL_VERSION; // If current version differs from last upgrade if (empty($conf->global->MAIN_VERSION_LAST_UPGRADE)) { @@ -171,7 +171,7 @@ if (GETPOST('target') == 'remote') { } -if (!$error && $xml) { +if (empty($error) && !empty($xml)) { $checksumconcat = array(); $file_list = array(); $out = ''; diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 0d4f60f3851..428c80676a2 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -157,7 +157,7 @@ $title = $langs->trans("BackupDumpWizard"); print load_fiche_titre($title); -print ''; +print '
'; print ''; print '
'; print $langs->trans("DatabaseName").' : '.$dolibarr_main_db_name.'
'; diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php index 935804ada10..fbc2412a9df 100644 --- a/htdocs/admin/tools/listevents.php +++ b/htdocs/admin/tools/listevents.php @@ -42,7 +42,7 @@ if ($user->socid > 0) { } // Load translation files required by the page -$langs->loadLangs(array("companies", "admin", "users", "other")); +$langs->loadLangs(array("companies", "admin", "users", "other","withdrawals")); // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; @@ -285,7 +285,7 @@ if ($result) { $param .= "&date_endyear=".urlencode($date_endyear); } - $langs->load('withdrawals'); + $center = ''; if ($num) { $center = ''.$langs->trans("Purge").''; } diff --git a/htdocs/asset/document.php b/htdocs/asset/document.php index e6f5ed9b353..91e46269994 100644 --- a/htdocs/asset/document.php +++ b/htdocs/asset/document.php @@ -40,12 +40,6 @@ $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result=restrictedArea($user, 'asset', $id, ''); - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -69,6 +63,14 @@ if ($object->fetch($id)) { $upload_dir = $conf->asset->dir_output."/".dol_sanitizeFileName($object->ref); } +$permissiontoadd = $user->rights->asset->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php + +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result=restrictedArea($user, 'asset', $id, ''); + /* * Actions diff --git a/htdocs/bom/bom_document.php b/htdocs/bom/bom_document.php index c0196670cfb..e59b22c45b2 100644 --- a/htdocs/bom/bom_document.php +++ b/htdocs/bom/bom_document.php @@ -85,6 +85,8 @@ if ($id > 0 || !empty($ref)) { $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); restrictedArea($user, 'bom', $object->id, 'bom_bom', '', '', 'rowid', $isdraft); +$permissiontoadd = $user->rights->bom->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php + /* * Actions diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 817c750a571..eeca990ef28 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -754,6 +754,7 @@ if ($type == Categorie::TYPE_CONTACT) { $num = count($contacts); $nbtotalofrecords = ''; $newcardbutton = ''; + $objsoc = new Societe($db); print_barre_liste($langs->trans("Contact"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'contact', 0, $newcardbutton, '', $limit); print ''."\n"; @@ -770,6 +771,11 @@ if ($type == Categorie::TYPE_CONTACT) { print "\t".''."\n"; print '\n"; // Link to delete from category print ''; @@ -2063,7 +2063,7 @@ if ($action == 'create') { print ''; print '
'; print $contact->getNomUrl(1, 'category'); + if ($contact->socid > 0) { + $objsoc->fetch($contact->socid); + print ' - '; + print $objsoc->getNomUrl(1, 'contact'); + } print "'; diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index f521fa2ab59..c55d4e114cc 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -88,6 +88,8 @@ if ($user->socid && $socid) { $result = restrictedArea($user, 'societe', $socid); } +$permissiontoadd = $user->rights->agenda->myactions->read; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php + /* * Actions diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 654dea6d697..86aff8a36e0 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -281,7 +281,13 @@ if (empty($reshook)) { complete_substitutions_array($substitutionarray, $langs); $newsubject = make_substitutions($subject, $substitutionarray); - $newmessage = make_substitutions($message, $substitutionarray); + $newmessage = make_substitutions($message, $substitutionarray, null, 0); + + $moreinheader = ''; + if (preg_match('/__UNSUBSCRIBE__/', $message)) { + $moreinheader = "List-Unsubscribe: <__UNSUBSCRIBE_URL__>\n"; + $moreinheader = make_substitutions($moreinheader, $substitutionarray); + } $arr_file = array(); $arr_mime = array(); @@ -299,7 +305,7 @@ if (empty($reshook)) { // Mail making $trackid = 'emailing-'.$obj->fk_mailing.'-'.$obj->rowid; - $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css, $trackid, '', 'emailing'); + $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css, $trackid, $moreinheader, 'emailing'); if ($mail->error) { $res = 0; diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 29310aa831b..984d77e7263 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -347,7 +347,7 @@ if (empty($reshook)) { $duration = GETPOST('duree_validite', 'int'); if (empty($datep)) { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("DatePropal")), null, 'errors'); $action = 'create'; $error++; } @@ -1622,7 +1622,7 @@ if ($action == 'create') { } // Date - print '
'.$langs->trans('Date').''; + print '
'.$langs->trans('DatePropal').''; print $form->selectDate('', '', '', '', '', "addprop", 1, 1); print '
'; print ''; if ($action != 'editdate' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { print ''; diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php index 4e592c8371e..2b21c545c63 100644 --- a/htdocs/comm/propal/document.php +++ b/htdocs/comm/propal/document.php @@ -80,6 +80,8 @@ if (!$sortfield) { $object = new Propal($db); $object->fetch($id, $ref); +$permissiontoadd = $user->rights->propale->creer; + // Security check if (!empty($user->socid)) { $socid = $user->socid; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 43c83117457..e1ec555837f 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -10,7 +10,7 @@ * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2016-2018 Ferran Marcet + * Copyright (C) 2016-2021 Ferran Marcet * Copyright (C) 2017-2018 Charlene Benke * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2019 Alexandre Spangaro @@ -182,7 +182,7 @@ $arrayfields = array( 'state.nom'=>array('label'=>"StateShort", 'checked'=>0), 'country.code_iso'=>array('label'=>"Country", 'checked'=>0), 'typent.code'=>array('label'=>"ThirdPartyType", 'checked'=>$checkedtypetiers), - 'p.date'=>array('label'=>"Date", 'checked'=>1), + 'p.date'=>array('label'=>"DatePropal", 'checked'=>1), 'p.fin_validite'=>array('label'=>"DateEnd", 'checked'=>1), 'p.date_livraison'=>array('label'=>"DeliveryDate", 'checked'=>0), 'ava.rowid'=>array('label'=>"AvailabilityPeriod", 'checked'=>0), @@ -711,24 +711,12 @@ if ($resql) { if ($sall) { $param .= '&sall='.urlencode($sall); } - if ($search_date_start) { - $param .= '&search_date_start='.urlencode($search_date_start); - } - if ($search_date_end) { - $param .= '&search_date_end='.urlencode($search_date_end); - } - if ($search_dateend_start) { - $param .= '&search_dateend_start='.urlencode($search_dateend_start); - } - if ($search_dateend_end) { - $param .= '&search_dateend_end='.urlencode($search_dateend_end); - } - if ($search_datedelivery_start) { - $param .= '&search_datedelivery_start='.urlencode($search_datedelivery_start); - } - if ($search_datedelivery_end) { - $param .= '&search_datedelivery_end='.urlencode($search_datedelivery_end); - } + if ($search_date_start) $param .= '&search_date_startday='.urlencode(dol_print_date($search_date_start, '%d')).'&search_date_startmonth='.urlencode(dol_print_date($search_date_start, '%m')).'&search_date_startyear='.urlencode(dol_print_date($search_date_start, '%Y')); + if ($search_date_end) $param .= '&search_date_endday='.urlencode(dol_print_date($search_date_end, '%d')).'&search_date_endmonth='.urlencode(dol_print_date($search_date_end, '%m')).'&search_date_endyear='.urlencode(dol_print_date($search_date_end, '%Y')); + if ($search_dateend_start) $param .= '&search_dateend_startday='.urlencode(dol_print_date($search_dateend_start, '%d')).'&search_dateend_startmonth='.urlencode(dol_print_date($search_dateend_start, '%m')).'&search_dateend_startyear='.urlencode(dol_print_date($search_dateend_start, '%Y')); + if ($search_dateend_end) $param .= '&search_dateend_endday='.urlencode(dol_print_date($search_dateend_end, '%d')).'&search_dateend_endmonth='.urlencode(dol_print_date($search_dateend_end, '%m')).'&search_dateend_endyear='.urlencode(dol_print_date($search_dateend_end, '%Y')); + if ($search_datedelivery_start) $param .= '&search_datedelivery_startday='.urlencode(dol_print_date($search_datedelivery_start, '%d')).'&search_datedelivery_startmonth='.urlencode(dol_print_date($search_datedelivery_start, '%m')).'&search_datedelivery_startyear='.urlencode(dol_print_date($search_datedelivery_start, '%Y')); + if ($search_datedelivery_end) $param .= '&search_datedelivery_endday='.urlencode(dol_print_date($search_datedelivery_end, '%d')).'&search_datedelivery_endmonth='.urlencode(dol_print_date($search_datedelivery_end, '%m')).'&search_datedelivery_endyear='.urlencode(dol_print_date($search_datedelivery_end, '%Y')); if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } @@ -787,37 +775,37 @@ if ($resql) { $param .= '&search_categ_cus='.urlencode($search_categ_cus); } if ($search_product_category != '') { - $param .= '&search_product_category='.$search_product_category; + $param .= '&search_product_category='.urlencode($search_product_category); } if ($search_fk_cond_reglement > 0) { - $param .= '&search_fk_cond_reglement='.$search_fk_cond_reglement; + $param .= '&search_fk_cond_reglement='.urlencode($search_fk_cond_reglement); } if ($search_fk_shipping_method > 0) { - $param .= '&search_fk_shipping_method='.$search_fk_shipping_method; + $param .= '&search_fk_shipping_method='.urlencode($search_fk_shipping_method); } if ($search_fk_input_reason > 0) { - $param .= '&search_fk_input_reason='.$search_fk_input_reason; + $param .= '&search_fk_input_reason='.urlencode($search_fk_input_reason); } if ($search_fk_mode_reglement > 0) { - $param .= '&search_fk_mode_reglement='.$search_fk_mode_reglement; + $param .= '&search_fk_mode_reglement='.urlencode($search_fk_mode_reglement); } if ($search_type_thirdparty > 0) { - $param .= '&search_type_thirdparty='.$search_type_thirdparty; + $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); } if ($search_town) { - $param .= '&search_town='.$search_town; + $param .= '&search_town='.urlencode($search_town); } if ($search_zip) { - $param .= '&search_zip='.$search_zip; + $param .= '&search_zip='.urlencode($search_zip); } if ($search_state) { - $param .= '&search_state='.$search_state; + $param .= '&search_state='.urlencode($search_state); } if ($search_town) { - $param .= '&search_town='.$search_town; + $param .= '&search_town='.urlencode($search_town); } if ($search_country) { - $param .= '&search_country='.$search_country; + $param .= '&search_country='.urlencode($search_country); } // Add $param from extra fields @@ -825,23 +813,22 @@ if ($resql) { // List of mass actions available $arrayofmassactions = array( - 'generate_doc'=>img_picto('', 'pdf').' '.$langs->trans("ReGeneratePDF"), - 'builddoc'=>img_picto('', 'pdf').' '.$langs->trans("PDFMerge"), - + 'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), + 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), ); if ($permissiontosendbymail) { - $arrayofmassactions['presend']=img_picto('', 'email').' '.$langs->trans("SendByMail"); + $arrayofmassactions['presend']=img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"); } if ($permissiontovalidate) { - $arrayofmassactions['prevalidate']=img_picto('', 'check').' '.$langs->trans("Validate"); + $arrayofmassactions['prevalidate']=img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"); } if ($permissiontoclose) { - $arrayofmassactions['presign']=img_picto('', 'propal').' '.$langs->trans("Sign"); - $arrayofmassactions['nopresign']=img_picto('', 'propal').' '.$langs->trans("NoSign"); - $arrayofmassactions['setbilled'] =img_picto('', 'bill').' '.$langs->trans("ClassifyBilled"); + $arrayofmassactions['presign']=img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans("Sign"); + $arrayofmassactions['nopresign']=img_picto('', 'propal', 'class="pictofixedwidth"').$langs->trans("NoSign"); + $arrayofmassactions['setbilled'] =img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("ClassifyBilled"); } if ($permissiontodelete) { - $arrayofmassactions['predelete'] = img_picto('', 'delete').' '.$langs->trans("Delete"); + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if (in_array($massaction, array('presend', 'predelete', 'closed'))) { diff --git a/htdocs/commande/document.php b/htdocs/commande/document.php index b4dddc9a1bf..c289112ee9f 100644 --- a/htdocs/commande/document.php +++ b/htdocs/commande/document.php @@ -44,12 +44,6 @@ $confirm = GETPOST('confirm'); $id = GETPOST('id', 'int'); $ref = GETPOST('ref'); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'commande', $id, ''); - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -78,6 +72,14 @@ if (!$sortfield) { $object = new Commande($db); +$permissiontoadd = $user->rights->commande->creer; + +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'commande', $id, ''); + /* * Actions diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 3747b2107b2..5bb8e6ccb0c 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -9,7 +9,7 @@ * Copyright (C) 2015-2018 Frédéric France * Copyright (C) 2015 Marcos García * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2016-2021 Ferran Marcet * Copyright (C) 2018 Charlene Benke * Copyright (C) 2021 Anthony Berton * @@ -706,10 +706,10 @@ if ($resql) { $param .= '&search_status='.urlencode($search_status); } if ($search_datecloture_start) { - $param .= '&search_datecloture_start='.urlencode($search_datecloture_start); + $param .= '&search_datecloture_startday='.dol_print_date($search_datecloture_start, '%d').'&search_datecloture_startmonth='.dol_print_date($search_datecloture_start, '%m').'&search_datecloture_startyear='.dol_print_date($search_datecloture_start, '%Y'); } if ($search_datecloture_end) { - $param .= '&search_datecloture_end='.urlencode($search_datecloture_end); + $param .= '&search_datecloture_endday='.dol_print_date($search_datecloture_end, '%d').'&search_datecloture_endmonth='.dol_print_date($search_datecloture_end, '%m').'&search_datecloture_endyear='.dol_print_date($search_datecloture_end, '%Y'); } if ($search_dateorder_start) { $param .= '&search_dateorder_start_day='.dol_print_date($search_dateorder_start, '%d').'&search_dateorder_start_month='.dol_print_date($search_dateorder_start, '%m').'&search_dateorder_start_year='.dol_print_date($search_dateorder_start, '%Y'); @@ -805,16 +805,16 @@ if ($resql) { $param .= '&search_billed='.urlencode($search_billed); } if ($search_fk_cond_reglement > 0) { - $param .= '&search_fk_cond_reglement='.$search_fk_cond_reglement; + $param .= '&search_fk_cond_reglement='.urlencode($search_fk_cond_reglement); } if ($search_fk_shipping_method > 0) { - $param .= '&search_fk_shipping_method='.$search_fk_shipping_method; + $param .= '&search_fk_shipping_method='.urlencode($search_fk_shipping_method); } if ($search_fk_mode_reglement > 0) { - $param .= '&search_fk_mode_reglement='.$search_fk_mode_reglement; + $param .= '&search_fk_mode_reglement='.urlencode($search_fk_mode_reglement); } if ($search_fk_input_reason > 0) { - $param .= '&search_fk_input_reason='.$search_fk_input_reason; + $param .= '&search_fk_input_reason='.urlencode($search_fk_input_reason); } // Add $param from extra fields @@ -887,7 +887,6 @@ if ($resql) { } if ($massaction == 'createbills') { - //var_dump($_REQUEST); print ''; print '
'; - print $langs->trans('Date'); + print $langs->trans('DatePropal'); print 'id.'">'.img_edit($langs->trans('SetDate'), 1).'
'; diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index bf30b1831f9..30aa32a8d58 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -829,7 +829,7 @@ if ($action == 'create') { print ''; print ''; print ''; - print ''."\n\n"; + print ''."\n\n"; print dol_get_fiche_head(array(), 0, '', 0); diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 48b7c505264..e5b4b2d2398 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1093,6 +1093,19 @@ if (empty($reshook)) { } } $id = $object->create($user); + if ($id < 0) { + $error++; + } else { + // copy internal contacts + if ($object->copy_linked_contact($facture_source, 'internal') < 0) { + $error++; + } elseif ($facture_source->socid == $object->socid) { + // copy external contacts if same company + if ($object->copy_linked_contact($facture_source, 'external') < 0) { + $error++; + } + } + } // NOTE: Pb with situation invoice // NOTE: fields total on situation invoice are stored as cumulative values on total of lines (bad) but delta on invoice total diff --git a/htdocs/compta/facture/document.php b/htdocs/compta/facture/document.php index 664b84d4444..16cdee4ac53 100644 --- a/htdocs/compta/facture/document.php +++ b/htdocs/compta/facture/document.php @@ -72,6 +72,8 @@ if ($object->fetch($id, $ref)) { $upload_dir = $conf->facture->dir_output."/".dol_sanitizeFileName($object->ref); } +$permissiontoadd = $user->rights->facture->creer; + // Security check if ($user->socid) { $socid = $user->socid; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 14b0383fa8d..1ac8765171d 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -10,7 +10,7 @@ * Copyright (C) 2013 Florian Henry * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2015-2016 Ferran Marcet + * Copyright (C) 2015-2021 Ferran Marcet * Copyright (C) 2017 Josep Lluís Amador * Copyright (C) 2018 Charlene Benke * Copyright (C) 2019-2021 Alexandre Spangaro diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index 39b5ded892b..04eee81ced0 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -126,8 +126,8 @@ if ($action == 'create' && GETPOST("accountid", "int") > 0 && $user->rights->ban // Define output language $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } //if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; if (!empty($newlang)) { @@ -177,8 +177,8 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $user->rights->banque- // Define output language $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } //if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; if (!empty($newlang)) { @@ -219,8 +219,8 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) { $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } //if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$object->client->default_lang; if (!empty($newlang)) { diff --git a/htdocs/core/actions_linkedfiles.inc.php b/htdocs/core/actions_linkedfiles.inc.php index 13814511297..750ed2b2d9a 100644 --- a/htdocs/core/actions_linkedfiles.inc.php +++ b/htdocs/core/actions_linkedfiles.inc.php @@ -21,13 +21,14 @@ // Variable $upload_dir must be defined when entering here. // Variable $upload_dirold may also exists. // Variable $confirm must be defined. +// If variable $permissiontoadd is defined, we check it is true. Note: A test on permission should already have been done into the restrictedArea() method called by parent page. //var_dump($upload_dir); //var_dump($upload_dirold); // Submit file/link -if (GETPOST('sendit', 'alpha') && !empty($conf->global->MAIN_UPLOAD_DOC)) { +if (GETPOST('sendit', 'alpha') && !empty($conf->global->MAIN_UPLOAD_DOC) && (!isset($permissiontoadd) || $permissiontoadd)) { if (!empty($_FILES)) { if (is_array($_FILES['userfile']['tmp_name'])) { $userfiles = $_FILES['userfile']['tmp_name']; @@ -65,7 +66,7 @@ if (GETPOST('sendit', 'alpha') && !empty($conf->global->MAIN_UPLOAD_DOC)) { } } } -} elseif (GETPOST('linkit', 'restricthtml') && !empty($conf->global->MAIN_UPLOAD_DOC)) { +} elseif (GETPOST('linkit', 'restricthtml') && !empty($conf->global->MAIN_UPLOAD_DOC) && (!isset($permissiontoadd) || $permissiontoadd)) { $link = GETPOST('link', 'alpha'); if ($link) { if (substr($link, 0, 7) != 'http://' && substr($link, 0, 8) != 'https://' && substr($link, 0, 7) != 'file://' && substr($link, 0, 7) != 'davs://') { @@ -77,7 +78,7 @@ if (GETPOST('sendit', 'alpha') && !empty($conf->global->MAIN_UPLOAD_DOC)) { // Delete file/link -if ($action == 'confirm_deletefile' && $confirm == 'yes') { +if ($action == 'confirm_deletefile' && $confirm == 'yes' && (!isset($permissiontoadd) || $permissiontoadd)) { $urlfile = GETPOST('urlfile', 'alpha', 0, null, null, 1); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). if (GETPOST('section', 'alpha')) { // For a delete from the ECM module, upload_dir is ECM root dir and urlfile contains relative path from upload_dir @@ -149,7 +150,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes') { exit; } } -} elseif ($action == 'confirm_updateline' && GETPOST('save', 'alpha') && GETPOST('link', 'alpha')) { +} elseif ($action == 'confirm_updateline' && GETPOST('save', 'alpha') && GETPOST('link', 'alpha') && (!isset($permissiontoadd) || $permissiontoadd)) { require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; $langs->load('link'); $link = new Link($db); @@ -167,7 +168,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes') { } else { //error fetching } -} elseif ($action == 'renamefile' && GETPOST('renamefilesave', 'alpha')) { +} elseif ($action == 'renamefile' && GETPOST('renamefilesave', 'alpha') && (!isset($permissiontoadd) || $permissiontoadd)) { // For documents pages, upload_dir contains already path to file from module dir, so we clean path into urlfile. if (!empty($upload_dir)) { $filenamefrom = dol_sanitizeFileName(GETPOST('renamefilefrom', 'alpha'), '_', 0); // Do not remove accents diff --git a/htdocs/core/ajax/row.php b/htdocs/core/ajax/row.php index 4662c3a1406..96dc792938f 100644 --- a/htdocs/core/ajax/row.php +++ b/htdocs/core/ajax/row.php @@ -49,6 +49,9 @@ if (!defined('NOREQUIRETRAN')) { require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/genericobject.class.php'; +// Security check +// This is done later into view. + /* * View @@ -59,16 +62,16 @@ top_httphead(); print ''."\n"; // Registering the location of boxes -if (GETPOST('roworder', 'alpha', 2) && GETPOST('table_element_line', 'aZ09', 2) - && GETPOST('fk_element', 'aZ09', 2) && GETPOST('element_id', 'int', 2)) { - $roworder = GETPOST('roworder', 'alpha', 2); - $table_element_line = GETPOST('table_element_line', 'aZ09', 2); - $fk_element = GETPOST('fk_element', 'aZ09', 2); - $element_id = GETPOST('element_id', 'int', 2); +if (GETPOST('roworder', 'alpha', 3) && GETPOST('table_element_line', 'aZ09', 3) + && GETPOST('fk_element', 'aZ09', 3) && GETPOST('element_id', 'int', 3)) { + $roworder = GETPOST('roworder', 'alpha', 3); + $table_element_line = GETPOST('table_element_line', 'aZ09', 3); + $fk_element = GETPOST('fk_element', 'aZ09', 3); + $element_id = GETPOST('element_id', 'int', 3); dol_syslog("AjaxRow roworder=".$roworder." table_element_line=".$table_element_line." fk_element=".$fk_element." element_id=".$element_id, LOG_DEBUG); - // Make test on pemrission + // Make test on permission $perm = 0; if ($table_element_line == 'propaldet' && $user->rights->propal->creer) { $perm = 1; @@ -92,6 +95,10 @@ if (GETPOST('roworder', 'alpha', 2) && GETPOST('table_element_line', 'aZ09', 2) $perm = 1; } elseif ($table_element_line == 'facture_fourn_det' && $user->rights->fourn->facture->creer) { $perm = 1; + } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_product' && (!empty($user->rights->produit->creer) || !empty($user->rights->service->creer))) { + $perm = 1; + } elseif ($table_element_line == 'ecm_files' && $fk_element == 'fk_ticket' && !empty($user->rights->ticket->write)) { + $perm = 1; } else { $tmparray = explode('_', $table_element_line); $tmpmodule = $tmparray[0]; $tmpobject = preg_replace('/line$/', '', $tmparray[1]); @@ -101,7 +108,10 @@ if (GETPOST('roworder', 'alpha', 2) && GETPOST('table_element_line', 'aZ09', 2) } if (! $perm) { + // We should not be here. If we are not allowed to reorder rows, feature should not be visible on script. + // If we are here, it is a hack attempt, so we report a warning. print 'Bad permission to modify position of lines for object in table '.$table_element_line; + dol_syslog('Bad permission to modify position of lines for object in table '.$table_element_line.', fk_element '.$fk_element, LOG_WARNING); accessforbidden('Bad permission to modify position of lines for object in table '.$table_element_line); } diff --git a/htdocs/core/boxes/box_dolibarr_state_board.php b/htdocs/core/boxes/box_dolibarr_state_board.php index d26dd2cb075..348ffeda4cd 100644 --- a/htdocs/core/boxes/box_dolibarr_state_board.php +++ b/htdocs/core/boxes/box_dolibarr_state_board.php @@ -60,13 +60,6 @@ class box_dolibarr_state_board extends ModeleBoxes global $conf, $user; $this->db = $db; - - // disable box for such cases - if (!empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) { - $this->enabled = 0; // disabled by this option - } - - $this->hidden = !(!empty($user->rights->societe->lire) && empty($user->socid)); } /** diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 7eecea00ff6..b1819e24ab0 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1259,7 +1259,7 @@ class DolGraph if ($i > 0) { $this->stringtoshow .= ', '; } - $this->stringtoshow .= "'" . dol_escape_js(dol_trunc($val, 22)) . "'"; + $this->stringtoshow .= "'" . dol_escape_js(dol_trunc($val, 25)) . "'"; // Lower than 25 make some important label (that we can't shorten) to be truncated $i++; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 625e8e23d57..9b90ed0b30a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7692,8 +7692,12 @@ class Form 'order'=>array('enabled'=>$conf->commande->enabled, 'perms'=>1, 'label'=>'LinkToOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('commande').')'), 'invoice'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_client, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('invoice').')'), 'invoice_template'=>array('enabled'=>$conf->facture->enabled, 'perms'=>1, 'label'=>'LinkToTemplateInvoice', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.titre as ref, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_rec as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('invoice').')'), - 'contrat'=>array('enabled'=>$conf->contrat->enabled, 'perms'=>1, 'label'=>'LinkToContract', - 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_customer as ref_client, t.ref_supplier, SUM(td.total_ht) as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t, ".MAIN_DB_PREFIX."contratdet as td WHERE t.fk_soc = s.rowid AND td.fk_contrat = t.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('contract').')'), + 'contrat'=>array( + 'enabled'=>$conf->contrat->enabled, + 'perms'=>1, + 'label'=>'LinkToContract', + 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_customer as ref_client, t.ref_supplier, SUM(td.total_ht) as total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."contrat as t, ".MAIN_DB_PREFIX."contratdet as td WHERE t.fk_soc = s.rowid AND td.fk_contrat = t.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('contract').') GROUP BY s.rowid, s.nom, s.client, t.rowid, t.ref, t.ref_customer, t.ref_supplier' + ), 'fichinter'=>array('enabled'=>$conf->ficheinter->enabled, 'perms'=>1, 'label'=>'LinkToIntervention', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."fichinter as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('intervention').')'), 'supplier_proposal'=>array('enabled'=>$conf->supplier_proposal->enabled, 'perms'=>1, 'label'=>'LinkToSupplierProposal', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, '' as ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('supplier_proposal').')'), 'order_supplier'=>array('enabled'=>$conf->supplier_order->enabled, 'perms'=>1, 'label'=>'LinkToSupplierOrder', 'sql'=>"SELECT s.rowid as socid, s.nom as name, s.client, t.rowid, t.ref, t.ref_supplier, t.total_ht FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande_fournisseur as t WHERE t.fk_soc = s.rowid AND t.fk_soc IN (".$this->db->sanitize($listofidcompanytoscan).') AND t.entity IN ('.getEntity('commande_fournisseur').')'), diff --git a/htdocs/core/class/html.formticket.class.php b/htdocs/core/class/html.formticket.class.php index 7d012077700..3cec6c19789 100644 --- a/htdocs/core/class/html.formticket.class.php +++ b/htdocs/core/class/html.formticket.class.php @@ -103,11 +103,13 @@ class FormTicket */ public function __construct($db) { + global $conf; + $this->db = $db; $this->action = 'add'; - $this->withcompany = 1; + $this->withcompany = $conf->societe->enabled ? 1 : 0; $this->withfromsocid = 0; $this->withfromcontactid = 0; //$this->withthreadid=0; diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php index c11bdd5563d..6a8a91dbb05 100644 --- a/htdocs/core/class/rssparser.class.php +++ b/htdocs/core/class/rssparser.class.php @@ -1,19 +1,19 @@ * -* 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 -* the Free Software Foundation; either version 3 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -*/ + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ /** * \file htdocs/core/class/rssparser.class.php @@ -538,22 +538,18 @@ class RssParser if ($el == 'channel') { $this->inchannel = true; - } elseif ($el == 'item' or $el == 'entry') { + } elseif ($el == 'item' || $el == 'entry') { $this->initem = true; if (isset($attrs['rdf:about'])) { $this->current_item['about'] = $attrs['rdf:about']; } - } elseif ($this->_format == 'rss' and - $this->current_namespace == '' and - $el == 'textinput') { + } elseif ($this->_format == 'rss' && $this->current_namespace == '' && $el == 'textinput') { // if we're in the default namespace of an RSS feed, // record textinput or image fields $this->intextinput = true; - } elseif ($this->_format == 'rss' and - $this->current_namespace == '' and - $el == 'image') { + } elseif ($this->_format == 'rss' && $this->current_namespace == '' && $el == 'image') { $this->inimage = true; - } elseif ($this->_format == 'atom' and in_array($el, $this->_CONTENT_CONSTRUCTS)) { + } elseif ($this->_format == 'atom' && in_array($el, $this->_CONTENT_CONSTRUCTS)) { // handle atom content constructs // avoid clashing w/ RSS mod_content if ($el == 'content') { @@ -561,7 +557,7 @@ class RssParser } $this->incontent = $el; - } elseif ($this->_format == 'atom' and $this->incontent) { + } elseif ($this->_format == 'atom' && $this->incontent) { // if inside an Atom content construct (e.g. content or summary) field treat tags as text // if tags are inlined, then flatten $attrs_str = join(' ', array_map('map_attrs', array_keys($attrs), array_values($attrs))); @@ -569,7 +565,7 @@ class RssParser $this->append_content("<$element $attrs_str>"); array_unshift($this->stack, $el); - } elseif ($this->_format == 'atom' and $el == 'link') { + } elseif ($this->_format == 'atom' && $el == 'link') { // Atom support many links per containging element. // Magpie treats link elements of type rel='alternate' // as being equivalent to RSS's simple link element. diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 513b73658f7..303382f285b 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -906,7 +906,7 @@ function listOfSessions() if (preg_match('/dol_login/i', $sessValues) && // limit to dolibarr session (preg_match('/dol_entity\|i:'.$conf->entity.';/i', $sessValues) || preg_match('/dol_entity\|s:([0-9]+):"'.$conf->entity.'"/i', $sessValues)) && // limit to current entity - preg_match('/dol_company\|s:([0-9]+):"('.$conf->global->MAIN_INFO_SOCIETE_NOM.')"/i', $sessValues)) { // limit to company name + preg_match('/dol_company\|s:([0-9]+):"('.getDolGlobalString('MAIN_INFO_SOCIETE_NOM').')"/i', $sessValues)) { // limit to company name $tmp = explode('_', $file); $idsess = $tmp[1]; $regs = array(); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 970ec73e373..a987cf03e4c 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -634,17 +634,17 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null $out = checkVal($out, $check, $filter, $options); } - // Sanitizing for special parameters. There is no reason to allow the backtopage, backtolist or backtourl parameter to contains an external URL. + // Sanitizing for special parameters. + // Note: There is no reason to allow the backtopage, backtolist or backtourl parameter to contains an external URL. if ($paramname == 'backtopage' || $paramname == 'backtolist' || $paramname == 'backtourl') { - $out = str_replace('\\', '/', $out); - $out = str_replace(array(':', ';', '@'), '', $out); - + $out = str_replace('\\', '/', $out); // Can be before the loop because only 1 char is replaced. No risk to get it after other replacements. + $out = str_replace(array(':', ';', '@'), '', $out); // Can be before the loop because only 1 char is replaced. No risk to get it after other replacements. do { $oldstringtoclean = $out; $out = str_ireplace(array('javascript', 'vbscript', '&colon', '&#'), '', $out); } while ($oldstringtoclean != $out); - $out = preg_replace(array('/^[a-z]*\/\/+/i'), '', $out); + $out = preg_replace(array('/^[a-z]*\/\/+/i'), '', $out); // We remove schema*// to remove external URL } // Code for search criteria persistence. @@ -684,7 +684,7 @@ function GETPOSTINT($paramname, $method = 0, $filter = null, $options = null, $n } /** - * Return a value after checking on a rule. + * Return a value after checking on a rule. A sanitization may also have been done. * * @param string $out Value to check/clear. * @param string $check Type of check/sanitizing @@ -777,6 +777,11 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = case 'restricthtml': // Recommended for most html textarea do { $oldstringtoclean = $out; + + // We replace chars encoded with numeric HTML entities with real char (to avoid to have numeric entities used for obfuscation of injections) + $out = preg_replace_callback('/&#(x?[0-9][0-9a-f]+);/i', 'realCharForNumericEntities', $out); + $out = preg_replace('/&#x?[0-9]+/i', '', $out); // For example if we have javascript with an entities without the ; to hide the 'a' of 'javascript'. + $out = dol_string_onlythesehtmltags($out, 0, 1, 1); // We should also exclude non expected attributes @@ -797,7 +802,6 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options = } - if (!function_exists('dol_getprefix')) { /** * Return a prefix to use for this Dolibarr instance, for session/cookie names or email id. @@ -7317,7 +7321,6 @@ function make_substitutions($text, $substitutionarray, $outputlangs = null, $con } else { $value = dol_nl2br("$value"); } - $text = str_replace("$key", "$value", $text); // We must keep the " to work when value is 123.5 for example } } @@ -9739,8 +9742,8 @@ function dolGetButtonAction($label, $html = '', $actionType = 'default', $url = /** * Add space between dolGetButtonTitle * - * @param string $moreClass more css class label - * @return string html of title separator + * @param string $moreClass more css class label + * @return string html of title separator */ function dolGetButtonTitleSeparator($moreClass = "") { diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 6862b6d59e9..16891214ca5 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -482,9 +482,9 @@ function getNumberInvoicesPieChart($mode) $sql = "SELECT sum(".$db->ifsql("f.date_lim_reglement < '".date_format($datenowsub30, 'Y-m-d')."'", 1, 0).") as nblate30"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement < '".date_format($datenowsub15, 'Y-m-d')."'", 1, 0).") as nblate15"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement < '".date_format($now, 'Y-m-d')."'", 1, 0).") as nblatenow"; - $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd30, 'Y-m-d')."'", 1, 0).") as nbnotlate30"; - $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd15, 'Y-m-d')."'", 1, 0).") as nbnotlate15"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement >= '".date_format($now, 'Y-m-d')."'", 1, 0).") as nbnotlatenow"; + $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd15, 'Y-m-d')."'", 1, 0).") as nbnotlate15"; + $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd30, 'Y-m-d')."'", 1, 0).") as nbnotlate30"; if ($mode == 'customers') { $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; } elseif ($mode == 'fourn') { @@ -513,7 +513,8 @@ function getNumberInvoicesPieChart($mode) foreach ($dataseries as $key=>$value) { $total+=$value[1]; } - $colorseries = array($badgeStatus8, $badgeStatus1, $badgeStatus3, $badgeStatus2, $badgeStatus4, $badgeStatus11); + + $colorseries = array($badgeStatus8, $badgeStatus1, $badgeStatus3, $badgeStatus4, $badgeStatus11, '-'.$badgeStatus11); if ($conf->use_javascript_ajax) { $result = '
'; $result .= '
'; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 1440a02983f..de4d67b1647 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -350,7 +350,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files) $createok = 1; $nbko = 0; - $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update'); + $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update') || GETPOST('roworder', 'alpha', 2); $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'); if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) { diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 15e7286ab08..880019d7b97 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -316,8 +316,8 @@ function show_list_sending_receive($origin, $origin_id, $filter = '') $outputlangs = $langs; $newlang = ''; - if (empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } if (empty($newlang)) { $newlang = $object->thirdparty->default_lang; diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index e2e06487de8..4d9d4bb2fa2 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -84,7 +84,7 @@ function ticket_prepare_head($object) $head[$h][2] = 'tabTicket'; $h++; - if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && empty($user->socid)) { + if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && empty($user->socid) && $conf->societe->enabled) { $nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external')); $head[$h][0] = DOL_URL_ROOT.'/ticket/contact.php?track_id='.$object->track_id; $head[$h][1] = $langs->trans('ContactsAddresses'); @@ -157,7 +157,8 @@ function showDirectPublicLink($object) $out = ''; if (empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) { - $out .= ''.$langs->trans("PublicInterfaceNotEnabled").''; + $langs->load('errors'); + $out .= ''.$langs->trans("ErrorPublicInterfaceNotEnabled").''; } else { $out .= img_picto('', 'object_globe.png').' '.$langs->trans("TicketPublicAccess").'
'; if ($url) { diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 4fa0f053236..89fd777cd20 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -502,7 +502,7 @@ function includeContainer($containerref) } $includehtmlcontentopened++; if ($includehtmlcontentopened > $MAXLEVEL) { - print 'ERROR: RECURSIVE CONTENT LEVEL. Depth of recursive call is more than the limit of '.$MAXLEVEL.".\n"; + print 'ERROR: RECURSIVE CONTENT LEVEL. Depth of recursive call is more than the limit of '.((int) $MAXLEVEL).".\n"; return; } @@ -549,20 +549,20 @@ function getStructuredData($type, $data = array()) "@type": "SoftwareApplication", "name": "'.dol_escape_json($data['name']).'", "operatingSystem": "'.dol_escape_json($data['os']).'", - "applicationCategory": "https://schema.org/'.$data['applicationCategory'].'",'; + "applicationCategory": "https://schema.org/'.dol_escape_json($data['applicationCategory']).'",'; if (!empty($data['ratingcount'])) { $ret .= ' "aggregateRating": { "@type": "AggregateRating", - "ratingValue": "'.$data['ratingvalue'].'", - "ratingCount": "'.$data['ratingcount'].'" + "ratingValue": "'.dol_escape_json($data['ratingvalue']).'", + "ratingCount": "'.dol_escape_json($data['ratingcount']).'" },'; } $ret .= ' "offers": { "@type": "Offer", - "price": "'.$data['price'].'", - "priceCurrency": "'.($data['currency'] ? $data['currency'] : $conf->currency).'" + "price": "'.dol_escape_json($data['price']).'", + "priceCurrency": "'.dol_escape_json($data['currency'] ? $data['currency'] : $conf->currency).'" } }'."\n"; $ret .= ''."\n"; @@ -618,7 +618,7 @@ function getStructuredData($type, $data = array()) $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl); $title = str_replace('__WEBSITE_KEY__', $website->ref, $title); - $image = '/medias/'.str_replace('__WEBSITE_KEY__', $website->ref, $image); + $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname); $description = str_replace('__WEBSITE_KEY__', $website->ref, $description); @@ -666,6 +666,8 @@ function getStructuredData($type, $data = array()) $ret .= '"description": "'.dol_escape_json($description).'"'; $ret .= "\n".'}'."\n"; $ret .= ''."\n"; + } else { + $ret .= ''."\n"; } } elseif ($type == 'product') { $ret = ''."\n"; @@ -691,8 +693,8 @@ function getStructuredData($type, $data = array()) "offers": { "@type": "Offer", "url": "https://example.com/anvil", - "priceCurrency": "'.($data['currency'] ? $data['currency'] : $conf->currency).'", - "price": "'.$data['price'].'", + "priceCurrency": "'.dol_escape_json($data['currency'] ? $data['currency'] : $conf->currency).'", + "price": "'.dol_escape_json($data['price']).'", "itemCondition": "https://schema.org/UsedCondition", "availability": "https://schema.org/InStock", "seller": { diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index e35d9d4490c..74c66e899f4 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -227,6 +227,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $tmpentry = array( 'enabled'=>(!empty($conf->propal->enabled) || !empty($conf->commande->enabled) + || !empty($conf->fournisseur->enabled) || !empty($conf->supplier_proposal->enabled) || !empty($conf->supplier_order->enabled) || !empty($conf->contrat->enabled) @@ -235,6 +236,8 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'perms'=>(!empty($user->rights->propal->lire) || !empty($user->rights->commande->lire) || !empty($user->rights->supplier_proposal->lire) + || !empty($user->rights->fournisseur->lire) + || !empty($user->rights->fournisseur->commande->lire) || !empty($user->rights->supplier_order->lire) || !empty($user->rights->contrat->lire) || !empty($user->rights->ficheinter->lire) diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index df1a625fdc8..b56fbc758db 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -1516,7 +1516,7 @@ class pdf_azur extends ModelePDFPropales $posy += 4; $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $pdf->MultiCell(100, 3, $outputlangs->transnoentities("Date")." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R'); + $pdf->MultiCell(100, 3, $outputlangs->transnoentities("DatePropal")." : ".dol_print_date($object->date, "day", false, $outputlangs, true), '', 'R'); $posy += 4; $pdf->SetXY($posx, $posy); diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index c4a21812b01..284407383d4 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -115,12 +115,14 @@ if (isset($extrafields->attributes[$elementtype]['type']) && is_array($extrafiel } print ''; } - print ''."\n"; + print ''."\n"; print ""; } } else { - $colspan = 13; + $colspan = 14; if (!empty($conf->multicompany->enabled)) { $colspan++; } diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index bca1386c82e..9c1387d7d58 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -58,8 +58,8 @@ if ($action == 'presend') { // Define output language $outputlangs = $langs; $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { $newlang = $object->thirdparty->default_lang; diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php index 7268da76007..f1b62676887 100644 --- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -26,6 +26,10 @@ if (!empty($extrafieldsobjectkey) && !empty($search_array_options) && is_array($ if ($crit != '' && in_array($typ, array('date', 'datetime', 'timestamp'))) { if (is_numeric($crit)) { + if ($typ == 'date') { + include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + $crit = dol_get_first_hour($crit); + } $sql .= " AND ".$extrafieldsobjectprefix.$tmpkey." = '".$db->idate($crit)."'"; } elseif (is_array($crit)) { if ($crit['start'] !== '' && $crit['end'] !== '') { diff --git a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php index b8454b80ea1..28565114a21 100644 --- a/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php +++ b/htdocs/core/triggers/interface_50_modLdap_Ldapsynchro.class.php @@ -183,7 +183,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers $this->error = "ErrorLDAP ".$ldap->error; } } - } elseif ($action == 'USER_SETINGROUP') { + /*} elseif ($action == 'USER_SETINGROUP') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { $ldap = new Ldap(); @@ -217,7 +217,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers $this->error = "ErrorLDAP ".$ldap->error; } } - } elseif ($action == 'USER_REMOVEFROMGROUP') { + } elseif ($action == 'USER_REMOVEFROMGROUP') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); if (!empty($conf->global->LDAP_SYNCHRO_ACTIVE) && $conf->global->LDAP_SYNCHRO_ACTIVE === 'dolibarr2ldap') { $ldap = new Ldap(); @@ -250,7 +250,7 @@ class InterfaceLdapsynchro extends DolibarrTriggers if ($result < 0) { $this->error = "ErrorLDAP ".$ldap->error; } - } + } */ } elseif ($action == 'USERGROUP_CREATE') { // Groupes dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -262,8 +262,8 @@ class InterfaceLdapsynchro extends DolibarrTriggers $info = $object->_load_ldap_info(); $dn = $object->_load_ldap_dn($info); - // Get a gid number for objectclass PosixGroup - if (in_array('posixGroup', $info['objectclass'])) { + // Get a gid number for objectclass PosixGroup if none was provided + if (empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID]) && in_array('posixGroup', $info['objectclass'])) { $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); } diff --git a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php index f2d77553827..4e808d5bf15 100644 --- a/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_99_modZapier_ZapierTriggers.class.php @@ -111,13 +111,9 @@ class InterfaceZapierTriggers extends DolibarrTriggers //case 'USER_NEW_PASSWORD': //case 'USER_ENABLEDISABLE': //case 'USER_DELETE': - //case 'USER_SETINGROUP': - //case 'USER_REMOVEFROMGROUP': - // case 'USER_LOGIN': - // case 'USER_LOGIN_FAILED': - // case 'USER_LOGOUT': - // Warning: To increase performances, this action is triggered only if constant MAIN_ACTIVATE_UPDATESESSIONTRIGGER is set to 1. - // // case 'USER_UPDATE_SESSION': + //case 'USER_LOGIN': + //case 'USER_LOGIN_FAILED': + //case 'USER_LOGOUT': // Actions case 'ACTION_MODIFY': diff --git a/htdocs/delivery/card.php b/htdocs/delivery/card.php index 2c6415f17b7..4855c9c1e49 100644 --- a/htdocs/delivery/card.php +++ b/htdocs/delivery/card.php @@ -542,8 +542,8 @@ if ($action == 'create') { // Create. Seems to no be used if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { $outputlangs = $langs; $newlang = ''; - if (empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } if (empty($newlang)) { $newlang = $object->thirdparty->default_lang; diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 49675c263f9..a1070d02ef1 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -2,7 +2,7 @@ /* Copyright (C) 2001-2005 Rodolphe Quiedeville * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin - * Copyright (C) 2016-2018 Ferran Marcet + * Copyright (C) 2016-2021 Ferran Marcet * Copyright (C) 2019 Nicolas ZABOURI * Copyright (C) 2020 Thibault FOUCART * @@ -434,20 +434,18 @@ if ($search_zip) { if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) { $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); } - -if ($search_datedelivery_start) { - $param .= '&search_datedelivery_start='.urlencode($search_datedelivery_start); +if ($search_datedelivery_start) { + $param .= '&search_datedelivery_startday='.urlencode(dol_print_date($search_datedelivery_start, '%d')).'&search_datedelivery_startmonth='.urlencode(dol_print_date($search_datedelivery_start, '%m')).'&search_datedelivery_startyear='.urlencode(dol_print_date($search_datedelivery_start, '%Y')); } if ($search_datedelivery_end) { - $param .= '&search_datedelivery_end='.urlencode($search_datedelivery_end); + $param .= '&search_datedelivery_endday='.urlencode(dol_print_date($search_datedelivery_end, '%d')).'&search_datedelivery_endmonth='.urlencode(dol_print_date($search_datedelivery_end, '%m')).'&search_datedelivery_endyear='.urlencode(dol_print_date($search_datedelivery_end, '%Y')); } if ($search_datereceipt_start) { - $param .= '&search_datereceipt_start='.urlencode($search_datereceipt_start); + $param .= '&search_datereceipt_startday='.urlencode(dol_print_date($search_datereceipt_start, '%d')).'&search_datereceipt_startmonth='.urlencode(dol_print_date($search_datereceipt_start, '%m')).'&search_datereceipt_startyear='.urlencode(dol_print_date($search_datereceipt_start, '%Y')); } if ($search_datereceipt_end) { - $param .= '&search_datereceipt_end='.urlencode($search_datereceipt_end); + $param .= '&search_datereceipt_endday='.urlencode(dol_print_date($search_datereceipt_end, '%d')).'&search_datereceipt_endmonth='.urlencode(dol_print_date($search_datereceipt_end, '%m')).'&search_datereceipt_endyear='.urlencode(dol_print_date($search_datereceipt_end, '%Y')); } - if ($search_product_category != '') { $param .= '&search_product_category='.urlencode($search_product_category); } @@ -863,10 +861,6 @@ while ($i < min($num, $limit)) { if (!empty($arrayfields['e.date_delivery']['checked'])) { print '\n"; } // Tracking number diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 1231f0b513e..8f5903dd988 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -687,8 +687,8 @@ if ($id > 0 || !empty($ref)) { $outputlangs = $langs; $newlang = ''; - if (empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); } if (empty($newlang)) { $newlang = $object->thirdparty->default_lang; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index a4c565bc1be..cb6dcfc94b8 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -55,6 +55,7 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); +$id = GETPOST('id', 'int'); $date_start = dol_mktime(0, 0, 0, GETPOST('date_debutmonth', 'int'), GETPOST('date_debutday', 'int'), GETPOST('date_debutyear', 'int')); $date_end = dol_mktime(0, 0, 0, GETPOST('date_finmonth', 'int'), GETPOST('date_finday', 'int'), GETPOST('date_finyear', 'int')); $date = dol_mktime(0, 0, 0, GETPOST('datemonth', 'int'), GETPOST('dateday', 'int'), GETPOST('dateyear', 'int')); @@ -120,7 +121,6 @@ if ($object->id > 0) { } // Security check -$id = GETPOST("id", 'int'); if ($user->socid) { $socid = $user->socid; } diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index be8c735edc1..8198883e58f 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -171,9 +171,6 @@ $langs->load("boxes"); $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.statut as user_status, u.photo, u.email, u.admin,"; $sql .= " d.rowid, d.ref, d.date_debut as dated, d.date_fin as datef, d.date_create as dm, d.total_ht, d.total_ttc, d.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as d, ".MAIN_DB_PREFIX."user as u"; -if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; -} $sql .= " WHERE u.rowid = d.fk_user_author"; // RESTRICT RIGHTS if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous) @@ -183,12 +180,6 @@ if (empty($user->rights->expensereport->readall) && empty($user->rights->expense $sql .= " AND d.fk_user_author IN (".$db->sanitize(join(',', $childids)).")\n"; } $sql .= ' AND d.entity IN ('.getEntity('expensereport').')'; -if (!$user->rights->societe->client->voir && !$user->socid) { - $sql .= " AND d.fk_user_author = s.rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); -} -if ($socid) { - $sql .= " AND d.fk_user_author = ".$socid; -} $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($max, 0); diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index e83899d28d1..ce1dc4e3c09 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -138,8 +138,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen $fieldstosearchall = array( 'd.ref'=>'Ref', 'd.note_public'=>"NotePublic", - 'u.lastname'=>'Lastname', - 'u.firstname'=>"Firstname", + 'u.lastname'=>'EmployeeLastname', + 'u.firstname'=>"EmployeeFirstname", 'u.login'=>"Login", ); if (empty($user->socid)) { diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 331e211e5ac..d094916ef38 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -280,6 +280,11 @@ class CommandeFournisseur extends CommonOrder const STATUS_REFUSED = 9; + /** + * The constant used into source field to track the order was generated by the replenishement feature + */ + const SOURCE_ID_REPLENISHMENT = 42; + /** @@ -2070,6 +2075,18 @@ class CommandeFournisseur extends CommonOrder // End call triggers } + // Test we can delete + $this->fetchObjectLinked(null, 'order_supplier'); + if (!empty($this->linkedObjects)) { + foreach ($this->linkedObjects['reception'] as $element) { + if ($element->statut >= 0) { + $this->errors[] = $langs->trans('ReceptionExist'); + $error++; + break; + } + } + } + $main = MAIN_DB_PREFIX.'commande_fournisseurdet'; $ef = $main."_extrafields"; $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = ".$this->id.")"; diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index bb0ad661c82..9c201497566 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -2325,7 +2325,7 @@ if ($action == 'create') { print dol_get_fiche_end(); /** - * Boutons actions + * Buttons for actions */ if ($user->socid == 0 && $action != 'editline' && $action != 'delete') { @@ -2433,11 +2433,19 @@ if ($action == 'create') { } // Ship - + $hasreception = 0; if (!empty($conf->stock->enabled) && (!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION) || !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE))) { $labelofbutton = $langs->trans('ReceiveProducts'); if ($conf->reception->enabled) { $labelofbutton = $langs->trans("CreateReception"); + if (!empty($object->linkedObjects)) { + foreach ($object->linkedObjects['reception'] as $element) { + if ($element->statut >= 0) { + $hasreception = 1; + break; + } + } + } } if (in_array($object->statut, array(3, 4, 5))) { @@ -2508,7 +2516,11 @@ if ($action == 'create') { // Delete if (!empty($usercandelete) || ($object->statut == CommandeFournisseur::STATUS_DRAFT && !empty($usercancreate))) { - print ''.$langs->trans("Delete").''; + if ($hasreception) { + print ''.$langs->trans("Delete").''; + } else { + print ''.$langs->trans("Delete").''; + } } } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index d32e466444c..fb1891051e6 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -1284,6 +1284,7 @@ if ($resql) { $objectstatic->id = $obj->rowid; $objectstatic->ref = $obj->ref; $objectstatic->ref_supplier = $obj->ref_supplier; + $objectstatic->socid = $obj->socid; $objectstatic->total_ht = $obj->total_ht; $objectstatic->total_tva = $obj->total_tva; $objectstatic->total_ttc = $obj->total_ttc; diff --git a/htdocs/hrm/index.php b/htdocs/hrm/index.php index 09485357956..50fd4c3f521 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -40,8 +40,13 @@ if ($conf->deplacement->enabled) { if ($conf->expensereport->enabled) { require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; } -require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentcandidature.class.php'; -require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; +if ($conf->recruitment->enabled) { + require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentcandidature.class.php'; + require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; +} +if ($conf->holiday->enabled) { + require_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; +} $hookmanager = new HookManager($db); $hookmanager->initHooks('hrmindex'); @@ -60,10 +65,6 @@ if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INF $setupcompanynotcomplete = 1; } -$holiday = new Holiday($db); -$holidaystatic = new Holiday($db); -$staticrecruitmentcandidature = new RecruitmentCandidature($db); - $max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; @@ -73,7 +74,8 @@ $max = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; // Update sold if (!empty($conf->holiday->enabled) && !empty($setupcompanynotcomplete)) { - $result = $holiday->updateBalance(); + $holidaystatic = new Holiday($db); + $result = $holidaystatic->updateBalance(); } @@ -144,6 +146,7 @@ if (!empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) { // This is usel if (!empty($conf->holiday->enabled)) { if (empty($conf->global->HOLIDAY_HIDE_BALANCE)) { + $holidaystatic = new Holiday($db); $user_id = $user->id; print '
'; @@ -154,9 +157,9 @@ if (!empty($conf->holiday->enabled)) { $out = ''; $nb_holiday = 0; - $typeleaves = $holiday->getTypes(1, 1); + $typeleaves = $holidaystatic->getTypes(1, 1); foreach ($typeleaves as $key => $val) { - $nb_type = $holiday->getCPforUser($user->id, $val['rowid']); + $nb_type = $holidaystatic->getCPforUser($user->id, $val['rowid']); $nb_holiday += $nb_type; $out .= ' - '.($langs->trans($val['code']) != $val['code'] ? $langs->trans($val['code']) : $val['label']).': '.($nb_type ? price2num($nb_type) : 0).'
'; } @@ -179,7 +182,7 @@ print '
'; // Latest leave requests if (!empty($conf->holiday->enabled) && $user->rights->holiday->read) { $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.photo, u.statut as user_status,"; - $sql .= " x.rowid, x.rowid as ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; + $sql .= " x.rowid, x.ref, x.fk_type, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.tms as dm, x.statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE u.rowid = x.fk_user"; $sql .= " AND x.entity = ".$conf->entity; @@ -330,20 +333,23 @@ if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->lire) // Last modified job position if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read) { - $sql = "SELECT rc.rowid, rc.ref, rc.email, rc.lastname, rc.firstname, rc.date_creation, rc.tms, rc.status"; + $staticrecruitmentcandidature = new RecruitmentCandidature($db); + $staticrecruitmentjobposition = new RecruitmentJobPosition($db); + $sql = "SELECT rc.rowid, rc.ref, rc.email, rc.lastname, rc.firstname, rc.date_creation, rc.tms, rc.status,"; + $sql.= " rp.rowid as jobid, rp.ref as jobref, rp.label"; $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s ON rc.fk_recruitmentjobposition = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as rp ON rc.fk_recruitmentjobposition = rp.rowid"; + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } - $sql .= " WHERE rc.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; - if (!$user->rights->societe->client->voir && !$socid) { - $sql .= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; + $sql .= " WHERE rc.entity IN (".getEntity($staticrecruitmentcandidature->element).")"; + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { + $sql .= " AND rp.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; } if ($socid) { - $sql .= " AND s.fk_soc = $socid"; + $sql .= " AND rp.fk_soc = $socid"; } - $sql .= " ORDER BY rc.tms DESC"; + $sql .= $db->order("rc.tms", "DESC"); $sql .= $db->plimit($max, 0); $resql = $db->query($sql); @@ -354,8 +360,8 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme print '
'; print '
'.img_edit().''; - print '  '.img_delete().''; + print ''.img_edit().''; + print '  '.img_delete().''; + print '
'; print dol_print_date($db->jdate($obj->delivery_date), "dayhour"); - /*$now = time(); - if ( ($now - $db->jdate($obj->date_expedition)) > $conf->warnings->lim && $obj->statutid == 1 ) - { - }*/ print "
'; print ''; - print ''; print ''; print ''; @@ -370,11 +376,15 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme $staticrecruitmentcandidature->firstname = $objp->firstname; $staticrecruitmentcandidature->lastname = $objp->lastname; + $staticrecruitmentjobposition->id = $objp->jobid; + $staticrecruitmentjobposition->ref = $objp->jobref; + $staticrecruitmentjobposition->label = $objp->label; + print ''; print ''; - print '"; - print '"; + print ''; + print ''; + print ''; print '"; diff --git a/htdocs/install/mysql/data/llx_00_c_country.sql b/htdocs/install/mysql/data/llx_00_c_country.sql index fa2b4339983..296b6d0e412 100644 --- a/htdocs/install/mysql/data/llx_00_c_country.sql +++ b/htdocs/install/mysql/data/llx_00_c_country.sql @@ -117,13 +117,13 @@ INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (86 INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (87,'GQ','GNQ','Guinée Equatoriale',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (88,'ER','ERI','Erythrée',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (89,'EE','EST','Estonia',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (90,'ET','ETH','Ethiopie',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (91,'FK','FLK','Iles Falkland',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (92,'FO','FRO','Iles Féroé',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (93,'FJ','FJI','Iles Fidji',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (94,'FI','FIN','Finlande',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (95,'GF','GUF','Guyane française',1,0); -INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (96,'PF','PYF','Polynésie française',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (90,'ET','ETH','Ethiopia',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (91,'FK','FLK','Falkland Islands',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (92,'FO','FRO','Faroe Islands',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (93,'FJ','FJI','Fidji Islands',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (94,'FI','FIN','Finland',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (95,'GF','GUF','French Guiana',1,0); +INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (96,'PF','PYF','French Polynesia',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (97,'TF','ATF','Terres australes françaises',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (98,'GM','GMB','Gambie',1,0); INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (99,'GE','GEO','Georgia',1,0); diff --git a/htdocs/install/mysql/data/llx_20_c_departements.sql b/htdocs/install/mysql/data/llx_20_c_departements.sql index 7436c123100..5e739f07b72 100644 --- a/htdocs/install/mysql/data/llx_20_c_departements.sql +++ b/htdocs/install/mysql/data/llx_20_c_departements.sql @@ -765,16 +765,16 @@ INSERT INTO llx_c_departements (fk_region, code_departement, cheflieu, tncc, ncc -- Panama - 10 Provinces (id country=178) -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-1', '', 0, '', 'Bocas del Toro'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-2', '', 0, '', 'Coclé'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-3', '', 0, '', 'Colón'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-4', '', 0, '', 'Chiriquí'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-5', '', 0, '', 'Darién'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-6', '', 0, '', 'Herrera'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-7', '', 0, '', 'Los Santos'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-8', '', 0, '', 'Panamá'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-9', '', 0, '', 'Veraguas'); -INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES (17801, 'PA-13', '', 0, '', 'Panamá Oeste'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-1', 17801, '', 0, '', 'Bocas del Toro'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-2', 17801, '', 0, '', 'Coclé'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-3', 17801, '', 0, '', 'Colón'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-4', 17801, '', 0, '', 'Chiriquí'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-5', 17801, '', 0, '', 'Darién'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-6', 17801, '', 0, '', 'Herrera'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-7', 17801, '', 0, '', 'Los Santos'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-8', 17801, '', 0, '', 'Panamá'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-9', 17801, '', 0, '', 'Veraguas'); +INSERT INTO llx_c_departements (code_departement, fk_region, cheflieu, tncc, ncc, nom) VALUES ('PA-13', 17801, '', 0, '', 'Panamá Oeste'); -- Provinces Peru (id country=181) diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index da2cd34fa00..cf5da55d719 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -491,11 +491,15 @@ CREATE TABLE llx_knowledgemanagement_knowledgerecord( import_key varchar(14), model_pdf varchar(255), question text NOT NULL, - answer text, + answer text, + fk_ticket integer, status integer NOT NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; +ALTER TABLE llx_knowledgemanagement_knowledgerecord ADD COLUMN fk_ticket integer; + + create table llx_knowledgemanagement_knowledgerecord_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, diff --git a/htdocs/install/mysql/tables/llx_c_ticket_category.sql b/htdocs/install/mysql/tables/llx_c_ticket_category.sql index 10d16331a06..57bd15f2c23 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_category.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_category.sql @@ -15,7 +15,7 @@ -- along with this program. If not, see . -- --- Table with the categories of a ticket +-- Table with the custom category tree for the category of a ticket -- create table llx_c_ticket_category diff --git a/htdocs/install/mysql/tables/llx_c_ticket_type.sql b/htdocs/install/mysql/tables/llx_c_ticket_type.sql index d480036d5d5..462d1a71535 100644 --- a/htdocs/install/mysql/tables/llx_c_ticket_type.sql +++ b/htdocs/install/mysql/tables/llx_c_ticket_type.sql @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -- --- +-- Type of ticket. For example: COM, ISSUE, REQUEST, PROJECT, OTHER, ... create table llx_c_ticket_type ( diff --git a/htdocs/install/mysql/tables/llx_knowledgemanagement_knowledgerecord.sql b/htdocs/install/mysql/tables/llx_knowledgemanagement_knowledgerecord.sql index 9c2866980ec..5c9e4cf199f 100644 --- a/htdocs/install/mysql/tables/llx_knowledgemanagement_knowledgerecord.sql +++ b/htdocs/install/mysql/tables/llx_knowledgemanagement_knowledgerecord.sql @@ -27,7 +27,8 @@ CREATE TABLE llx_knowledgemanagement_knowledgerecord( import_key varchar(14), model_pdf varchar(255), question text NOT NULL, - answer text, + answer text, + fk_ticket integer, status integer NOT NULL -- END MODULEBUILDER FIELDS ) ENGINE=innodb; diff --git a/htdocs/knowledgemanagement/class/knowledgerecord.class.php b/htdocs/knowledgemanagement/class/knowledgerecord.class.php index 2dba1581d9e..4d46794aaf8 100644 --- a/htdocs/knowledgemanagement/class/knowledgerecord.class.php +++ b/htdocs/knowledgemanagement/class/knowledgerecord.class.php @@ -110,8 +110,8 @@ class KnowledgeRecord extends CommonObject 'fk_user_valid' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>'1', 'position'=>512, 'notnull'=>0, 'visible'=>-2,), '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,), - 'question' => array('type'=>'text', 'label'=>'Question', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1,), - 'answer' => array('type'=>'html', 'label'=>'Solution', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>-1,), + 'question' => array('type'=>'text', 'label'=>'Question', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'csslist'=>'tdoverflow300'), + 'answer' => array('type'=>'html', 'label'=>'Solution', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>3, 'csslist'=>'tdoverflow300'), 'status' => array('type'=>'integer', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'default'=>0, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Valid'),), ); public $rowid; diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 405689a57e5..8329346c163 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -286,9 +286,9 @@ ReportPurchaseTurnover=Purchase turnover invoiced ReportPurchaseTurnoverCollected=Purchase turnover collected IncludeVarpaysInResults = Include various payments in reports IncludeLoansInResults = Include loans in reports -InvoiceLate30Days = Invoices late 30 days -InvoiceLate15Days = Invoices late 15 days +InvoiceLate30Days = Invoices late > 30 days +InvoiceLate15Days = Invoices late > 15 days InvoiceLateMinus15Days = Invoices late -InvoiceNotLate = To pay < 15 days -InvoiceNotLate15Days = To pay > 15 days -InvoiceNotLate30Days = To pay in > 30 days +InvoiceNotLate = To be collected < 15 days +InvoiceNotLate15Days = To be collected in 15 days +InvoiceNotLate30Days = To be collected in 30 days diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index d91989190e0..72d78178cf1 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -430,6 +430,7 @@ LT1IN=CGST LT2IN=SGST LT1GC=Additionnal cents VATRate=Tax Rate +RateOfTaxN=Rate of tax %s VATCode=Tax Rate code VATNPR=Tax Rate NPR DefaultTaxRate=Default tax rate diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang index 760ff884fa0..338602e722e 100644 --- a/htdocs/langs/en_US/receptions.lang +++ b/htdocs/langs/en_US/receptions.lang @@ -44,4 +44,4 @@ ValidateOrderFirstBeforeReception=You must first validate the order before being ReceptionsNumberingModules=Numbering module for receptions ReceptionsReceiptModel=Document templates for receptions NoMorePredefinedProductToDispatch=No more predefined products to dispatch - +ReceptionExist=A reception exists diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 0c3679adac5..7b40647ebcb 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -50,9 +50,33 @@ if (!empty($_SERVER['MAIN_SHOW_TUNING_INFO'])) { } } + +/** + * Return the real char for a numeric entities. + * This function is required by testSqlAndScriptInject(). + * + * @param string $matches String of numeric entity + * @return string New value + */ +function realCharForNumericEntities($matches) +{ + $newstringnumentity = $matches[1]; + + if (preg_match('/^x/i', $newstringnumentity)) { + $newstringnumentity = hexdec(preg_replace('/^x/i', '', $newstringnumentity)); + } + + // The numeric value we don't want as entities + if (($newstringnumentity >= 65 && $newstringnumentity <= 90) || ($newstringnumentity >= 97 && $newstringnumentity <= 122)) { + return chr((int) $newstringnumentity); + } + + return '&#'.$matches[1]; +} + /** * Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF). - * Warning: Such a protection can't be enough. It is not reliable as it will alwyas be possible to bypass this. Good protection can + * Warning: Such a protection can't be enough. It is not reliable as it will always be possible to bypass this. Good protection can * only be guaranted by escaping data during output. * * @param string $val Value brut found int $_GET, $_POST or PHP_SELF @@ -61,7 +85,7 @@ if (!empty($_SERVER['MAIN_SHOW_TUNING_INFO'])) { */ function testSqlAndScriptInject($val, $type) { - // Decode string first bcause a lot of things are obfuscated by encoding or multiple encoding. + // Decode string first because a lot of things are obfuscated by encoding or multiple encoding. // So
-
- '.$langs->trans("ThirdParty").' -
+ '. img_picto('', 'object_company') .'
'. $langs->trans("ThirdParty") .'
'; } @@ -2228,9 +2252,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Contact").' -
+ '. img_picto('', 'object_contact') .'
'. $langs->trans("Contact") .'
'; } @@ -2241,9 +2263,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Proposal").' -
+ '. img_picto('', 'object_propal') .'
'. $langs->trans("Proposal") .'
'; } @@ -2254,9 +2274,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Order").' -
+ '. img_picto('', 'object_order') .'
'. $langs->trans("Order") .'
'; } @@ -2267,9 +2285,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Bill").' -
+ '. img_picto('', 'object_bill') .'
'. $langs->trans("Bill") .'
'; } @@ -2280,9 +2296,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Contract").' -
+ '. img_picto('', 'object_contract') .'
'. $langs->trans("Contract") .'
'; } @@ -2293,9 +2307,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("AskPrice").' -
+ '. img_picto('', 'object_propal') .'
'. $langs->trans("AskPrice") .'
'; } @@ -2306,9 +2318,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("SupplierOrder").' -
+ '. img_picto('', 'object_order') .'
'. $langs->trans("SupplierOrder") .'
'; } @@ -2319,9 +2329,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("SupplierBill").' -
+ '. img_picto('', 'object_bill') .'
'. $langs->trans("SupplierBill") .'
'; } @@ -2332,9 +2340,7 @@ function top_menu_quickadd()
-
- '.$langs->trans("Product").' -
+ '. img_picto('', 'object_product') .'
'. $langs->trans("Product") .'
'; } @@ -2345,9 +2351,29 @@ function top_menu_quickadd()
-
- '.$langs->trans("Service").' -
+ '. img_picto('', 'object_service') .'
'. $langs->trans("Service") .' +
+ '; + } + + if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->creer) { + $langs->load("trips"); + $dropDownQuickAddHtml .= ' + + + '; + } + + if (!empty($conf->holiday->enabled) && $user->rights->holiday->write) { + $langs->load("holiday"); + $dropDownQuickAddHtml .= ' + + '; } diff --git a/htdocs/modulebuilder/template/class/actions_mymodule.class.php b/htdocs/modulebuilder/template/class/actions_mymodule.class.php index 8559411a3d4..24be0243b8d 100644 --- a/htdocs/modulebuilder/template/class/actions_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/actions_mymodule.class.php @@ -303,5 +303,56 @@ class ActionsMyModule return 0; } + /** + * Execute action completeTabsHead + * + * @param array $parameters Array of parameters + * @param CommonObject $object The object to process (an invoice if you are in invoice module, a propale in propale's module, etc...) + * @param string $action 'add', 'update', 'view' + * @param Hookmanager $hookmanager hookmanager + * @return int <0 if KO, + * =0 if OK but we want to process standard actions too, + * >0 if OK and we want to replace standard actions. + */ + public function completeTabsHead(&$parameters, &$object, &$action, $hookmanager) + { + global $langs, $conf, $user; + + if (!isset($parameters['object']->element)) { + return 0; + } + if ($parameters['mode'] == 'remove') { + // utilisé si on veut faire disparaitre des onglets. + return 0; + } elseif ($parameters['mode'] == 'add') { + $langs->load('mymodule@mymodule'); + // utilisé si on veut ajouter des onglets. + $counter = count($parameters['head']); + $element = $parameters['object']->element; + $id = $parameters['object']->id; + // verifier le type d'onglet comme member_stats où ça ne doit pas apparaitre + // if (in_array($element, ['societe', 'member', 'contrat', 'fichinter', 'project', 'propal', 'commande', 'facture', 'order_supplier', 'invoice_supplier'])) { + if (in_array($element, ['context1', 'context2'])) { + $datacount = 0; + + $parameters['head'][$counter][0] = dol_buildpath('/mymodule/mymodule_tab.php', 1) . '?id=' . $id . '&module='.$element; + $parameters['head'][$counter][1] = $langs->trans('MyModuleTab'); + if ($datacount > 0) { + $parameters['head'][$counter][1] .= '' . $datacount . ''; + } + $parameters['head'][$counter][2] = 'mymoduleemails'; + $counter++; + } + if ($counter > 0 && (int) DOL_VERSION < 14) { + $this->results = $parameters['head']; + // return 1 to replace standard code + return 1; + } else { + // en V14 et + $parameters['head'] est modifiable par référence + return 0; + } + } + } + /* Add here any other hooked methods... */ } diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 28868add880..e29057c5423 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -119,8 +119,6 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'USER_NEW_PASSWORD': //case 'USER_ENABLEDISABLE': //case 'USER_DELETE': - //case 'USER_SETINGROUP': - //case 'USER_REMOVEFROMGROUP': // Actions //case 'ACTION_MODIFY': diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php index 8598cc3dd18..e3fa6390e93 100644 --- a/htdocs/modulebuilder/template/myobject_document.php +++ b/htdocs/modulebuilder/template/myobject_document.php @@ -124,7 +124,7 @@ if ($id > 0 || !empty($ref)) { $upload_dir = $conf->mymodule->multidir_output[$object->entity ? $object->entity : $conf->entity]."/myobject/".get_exdir(0, 0, 0, 1, $object); } -$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php +$permissiontoadd = $user->rights->mymodule->myobject->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php // Security check (enable the most restrictive one) //if ($user->socid > 0) accessforbidden(); diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index a5f28c50ee8..69429677c27 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -66,13 +66,13 @@ class FormProduct * 'warehouseclosed' = select products from closed warehouses, * 'warehouseinternal' = select products from warehouses for internal correct/transfer only * @param boolean $sumStock sum total stock of a warehouse, default true - * @param string $exclude warehouses ids to exclude + * @param array $exclude warehouses ids to exclude * @param bool|int $stockMin [=false] Value of minimum stock to filter or false not not filter by minimum stock * @param string $orderBy [='e.ref'] Order by * @return int Nb of loaded lines, 0 if already loaded, <0 if KO * @throws Exception */ - public function loadWarehouses($fk_product = 0, $batch = '', $status = '', $sumStock = true, $exclude = '', $stockMin = false, $orderBy = 'e.ref') + public function loadWarehouses($fk_product = 0, $batch = '', $status = '', $sumStock = true, $exclude = array(), $stockMin = false, $orderBy = 'e.ref') { global $conf, $langs; @@ -80,10 +80,6 @@ class FormProduct return 0; // Cache already loaded and we do not want a list with information specific to a product } - if (is_array($exclude)) { - $excludeGroups = implode("','", $exclude); - } - $warehouseStatus = array(); if (preg_match('/warehouseclosed/', $status)) { @@ -121,7 +117,7 @@ class FormProduct $sql .= " AND e.statut = 1"; } - if (!empty($exclude)) { + if (is_array($exclude) && !empty($exclude)) { $sql .= ' AND e.rowid NOT IN('.$this->db->sanitize(implode(',', $exclude)).')'; } @@ -220,7 +216,7 @@ class FormProduct * @param int $forcecombo 1=Force combo iso ajax select2 * @param array $events Events to add to select2 * @param string $morecss Add more css classes to HTML select - * @param string $exclude Warehouses ids to exclude + * @param array $exclude Warehouses ids to exclude * @param int $showfullpath 1=Show full path of name (parent ref into label), 0=Show only ref of current warehouse * @param bool|int $stockMin [=false] Value of minimum stock to filter or false not not filter by minimum stock * @param string $orderBy [='e.ref'] Order by @@ -228,7 +224,7 @@ class FormProduct * * @throws Exception */ - public function selectWarehouses($selected = '', $htmlname = 'idwarehouse', $filterstatus = '', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $showstock = 0, $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = '', $showfullpath = 1, $stockMin = false, $orderBy = 'e.ref') + public function selectWarehouses($selected = '', $htmlname = 'idwarehouse', $filterstatus = '', $empty = 0, $disabled = 0, $fk_product = 0, $empty_label = '', $showstock = 0, $forcecombo = 0, $events = array(), $morecss = 'minwidth200', $exclude = array(), $showfullpath = 1, $stockMin = false, $orderBy = 'e.ref') { global $conf, $langs, $user, $hookmanager; diff --git a/htdocs/product/document.php b/htdocs/product/document.php index af44521dc05..372e3c19bdc 100644 --- a/htdocs/product/document.php +++ b/htdocs/product/document.php @@ -113,7 +113,7 @@ if ($reshook < 0) { if (empty($reshook)) { // Delete line if product propal merge is linked to a file if (!empty($conf->global->PRODUIT_PDF_MERGE_PROPAL)) { - if ($action == 'confirm_deletefile' && $confirm == 'yes') { + if ($action == 'confirm_deletefile' && $confirm == 'yes' && $permissiontoadd) { //extract file name $urlfile = GETPOST('urlfile', 'alpha'); $filename = basename($urlfile); @@ -131,7 +131,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; } -if ($action == 'filemerge') { +if ($action == 'filemerge' && $permissiontoadd) { $is_refresh = GETPOST('refresh'); if (empty($is_refresh)) { $filetomerge_file_array = GETPOST('filetoadd'); diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 73124fd7bad..fe16aca2783 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -224,17 +224,24 @@ if ($action == 'order' && GETPOST('valid')) { $suppliersid = array_keys($suppliers); foreach ($suppliers as $supplier) { $order = new CommandeFournisseur($db); + // Check if an order for the supplier exists $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."commande_fournisseur"; $sql .= " WHERE fk_soc = ".((int) $suppliersid[$i]); - $sql .= " AND source = 42 AND fk_statut = 0"; + $sql .= " AND source = ".((int) $order::SOURCE_ID_REPLENISHMENT)." AND fk_statut = ".$order::STATUS_DRAFT; $sql .= " AND entity IN (".getEntity('commande_fournisseur').")"; $sql .= " ORDER BY date_creation DESC"; $resql = $db->query($sql); if ($resql && $db->num_rows($resql) > 0) { $obj = $db->fetch_object($resql); + $order->fetch($obj->rowid); + $order->fetch_thirdparty(); + foreach ($supplier['lines'] as $line) { + if (empty($line->remise_percent)) { + $line->remise_percent = $order->thirdparty->remise_supplier_percent; + } $result = $order->addline( $line->desc, $line->subprice, @@ -268,13 +275,19 @@ if ($action == 'order' && GETPOST('valid')) { } else { $order->socid = $suppliersid[$i]; $order->fetch_thirdparty(); - //trick to know which orders have been generated this way - $order->source = 42; + + // Trick to know which orders have been generated using the replenishment feature + $order->source = $order::SOURCE_ID_REPLENISHMENT; + foreach ($supplier['lines'] as $line) { + if (empty($line->remise_percent)) { + $line->remise_percent = $order->thirdparty->remise_supplier_percent; + } $order->lines[] = $line; } $order->cond_reglement_id = $order->thirdparty->cond_reglement_supplier_id; $order->mode_reglement_id = $order->thirdparty->mode_reglement_supplier_id; + $id = $order->create($user); if ($id < 0) { $fail++; diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index 788c75f1141..b36d530d624 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -363,7 +363,7 @@ print $form->select_produits($productid, 'productid', '', 0, 0, -1, 2, '', 0, ar print '   '; print img_picto('', 'stock').' '; print $langs->trans('Warehouse').' '; -print $formproduct->selectWarehouses((GETPOSTISSET('fk_warehouse') ? $fk_warehouse : 'ifone'), 'fk_warehouse', '', 1, 0, 0, '', 0, 0, null, '', '', 1, false, 'e.ref'); +print $formproduct->selectWarehouses((GETPOSTISSET('fk_warehouse') ? $fk_warehouse : 'ifone'), 'fk_warehouse', '', 1, 0, 0, '', 0, 0, null, '', null, 1, false, 'e.ref'); print ''; $parameters = array(); diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 3f9ec04d437..6bb905d6696 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -40,11 +40,6 @@ $ref = GETPOST('ref', 'alpha'); $mine = (GETPOST('mode', 'alpha') == 'mine' ? 1 : 0); //if (! $user->rights->projet->all->lire) $mine=1; // Special for projects -// Security check -$socid = 0; -//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result = restrictedArea($user, 'projet', $id, 'projet&project'); - $object = new Project($db); include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once @@ -82,6 +77,11 @@ if (!$sortfield) { $sortfield = "name"; } +// Security check +$socid = 0; +//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. +$result = restrictedArea($user, 'projet', $id, 'projet&project'); + /* diff --git a/htdocs/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index 3b6ff756b3c..7e369fe6bb2 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -331,18 +331,18 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms, s.status, COUNT(rc.rowid) as nbapplications"; $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc ON rc.fk_recruitmentjobposition = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; - if (!$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { $sql .= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; } if ($socid) { $sql .= " AND s.fk_soc = $socid"; } $sql .= " GROUP BY s.rowid, s.ref, s.label, s.date_creation, s.tms, s.status"; - $sql .= " ORDER BY s.tms DESC"; + $sql .= $db->order('s.tms', 'DESC'); $sql .= $db->plimit($max, 0); $resql = $db->query($sql); @@ -402,17 +402,17 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme $sql = "SELECT rc.rowid, rc.ref, rc.email, rc.lastname, rc.firstname, rc.date_creation, rc.tms, rc.status"; $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s ON rc.fk_recruitmentjobposition = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE rc.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; - if (!$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { $sql .= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id; } if ($socid) { $sql .= " AND s.fk_soc = $socid"; } - $sql .= " ORDER BY rc.tms DESC"; + $sql .= $db->order('rc.tms', 'DESC'); $sql .= $db->plimit($max, 0); $resql = $db->query($sql); diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 946ceeb42f3..e53675d8bb6 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2570,7 +2570,19 @@ class Societe extends CommonObject } } $label .= '
'.$langs->trans('Email').': '.$this->email; - if (!empty($this->country_code)) { + if (!empty($this->phone) || !empty($this->fax)) { + $phonelist = array(); + if ($this->phone) { + $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); + } + if ($this->fax) { + $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); + } + $label .= '
'.$langs->trans('Phone').': '.implode(' ', $phonelist); + } + if (!empty($this->address)) { + $label .= '
'.$langs->trans("Address").': '.dol_format_address($this, 1, ' ', $langs); // Address + country + } elseif (!empty($this->country_code)) { $label .= '
'.$langs->trans('Country').': '.$this->country_code; } if (!empty($this->tva_intra) || (!empty($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP) && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) { diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php index 4ed26f67018..653069882e0 100644 --- a/htdocs/societe/document.php +++ b/htdocs/societe/document.php @@ -76,6 +76,7 @@ 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('thirdpartydocument', 'globalcard')); +$permissiontoadd = $user->rights->societe->creer; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php // Security check if ($user->socid > 0) { diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index 9bf6cbc13c4..fee91e959aa 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -81,12 +81,9 @@ if (!$action) { // Security check $id = GETPOST("id", 'int'); $socid = 0; -//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. +if ($user->socid > 0) $socid = $user->socid; $result = restrictedArea($user, 'ticket', $id, ''); -if (!$user->rights->ticket->read) { - accessforbidden(); -} // restrict access for externals users if ($user->socid > 0 && ($object->fk_soc != $user->socid)) { accessforbidden(); diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 4b4b8e594d4..5e2ef1e804b 100644 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -112,8 +112,8 @@ if ($id || $track_id || $ref) { $url_page_current = DOL_URL_ROOT.'/ticket/card.php'; // Security check - Protection if external user -//if ($user->socid > 0) accessforbidden(); -//if ($user->socid > 0) $socid = $user->socid; +$socid = 0; +if ($user->socid > 0) $socid = $user->socid; $result = restrictedArea($user, 'ticket', $object->id); $triggermodname = 'TICKET_MODIFY'; @@ -1320,15 +1320,28 @@ if ($action == 'create' || $action == 'presend') { // add a message if ($action == 'presend' || $action == 'presend_addmessage') { + if ($object->fk_soc > 0) { + $object->fetch_thirdparty(); + } + + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) { + $newlang = GETPOST('lang_id', 'aZ09'); + } + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && is_object($object->thirdparty)) { + $newlang = $object->thirdparty->default_lang; + } + $arrayoffamiliestoexclude = array('objectamount'); + $action = 'add_message'; // action to use to post the message $modelmail = 'ticket_send'; // Substitution array $morehtmlright = ''; $help = ""; - $substitutionarray = array(); + $substitutionarray = getCommonSubstitutionArray($newlang, 0, $arrayoffamiliestoexclude, $object); if ($object->fk_soc > 0) { - $object->fetch_thirdparty(); $substitutionarray['__THIRDPARTY_NAME__'] = $object->thirdparty->name; } $substitutionarray['__USER_SIGNATURE__'] = $user->signature; @@ -1361,16 +1374,6 @@ if ($action == 'create' || $action == 'presend') { print '
'; - // Define output language - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && !empty($_REQUEST['lang_id'])) { - $newlang = $_REQUEST['lang_id']; - } - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) { - $newlang = $object->default_lang; - } - $formticket = new FormTicket($db); $formticket->action = $action; diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 6c883be6b1a..5180abe6140 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2917,7 +2917,7 @@ class Ticket extends CommonObject $sql = "SELECT p.rowid, p.ref, p.datec as datec"; $sql .= " FROM ".MAIN_DB_PREFIX."ticket as p"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".$user->id; $clause = " AND"; diff --git a/htdocs/ticket/contact.php b/htdocs/ticket/contact.php index 7e04dd12104..8d450ffb44b 100644 --- a/htdocs/ticket/contact.php +++ b/htdocs/ticket/contact.php @@ -50,11 +50,6 @@ $source = GETPOST('source', 'alpha'); $ligne = GETPOST('ligne', 'int'); $lineid = GETPOST('lineid', 'int'); -// Protection if external user -if ($user->socid > 0) { - $socid = $user->socid; - accessforbidden(); -} // Store current page url $url_page_current = dol_buildpath('/ticket/contact.php', 1); @@ -62,6 +57,24 @@ $url_page_current = dol_buildpath('/ticket/contact.php', 1); $object = new Ticket($db); +$permissiontoadd = $user->rights->ticket->write; + +// Security check +$id = GETPOST("id", 'int'); +$socid = 0; +if ($user->socid > 0) $socid = $user->socid; +$result = restrictedArea($user, 'ticket', $object->id, ''); + +// restrict access for externals users +if ($user->socid > 0 && ($object->fk_soc != $user->socid)) { + accessforbidden(); +} +// or for unauthorized internals users +if (!$user->socid && (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) { + accessforbidden(); +} + + /* * Actions */ diff --git a/htdocs/ticket/document.php b/htdocs/ticket/document.php index 5e4d80cd8be..8edd2787c44 100644 --- a/htdocs/ticket/document.php +++ b/htdocs/ticket/document.php @@ -43,11 +43,6 @@ $track_id = GETPOST('track_id', 'alpha'); $action = GETPOST('action', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -if (!$user->rights->ticket->read) { - accessforbidden(); -} - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -75,6 +70,21 @@ if ($result < 0) { $upload_dir = $conf->ticket->dir_output."/".dol_sanitizeFileName($object->ref); } +$permissiontoadd = $user->rights->ticket->write; + +// Security check - Protection if external user +$result = restrictedArea($user, 'ticket', $object->id); + +// restrict access for externals users +if ($user->socid > 0 && ($object->fk_soc != $user->socid)) { + accessforbidden(); +} +// or for unauthorized internals users +if (!$user->socid && ($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) { + accessforbidden(); +} + + /* * Actions diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index c3e70def7da..68615424abf 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -76,16 +76,14 @@ if (!$action) { $action = 'view'; } +$permissiontoadd = $user->rights->ticket->write; // Security check $id = GETPOST("id", 'int'); $socid = 0; -//if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. -$result = restrictedArea($user, 'ticket', $id, ''); +if ($user->socid > 0) $socid = $user->socid; +$result = restrictedArea($user, 'ticket', $object->id, ''); -if (!$user->rights->ticket->read) { - accessforbidden(); -} // restrict access for externals users if ($user->socid > 0 && ($object->fk_soc != $user->socid)) { accessforbidden(); @@ -96,7 +94,6 @@ if (!$user->socid && (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && } - /* * Actions */ diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index f5f0b73a70f..e760997f3c8 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -21,6 +21,7 @@ use Luracast\Restler\RestException; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + /** * API class for users * @@ -47,6 +48,7 @@ class Users extends DolibarrApi public function __construct() { global $db, $conf; + $this->db = $db; $this->useraccount = new User($this->db); } @@ -62,15 +64,15 @@ class Users extends DolibarrApi * @param int $limit Limit for list * @param int $page Page number * @param string $user_ids User ids filter field. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * @param int $category Use this param to filter list by category + * @param int $category Use this param to filter list by category * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" * @return array Array of User objects */ public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $category = 0, $sqlfilters = '') { - global $db, $conf; + global $conf; - if (!DolibarrApiAccess::$user->rights->user->user->lire) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, "You are not allowed to read list of users"); } @@ -149,7 +151,7 @@ class Users extends DolibarrApi */ public function get($id, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } @@ -187,7 +189,7 @@ class Users extends DolibarrApi */ public function getByLogin($login, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } @@ -221,7 +223,7 @@ class Users extends DolibarrApi */ public function getByEmail($email, $includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } @@ -254,7 +256,7 @@ class Users extends DolibarrApi */ public function getInfo($includepermissions = 0) { - if (empty(DolibarrApiAccess::$user->rights->user->user->lire)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } @@ -295,7 +297,7 @@ class Users extends DolibarrApi public function post($request_data = null) { // Check user authorization - if (empty(DolibarrApiAccess::$user->rights->user->user->creer)) { + if (empty(DolibarrApiAccess::$user->rights->user->creer) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, "User creation not allowed for login ".DolibarrApiAccess::$user->login); } @@ -345,7 +347,7 @@ class Users extends DolibarrApi public function put($id, $request_data = null) { // Check user authorization - if (empty(DolibarrApiAccess::$user->rights->user->creer)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->creer) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, "User update not allowed"); } @@ -423,7 +425,7 @@ class Users extends DolibarrApi */ public function getGroups($id) { - if (!DolibarrApiAccess::$user->rights->user->user->lire) { + if (empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(403); } @@ -463,7 +465,7 @@ class Users extends DolibarrApi { global $conf; - if (empty(DolibarrApiAccess::$user->rights->user->user->creer)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->creer) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401); } @@ -512,12 +514,12 @@ class Users extends DolibarrApi */ public function listGroups($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $group_ids = 0, $sqlfilters = '') { - global $db, $conf; + global $conf; $obj_ret = array(); - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->user->lire)) || - !empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->group_advance->read)) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) || + !empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->group_advance->read) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, "You are not allowed to read groups"); } @@ -590,8 +592,8 @@ class Users extends DolibarrApi { global $db, $conf; - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->user->lire)) || - !empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->group_advance->read)) { + if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->user->lire) && empty(DolibarrApiAccess::$user->admin)) || + !empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty(DolibarrApiAccess::$user->rights->user->group_advance->read) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, "You are not allowed to read groups"); } @@ -616,7 +618,7 @@ class Users extends DolibarrApi */ public function delete($id) { - if (empty(DolibarrApiAccess::$user->rights->user->user->supprimer)) { + if (empty(DolibarrApiAccess::$user->rights->user->user->supprimer) && empty(DolibarrApiAccess::$user->admin)) { throw new RestException(401, 'Not allowed'); } $result = $this->useraccount->fetch($id); diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 2752ee745a1..981374996cf 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -2411,8 +2411,18 @@ class User extends CommonObject $label .= '
'.$langs->trans("Job").': '.dol_string_nohtmltag($this->job); } $label .= '
'.$langs->trans("Email").': '.dol_string_nohtmltag($this->email); - if (!empty($this->phone)) { - $label .= '
'.$langs->trans("Phone").': '.dol_string_nohtmltag($this->phone); + if (!empty($this->office_phone) || !empty($this->office_fax) || !empty($this->fax)) { + $phonelist = array(); + if ($this->office_phone) { + $phonelist[] = dol_print_phone($this->office_phone, $this->country_code, $this->id, 0, '', ' ', 'phone'); + } + if ($this->office_fax) { + $phonelist[] = dol_print_phone($this->office_fax, $this->country_code, $this->id, 0, '', ' ', 'fax'); + } + if ($this->user_mobile) { + $phonelist[] = dol_print_phone($this->user_mobile, $this->country_code, $this->id, 0, '', ' ', 'mobile'); + } + $label .= '
'.$langs->trans('Phone').': '.implode(' ', $phonelist); } if (!empty($this->admin)) { $label .= '
'.$langs->trans("Administrator").': '.yn($this->admin); @@ -2795,10 +2805,10 @@ class User extends CommonObject if (!empty($conf->global->LDAP_FIELD_USERID)) { $info[$conf->global->LDAP_FIELD_USERID] = $this->id; } - if (!empty($info[$conf->global->LDAP_FIELD_GROUPID])) { + if (!empty($conf->global->LDAP_FIELD_GROUPID)) { $usergroup = new UserGroup($this->db); $groupslist = $usergroup->listGroupsForUser($this->id); - $info[$conf->global->LDAP_FIELD_GROUPID] = '1'; + $info[$conf->global->LDAP_FIELD_GROUPID] = '65534'; if (!empty($groupslist)) { foreach ($groupslist as $groupforuser) { $info[$conf->global->LDAP_FIELD_GROUPID] = $groupforuser->id; //Select first group in list @@ -2806,8 +2816,8 @@ class User extends CommonObject } } } - if (!empty($this->firstname) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) { - $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY] = "{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->firstname"; + if (!empty($conf->global->LDAP_FIELD_HOMEDIRECTORY) && !empty($conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX)) { + $info[$conf->global->LDAP_FIELD_HOMEDIRECTORY] = "{$conf->global->LDAP_FIELD_HOMEDIRECTORYPREFIX}/$this->login"; } return $info; diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 3738c63b435..cacaeb54fc1 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -856,7 +856,7 @@ class UserGroup extends CommonObject } $info[$conf->global->LDAP_GROUP_FIELD_GROUPMEMBERS] = (!empty($valueofldapfield) ? $valueofldapfield : ''); } - if (!empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID])) { + if (!empty($conf->global->LDAP_GROUP_FIELD_GROUPID)) { $info[$conf->global->LDAP_GROUP_FIELD_GROUPID] = $this->id; } return $info; diff --git a/htdocs/user/group/card.php b/htdocs/user/group/card.php index 33921544b45..19b78cf06e9 100644 --- a/htdocs/user/group/card.php +++ b/htdocs/user/group/card.php @@ -138,7 +138,11 @@ if (empty($reshook)) { if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { $object->entity = 0; } else { - $object->entity = GETPOST("entity"); + if ($conf->entity == 1 && $user->admin && !$user->entity) { // Same permissions test than the one used to show the combo of entities into the form + $object->entity = GETPOSTISSET("entity") ? GETPOST("entity") : $conf->entity; + } else { + $object->entity = $conf->entity; + } } $db->begin(); diff --git a/htdocs/user/group/ldap.php b/htdocs/user/group/ldap.php index aee79688aee..458978d25ea 100644 --- a/htdocs/user/group/ldap.php +++ b/htdocs/user/group/ldap.php @@ -67,8 +67,8 @@ if ($action == 'dolibarr2ldap') { if ($result > 0) { $info = $object->_load_ldap_info(); - // Get a gid number for objectclass PosixGroup - if (in_array('posixGroup', $info['objectclass'])) { + // Get a gid number for objectclass PosixGroup if none was provided + if (empty($info[$conf->global->LDAP_GROUP_FIELD_GROUPID]) && in_array('posixGroup', $info['objectclass'])) { $info['gidNumber'] = $ldap->getNextGroupGid('LDAP_KEY_GROUPS'); } diff --git a/htdocs/website/index.php b/htdocs/website/index.php index da1244b567c..69ff8127e6c 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2390,6 +2390,18 @@ if ($action == 'generatesitemaps' && $usercanedit) { } } + // Now add sitempas extension for news + // TODO When adding and when not ? + /* + + The Example Times + en + + 2008-12-23 + Companies A, B in Merger Talks + + */ + $root->appendChild($url); $i++; } diff --git a/scripts/emailings/mailing-send.php b/scripts/emailings/mailing-send.php index d3c8e152c6b..0d59a1b5db5 100755 --- a/scripts/emailings/mailing-send.php +++ b/scripts/emailings/mailing-send.php @@ -269,6 +269,12 @@ if ($resql) { $substitutionisok = true; + $moreinheader = ''; + if (preg_match('/__UNSUBSCRIBE__/', $message)) { + $moreinheader = "List-Unsubscribe: <__UNSUBSCRIBE_URL__>\n"; + $moreinheader = make_substitutions($moreinheader, $substitutionarray); + } + $arr_file = array(); $arr_mime = array(); $arr_name = array(); @@ -285,7 +291,7 @@ if ($resql) { } // Fabrication du mail $trackid = 'emailing-'.$obj->fk_mailing.'-'.$obj->rowid; - $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css, $trackid, '', 'emailing'); + $mail = new CMailFile($newsubject, $sendto, $from, $newmessage, $arr_file, $arr_mime, $arr_name, '', '', 0, $msgishtml, $errorsto, $arr_css, $trackid, $moreinheader, 'emailing'); if ($mail->error) { $res = 0; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 5c5274c0437..bd4d0e9b76d 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -198,20 +198,29 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=testSqlAndScriptInject($test, 0); $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 0b'); - // Should detect XSS + + // Should detect attack $expectedresult=1; $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php/'; $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject for PHP_SELF that should detect XSS'); + $test = 'javascript:'; + $result=testSqlAndScriptInject($test, 0); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for javascript1. Should find an attack and did not.'); + + $test = 'javascript:'; + $result=testSqlAndScriptInject($test, 0); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for javascript2. Should find an attack and did not.'); + $test = 'javascript&colon;alert(1)'; $result=testSqlAndScriptInject($test, 0); - $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject expected 1a'); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for javascript2'); $test=""; $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa'); + $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa1'); $test=""; $result=testSqlAndScriptInject($test, 2); @@ -328,9 +337,12 @@ class SecurityTest extends PHPUnit\Framework\TestCase $_POST["param10"]='is_object($object) ? ($object->id < 10 ? round($object->id / 2, 2) : (2 * $user->id) * (int) substr($mysoc->zip, 1, 2)) : \'objnotdefined\''; $_POST["param11"]=' Name '; $_POST["param12"]='aaa'; + $_POST["param13"]='n n > < " XSS'; + $_POST["param13b"]='n n > < " XSS'; //$_POST["param13"]='javascript%26colon%26%23x3B%3Balert(1)'; //$_POST["param14"]='javascripT&javascript#x3a alert(1)'; + $result=GETPOST('id', 'int'); // Must return nothing print __METHOD__." result=".$result."\n"; $this->assertEquals($result, ''); @@ -343,7 +355,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals($result, 333, 'Test on param1 with 3rd param = 2'); - // Test alpha + // Test with alpha $result=GETPOST("param2", 'alpha'); print __METHOD__." result=".$result."\n"; @@ -357,7 +369,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals($result, 'dir'); - // Test aZ09 + // Test with aZ09 $result=GETPOST("param1", 'aZ09'); print __METHOD__." result=".$result."\n"; @@ -379,25 +391,22 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals($_GET["param5"], $result); - $result=GETPOST("param6", 'alpha'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals('>', $result); + // Test with nohtml $result=GETPOST("param6", 'nohtml'); print __METHOD__." result=".$result."\n"; $this->assertEquals('">', $result); - $result=GETPOST("param6b"); + // Test with alpha = alphanohtml. We must convert the html entities like n and disable all entities + + $result=GETPOST("param6", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('>', $result); + + $result=GETPOST("param6b", 'alphanohtml'); print __METHOD__." result=".$result."\n"; $this->assertEquals('abc', $result); - // With restricthtml we must remove html open/close tag and content but not htmlentities like n - - $result=GETPOST("param7", 'restricthtml'); - print __METHOD__." result=".$result."\n"; - $this->assertEquals('"c:\this is a path~1\aaan" abcdef', $result); - - // With alphanohtml, we must convert the html entities like n and disable all entities $result=GETPOST("param8a", 'alphanohtml'); print __METHOD__." result=".$result."\n"; $this->assertEquals("Hackersvg onload='console.log(123)'", $result); @@ -434,24 +443,39 @@ class SecurityTest extends PHPUnit\Framework\TestCase print __METHOD__." result=".$result."\n"; $this->assertEquals("Name", $result, 'Test an email string with alphanohtml'); + $result=GETPOST("param13", 'alphanohtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('n n > < XSS', $result, 'Test that html entities are decoded with alpha'); + + // Test with alphawithlgt + $result=GETPOST("param11", 'alphawithlgt'); print __METHOD__." result=".$result."\n"; $this->assertEquals(trim($_POST["param11"]), $result, 'Test an email string with alphawithlgt'); + // Test with restricthtml we must remove html open/close tag and content but not htmlentities (we can decode html entities for ascii chars like n) + + $result=GETPOST("param6", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('">', $result); + + $result=GETPOST("param7", 'restricthtml'); + print __METHOD__." result=".$result."\n"; + $this->assertEquals('"c:\this is a path~1\aaan" abcdef', $result); + $result=GETPOST("param12", 'restricthtml'); print __METHOD__." result=".$result."\n"; $this->assertEquals(trim($_POST["param12"]), $result, 'Test a string with DOCTYPE and restricthtml'); - /*$result=GETPOST("param13", 'alphanohtml'); + $result=GETPOST("param13", 'restricthtml'); print __METHOD__." result=".$result."\n"; - $this->assertEquals(trim($_POST["param13"]), $result, 'Test a string and alphanohtml'); + $this->assertEquals('n n > < " XSS', $result, 'Test that HTML entities are decoded with restricthtml, but only for common alpha chars'); - $result=GETPOST("param14", 'alphanohtml'); + $result=GETPOST("param13b", 'restricthtml'); print __METHOD__." result=".$result."\n"; - $this->assertEquals(trim($_POST["param14"]), $result, 'Test a string and alphanohtml'); - */ + $this->assertEquals('n n > < " XSS', $result, 'Test that HTML entities are decoded with restricthtml, but only for common alpha chars'); - // Special test for GETPOST of backtopage or backtolist parameter + // Special test for GETPOST of backtopage, backtolist or backtourl parameter $_POST["backtopage"]='//www.google.com'; $result=GETPOST("backtopage");
'; - print $langs->trans("BoxTitleLatestModifiedCandidatures", $max); + print ''; + print $langs->trans("BoxTitleLatestModifiedCandidatures", min($max, $num)); print ''.$langs->trans("FullList").'
'.$staticrecruitmentcandidature->getNomUrl(1, '').''; - print "'.dol_print_date($db->jdate($objp->tms), 'day')."'.$staticrecruitmentcandidature->getFullName($langs).''.$staticrecruitmentjobposition->getNomUrl(1).''.dol_print_date($db->jdate($objp->tms), 'day').''; print $staticrecruitmentcandidature->getLibStatut(3); print "