Compare commits

...

14 Commits

Author SHA1 Message Date
Laurent Destailleur
a56645784c Prepare 23.0 2026-01-11 18:58:17 +01:00
Laurent Destailleur
b533548caa Prepare 23.0 2026-01-11 18:57:40 +01:00
Laurent Destailleur
aa0563a54a Debug v23 2026-01-11 18:41:11 +01:00
Laurent Destailleur
9c68ba8759 Debug v23 2026-01-11 18:17:21 +01:00
Laurent Destailleur
2759d409e4 Debug v23 2026-01-11 17:57:15 +01:00
Laurent Destailleur
049fcba06a Doc 2026-01-11 17:53:04 +01:00
Laurent Destailleur
342a6f754b Fix CI 2026-01-11 17:51:13 +01:00
Laurent Destailleur
a96bba2199 CSS v23 2026-01-11 17:40:21 +01:00
Laurent Destailleur
6e9225ce8b Debug v23 2026-01-11 16:17:12 +01:00
Laurent Destailleur
a41e9941f9 CSS 2026-01-11 16:00:00 +01:00
Laurent Destailleur
99b88e876f css 2026-01-11 14:26:55 +01:00
Laurent Destailleur
c698f4dc28 Backport some fixes of #36851 2026-01-11 13:12:38 +01:00
Laurent Destailleur
391fd8dab6 FIX icon of mastodon social network 2026-01-11 12:55:58 +01:00
spsolauv
8e37e310e0 CLOSE issue 36744 fix user can delete some actioncomm on which he has not the right (#36747)
* CLOSE issue 36744 fix user can delete some actioncomm on which he has not the right

* Fix whitespace

* Refactor delete confirmation logic for user access

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-01-11 12:34:47 +01:00
23 changed files with 2476 additions and 2106 deletions

File diff suppressed because one or more lines are too long

View File

@@ -256,6 +256,7 @@ export list="
--ignore-table=$base.llx_c_ticketsup_type
--ignore-table=$base.llx_cabinetmed_c_banques
--ignore-table=$base.llx_cabinetmed_c_examconclusion
--ignore-table=$base.llx_cabinetmed_cons
--ignore-table=$base.llx_cabinetmed_cons_extrafields
--ignore-table=$base.llx_cabinetmed_diaglec
--ignore-table=$base.llx_cabinetmed_examaut
@@ -269,6 +270,7 @@ export list="
--ignore-table=$base.llx_congespayes_events
--ignore-table=$base.llx_congespayes_logs
--ignore-table=$base.llx_congespayes_users
--ignore-table=$base.llx_deplacement
--ignore-table=$base.llx_dolicloud_customers
--ignore-table=$base.llx_dolicloud_stats
--ignore-table=$base.llx_dolicloud_emailstemplates

View File

@@ -26,6 +26,13 @@
// Load Dolibarr environment
require '../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/events.class.php';
@@ -36,14 +43,6 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once DOL_DOCUMENT_ROOT.'/emailcollector/class/emailcollector.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Translate $langs
* @var User $user
*/
// Load translation files required by page
$langs->loadLangs(array("admin", "other"));
@@ -53,7 +52,7 @@ $show_files = GETPOSTINT('show_files'); // Show files area generated by bulk act
$confirm = GETPOST('confirm', 'alpha'); // Result of a confirmation
$cancel = GETPOST('cancel', 'alpha'); // We click on a Cancel button
$toselect = GETPOST('toselect', 'array:int'); // Array of ids of elements selected into a list
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'emailcollectorlist'; // To manage different context of search
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : getDolDefaultContextPage(__FILE__); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // Go back to a dedicated page
$optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print')
$mode = GETPOST('mode', 'aZ');
@@ -125,12 +124,13 @@ foreach ($object->fields as $key => $val) {
}
// Definition of array of fields for columns
$tableprefix = 't';
$arrayfields = array();
foreach ($object->fields as $key => $val) {
// If $val['visible']==0, then we never show the field
if (!empty($val['visible'])) {
$visible = (int) dol_eval((string) $val['visible'], 1);
$arrayfields['t.'.$key] = array(
$arrayfields[$tableprefix.'.'.$key] = array(
'label' => $val['label'],
'checked' => (($visible < 0) ? '0' : '1'),
'enabled' => (string) (int) (abs($visible) != 3 && (bool) dol_eval((string) $val['enabled'], 1)),
@@ -257,25 +257,42 @@ foreach ($search as $key => $val) {
if ($key == 'status' && $search[$key] == -1) {
continue;
}
$mode_search = (($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key])) ? 1 : 0);
if ((strpos($object->fields[$key]['type'], 'integer:') === 0) || (strpos($object->fields[$key]['type'], 'sellist:') === 0) || !empty($object->fields[$key]['arrayofkeyval'])) {
if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($object->fields[$key]['arrayofkeyval']) || !array_key_exists('0', $object->fields[$key]['arrayofkeyval'])))) {
$field_spec = $object->fields[$key];
// @phpstan-ignore-next-line PHPStan thinks that $field_spec is never null
if ($field_spec === null) {
continue;
}
$mode_search = (($object->isInt($field_spec) || $object->isFloat($field_spec)) ? 1 : 0);
if ((strpos($field_spec['type'], 'integer:') === 0) || (strpos($field_spec['type'], 'sellist:') === 0) || !empty($field_spec['arrayofkeyval'])) {
if ($search[$key] == '-1' || ($search[$key] === '0' && (empty($field_spec['arrayofkeyval']) || !array_key_exists('0', $field_spec['arrayofkeyval'])))) {
$search[$key] = '';
}
$mode_search = 2;
}
if ($search[$key] != '') {
$sql .= natural_search("t.".$db->sanitize($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
if ($field_spec['type'] === 'boolean') {
$mode_search = 1;
if ($search[$key] == '-1') {
$search[$key] = '';
}
}
if (empty($field_spec['searchmulti'])) {
if (!is_array($search[$key]) && $search[$key] != '') {
$sql .= natural_search("t.".$db->escape($key), $search[$key], (($key == 'status') ? 2 : $mode_search));
}
} else {
if (is_array($search[$key]) && !empty($search[$key])) {
$sql .= natural_search("t.".$db->escape($key), implode(',', $search[$key]), (($key == 'status') ? 2 : $mode_search));
}
}
} else {
if (preg_match('/(_dtstart|_dtend)$/', $key) && $search[$key] != '') {
$columnName = preg_replace('/(_dtstart|_dtend)$/', '', $key);
if (preg_match('/^(date|timestamp|datetime)/', $object->fields[$columnName]['type'])) {
if (preg_match('/_dtstart$/', $key)) {
$sql .= " AND t.".$db->escape($columnName)." >= '".$db->idate($search[$key])."'";
$sql .= " AND t.".$db->sanitize($columnName)." >= '".$db->idate($search[$key])."'";
}
if (preg_match('/_dtend$/', $key)) {
$sql .= " AND t.".$db->escape($columnName)." <= '".$db->idate($search[$key])."'";
$sql .= " AND t.".$db->sanitize($columnName)." <= '".$db->idate($search[$key])."'";
}
}
}
@@ -364,7 +381,7 @@ $param = '';
if (!empty($mode)) {
$param .= '&mode='.urlencode($mode);
}
if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
if (!empty($contextpage) && $contextpage != getDolDefaultContextPage(__FILE__)) {
$param .= '&contextpage='.urlencode($contextpage);
}
if ($limit > 0 && $limit != $conf->liste_limit) {
@@ -383,17 +400,18 @@ foreach ($search as $key => $val) {
$param .= '&search_'.$key.'[]='.urlencode($skey);
}
}
} elseif (preg_match('/(_dtstart|_dtend)$/', $key) && !empty($val)) {
$param .= '&search_'.$key.'month='.GETPOSTINT('search_'.$key.'month');
$param .= '&search_'.$key.'day='.GETPOSTINT('search_'.$key.'day');
$param .= '&search_'.$key.'year='.GETPOSTINT('search_'.$key.'year');
} elseif ($search[$key] != '') {
$param .= '&search_'.$key.'='.urlencode($search[$key]);
}
}
if ($optioncss != '') {
$param .= '&optioncss='.urlencode($optioncss);
}
// Add $param from extra fields
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
// Add $param from hooks
$parameters = array();
$parameters = array('param' => &$param);
$reshook = $hookmanager->executeHooks('printFieldListSearchParam', $parameters, $object); // Note that $action and $object may have been modified by hook
$param .= $hookmanager->resPrint;
@@ -402,7 +420,7 @@ $arrayofmassactions = array(
//'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"),
//'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"),
);
if ($permissiontodelete) {
if (!empty($permissiontodelete)) {
$arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
if (GETPOSTINT('nomassaction') || in_array($massaction, array('presend', 'predelete'))) {
@@ -421,6 +439,8 @@ print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
print '<input type="hidden" name="page" value="'.$page.'">';
print '<input type="hidden" name="contextpage" value="'.$contextpage.'">';
print '<input type="hidden" name="page_y" value="">';
print '<input type="hidden" name="mode" value="'.$mode.'">';
$newcardbutton = '';
$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', 'emailcollector_card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd);
@@ -446,6 +466,9 @@ if (empty($reshook)) {
} else {
$moreforfilter = $hookmanager->resPrint;
}
$parameters = array(
'arrayfields' => &$arrayfields,
);
if (!empty($moreforfilter)) {
print '<div class="liste_titre liste_titre_bydiv centpercent">';
@@ -484,11 +507,15 @@ foreach ($object->fields as $key => $val) {
$cssforfield .= ($cssforfield ? ' ' : '').'right';
}
if (!empty($arrayfields['t.'.$key]['checked'])) {
print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').'">';
print '<td class="liste_titre'.($cssforfield ? ' '.$cssforfield : '').($key == 'status' ? ' parentonrightofpage' : '').'">';
if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) {
print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), $val['notnull'], 0, 0, '', 1, 0, 0, '', 'maxwidth100', 1);
if (empty($val['searchmulti'])) {
print $form->selectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 1, 0, 0, '', 1, 0, 0, '', 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
} else {
print $form->multiselectarray('search_'.$key, $val['arrayofkeyval'], (isset($search[$key]) ? $search[$key] : ''), 0, 0, 'maxwidth100'.($key == 'status' ? ' search_status width100 onrightofpage' : ''), 1);
}
} elseif ((strpos($val['type'], 'integer:') === 0) || (strpos($val['type'], 'sellist:') === 0)) {
print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', 'maxwidth125', 1);
print $object->showInputField($val, $key, (isset($search[$key]) ? $search[$key] : ''), '', '', 'search_', $cssforfield.' maxwidth125', 1);
} elseif (preg_match('/^(date|timestamp|datetime)/', $val['type'])) {
print '<div class="nowrap">';
print $form->selectDate($search[$key.'_dtstart'] ? $search[$key.'_dtstart'] : '', "search_".$key."_dtstart", 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'));
@@ -499,9 +526,11 @@ foreach ($object->fields as $key => $val) {
} elseif ($key == 'lang') {
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php';
$formadmin = new FormAdmin($db);
print $formadmin->select_language($search[$key], 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
print $formadmin->select_language((isset($search[$key]) ? $search[$key] : ''), 'search_lang', 0, array(), 1, 0, 0, 'minwidth100imp maxwidth125', 2);
} elseif ($val['type'] === 'boolean') {
print $form->selectyesno('search_' . $key, $search[$key] ?? '', 1, false, 1);
} else {
print '<input type="text" class="flat maxwidth'.($val['type'] == 'integer' ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
print '<input type="text" class="flat maxwidth'.(in_array($val['type'], array('integer', 'price')) ? '50' : '75').'" name="search_'.$key.'" value="'.dol_escape_htmltag(isset($search[$key]) ? $search[$key] : '').'">';
}
print '</td>';
}
@@ -561,7 +590,6 @@ if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
$totalarray['nbfield']++;
}
$totalarray['nbfield']++;
print '</tr>'."\n";

View File

@@ -202,6 +202,7 @@ if ($reshook < 0) {
$result = restrictedArea($user, 'agenda', $object, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id');
$usercancreate = $user->hasRight('agenda', 'allactions', 'create') || ((empty($object->id) || $object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'));
$usercandelete = $user->hasRight('agenda', 'allactions', 'delete') || (($object->authorid === $user->id || $object->userownerid === $user->id) && $user->hasRight('agenda', 'myactions', 'delete'));
/*
@@ -1206,22 +1207,19 @@ if (empty($reshook) && $action == 'update' && $usercancreate) {
}
// Delete event
if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes' && $usercancreate) {
if (empty($reshook) && $action == 'confirm_delete' && GETPOST("confirm") == 'yes' && $usercandelete) {
$object->fetch($id);
$object->fetch_optionals();
$object->fetch_userassigned();
$object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
if ($user->hasRight('agenda', 'myactions', 'delete')
|| $user->hasRight('agenda', 'allactions', 'delete')) {
$result = $object->delete($user);
$result = $object->delete($user);
if ($result >= 0) {
header("Location: index.php");
exit;
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
if ($result >= 0) {
header("Location: index.php");
exit;
} else {
setEventMessages($object->error, $object->errors, 'errors');
}
}
@@ -2977,8 +2975,7 @@ if ($id > 0 && $action != 'create') {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("ToClone").'</a></div>';
}
if ($user->hasRight('agenda', 'allactions', 'delete') ||
(($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'delete'))) {
if ($usercandelete) {
print '<div class="inline-block divButAction"><a class="butActionDelete" href="card.php?action=delete&token='.newToken().'&id='.$object->id.'">'.$langs->trans("Delete").'</a></div>';
} else {
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans("NotAllowed").'">'.$langs->trans("Delete").'</a></div>';

View File

@@ -1725,9 +1725,12 @@ function onKanbanColumnChange(item, newColumn) {
item.data('original-column', newColumn);
}
if (typeof jQuery.fn.on === 'function') {
/*
* Intuitive table selection
*/
* Intuitive table selection (with keyboard selection)
*/
$(function() {
/**
@@ -1818,4 +1821,6 @@ $(function() {
});
});
}
// End of lib_head.js.php

View File

@@ -942,18 +942,20 @@ function isInSEPA($object)
/**
* Show html area for list of projects
*
* @param Conf $conf Object conf
* @param Translate $langs Object langs
* @param DoliDB $db Database handler
* @param Societe $object Third party object
* @param string $backtopage Url to go once contact is created
* @param int<0,1> $nocreatelink 1=Hide create project link
* @param string $morehtmlright More html on right of title
* @param Conf $conf Object conf
* @param Translate $langs Object langs
* @param DoliDB $db Database handler
* @param Societe $object Third party object
* @param string $backtopage Url to go once contact is created
* @param int<0,1> $nocreatelink 1=Hide create project link
* @param string $morehtmlright More html on right of title
* @param string $massactionbutton Mass action button
* @return int
*/
function show_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatelink = 0, $morehtmlright = '')
function show_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatelink = 0, $morehtmlright = '', $massactionbutton = '')
{
global $user, $action, $hookmanager, $form, $massactionbutton, $massaction, $arrayofselected, $arrayofmassactions;
global $user, $action, $hookmanager, $form;
global $massaction, $arrayofselected, $arrayofmassactions;
$i = -1;
@@ -966,7 +968,7 @@ function show_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatel
}
print "\n";
print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"), $newcardbutton . $morehtmlright, '');
print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"), $newcardbutton . $morehtmlright, '', 0, '', '', $massactionbutton);
print '<div class="div-table-responsive">' . "\n";
print '<table class="noborder centpercent">';

View File

@@ -2038,13 +2038,13 @@ class EmailCollector extends CommonObject
$replytostring = '';
if (getDolGlobalString('MAIN_IMAP_USE_PHPIMAP')) {
$fromstring = $overview['from'];
$replytostring = empty($overview['in_reply-to']) ? $headers['Reply-To'] : $overview['in_reply-to'];
$fromstring = $this->decodeSMTPSubject((string) ($overview['from'] ?? ''));
$replytostring = !empty($headers['Reply-To']) ? $this->decodeSMTPSubject($headers['Reply-To']) : '';
$sender = $overview['sender'];
$to = $overview['to'];
$sendtocc = empty($overview['cc']) ? '' : $overview['cc'];
$sendtobcc = empty($overview['bcc']) ? '' : $overview['bcc'];
$sender = $this->decodeSMTPSubject((string) ($overview['sender'] ?? ''));
$to = $this->decodeSMTPSubject((string) ($overview['to'] ?? ''));
$sendtocc = $this->decodeSMTPSubject((string) ($overview['cc'] ?? ''));
$sendtobcc = $this->decodeSMTPSubject((string) ($overview['bcc'] ?? ''));
$tmpdate = $overview['date']->toDate(); // @phan-suppress-current-line PhanPluginUnknownObjectMethodCall
$tmptimezone = $tmpdate->getTimezone()->getName(); // @phan-suppress-current-line PhanPluginUnknownObjectMethodCall
@@ -2060,7 +2060,7 @@ class EmailCollector extends CommonObject
$dateemail += (60 * (int) $reg[3]);
}
}
$subject = $overview['subject'];
$subject = $this->decodeSMTPSubject((string) ($overview['subject'] ?? ''));
} else {
$fromstring = $overview[0]->from;
$replytostring = (!empty($overview['in_reply-to']) ? $overview['in_reply-to'] : (!empty($headers['Reply-To']) ? $headers['Reply-To'] : "")) ;
@@ -2450,8 +2450,11 @@ class EmailCollector extends CommonObject
$actioncode = 'EMAIL';
}
// If sender is in the list MAIL_FROM_EMAILS_TO_CONSIDER_SENDING
$arrayofemailtoconsideresender = explode(',', getDolGlobalString('MAIL_FROM_EMAILS_TO_CONSIDER_SENDING'));
foreach ($arrayofemailtoconsideresender as $emailtoconsidersender) {
$arrayofemailtoconsidersender = array_filter(array_map('trim', explode(',', getDolGlobalString('MAIL_FROM_EMAILS_TO_CONSIDER_SENDING'))));
foreach ($arrayofemailtoconsidersender as $emailtoconsidersender) {
if ($emailtoconsidersender === '') {
continue;
}
if (preg_match('/'.preg_quote($emailtoconsidersender, '/').'/', $fromstring)) {
$actioncode = 'EMAIL';
}

View File

@@ -243,15 +243,22 @@ input:focus, textarea:focus, button:focus, select:focus {
input[type=text], input[type=password] {
border: 1px solid #ACBCBB;
padding: 4px;
border-radius: 4px;
padding: 5px;
}
select {
padding: 4px;
background-color: #fff;
border-radius: 4px;
padding: 5px;
}
input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus {
border: 1px solid #ACBCBB;
box-shadow: 0 0 5px #C091AF;
}
input[type=checkbox] {
transform: scale(1.25);
}
input:-webkit-autofill {
background: #FBFFEA none !important;
-webkit-box-shadow: 0 0 0 50px #FBFFEA inset;
@@ -464,7 +471,12 @@ a.button:hover {
.text-security {
-webkit-text-security: disc;
}
.width75 {
width: 75px;
}
.width100 {
width: 100px;
}
.pictofixedwidth {
text-align: start;

View File

@@ -471,7 +471,7 @@ if (!empty($force_install_noedit)) {
<tr class="hidesqlite">
<td class="label"><label for="db_port"><?php echo $langs->trans("Port"); ?></label></td>
<td class="label">
<input type="text"
<input type="text" class="width75"
name="db_port"
id="db_port"
value="<?php print (!empty($force_install_port)) ? $force_install_port : $dolibarr_main_db_port; ?>"

View File

@@ -417,6 +417,7 @@ ALTER TABLE llx_pos_cash_fence ADD COLUMN lifetime_start datetime DEFAULT NULL;
UPDATE llx_cronjob set test = 'getDolDBType() == \'mysqli\'' WHERE label = 'MakeLocalDatabaseDumpShort';
UPDATE llx_cronjob set test = 'getDolGlobalString(\'MAIN_ALLOW_BACKUP_BY_EMAIL\') && getDolDBType() == \'mysqli\'' WHERE label = 'MakeSendLocalDatabaseDumpShort';
UPDATE llx_c_socialnetworks SET icon = 'fa-mastodon' WHERE icon = '' AND code = 'mastodon';
-- end of migration

View File

@@ -583,7 +583,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print '<tr><td>';
print $langs->trans("ConfFileReload");
print '</td>';
print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print '<td>'.img_picto('OK', 'tick').'</td></tr>';
// Create database user if requested
if (isset($db_create_user) && ($db_create_user == "1" || $db_create_user == "on")) {
@@ -641,7 +641,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("UserCreation").' : ';
print $dolibarr_main_db_user;
print '</td>';
print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print '<td>'.img_picto('OK', 'tick').'</td></tr>';
} else {
if ($db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS'
|| $db->errno() == 'DB_ERROR_KEY_NAME_ALREADY_EXISTS'
@@ -669,7 +669,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("UserCreation").' : ';
print $dolibarr_main_db_user;
print '</td>';
print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
print '<td>'.img_picto('Error', 'warning', 'class="error"').'</td>';
print '</tr>';
// warning message due to connection failure
@@ -700,7 +700,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : ";
print $dolibarr_main_db_name;
print '</td>';
print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print '<td>'.img_picto('OK', 'tick').'</td></tr>';
$newdb->select_db($dolibarr_main_db_name);
$check1 = $newdb->getDefaultCharacterSetDatabase();
@@ -728,7 +728,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("DatabaseCreation")." (".$langs->trans("User")." ".$userroot.") : ";
print $dolibarr_main_db_name;
print '</td>';
print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td>';
print '<td>'.img_picto('Error', 'warning', 'class="error"').'</td>';
print '</tr>';
// warning message
@@ -757,7 +757,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
print $dolibarr_main_db_host;
print "</td><td>";
print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
print img_picto('OK', 'tick');
print "</td></tr>";
// server access ok, basic access ok
@@ -767,7 +767,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
print $dolibarr_main_db_name;
print "</td><td>";
print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
print img_picto('OK', 'tick');
print "</td></tr>";
$error = 0;
@@ -777,7 +777,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("DatabaseConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
print $dolibarr_main_db_name;
print '</td><td>';
print '<img src="../theme/eldy/img/error.png" alt="Error">';
print img_picto('Error', 'warning', 'class="error"');
print "</td></tr>";
// warning message
@@ -795,7 +795,7 @@ if (!$error && $db->connected && $action == "set") { // Test on permission not r
print $langs->trans("ServerConnection")." (".$langs->trans("User")." ".$conf->db->user.") : ";
print $dolibarr_main_db_host;
print '</td><td>';
print '<img src="../theme/eldy/img/error.png" alt="Error">';
print img_picto('Error', 'warning', 'class="error"');
print "</td></tr>";
// warning message
@@ -1097,7 +1097,7 @@ function write_conf_file($conffile)
print $langs->trans("SaveConfigurationFile");
print ' <strong>'.$conffile.'</strong>';
print "</td><td>";
print '<img src="../theme/eldy/img/tick.png" alt="Ok">';
print img_picto('OK', 'tick');
print "</td></tr>";
} else {
$error++;

View File

@@ -134,10 +134,10 @@ if ($action == "set") { // Test on permission not required. Already managed by
if ($db->connected) {
print "<tr><td>";
print $langs->trans("ServerConnection")." : ".$conf->db->host.'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print $langs->trans("ServerConnection")." : ".$conf->db->host.'</td><td>'.img_picto('OK', 'tick').'</td></tr>';
$ok = 1;
} else {
print "<tr><td>Failed to connect to server : ".$conf->db->host.'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
print "<tr><td>Failed to connect to server : ".$conf->db->host.'</td><td>'.img_picto('Error', 'warning', 'class="error"').'</td></tr>';
}
if ($ok) {
@@ -145,7 +145,7 @@ if ($action == "set") { // Test on permission not required. Already managed by
dolibarr_install_syslog("step2: successful connection to database: ".$conf->db->name);
} else {
dolibarr_install_syslog("step2: failed connection to database :".$conf->db->name, LOG_ERR);
print "<tr><td>Failed to select database ".$conf->db->name.'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
print "<tr><td>Failed to select database ".$conf->db->name.'</td><td>'.img_picto('Error', 'warning', 'class="error"').'</td></tr>';
$ok = 0;
}
}
@@ -268,11 +268,11 @@ if ($action == "set") { // Test on permission not required. Already managed by
if ($tablefound) {
if ($error == 0) {
print '<tr><td>';
print $langs->trans("TablesAndPrimaryKeysCreation").'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print $langs->trans("TablesAndPrimaryKeysCreation").'</td><td>'.img_picto('OK', 'tick').'</td></tr>';
$ok = 1;
}
} else {
print '<tr><td>'.$langs->trans("ErrorFailedToFindSomeFiles", $dir).'</td><td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
print '<tr><td>'.$langs->trans("ErrorFailedToFindSomeFiles", $dir).'</td><td>'.img_picto('Error', 'warning', 'class="error"').'</td></tr>';
dolibarr_install_syslog("step2: failed to find files to create database in directory ".$dir, LOG_ERR);
}
}
@@ -394,7 +394,7 @@ if ($action == "set") { // Test on permission not required. Already managed by
if ($tablefound && $error == 0) {
print '<tr><td>';
print $langs->trans("OtherKeysCreation").'</td><td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print $langs->trans("OtherKeysCreation").'</td><td>'.img_picto('OK', 'tick').'</td></tr>';
$okkeys = 1;
}
}
@@ -469,9 +469,9 @@ if ($action == "set") { // Test on permission not required. Already managed by
print "<tr><td>".$langs->trans("FunctionsCreation")."</td>";
if ($ok) {
print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print '<td>'.img_picto('OK', 'tick').'</td></tr>';
} else {
print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
print '<td>'.img_picto('Error', 'warning', 'class="error"').'</td></tr>';
$ok = 1;
}
}
@@ -584,9 +584,9 @@ if ($action == "set") { // Test on permission not required. Already managed by
print "<tr><td>".$langs->trans("ReferenceDataLoading")."</td>";
if ($ok) {
print '<td><img src="../theme/eldy/img/tick.png" alt="Ok"></td></tr>';
print '<td>'.img_picto('OK', 'tick').'</td></tr>';
} else {
print '<td><img src="../theme/eldy/img/error.png" alt="Error"></td></tr>';
print '<td>'.img_picto('Error', 'warning', 'class="error"').'</td></tr>';
$ok = 1; // Data loading are not blocking errors
}
}

View File

@@ -526,11 +526,11 @@ if ($action == "set") {
print "<br>";
print $langs->trans("YouNeedToPersonalizeSetup")."<br><br><br>";
print '<span class="opacitymedium">'.$langs->trans("YouNeedToPersonalizeSetup")."</span><br><br><br>";
print '<div class="center divlinktogotosetup"><a href="../admin/index.php?mainmenu=home&leftmenu=setup'.(isset($login) ? '&username='.urlencode($login) : '').'">';
print '<span class="fas fa-external-link-alt"></span> '.$langs->trans("GoToSetupArea");
print '</a></div><br>';
print '</a></div><br><br>';
} else {
// If here MAIN_VERSION_LAST_UPGRADE is not empty
print $langs->trans("VersionLastUpgrade").': <b><span class="ok">' . getDolGlobalString('MAIN_VERSION_LAST_UPGRADE').'</span></b><br>';
@@ -540,7 +540,8 @@ if ($action == "set") {
print '<div class="center"><a href="'.$dolibarr_main_url_root.'/install/index.php">';
print '<span class="fas fa-link-alt"></span> '.$langs->trans("GoToUpgradePage");
print '</a></div>';
print '</a>';
print '</div>';
}
}
} elseif (empty($action) || preg_match('/upgrade/i', $action)) {

View File

@@ -752,7 +752,7 @@ print $hookmanager->resPrint;
}*/
// Action column
if (!$conf->main_checkbox_left_column) {
print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n";
$totalarray['nbfield']++;
}
print '</tr>'."\n";

View File

@@ -491,7 +491,7 @@ if ($usertoprocess->id != $user->id) {
}
print '<div class="taskiddiv inline-block">';
print img_picto('', 'projecttask', 'class="pictofixedwidth"');
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx', '', 'all', $usertoprocess);
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx maxwidth500', '', 'all', $usertoprocess);
print '</div>';
print ' ';
print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'position', 0, 'maxwidth150onsmartphone');

View File

@@ -503,7 +503,7 @@ if ($usertoprocess->id != $user->id) {
}
print '<div class="taskiddiv inline-block">';
print img_picto('', 'projecttask', 'class="pictofixedwidth"');
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx', '', 'all', $usertoprocess);
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx maxwidth500', '', 'all', $usertoprocess);
print '</div>';
print ' ';
print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'position', 0, 'maxwidth150onsmartphone');

View File

@@ -502,7 +502,7 @@ if ($usertoprocess->id != $user->id) {
}
print '<div class="taskiddiv inline-block">';
print img_picto('', 'projecttask', 'class="pictofixedwidth"');
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx', '', 'all', $usertoprocess);
$formproject->selectTasks($socid ? $socid : -1, $taskid, 'taskid', 32, 0, '-- '.$langs->trans("ChooseANotYetAssignedTask").' --', 1, 0, 0, 'widthcentpercentminusx maxwidth500', '', 'all', $usertoprocess);
print '</div>';
print ' ';
print $formcompany->selectTypeContact($object, '', 'type', 'internal', 'position', 0, 'maxwidth150onsmartphone');

View File

@@ -409,12 +409,14 @@ if ($usersection) {
// Output payment summary form
print '<tr><td class="left">';
print '<div class="nowidthimp nopaddingtoponsmartphone" id="tablepublicpayment">';
if ($usersection) {
print '<div class="nowidthimp nopaddingtoponsmartphone" id="tablepublicpayment">';
print $usersection;
print $usersection;
print '</div>'."\n";
print "\n";
print '</div>'."\n";
print "\n";
}
print '</td></tr>'."\n";
@@ -506,21 +508,23 @@ if (!getDolUserInt('USER_PUBLIC_HIDE_COMPANY', 0, $object)) {
// Output payment summary form
print '<tr><td class="left">';
print '<div class="nowidthimp nopaddingtoponsmartphone" id="tablepublicpayment">';
if ($companysection || $mysoc->name) {
print '<div class="nowidthimp nopaddingtoponsmartphone" id="tablepublicpayment">';
// Add company info
if ($mysoc->name) {
print '<div class="center bold">';
print dol_escape_htmltag($mysoc->name);
print '</div>';
print '<br>';
// Add company info
if ($mysoc->name) {
print '<div class="center bold">';
print dol_escape_htmltag($mysoc->name);
print '</div>';
print '<br>';
}
print $companysection;
print '</div>'."\n";
print "\n";
}
print $companysection;
print '</div>'."\n";
print "\n";
print '</td></tr>'."\n";
print '</table>'."\n";

View File

@@ -24,6 +24,7 @@
* @var User $user
*
* @var string $canvas
* @var int $socid
*/
// Protection to avoid direct call of template
if (empty($conf) || !is_object($conf)) {
@@ -308,7 +309,7 @@ $result = show_subsidiaries($conf, $langs, $db, $soc);
$result = show_contacts($conf, $langs, $db, $soc);
// Projects list
$result = show_projects($conf, $langs, $db, $soc);
$result = show_projects($conf, $langs, $db, $soc, $_SERVER["PHP_SELF"].'?socid='.$socid, 1, '', '');
?>
<!-- END PHP TEMPLATE -->

View File

@@ -237,6 +237,6 @@ $result = show_subsidiaries($conf, $langs, $db, $object);
$result = show_contacts($conf, $langs, $db, $object);
// Projects list
$result = show_projects($conf, $langs, $db, $object);
$result = show_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?socid='.$object->id, 1, '', '');
print "<!-- END PHP TEMPLATE -->\n";

View File

@@ -31,11 +31,6 @@
// Load Dolibarr environment
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
@@ -43,6 +38,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
$form = new Form($db);
@@ -186,14 +185,16 @@ if ($socid) {
if (empty($conf->dol_optimize_smallscreen)) {
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'?socid='.$object->id.'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<div class="nobordernopadding center valignmiddle col-center">'.$massactionbutton.'</div>';
//print '<div class="nobordernopadding center valignmiddle col-center">'.$massactionbutton.'</div>';
}
// Projects list
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
$arrayofselected = is_array($toselect) ? $toselect : array();
$result = show_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?socid='.$object->id, 1, $newcardbutton);
$result = show_projects($conf, $langs, $db, $object, $_SERVER["PHP_SELF"].'?socid='.$object->id, 1, $newcardbutton, $massactionbutton);
if (empty($conf->dol_optimize_smallscreen)) {
print '</form>';

View File

@@ -387,7 +387,7 @@ span.massactionselect, input.inputsearch_dropdownselectedfields {
.liste_titre input, .liste_titre select {
border: none;
border<?php echo getDolGlobalString('THEME_SHOW_BORDER_ON_INPUT') ? '' : '-bottom'; ?>: solid 1px var(<?php echo getDolGlobalString('THEME_SHOW_BORDER_ON_INPUT') ? '--colorbacktitle1' : '--inputbordercolor'; ?>);
border<?php echo getDolGlobalString('THEME_SHOW_BORDER_ON_INPUT') ? '' : '-bottom'; ?>: solid 1px var(<?php echo getDolGlobalString('THEME_SHOW_BORDER_ON_INPUT') ? '--colorbacktitle1' : '--inputbordercolor'; ?>) !important;
}
.divadvancedsearchfieldcompinput,
@@ -5390,9 +5390,9 @@ ul.noborder li:nth-child(even):not(.liste_titre) {
.boxstats:hover {
box-shadow: 0px 0px 8px 0px rgba(0,0,0,0.20);
}
span.boxstatstext span:not(.fas) {
/*span.boxstatstext span:not(.fas) {
opacity: 0.5;
}
}*/
span.boxstatstext {
opacity: 0.5; /* a bug if browser make z-index was discovered when opacity is set, if still present, we must disable it */
line-height: 18px;
@@ -7415,6 +7415,9 @@ input.select2-input {
border: none;
border-bottom: solid 1px var(--inputbordercolor) !important; /* required to avoid to lose bottom line when focus is lost on select2. */
}
li.select2-selection__choice {
white-space: break-spaces;
}
.select2-results .select2-highlighted.optionblue {
color: #FFF !important;
}

View File

@@ -7283,6 +7283,10 @@ input.select2-input {
border: none;
border-bottom: 1px solid #ccc !important;
}
li.select2-selection__choice {
white-space: break-spaces;
}
.select2-results .select2-highlighted.optionblue {
color: #FFF !important;
}