Merge branch '14.0' of git@github.com:Dolibarr/dolibarr.git into develop

This commit is contained in:
Laurent Destailleur 2021-08-23 16:04:16 +02:00
commit 4460206709
12 changed files with 128 additions and 60 deletions

View File

@ -1821,8 +1821,16 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
$company = new Societe($db);
$result = $company->fetch($object->socid);
print $company->getNomUrl(1);
// Show link to invoices
$tmparray = $company->getOutstandingBills('customer');
if (!empty($tmparray['refs'])) {
print ' - '.img_picto($langs->trans("Invoices"), 'bill', 'class="paddingright"').'<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->socid.'">'.$langs->trans("Invoices").': '.count($tmparray['refs']);
// TODO Add alert if warning on at least one invoice late
print '</a>';
}
} else {
print $langs->trans("NoThirdPartyAssociatedToMember");
print '<span class="opacitymedium">'.$langs->trans("NoThirdPartyAssociatedToMember").'</span>';
}
}
print '</td></tr>';
@ -1846,7 +1854,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
}
print '</td></tr>';
//VCard
// VCard
print '<tr><td>';
print $langs->trans("VCard").'</td><td colspan="3">';
print '<a href="'.DOL_URL_ROOT.'/adherents/vcard.php?id='.$object->id.'">';

View File

@ -209,7 +209,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && !
// Subscription informations
$datesubscription = 0;
$datesubend = 0;
$paymentdate = 0;
$paymentdate = ''; // Do not use 0 here, default value is '' that means not filled where 0 means 1970-01-01
if (GETPOST("reyear", "int") && GETPOST("remonth", "int") && GETPOST("reday", "int")) {
$datesubscription = dol_mktime(0, 0, 0, GETPOST("remonth", "int"), GETPOST("reday", "int"), GETPOST("reyear", "int"));
}
@ -260,7 +260,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && !
}
// Check if a payment is mandatory or not
if (!$error && $adht->subscription) { // Member type need subscriptions
if ($adht->subscription) { // Member type need subscriptions
if (!is_numeric($amount)) {
// If field is '' or not a numeric value
$errmsg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount"));
@ -268,28 +268,35 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && !
$error++;
$action = 'addsubscription';
} else {
// If an amount has been provided, we check also fields that becomes mandatory when amount is not null.
if (!empty($conf->banque->enabled) && GETPOST("paymentsave") != 'none') {
if (GETPOST("subscription")) {
if (!GETPOST("label")) {
$errmsg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Label"));
setEventMessages($errmsg, null, 'errors');
$error++;
$action = 'addsubscription';
}
if (GETPOST("paymentsave") != 'invoiceonly' && !GETPOST("operation")) {
$errmsg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("PaymentMode"));
setEventMessages($errmsg, null, 'errors');
$error++;
$action = 'addsubscription';
}
if (GETPOST("paymentsave") != 'invoiceonly' && !(GETPOST("accountid", 'int') > 0)) {
$errmsg = $langs->trans("ErrorFieldRequired", $langs->transnoentities("FinancialAccount"));
setEventMessages($errmsg, null, 'errors');
$error++;
$action = 'addsubscription';
}
} else {
if (GETPOST("accountid")) {
if (GETPOST("accountid", 'int')) {
$errmsg = $langs->trans("ErrorDoNotProvideAccountsIfNullAmount");
setEventMessages($errmsg, null, 'errors');
$error++;
$action = 'addsubscription';
}
}
if ($errmsg) {
$error++;
setEventMessages($errmsg, null, 'errors');
$error++;
$action = 'addsubscription';
}
}
}
}
@ -601,8 +608,16 @@ if ($rowid > 0) {
$company = new Societe($db);
$result = $company->fetch($object->fk_soc);
print $company->getNomUrl(1);
// Show link to invoices
$tmparray = $company->getOutstandingBills('customer');
if (!empty($tmparray['refs'])) {
print ' - '.img_picto($langs->trans("Invoices"), 'bill', 'class="paddingright"').'<a href="'.DOL_URL_ROOT.'/compta/facture/list.php?socid='.$object->socid.'">'.$langs->trans("Invoices").': '.count($tmparray['refs']);
// TODO Add alert if warning on at least one invoice late
print '</a>';
}
} else {
print $langs->trans("NoThirdPartyAssociatedToMember");
print '<span class="opacitymedium">'.$langs->trans("NoThirdPartyAssociatedToMember").'</span>';
}
}
print '</td></tr>';
@ -628,7 +643,7 @@ if ($rowid > 0) {
if ($object->user_id) {
$form->form_users($_SERVER['PHP_SELF'].'?rowid='.$object->id, $object->user_id, 'none');
} else {
print $langs->trans("NoDolibarrAccess");
print '<span class="opacitymedium">'.$langs->trans("NoDolibarrAccess").'</span>';
}
}
print '</td></tr>';
@ -970,17 +985,18 @@ if ($rowid > 0) {
print '<tr><td class="tdtop fieldrequired">'.$langs->trans('MoreActions');
print '</td>';
print '<td>';
print '<input type="radio" class="moreaction" id="none" name="paymentsave" value="none"'.(empty($bankdirect) && empty($invoiceonly) && empty($bankviainvoice) ? ' checked' : '').'> '.$langs->trans("None").'<br>';
print '<input type="radio" class="moreaction" id="none" name="paymentsave" value="none"'.(empty($bankdirect) && empty($invoiceonly) && empty($bankviainvoice) ? ' checked' : '').'>';
print '<label for="none"> '.$langs->trans("None").'</label><br>';
// Add entry into bank accoun
if (!empty($conf->banque->enabled)) {
print '<input type="radio" class="moreaction" id="bankdirect" name="paymentsave" value="bankdirect"'.(!empty($bankdirect) ? ' checked' : '');
print '> '.$langs->trans("MoreActionBankDirect").'<br>';
print '><label for="bankdirect"> '.$langs->trans("MoreActionBankDirect").'</label><br>';
}
// Add invoice with no payments
if (!empty($conf->societe->enabled) && !empty($conf->facture->enabled)) {
print '<input type="radio" class="moreaction" id="invoiceonly" name="paymentsave" value="invoiceonly"'.(!empty($invoiceonly) ? ' checked' : '');
//if (empty($object->fk_soc)) print ' disabled';
print '> '.$langs->trans("MoreActionInvoiceOnly");
print '><label for="invoiceonly"> '.$langs->trans("MoreActionInvoiceOnly");
if ($object->fk_soc) {
print ' ('.$langs->trans("ThirdParty").': '.$company->getNomUrl(1).')';
} else {
@ -1004,13 +1020,13 @@ if ($rowid > 0) {
}
print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product
}
print '<br>';
print '</label><br>';
}
// Add invoice with payments
if (!empty($conf->banque->enabled) && !empty($conf->societe->enabled) && !empty($conf->facture->enabled)) {
print '<input type="radio" class="moreaction" id="bankviainvoice" name="paymentsave" value="bankviainvoice"'.(!empty($bankviainvoice) ? ' checked' : '');
//if (empty($object->fk_soc)) print ' disabled';
print '> '.$langs->trans("MoreActionBankViaInvoice");
print '><label for="bankviainvoice"> '.$langs->trans("MoreActionBankViaInvoice");
if ($object->fk_soc) {
print ' ('.$langs->trans("ThirdParty").': '.$company->getNomUrl(1).')';
} else {
@ -1034,7 +1050,7 @@ if ($rowid > 0) {
}
print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product
}
print '<br>';
print '</label><br>';
}
print '</td></tr>';

View File

@ -165,24 +165,27 @@ $urlvcal = '<a href="'.$urlwithroot.'/public/agenda/agendaexport.php?format=vcal
$urlvcal .= $urlwithroot.'/public/agenda/agendaexport.php?format=vcal'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').'</a>';
$message .= img_picto('', 'globe').' '.str_replace('{url}', $urlvcal, '<span class="opacitymedium">'.$langs->trans("WebCalUrlForVCalExport", 'vcal', '').'</span>');
$message .= '<div class="urllink">';
$message .= '<input type="text" id="onlinepaymenturl" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=vcal'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '<input type="text" id="onlinepaymenturl1" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=vcal'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '</div>';
$message .= ajax_autoselect('onlinepaymenturl1');
$message .= '<br>';
$urlical = '<a href="'.$urlwithroot.'/public/agenda/agendaexport.php?format=ical&type=event'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'" target="_blank">';
$urlical .= $urlwithroot.'/public/agenda/agendaexport.php?format=ical&type=event'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').'</a>';
$message .= img_picto('', 'globe').' '.str_replace('{url}', $urlical, '<span class="opacitymedium">'.$langs->trans("WebCalUrlForVCalExport", 'ical/ics', '').'</span>');
$message .= '<div class="urllink">';
$message .= '<input type="text" id="onlinepaymenturl" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=ical'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '<input type="text" id="onlinepaymenturl2" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=ical'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '</div>';
$message .= ajax_autoselect('onlinepaymenturl2');
$message .= '<br>';
$urlrss = '<a href="'.$urlwithroot.'/public/agenda/agendaexport.php?format=rss'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'" target="_blank">';
$urlrss .= $urlwithroot.'/public/agenda/agendaexport.php?format=rss'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : 'KEYNOTDEFINED').'</a>';
$message .= img_picto('', 'globe').' '.str_replace('{url}', $urlrss, '<span class="opacitymedium">'.$langs->trans("WebCalUrlForVCalExport", 'rss', '').'</span>');
$message .= '<div class="urllink">';
$message .= '<input type="text" id="onlinepaymenturl" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=rss'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '<input type="text" id="onlinepaymenturl3" class="quatrevingtpercent" value="'.$urlwithroot.'/public/agenda/agendaexport.php?format=rss'.$getentity.'&exportkey='.($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY ?urlencode($conf->global->MAIN_AGENDA_XCAL_EXPORTKEY) : '...').'">';
$message .= '</div>';
$message .= ajax_autoselect('onlinepaymenturl3');
$message .= '<br>';
print $message;

View File

@ -272,6 +272,19 @@ function societe_prepare_head(Societe $object)
$h++;
}
if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'thirdparty') {
if (!empty($user->rights->partnership->read)) {
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
$head[$h][0] = DOL_URL_ROOT.'/societe/partnership.php?socid='.$object->id;
$head[$h][1] = $langs->trans("Partnership");
$head[$h][2] = 'partnership';
if ($nbPartnership > 0) {
$head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbPartnership.'</span>';
}
$h++;
}
}
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab

View File

@ -753,9 +753,9 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
$out = dol_string_nohtmltag($out, 0);
// Remove also other dangerous string sequences
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
// '../' or '..\' is dangerous because it allows dir transversals
// Note &#38, '&#0000038', '&#x26'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#x2F', '../'), '', $out);
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#92', '&#0000092', '&#x2F', '../', '..\\'), '', $out);
} while ($oldstringtoclean != $out);
// keep lines feed
}
@ -768,9 +768,9 @@ function checkVal($out = '', $check = 'alphanohtml', $filter = null, $options =
// Remove html tags
$out = dol_html_entity_decode($out, ENT_COMPAT | ENT_HTML5, 'UTF-8');
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
// '../' is dangerous because it allows dir transversals
// '../' or '..\' is dangerous because it allows dir transversals
// Note &#38, '&#0000038', '&#x26'... is a simple char like '&' alone but there is no reason to accept such way to encode input data.
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#x2F', '../'), '', $out);
$out = str_ireplace(array('&#38', '&#0000038', '&#x26', '&quot', '&#34', '&#0000034', '&#x22', '"', '&#47', '&#0000047', '&#92', '&#0000092', '&#x2F', '../', '..\\'), '', $out);
} while ($oldstringtoclean != $out);
}
break;
@ -1323,8 +1323,8 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
if (count($tmparrayoftags)) {
foreach ($tmparrayoftags as $tagtoreplace) {
$tmp = str_replace('<'.$tagtoreplace.'>', '__BEGINTAGTOREPLACE'.$tagtoreplace.'__', $tmp);
$tmp = str_replace('</'.$tagtoreplace.'>', '__ENDTAGTOREPLACE'.$tagtoreplace.'__', $tmp);
$tmp = str_ireplace('<'.$tagtoreplace.'>', '__BEGINTAGTOREPLACE'.$tagtoreplace.'__', $tmp);
$tmp = str_ireplace('</'.$tagtoreplace.'>', '__ENDTAGTOREPLACE'.$tagtoreplace.'__', $tmp);
}
}
@ -1332,8 +1332,8 @@ function dol_escape_htmltag($stringtoescape, $keepb = 0, $keepn = 0, $noescapeta
if (count($tmparrayoftags)) {
foreach ($tmparrayoftags as $tagtoreplace) {
$result = str_replace('__BEGINTAGTOREPLACE'.$tagtoreplace.'__', '<'.$tagtoreplace.'>', $result);
$result = str_replace('__ENDTAGTOREPLACE'.$tagtoreplace.'__', '</'.$tagtoreplace.'>', $result);
$result = str_ireplace('__BEGINTAGTOREPLACE'.$tagtoreplace.'__', '<'.$tagtoreplace.'>', $result);
$result = str_ireplace('__ENDTAGTOREPLACE'.$tagtoreplace.'__', '</'.$tagtoreplace.'>', $result);
}
}

View File

@ -63,9 +63,7 @@ function member_prepare_head(Adherent $object)
$h++;
}
$tabtoadd = (!empty(getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR')) && getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') ? 'member' : 'thirdparty';
if ($tabtoadd == 'member') {
if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') {
if (!empty($user->rights->partnership->read)) {
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
$head[$h][0] = DOL_URL_ROOT.'/adherents/partnership.php?rowid='.$object->id;
@ -76,20 +74,8 @@ function member_prepare_head(Adherent $object)
}
$h++;
}
} else {
if (!empty($user->rights->partnership->read)) {
$nbPartnership = is_array($object->partnerships) ? count($object->partnerships) : 0;
$head[$h][0] = DOL_URL_ROOT.'/societe/partnership.php?socid='.$object->id;
$head[$h][1] = $langs->trans("Partnership");
$head[$h][2] = 'partnership';
if ($nbPartnership > 0) {
$head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbPartnership.'</span>';
}
$h++;
}
}
// Show more tabs from modules
// Entries must be declared in modules descriptor with line
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab

View File

@ -194,8 +194,9 @@ if (!in_array($type, array('text/x-javascript')) && !dolIsAllowedForPreview($ori
$type = 'application/octet-stream';
}
// Security: Delete string ../ into $original_file
$original_file = str_replace("../", "/", $original_file);
// Security: Delete string ../ or ..\ into $original_file
$original_file = str_replace('../', '/', $original_file);
$original_file = str_replace('..\\', '/', $original_file);
// Find the subdirectory name as the reference
$refname = basename(dirname($original_file)."/");

View File

@ -50,7 +50,7 @@ $ref = GETPOST('ref', 'alpha');
$fuserid = (GETPOST('fuserid', 'int') ?GETPOST('fuserid', 'int') : $user->id);
// Load translation files required by the page
$langs->loadLangs(array("other", "holiday", "mails"));
$langs->loadLangs(array("other", "holiday", "mails", "trips"));
$error = 0;
@ -264,6 +264,7 @@ if (empty($reshook)) {
}
}
// If update and we are an approver, we can update with another approver
if ($action == 'update' && GETPOSTISSET('savevalidator') && !empty($user->rights->holiday->approve)) {
$object->fetch($id);
@ -316,6 +317,8 @@ if (empty($reshook)) {
// If this is the requestor or has read/write rights
if ($cancreate) {
$approverid = GETPOST('valideur', 'int');
// TODO Check this approver user id has the permission for approval
$description = trim(GETPOST('description', 'restricthtml'));
// If no start date
@ -743,8 +746,8 @@ if (empty($reshook)) {
$object->fetch($id);
// If status pending validation and validator = validator or user, or rights to do for others
if (($object->statut == Holiday::STATUS_VALIDATED || $object->statut == Holiday::STATUS_APPROVED) && ($user->id == $object->fk_validator || in_array($object->fk_user, $childids)
|| (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance)))) {
if (($object->statut == Holiday::STATUS_VALIDATED || $object->statut == Holiday::STATUS_APPROVED) &&
(!empty($user->admin) || $user->id == $object->fk_validator || in_array($object->fk_user, $childids) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance)))) {
$db->begin();
$oldstatus = $object->statut;
@ -1438,25 +1441,48 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') {
if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit" class="butAction">'.$langs->trans("EditCP").'</a>';
}
if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) { // If draft
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=sendToValidate" class="butAction">'.$langs->trans("Validate").'</a>';
}
if ($object->statut == Holiday::STATUS_VALIDATED) { // If validated
// Button Approve / Refuse
if ($user->id == $object->fk_validator) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=valid" class="butAction">'.$langs->trans("Approve").'</a>';
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=refuse" class="butAction">'.$langs->trans("ActionRefuseCP").'</a>';
} else {
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("NotTheAssignedApprover").'">'.$langs->trans("Approve").'</a>';
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("NotTheAssignedApprover").'">'.$langs->trans("ActionRefuseCP").'</a>';
// Button Cancel (because we can't approve)
if (in_array($object->fk_user, $childids) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance))) {
if (($object->date_debut > dol_now()) || !empty($user->admin)) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'" class="butAction">'.$langs->trans("ActionCancelCP").'</a>';
} else {
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("HolidayStarted").'-'.$langs->trans("NotAllowed").'">'.$langs->trans("ActionCancelCP").'</a>';
}
}
}
}
if (($user->id == $object->fk_validator || in_array($object->fk_user, $childids) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance))) && ($object->statut == 2 || $object->statut == 3)) { // Status validated or approved
if (($object->date_debut > dol_now()) || $user->admin) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel" class="butAction">'.$langs->trans("ActionCancelCP").'</a>';
} else {
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("HolidayStarted").'">'.$langs->trans("ActionCancelCP").'</a>';
if ($object->statut == Holiday::STATUS_APPROVED) { // If validated or approved
if ($user->id == $object->fk_validator
|| in_array($object->fk_user, $childids)
|| (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->holiday->writeall_advance))) {
if (($object->date_debut > dol_now()) || !empty($user->admin)) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'" class="butAction">'.$langs->trans("ActionCancelCP").'</a>';
} else {
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("HolidayStarted").'-'.$langs->trans("NotAllowed").'">'.$langs->trans("ActionCancelCP").'</a>';
}
} else { // I have no rights on the user of the holiday.
if (!empty($user->admin)) { // If current validator can't cancel an approved leave, we allow admin user
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'" class="butAction">'.$langs->trans("ActionCancelCP").'</a>';
} else {
print '<a href="#" class="butActionRefused classfortooltip" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("ActionCancelCP").'</a>';
}
}
}
if ($cancreate && $object->statut == Holiday::STATUS_CANCELED) {
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=backtodraft" class="butAction">'.$langs->trans("SetToDraft").'</a>';
}

View File

@ -1664,6 +1664,7 @@ class Holiday extends CommonObject
$sql .= " WHERE u.entity IN (".getEntity('user').")";
}
$sql .= " AND u.statut > 0";
$sql .= " AND u.employee = 1"; // We only want employee users for holidays
if ($filters) {
$sql .= $filters;
}
@ -1754,6 +1755,7 @@ class Holiday extends CommonObject
}
$sql .= " AND u.statut > 0";
$sql .= " AND u.employee = 1"; // We only want employee users for holidays
if ($filters) {
$sql .= $filters;
}

View File

@ -50,6 +50,9 @@ $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
$socid = GETPOST('socid', 'int');
if (!empty($user->socid)) {
$socid = $user->socid;
}
if (empty($id) && $socid && (empty($conf->global->PARTNERSHIP_IS_MANAGED_FOR) || $conf->global->PARTNERSHIP_IS_MANAGED_FOR == 'thirdparty')) {
$id = $socid;
}

View File

@ -221,8 +221,9 @@ if (preg_match('/\.noexe$/i', $original_file)) {
accessforbidden('Error: Using the image wrapper to output a file ending with .noexe is not allowed.', 0, 0, 1);
}
// Security: Delete string ../ into $original_file
$original_file = str_replace("../", "/", $original_file);
// Security: Delete string ../ or ..\ into $original_file
$original_file = str_replace('../', '/', $original_file);
$original_file = str_replace('..\\', '/', $original_file);
// Find the subdirectory name as the reference
$refname = basename(dirname($original_file)."/");

View File

@ -349,7 +349,8 @@ class SecurityTest extends PHPUnit\Framework\TestCase
$_POST["param1"]="333";
$_GET["param2"]='a/b#e(pr)qq-rr\cc';
$_GET["param3"]='"&#110;a/b#e(pr)qq-rr\cc'; // Same than param2 + " and &#110;
$_GET["param4"]='../dir';
$_GET["param4a"]='..&#47;../dir';
$_GET["param4b"]='..&#92;..\dirwindows';
$_GET["param5"]="a_1-b";
$_POST["param6"]="&quot;&gt;<svg o&#110;load='console.log(&quot;123&quot;)'&gt;";
$_POST["param6b"]='<<<../>../>../svg><<<../>../>../animate =alert(1)>abc';
@ -394,10 +395,14 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'na/b#e(pr)qq-rr\cc', 'Test on param3');
$result=GETPOST("param4", 'alpha'); // Must return string sanitized from ../
$result=GETPOST("param4a", 'alpha'); // Must return string sanitized from ../
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'dir');
$result=GETPOST("param4b", 'alpha'); // Must return string sanitized from ../
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, 'dirwindows');
// Test with aZ09
$result=GETPOST("param1", 'aZ09');
@ -412,7 +417,11 @@ class SecurityTest extends PHPUnit\Framework\TestCase
print __METHOD__." result=".$result."\n";
$this->assertEquals($result, '');
$result=GETPOST("param4", 'aZ09'); // Must return '' as string contains car not in aZ09 definition
$result=GETPOST("param4a", 'aZ09'); // Must return '' as string contains car not in aZ09 definition
print __METHOD__." result=".$result."\n";
$this->assertEquals('', $result);
$result=GETPOST("param4b", 'aZ09'); // Must return '' as string contains car not in aZ09 definition
print __METHOD__." result=".$result."\n";
$this->assertEquals('', $result);