Merge branch 'Dolibarr:develop' into FIX-SECURITY-Fail2ban-public-pages

This commit is contained in:
fboitel 2022-11-24 19:10:35 +01:00 committed by GitHub
commit 00f5a2ddc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 366 additions and 138 deletions

View File

@ -165,6 +165,7 @@ NEW: Update ActionComm type_code on email message ticket
NEW: VAT - Admin - Add information on deadline day for submission of VAT declaration
NEW: expand/collapse permissions on user permission page
NEW: Show delivery mode on PDF for proposals
NEW: Add the target to select attendees of event for emailings
For developers or integrators:

View File

@ -741,7 +741,7 @@ class Adherent extends CommonObject
$sql .= ", state_id = ".($this->state_id > 0 ? $this->db->escape($this->state_id) : "null");
$sql .= ", email = '".$this->db->escape($this->email)."'";
$sql .= ", url = ".(!empty($this->url) ? "'".$this->db->escape($this->url)."'" : "null");
$sql .= ", socialnetworks = '".$this->db->escape(json_encode($this->socialnetworks))."'";
$sql .= ", socialnetworks = ".($this->socialnetworks ? "'".$this->db->escape(json_encode($this->socialnetworks))."'" : "null");
$sql .= ", phone = ".($this->phone ? "'".$this->db->escape($this->phone)."'" : "null");
$sql .= ", phone_perso = ".($this->phone_perso ? "'".$this->db->escape($this->phone_perso)."'" : "null");
$sql .= ", phone_mobile = ".($this->phone_mobile ? "'".$this->db->escape($this->phone_mobile)."'" : "null");
@ -2958,17 +2958,18 @@ class Adherent extends CommonObject
dol_syslog(__METHOD__.' - Process delta = '.$daysbeforeend, LOG_DEBUG);
if (!is_numeric($daysbeforeend)) {
$blockingerrormsg = "Value for delta is not a positive or negative numeric";
$blockingerrormsg = "Value for delta is not a numeric value";
$nbko++;
break;
}
$tmp = dol_getdate($now);
$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year']), $daysbeforeend, 'd');
$datetosearchfor = dol_time_plus_duree(dol_mktime(0, 0, 0, $tmp['mon'], $tmp['mday'], $tmp['year'], 'tzserver'), $daysbeforeend, 'd');
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
$sql .= " WHERE entity = ".$conf->entity; // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
$sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
$sql .= " AND datefin = '".$this->db->idate($datetosearchfor)."'";
//$sql .= " LIMIT 10000";
$resql = $this->db->query($sql);
if ($resql) {
@ -3001,7 +3002,7 @@ class Adherent extends CommonObject
dol_syslog("sendReminderForExpiredSubscription Language for member id ".$adherent->id." set to ".$outputlangs->defaultlang." mysoc->default_lang=".$mysoc->default_lang);
$arraydefaultmessage = null;
$labeltouse = $conf->global->ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION;
$labeltouse = getDolGlobalString('ADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION');
if (!empty($labeltouse)) {
$arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'member', $user, $outputlangs, 0, 1, $labeltouse);
@ -3025,7 +3026,7 @@ class Adherent extends CommonObject
$result = $cmail->sendfile();
if (!$result) {
$error++;
$this->error = $cmail->error;
$this->error .= $cmail->error.' ';
if (!is_null($cmail->errors)) {
$this->errors += $cmail->errors;
}
@ -3043,8 +3044,7 @@ class Adherent extends CommonObject
$extraparams = '';
$actionmsg = '';
$actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.
CMailFile::getValidAddress($sendto, 4, 0, 1);
$actionmsg2 = $langs->transnoentities('MailSentBy').' '.CMailFile::getValidAddress($from, 4, 0, 1).' '.$langs->transnoentities('To').' '.CMailFile::getValidAddress($sendto, 4, 0, 1);
if ($message) {
$actionmsg = $langs->transnoentities('MailFrom').': '.dol_escape_htmltag($from);
$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTo').': '.dol_escape_htmltag($sendto));
@ -3091,7 +3091,10 @@ class Adherent extends CommonObject
$actioncomm->create($user);
}
} else {
$blockingerrormsg = "Can't find email template, defined into member module setup, to use for reminding";
//$blockingerrormsg = "Can't find email template with label=".$labeltouse.", to use for the reminding email";
$error++;
$this->error .= "Can't find email template with label=".$labeltouse.", to use for the reminding email ";
$nbko++;
$listofmembersko[$adherent->id] = $adherent->id;
@ -3133,7 +3136,7 @@ class Adherent extends CommonObject
if ($listofids) {
$listofids .= ']';
}
$this->output .= $listofids;
$this->output .= ' ids='.$listofids;
}
if ($nbko) {
$this->output .= ' - Canceled for '.$nbko.' member (no email or email sending error)';
@ -3161,6 +3164,6 @@ class Adherent extends CommonObject
}
}
return 0;
return $nbko;
}
}

View File

@ -123,32 +123,35 @@ print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Parameter").'</td>';
print '<td>'.$langs->trans("Value").'</td>';
print '<td>'.$langs->trans("Example").'</td>';
print '<td class="hideonsmartphone">'.$langs->trans("Example").'</td>';
print "</tr>\n";
print '<tr class="oddeven"><td>';
$help = img_help(1, $langs->trans("EMailHelpMsgSPFDKIM"));
print $langs->trans("MailingEMailFrom").' '.$help.'</td><td>';
print '<input size="32" type="text" name="MAILING_EMAIL_FROM" value="'.$conf->global->MAILING_EMAIL_FROM.'">';
print '<input class="minwidth100" type="text" name="MAILING_EMAIL_FROM" value="'.$conf->global->MAILING_EMAIL_FROM.'">';
if (!empty($conf->global->MAILING_EMAIL_FROM) && !isValidEmail($conf->global->MAILING_EMAIL_FROM)) {
print ' '.img_warning($langs->trans("BadEMail"));
}
print '</td><td><span class="opacitymedium">'.dol_escape_htmltag(($mysoc->name ? $mysoc->name : 'MyName').' <noreply@example.com>').'</span></td>';
print '</td>';
print '<td class="hideonsmartphone"><span class="opacitymedium">'.dol_escape_htmltag(($mysoc->name ? $mysoc->name : 'MyName').' <noreply@example.com>').'</span></td>';
print '</tr>';
print '<tr class="oddeven"><td>';
print $langs->trans("MailingEMailError").'</td><td>';
print '<input size="32" type="text" name="MAILING_EMAIL_ERRORSTO" value="'.$conf->global->MAILING_EMAIL_ERRORSTO.'">';
print '<input class="minwidth100" type="text" name="MAILING_EMAIL_ERRORSTO" value="'.$conf->global->MAILING_EMAIL_ERRORSTO.'">';
if (!empty($conf->global->MAILING_EMAIL_ERRORSTO) && !isValidEmail($conf->global->MAILING_EMAIL_ERRORSTO)) {
print ' '.img_warning($langs->trans("BadEMail"));
}
print '</td><td><span class="opacitymedium">webmaster@example.com></span></td>';
print '</td>';
print '<td class="hideonsmartphone"><span class="opacitymedium">webmaster@example.com></span></td>';
print '</tr>';
print '<tr class="oddeven"><td>';
print $langs->trans("MailingDelay").'</td><td>';
print '<input class="width75" type="text" name="MAILING_DELAY" value="'.$conf->global->MAILING_DELAY.'">';
print '</td><td></td>';
print '</td>';
print '<td class="hideonsmartphone"></td>';
print '</tr>';
@ -157,11 +160,12 @@ print '</tr>';
print '<tr class="oddeven"><td>';
print $langs->trans("ActivateCheckReadKey").'</td><td>';
print '<input size="32" type="text" name="MAILING_EMAIL_UNSUBSCRIBE_KEY" id="MAILING_EMAIL_UNSUBSCRIBE_KEY" value="'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY.'">';
print '<input class="minwidth100 maxwdith250 widthcentpercentminusx" type="text" name="MAILING_EMAIL_UNSUBSCRIBE_KEY" id="MAILING_EMAIL_UNSUBSCRIBE_KEY" value="'.$conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY.'">';
if (!empty($conf->use_javascript_ajax)) {
print '&nbsp;'.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_token" class="linkobject"');
}
print '</td><td></td>';
print '</td>';
print '<td class="hideonsmartphone"></td>';
print '</tr>';
// default blacklist from mailing
@ -171,7 +175,7 @@ print '<td>';
$blacklist_setting=array(0=>$langs->trans('No'), 1=>$langs->trans('Yes'), 2=>$langs->trans('DefaultStatusEmptyMandatory'));
print $form->selectarray("MAILING_CONTACT_DEFAULT_BULK_STATUS", $blacklist_setting, $conf->global->MAILING_CONTACT_DEFAULT_BULK_STATUS);
print '</td>';
print '<td></td>';
print '<td class="hideonsmartphone"></td>';
print '</tr>';
@ -179,7 +183,8 @@ if (!empty($conf->use_javascript_ajax) && $conf->global->MAIN_FEATURES_LEVEL >=
print '<tr class="oddeven"><td>';
print $langs->trans("MailAdvTargetRecipients").'</td><td>';
print ajax_constantonoff('EMAILING_USE_ADVANCED_SELECTOR');
print '</td><td></td>';
print '</td>';
print '<td class="hideonsmartphone"></td>';
print '</tr>';
}

View File

@ -1646,8 +1646,10 @@ class ActionComm extends CommonObject
}
if (!empty($this->note_private)) {
$tooltip .= '<br><br><b>'.$langs->trans('Description').':</b><br>';
$texttoshow = dolGetFirstLineOfText($this->note_private, 10);
$texttoshow = dolGetFirstLineOfText($this->note_private, 10); // Try to limit length of content
$tooltip .= '<div class="tenlinesmax">'; // Restrict height of content into the tooltip
$tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
$tooltip .= '</div>';
}
$linkclose = '';
//if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color)

View File

@ -730,7 +730,7 @@ if ($action == 'create') {
// Print mail form
print load_fiche_titre($langs->trans("NewMailing"), $availablelink, 'object_email');
print dol_get_fiche_head();
print dol_get_fiche_head(array(), '', '', -3);
print '<table class="border centpercent">';
@ -768,7 +768,7 @@ if ($action == 'create') {
print dol_get_fiche_end();
print $form->buttonsSaveCancel("CreateMailing", '');
print $form->buttonsSaveCancel("CreateMailing", 'Cancel');
print '</form>';
} else {
@ -1314,7 +1314,7 @@ if ($action == 'create') {
print '<div class="center">';
print '<input type="submit" class="button buttonforacesave button-save" value="'.$langs->trans("Save").'" name="save">';
print '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
print '&nbsp; &nbsp; &nbsp;';
print '<input type="submit" class="button button-cancel" value="'.$langs->trans("Cancel").'" name="cancel">';
print '</div>';

View File

@ -394,7 +394,7 @@ if ($object->fetch($id) >= 0) {
if (empty($obj->picto)) {
$obj->picto = 'generic';
}
print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle pictomodule"');
print img_object($langs->trans("EmailingTargetSelector").': '.get_class($obj), $obj->picto, 'class="valignmiddle pictomodule pictofixedwidth"');
print ' ';
print $obj->getDesc();
print '</div>';
@ -633,10 +633,12 @@ if ($object->fetch($id) >= 0) {
include_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
include_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
$objectstaticmember = new Adherent($db);
$objectstaticuser = new User($db);
$objectstaticcompany = new Societe($db);
$objectstaticcontact = new Contact($db);
$objectstaticeventorganization = new ConferenceOrBoothAttendee($db);
while ($i < min($num, $limit)) {
$obj = $db->fetch_object($resql);
@ -662,6 +664,9 @@ if ($object->fetch($id) >= 0) {
} elseif ($obj->source_type == 'contact') {
$objectstaticcontact->fetch($obj->source_id);
print $objectstaticcontact->getNomUrl(1);
} elseif ($obj->source_type == 'eventorganizationattendee') {
$objectstaticeventorganization->fetch($obj->source_id);
print $objectstaticeventorganization->getNomUrl(1);
} else {
print $obj->source_url;
}

View File

@ -40,7 +40,7 @@
* \brief File of class to manage invoices
*/
include_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/commoninvoice.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';

View File

@ -72,13 +72,9 @@ foreach ($linkedObjectBlock as $key => $objectlink) {
print '<td class="linkedcol-date center">'.dol_print_date($objectlink->date, 'day').'</td>';
print '<td class="linkedcol-amount right nowraponall">';
if (!empty($objectlink) && $objectlink->element == 'facture' && $user->hasRight('facture', 'lire')) {
$sign = 1;
if ($objectlink->type == Facture::TYPE_CREDIT_NOTE) {
$sign = -1;
}
if ($objectlink->statut != 3) {
// If not abandonned
$total = $total + $sign * $objectlink->total_ht;
$total += $objectlink->total_ht;
echo price($objectlink->total_ht);
} else {
echo '<strike>'.price($objectlink->total_ht).'</strike>';

View File

@ -402,6 +402,9 @@ if ($resql) {
if (!empty($limit)) {
print '<input type="hidden" name="limit" value="'.$limit.'"/>';
}
if ($type != '') {
print '<input type="hidden" name="type" value="'.$type.'">';
}
$title = $langs->trans("InvoiceWaitingWithdraw");
if ($type == 'bank-transfer') {

View File

@ -192,6 +192,9 @@ if ($result) {
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
if ($type != '') {
print '<input type="hidden" name="type" value="'.$type.'">';
}
$title = $langs->trans("WithdrawalsLines");
if ($type == 'bank-transfer') {

View File

@ -161,7 +161,9 @@ if ($result) {
print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
if ($type != '') {
print '<input type="hidden" name="type" value="'.$type.'">';
}
$titlekey = "WithdrawalsReceipts";
$title = $langs->trans("WithdrawalsReceipts");
if ($type == 'bank-transfer') {

View File

@ -302,7 +302,7 @@ if ($modecompta == 'BOOKKEEPING') {
if (!empty($date_start) && !empty($date_end)) {
$sql .= " AND f.doc_date >= '".$db->idate($date_start)."' AND f.doc_date <= '".$db->idate($date_end)."'";
}
$sql .= " GROUP BY pcg_type DESC";
$sql .= " GROUP BY pcg_type";
if ($showaccountdetail == 'no') {
$sql .= ", name, socid"; // group by "accounting group" (INCOME/EXPENSE), then "customer".
}

View File

@ -271,12 +271,10 @@ class FormActions
break;
}
$ref = $actioncomm->getNomUrl(1, -1);
print '<tr class="oddeven">';
// Ref
print '<td class="nowraponall">'.$ref.'</td>';
print '<td class="nowraponall">'.$actioncomm->getNomUrl(1, -1).'</td>';
// Onwer
print '<td class="nowraponall tdoverflowmax125">';
@ -310,7 +308,7 @@ class FormActions
$labeltype .= ' - '.$arraylist[$actionstatic->code]; // Use code in priority on type_code
}
}
print '<td class="tdoverflowmax100" title="'.$labeltype.'">';
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($labeltype).'">';
print $actioncomm->getTypePicto();
print $labeltype;
print '</td>';

View File

@ -1279,7 +1279,7 @@ class FormMail extends Form
*
* @param DoliDB $dbs Database handler
* @param string $type_template Get message for model/type=$type_template, type='all' also included.
* @param User $user Get template public or limited to this user
* @param User $user Get templates public + limited to this user
* @param Translate $outputlangs Output lang object
* @param int $id Id of template to get, or -1 for first found with position 0, or 0 for first found whatever is position (priority order depends on lang provided or not) or -2 for exact match with label (no answer if not found)
* @param int $active 1=Only active template, 0=Only disabled, -1=All

View File

@ -66,14 +66,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for JSON mode
* @param string $filterkey Key to filter
* @param string $filterkey Key to filter on ref or title
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param string $morecss More css
* @param int $htmlid Html id to use instead of htmlname
* @param string $morefilter More filters (Must be a sql sanitized string)
* @return string Return html content
*/
public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '')
public function select_projects($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 16, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $morecss = '', $htmlid = '', $morefilter = '')
{
// phpcs:enable
global $langs, $conf, $form;
@ -96,16 +97,14 @@ class FormProjets
$selected_input_value = $project->ref;
}
$urloption = 'socid='.((int) $socid).'&htmlname='.urlencode($htmlname).'&discardclosed='.((int) $discard_closed);
if ($morefilter == 'usage_organize_event=1') {
$urloption .= '&usage_organize_event=1';
}
$out .= '<input type="text" class="minwidth200'.($morecss ? ' '.$morecss : '').'" name="search_'.$htmlname.'" id="search_'.$htmlname.'" value="'.$selected_input_value.'"'.$placeholder.' />';
$out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array(
// 'update' => array(
// 'projectid' => 'id'
// )
));
$out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/projet/ajax/projects.php', $urloption, $conf->global->PROJECT_USE_SEARCH_TO_SELECT, 0, array());
} else {
$out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss);
$out .= $this->select_projects_list($socid, $selected, $htmlname, $maxlength, $option_only, $show_empty, abs($discard_closed), $forcefocus, $disabled, 0, $filterkey, 1, $forceaddid, $htmlid, $morecss, $morefilter);
}
if ($discard_closed > 0) {
if (!empty($form)) {
@ -135,14 +134,15 @@ class FormProjets
* @param int $forcefocus Force focus on field (works with javascript only)
* @param int $disabled Disabled
* @param int $mode 0 for HTML mode and 1 for array return (to be used by json_encode for example)
* @param string $filterkey Key to filter
* @param string $filterkey Key to filter on title or ref
* @param int $nooutput No print output. Return it only.
* @param int $forceaddid Force to add project id in list, event if not qualified
* @param int $htmlid Html id to use instead of htmlname
* @param string $morecss More CSS
* @param string $morefilter More filters (Must be a sql sanitized string)
* @return int Nb of project if OK, <0 if KO
*/
public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500')
public function select_projects_list($socid = -1, $selected = '', $htmlname = 'projectid', $maxlength = 24, $option_only = 0, $show_empty = 1, $discard_closed = 0, $forcefocus = 0, $disabled = 0, $mode = 0, $filterkey = '', $nooutput = 0, $forceaddid = 0, $htmlid = '', $morecss = 'maxwidth500', $morefilter = '')
{
// phpcs:enable
global $user, $conf, $langs;
@ -187,6 +187,9 @@ class FormProjets
if (!empty($filterkey)) {
$sql .= natural_search(array('p.title', 'p.ref'), $filterkey);
}
if ($morefilter) {
$sql .= ' AND ('.$this->db->sanitize($morefilter, 0, 1).')';
}
$sql .= " ORDER BY p.ref ASC";
$resql = $this->db->query($sql);

View File

@ -136,15 +136,12 @@ abstract class DoliDB implements Database
*
* @param string $stringtosanitize String to escape
* @param int $allowsimplequote 1=Allow simple quotes in string. When string is used as a list of SQL string ('aa', 'bb', ...)
* @param string $allowsequals 1=Allow equals sign
* @return string String escaped
*/
public function sanitize($stringtosanitize, $allowsimplequote = 0)
public function sanitize($stringtosanitize, $allowsimplequote = 0, $allowsequals = 0)
{
if ($allowsimplequote) {
return preg_replace('/[^a-z0-9_\-\.,\']/i', '', $stringtosanitize);
} else {
return preg_replace('/[^a-z0-9_\-\.,]/i', '', $stringtosanitize);
}
return preg_replace('/[^a-z0-9_\-\.,'.($allowsequals ? '=' : '').($allowsimplequote ? "\'" : '').']/i', '', $stringtosanitize);
}
/**

View File

@ -1813,7 +1813,7 @@ function dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $di
* @param array $links Array of tabs (0=>url, 1=>label, 2=>code, 3=>not used, 4=>text after link, 5=>morecssonlink). Currently initialized by calling a function xxx_admin_prepare_head. Note that label into $links[$i][1] must be already HTML escaped.
* @param string $active Active tab name (document', 'info', 'ldap', ....)
* @param string $title Title
* @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no seaparation under tab (to start a tab just after)
* @param int $notab -1 or 0=Add tab header, 1=no tab header (if you set this to 1, using print dol_get_fiche_end() to close tab is not required), -2=Add tab header with no sepaaration under tab (to start a tab just after), -3=Add tab header but no footer separation
* @param string $picto Add a picto on tab title
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
@ -8858,7 +8858,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1'
$forbiddenphpstrings = array('$$');
$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST'));
$forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", 'verifCond');
$forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI", "verifCond", "base64_decode");
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask"));
$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func"));

View File

@ -0,0 +1,212 @@
<?php
/* Copyright (C) 2018-2018 Andre Schild <a.schild@aarboard.ch>
* Copyright (C) 2005-2010 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
*
* This file is an example to follow to add your own email selector inside
* the Dolibarr email tool.
* Follow instructions given in README file to know what to change to build
* your own emailing list selector.
* Code that need to be changed in this file are marked by "CHANGE THIS" tag.
*/
/**
* \file htdocs/core/modules/mailings/eventorganization.modules.php
* \ingroup mailing
* \brief Example file to provide a list of recipients for mailing module
*/
// Load Dolibarr Environment
include_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php';
/**
* Class to manage a list of personalised recipients for mailing feature
*/
class mailing_eventorganization extends MailingTargets
{
// This label is used if no translation is found for key XXX neither MailingModuleDescXXX where XXX=name is found
public $name = 'AttendeesOfOrganizedEvent';
public $desc = "Attendees of an organized event";
public $require_admin = 0;
public $require_module = array(); // This module allows to select by categories must be also enabled if category module is not activated
/**
* @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
*/
public $picto = 'conferenceorbooth';
/**
* @var DoliDB Database handler.
*/
public $db;
public $enabled = 'isModEnabled("eventorganization")';
/**
* Constructor
*
* @param DoliDB $db Database handler
*/
public function __construct($db)
{
global $conf, $langs;
$langs->load('companies');
$this->db = $db;
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* This is the main function that returns the array of emails
*
* @param int $mailing_id Id of mailing. No need to use it.
* @return int <0 if error, number of emails added if ok
*/
public function add_to_target($mailing_id)
{
// phpcs:enable
global $conf, $langs;
$cibles = array();
$addDescription = '';
$sql = "SELECT p.ref, p.entity, e.rowid as id, e.fk_project, e.email as email, e.email_company as company_name, e.firstname as firstname, e.lastname as lastname,";
$sql .= " 'eventorganizationattendee' as source";
$sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e,";
$sql .= " ".MAIN_DB_PREFIX."projet as p";
$sql .= " WHERE e.email <> ''";
$sql .= " AND e.fk_project = p.rowid";
$sql .= " AND p.entity IN (".getEntity('project').")";
$sql .= " AND e.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".((int) $mailing_id).")";
$sql .= " AND e.fk_project = ".((int) GETPOST('filter_eventorganization', 'int'));
$sql .= " ORDER BY e.email";
// Stock recipients emails into targets table
$result = $this->db->query($sql);
if ($result) {
$num = $this->db->num_rows($result);
$i = 0;
$j = 0;
dol_syslog(get_class($this)."::add_to_target mailing ".$num." targets found");
$old = '';
while ($i < $num) {
$obj = $this->db->fetch_object($result);
if ($old <> $obj->email) {
$otherTxt = ($obj->ref ? $langs->transnoentities("Project").'='.$obj->ref : '');
if (strlen($addDescription) > 0 && strlen($otherTxt) > 0) {
$otherTxt .= ";";
}
$otherTxt .= $addDescription;
$cibles[$j] = array(
'email' => $obj->email,
'fk_project' => $obj->fk_project,
'lastname' => $obj->lastname,
'firstname' => $obj->firstname,
'other' => $otherTxt,
'source_url' => $this->url($obj->id, $obj->source),
'source_id' => $obj->id,
'source_type' => $obj->source
);
$old = $obj->email;
$j++;
}
$i++;
}
} else {
dol_syslog($this->db->error());
$this->error = $this->db->error();
return -1;
}
return parent::addTargetsToDatabase($mailing_id, $cibles);
}
/**
* On the main mailing area, there is a box with statistics.
* If you want to add a line in this report you must provide an
* array of SQL request that returns two field:
* One called "label", One called "nb".
*
* @return array Array with SQL requests
*/
public function getSqlArrayForStats()
{
// CHANGE THIS: Optionnal
//var $statssql=array();
//$this->statssql[0]="SELECT field1 as label, count(distinct(email)) as nb FROM mytable WHERE email IS NOT NULL";
return array();
}
/**
* Return here number of distinct emails returned by your selector.
* For example if this selector is used to extract 500 different
* emails from a text file, this function must return 500.
*
* @param string $sql Requete sql de comptage
* @return int|string Nb of recipient, or <0 if error, or '' if NA
*/
public function getNbOfRecipients($sql = '')
{
global $conf;
$sql = "SELECT COUNT(DISTINCT(e.email)) as nb";
$sql .= " FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee as e, ";
$sql .= " ".MAIN_DB_PREFIX."projet as p";
$sql .= " WHERE e.email <> ''";
$sql .= " AND e.fk_project = p.rowid";
$sql .= " AND p.entity IN (".getEntity('project').")";
//print $sql;
// La requete doit retourner un champ "nb" pour etre comprise par parent::getNbOfRecipients
return parent::getNbOfRecipients($sql);
}
/**
* This is to add a form filter to provide variant of selector
* If used, the HTML select must be called "filter"
*
* @return string A html select zone
*/
public function formFilter()
{
global $conf, $langs;
$langs->load("companies");
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
$formproject = new FormProjets($this->db);
$s .= $formproject->select_projects(-1, 0, "filter_eventorganization", 0, 0, 1, 1, 0, 0, 0, '', 1, 0, '', '', 'usage_organize_event=1');
return $s;
}
/**
* Can include an URL link on each record provided by selector shown on target page.
*
* @param int $id ID
* @param string $sourcetype Source type
* @return string Url link
*/
public function url($id, $sourcetype = 'thirdparty')
{
if ($sourcetype == 'project') {
return '<a href="'.DOL_URL_ROOT.'/eventorganization/conferenceorboothattendee_card.php?id='.((int) $id).'">'.img_object('', "eventorganization").'</a>';
}
return '';
}
}

View File

@ -219,6 +219,7 @@ class mailing_thirdparties_services_expired extends MailingTargets
$s = '<select id="filter_services_expired" name="filter" class="flat">';
if (count($this->arrayofproducts)) {
$langs->loadLangs(array("products"));
$s .= '<option value="-1">'.$langs->trans("ProductOrService").'</option>';
} else {
$s .= '<option value="0">'.$langs->trans("ContactsAllShort").'</option>';

View File

@ -62,7 +62,7 @@ class modEventOrganization extends DolibarrModules
// Key used in llx_const table to save module status enabled/disabled (where EVENTORGANIZATION is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
$this->picto = 'action';
$this->picto = 'conferenceorbooth';
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
$this->module_parts = array(

View File

@ -55,6 +55,8 @@ ALTER TABLE llx_user DROP COLUMN idpers3;
-- v17
ALTER TABLE llx_mailing_cibles MODIFY COLUMN source_type varchar(32);
ALTER TABLE llx_actioncomm ADD INDEX idx_actioncomm_percent (percent);
UPDATE llx_c_paiement SET code = 'BANCON' WHERE code = 'BAN' AND libelle = 'Bancontact';

View File

@ -32,7 +32,7 @@ create table llx_mailing_cibles
statut smallint NOT NULL DEFAULT 0, -- -1 = error, 0 = not sent, ...
source_url varchar(255),
source_id integer,
source_type varchar(16),
source_type varchar(32),
date_envoi datetime,
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
error_text varchar(255) -- text with error if statut is -1

View File

@ -434,6 +434,9 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) {
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sqlfields = $sql; // $sql fields to remove for count total
$sql .= ' FROM '.MAIN_DB_PREFIX.'product as p';
if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) {
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
@ -602,11 +605,8 @@ $sql .= $hookmanager->resPrint;
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
/* $result = $db->query($sql);
$nbtotalofrecords = $db->num_rows($result);
*/
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/Ui', 'SELECT COUNT(*) as nbtotalofrecords FROM', $sql);
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/'.preg_quote($linktopfp, '/').'/', '', $sqlforcount);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
$resql = $db->query($sqlforcount);

View File

@ -110,12 +110,13 @@ $permissiontoadd = $user->rights->salaries->write; // Used by the include of act
$permissiontodelete = $user->rights->salaries->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
/**
/*
* Actions
*/
$parameters = array();
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
// Note that $action and $object may be modified by some hooks
$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
if ($reshook < 0) {
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
@ -123,14 +124,14 @@ if ($reshook < 0) {
if (empty($reshook)) {
$error = 0;
$backurlforlist = dol_buildpath('/salaries/list.php', 1);
$backurlforlist = DOL_URL_ROOT.'/salaries/list.php';
if (empty($backtopage) || ($cancel && empty($id))) {
if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
$backtopage = $backurlforlist;
} else {
$backtopage = dol_buildpath('/salaries/card.php', 1).'?id='.($id > 0 ? $id : '__ID__');
$backtopage = DOL_URL_ROOT.'/salaries/card.php?id='.($id > 0 ? $id : '__ID__');
}
}
}
@ -444,9 +445,10 @@ $form = new Form($db);
$formfile = new FormFile($db);
if (isModEnabled('project')) $formproject = new FormProjets($db);
$title = $langs->trans('Salary')." - ".$langs->trans('Card');
$title = $langs->trans('Salary')." - ".$object->ref;
$help_url = "";
llxHeader("", $title, $help_url);
llxHeader('', $title, $help_url);
if ($id > 0) {
@ -458,7 +460,7 @@ if ($id > 0) {
}
// Create
if ($action == 'create') {
if ($action == 'create' && $permissiontoadd) {
$year_current = dol_print_date(dol_now('gmt'), "%Y", 'gmt');
$pastmonth = strftime("%m", dol_now()) - 1;
$pastmonthyear = $year_current;
@ -480,7 +482,7 @@ if ($action == 'create') {
$datesp = dol_get_first_day($pastmonthyear, $pastmonth, false); $dateep = dol_get_last_day($pastmonthyear, $pastmonth, false);
}
print '<form name="salary" action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<form name="salary" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
if ($backtopage) {
@ -522,7 +524,7 @@ if ($action == 'create') {
print '</script>'."\n";
}
print dol_get_fiche_head('', '');
print dol_get_fiche_head('');
print '<table class="border centpercent">';
@ -692,13 +694,8 @@ if ($action == 'create') {
}
/* ************************************************************************** */
/* */
/* View mode */
/* */
/* ************************************************************************** */
if ($id) {
// View mode
if ($id > 0) {
$head = salaries_prepare_head($object);
$formconfirm = '';
@ -794,34 +791,26 @@ if ($id) {
$morehtmlref .= '</form>';
}
$usercancreate = $permissiontoadd;
// Project
if (isModEnabled('project')) {
$morehtmlref .= '<br>'.$langs->trans('Project').' ';
if ($user->rights->salaries->write) {
$langs->load("projects");
$morehtmlref .= '<br>';
if ($usercancreate) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
}
if ($action == 'classify') {
//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
$morehtmlref .= '<input type="hidden" name="action" value="classin">';
$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
$morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500');
$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
$morehtmlref .= '</form>';
} else {
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, ($action == 'classify' ? 1 : 0), 0, 1, '');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= ' : '.$proj->getNomUrl(1);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= ' - '.$proj->title;
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
} else {
$morehtmlref .= '';
}
}
}

View File

@ -78,7 +78,9 @@ $childids = $user->getAllChildIds(1);
// fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
$object = new Salary($db);
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('salarydoc', 'globalcard'));
if ($id > 0 || !empty($ref)) {
$object->fetch($id, $ref);
@ -105,7 +107,9 @@ if ($user->socid) {
}
restrictedArea($user, 'salaries', $object->id, 'salary', '');
$permissiontoread = $user->rights->salaries->read;
$permissiontoadd = $user->rights->salaries->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles
$permissiontodelete = $user->rights->salaries->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
/*
@ -176,34 +180,26 @@ if ($object->id) {
$morehtmlref .= '<br>'.$langs->trans('Employee').' : '.$userstatic->getNomUrl(-1);
$usercancreate = $permissiontoadd;
// Project
if (isModEnabled('project')) {
$morehtmlref .= '<br>'.$langs->trans('Project').' ';
if ($user->rights->salaries->write) {
$langs->load("projects");
$morehtmlref .= '<br>';
if ($usercancreate) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
}
if ($action == 'classify') {
//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
$morehtmlref .= '<input type="hidden" name="action" value="classin">';
$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
$morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500');
$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
$morehtmlref .= '</form>';
} else {
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, -1, $object->fk_project, 'none', 0, 0, 0, 1);
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, ($action == 'classify' ? 1 : 0), 0, 1, '');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= ' : '.$proj->getNomUrl(1);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= ' - '.$proj->title;
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
} else {
$morehtmlref .= '';
}
}
}

View File

@ -58,6 +58,9 @@ $childids = $user->getAllChildIds(1);
// fetch optionals attributes and labels
$extrafields->fetch_name_optionals_label($object->table_element);
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('salaryinfo', 'globalcard'));
$object = new Salary($db);
if ($id > 0 || !empty($ref)) {
$object->fetch($id, $ref);
@ -77,6 +80,10 @@ if ($id > 0 || !empty($ref)) {
restrictedArea($user, 'salaries', $object->id, 'salary', '');
$permissiontoread = $user->rights->salaries->read;
$permissiontoadd = $user->rights->salaries->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles
$permissiontodelete = $user->rights->salaries->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
/*
* Actions
@ -107,7 +114,6 @@ $title = $langs->trans('Salary')." - ".$langs->trans('Info');
$help_url = "";
llxHeader("", $title, $help_url);
$object = new Salary($db);
$object->fetch($id);
$object->info($id);
@ -139,34 +145,26 @@ if ($action != 'editlabel') {
$morehtmlref .= '<br>'.$langs->trans('Employee').' : '.$userstatic->getNomUrl(-1);
$usercancreate = $permissiontoadd;
// Project
if (isModEnabled('project')) {
$morehtmlref .= '<br>'.$langs->trans('Project').' ';
if ($user->rights->salaries->write) {
$langs->load("projects");
$morehtmlref .= '<br>';
if ($usercancreate) {
$morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
if ($action != 'classify') {
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
}
if ($action == 'classify') {
//$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1);
$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
$morehtmlref .= '<input type="hidden" name="action" value="classin">';
$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
$morehtmlref .= $formproject->select_projects(-1, $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1, 0, 'maxwidth500');
$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
$morehtmlref .= '</form>';
} else {
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1);
$morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
}
$morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, ($action == 'classify' ? 1 : 0), 0, 1, '');
} else {
if (!empty($object->fk_project)) {
$proj = new Project($db);
$proj->fetch($object->fk_project);
$morehtmlref .= ' : '.$proj->getNomUrl(1);
$morehtmlref .= $proj->getNomUrl(1);
if ($proj->title) {
$morehtmlref .= ' - '.$proj->title;
$morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
}
} else {
$morehtmlref .= '';
}
}
}
@ -180,7 +178,7 @@ print '<div class="underbanner clearboth"></div>';
print '<br>';
print '<table width="100%"><tr><td>';
print '<table class="centpercent"><tr><td>';
dol_print_object_info($object);
print '</td></tr></table>';

View File

@ -1154,7 +1154,7 @@ class Thirdparties extends DolibarrApi
*/
public function getCompanyBankAccount($id)
{
if (!DolibarrApiAccess::$user->rights->facture->lire) {
if (!DolibarrApiAccess::$user->rights->societe->lire) {
throw new RestException(401);
}
if (empty($id)) {

View File

@ -1395,6 +1395,12 @@ select.flat.selectlimit {
overflow: hidden;
height: auto !important;
}
.tenlinesmax {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
overflow: hidden;
}
.tablelistofcalendars {
margin-top: 25px !important;

View File

@ -1514,6 +1514,12 @@ select.flat.selectlimit {
overflow: hidden;
height: auto !important;
}
.tenlinesmax {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 10;
overflow: hidden;
}
.tablelistofcalendars {
margin-top: 25px !important;