2
0
forked from Wavyzz/dolibarr

FIX Hide a feature that is a security vulnerability.

This commit is contained in:
Laurent Destailleur
2024-09-20 00:19:36 +02:00
16 changed files with 184 additions and 145 deletions

View File

@@ -45,6 +45,10 @@ NEW: Accountancy - Add possibility for specific format FEC to sort with the FEC
NEW: Accountancy - Expense report - Add an option to use end period for transfer (#26706) NEW: Accountancy - Expense report - Add an option to use end period for transfer (#26706)
NEW: Accountancy - Show accounting result on balance NEW: Accountancy - Show accounting result on balance
NEW: Accountancy - Show import key if exist (#29265) NEW: Accountancy - Show import key if exist (#29265)
NEW: Accountancy - Auto-determine piece number in FEC import (#29672)
NEW: Accountancy - Option to transfer only reconciled lines from bank (#29408)
NEW: Accountancy - Separation of accounting default account for salary and expense report
NEW: Various payment - Use list of accounting account when edit (#27992)
NEW: Add option to change all service dates at once NEW: Add option to change all service dates at once
NEW: Add a default limit in nb to agenda export NEW: Add a default limit in nb to agenda export
NEW: Add a Feedback-ID into email headers NEW: Add a Feedback-ID into email headers
@@ -97,7 +101,6 @@ NEW: Allow smileys into emailing html content
NEW: Allow to set a default project for POS sales (#27042) NEW: Allow to set a default project for POS sales (#27042)
NEW: animation for display spinner when waiting response NEW: animation for display spinner when waiting response
NEW: Asset Module - make asset model creation in a single step (#26982) NEW: Asset Module - make asset model creation in a single step (#26982)
NEW: auto-determine piece number in FEC import (#29672)
NEW: auto fill infos in template email NEW: auto fill infos in template email
NEW: Automatically fill matching extra fields of object on line creation. (#27240) NEW: Automatically fill matching extra fields of object on line creation. (#27240)
NEW: Can add documents on a payment (#29660) NEW: Can add documents on a payment (#29660)
@@ -134,7 +137,7 @@ NEW: fetch object by element for website account card
NEW: filter on sale representative in contact list NEW: filter on sale representative in contact list
NEW: Filter shipments by selecting multiple shipping methods (#28376) NEW: Filter shipments by selecting multiple shipping methods (#28376)
NEW: Font param Look and Feel (#29302) NEW: Font param Look and Feel (#29302)
NEW: fuctionnality for stock configuration prompt in AI module (#28030) NEW: functionality for stock configuration prompt in AI module (#28030)
NEW: functionality to delete contact of company list NEW: functionality to delete contact of company list
NEW: functionality to display codebar on pdf files (#29623) NEW: functionality to display codebar on pdf files (#29623)
NEW: functionality to list event for user NEW: functionality to list event for user
@@ -166,7 +169,6 @@ NEW: notification action triggers for cancelling orders and invoices
NEW: now button when editing an event NEW: now button when editing an event
NEW: online signature of shipments (#29559) NEW: online signature of shipments (#29559)
NEW: On OAuth Google login, no prompt at all if already logged in Google NEW: On OAuth Google login, no prompt at all if already logged in Google
NEW: Option to transfer only reconciliated lines from bank (#29408)
NEW: Param to show main menu logo in color look and feel (#29305) NEW: Param to show main menu logo in color look and feel (#29305)
NEW: Payment page received from donations NEW: Payment page received from donations
NEW: possibility to define a completely inactive module (#29289) NEW: possibility to define a completely inactive module (#29289)
@@ -179,7 +181,6 @@ NEW: resource address, phone, email & maxusers (#28185)
NEW: Script for fast identification of missing/unused/duplicate translations NEW: Script for fast identification of missing/unused/duplicate translations
NEW: search member by date NEW: search member by date
NEW: See the documents of my subordinates (#28318) NEW: See the documents of my subordinates (#28318)
NEW: separation of expense report from salary accounting code
NEW: Show error on ical parse NEW: Show error on ical parse
NEW: Show the profit per attendee on events NEW: Show the profit per attendee on events
NEW: signed status CRUD to contract and fichinter NEW: signed status CRUD to contract and fichinter
@@ -206,7 +207,6 @@ NEW: Update expense report card.php to allow pdf preview even without thumbnail
NEW: update price with auto to use const for rounding prices (#29350) NEW: update price with auto to use const for rounding prices (#29350)
NEW: Use a nicer combo list to select the export accounting format NEW: Use a nicer combo list to select the export accounting format
NEW: users can set their own length for short lists NEW: users can set their own length for short lists
NEW: Various payment - Use list of account when edit (#27992)
NEW: warning message when cloning a product whose status is not to sell (#28374) NEW: warning message when cloning a product whose status is not to sell (#28374)
PERF: Performance enhancement on Invoice/Paiement area page PERF: Performance enhancement on Invoice/Paiement area page
PERF: Use cache for loaded users/contact on project list PERF: Use cache for loaded users/contact on project list
@@ -219,6 +219,7 @@ SEC: Reduce nb of var without WAF used when using the website module
For developers or integrators: For developers or integrators:
------------------------------ ------------------------------
NEW: Situation invoice - Add new official progressive mode - (constant INVOICE_USE_SITUATION = 2)
NEW: $noescapetags param of dol_escape_html works if attributes NEW: $noescapetags param of dol_escape_html works if attributes
NEW: Add createInvoiceFromContract to API invoice (#27277) NEW: Add createInvoiceFromContract to API invoice (#27277)
NEW: add debugging info to api/status if non-production NEW: add debugging info to api/status if non-production

View File

@@ -660,7 +660,7 @@ if (getDolGlobalInt('MAIN_ACTIVATE_FILECACHE')) {
} else { } else {
print img_picto('', 'minus', 'class="pictofixedwidth"'); print img_picto('', 'minus', 'class="pictofixedwidth"');
} }
print ' '.$form->textwithpicto($langs->trans("EnableFileCache").' ('.$langs->trans("Widgets").')', $langs->trans("Option").' MAIN_ACTIVATE_FILECACHE'); print $form->textwithpicto($langs->trans("EnableFileCache").' ('.$langs->trans("Widgets").')', $langs->trans("Option").' MAIN_ACTIVATE_FILECACHE');
print ': '.yn(getDolGlobalInt('MAIN_ACTIVATE_FILECACHE')); print ': '.yn(getDolGlobalInt('MAIN_ACTIVATE_FILECACHE'));
print '<br>'; print '<br>';
@@ -669,7 +669,7 @@ if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
} else { } else {
print img_picto('', 'minus', 'class="pictofixedwidth"'); print img_picto('', 'minus', 'class="pictofixedwidth"');
} }
print ' MAIN_ENABLE_AJAX_TOOLTIP : '; print 'MAIN_ENABLE_AJAX_TOOLTIP : ';
print yn(getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')); print yn(getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP'));
print '<br>'; print '<br>';

View File

@@ -379,11 +379,12 @@ if (empty($dolibarr_main_stream_to_disable)) {
} else { } else {
print implode(', ', $dolibarr_main_stream_to_disable); print implode(', ', $dolibarr_main_stream_to_disable);
} }
print '<span class="bold"> -> Current PHP streams allowed = </span>'; print '<span class="bold"> &nbsp; -> Current PHP streams allowed = </span>';
$arrayofstreams = stream_get_wrappers(); $arrayofstreams = stream_get_wrappers();
if (!empty($arrayofstreams)) { if (!empty($arrayofstreams)) {
sort($arrayofstreams); sort($arrayofstreams);
print(implode(', ', $arrayofstreams)).' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").': '.$langs->trans("TryToKeepOnly", 'file,http,https,php,zip').')</span>'."\n"; print '<span class="wordbreakall">'.implode(',', $arrayofstreams).'</span>';
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").': '.$langs->trans("TryToKeepOnly", 'file,http,https,php,zip').')</span>'."\n";
} }
print '</div>'; print '</div>';

View File

@@ -167,21 +167,12 @@ if ($action == 'updateMask') {
$error++; $error++;
} }
if (GETPOSTISSET('product_category_id')) {
$param_ticket_product_category = GETPOSTINT('product_category_id');
$res = dolibarr_set_const($db, 'TICKET_PRODUCT_CATEGORY', $param_ticket_product_category, 'chaine', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
}
$param_status = GETPOST('TICKET_SET_STATUS_ON_ANSWER'); $param_status = GETPOST('TICKET_SET_STATUS_ON_ANSWER');
$res = dolibarr_set_const($db, 'TICKET_SET_STATUS_ON_ANSWER', $param_status, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, 'TICKET_SET_STATUS_ON_ANSWER', $param_status, 'chaine', 0, '', $conf->entity);
if (!($res > 0)) { if (!($res > 0)) {
$error++; $error++;
} }
$param_delay_first_response = GETPOSTINT('delay_first_response'); $param_delay_first_response = GETPOSTINT('delay_first_response');
$res = dolibarr_set_const($db, 'TICKET_DELAY_BEFORE_FIRST_RESPONSE', $param_delay_first_response, 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, 'TICKET_DELAY_BEFORE_FIRST_RESPONSE', $param_delay_first_response, 'chaine', 0, '', $conf->entity);
if (!($res > 0)) { if (!($res > 0)) {
@@ -625,37 +616,6 @@ print $formcategory->textwithpicto('', $langs->trans("TicketAutoCheckNotifyThird
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
// Assign contact to a message
print '<tr class="oddeven"><td>'.$langs->trans("TicketAssignContactToMessage").'</td>';
print '<td class="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKET_ASSIGN_CONTACT_TO_MESSAGE');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $formcategory->selectarray("TICKET_ASSIGN_CONTACT_TO_MESSAGE", $arrval, getDolGlobalString('TICKET_ASSIGN_CONTACT_TO_MESSAGE'));
}
print '</td>';
print '<td class="center">';
print $formcategory->textwithpicto('', $langs->trans("TicketAssignContactToMessageHelp"), 1, 'help');
print '</td>';
print '</tr>';
if (isModEnabled('product')) {
$htmlname = "product_category_id";
print '<tr class="oddeven"><td>'.$langs->trans("TicketChooseProductCategory").'</td>';
print '<td class="left">';
print img_picto('', 'category', 'class="pictofixedwidth"');
$formcategory->selectProductCategory(getDolGlobalString('TICKET_PRODUCT_CATEGORY'), $htmlname);
if ($conf->use_javascript_ajax) {
print ajax_combobox('select_'.$htmlname);
}
print '</td>';
print '<td class="center">';
print $formcategory->textwithpicto('', $langs->trans("TicketChooseProductCategoryHelp"), 1, 'help');
print '</td>';
print '</tr>';
}
print '<tr class="oddeven">'; print '<tr class="oddeven">';
print '<td>'.$langs->trans("TicketsDelayBeforeFirstAnswer")."</td>"; print '<td>'.$langs->trans("TicketsDelayBeforeFirstAnswer")."</td>";
print '<td class="left"> print '<td class="left">

View File

@@ -28,6 +28,7 @@ require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php";
require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php"; require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php";
require_once DOL_DOCUMENT_ROOT."/core/lib/ticket.lib.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/ticket.lib.php";
require_once DOL_DOCUMENT_ROOT."/core/class/html.formcategory.class.php";
// Load translation files required by the page // Load translation files required by the page
$langs->loadLangs(array("admin", "ticket")); $langs->loadLangs(array("admin", "ticket"));
@@ -221,6 +222,7 @@ if ($action != '') {
$dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
$form = new Form($db); $form = new Form($db);
$formcategory = new FormCategory($db);
$help_url = "FR:Module_Ticket"; $help_url = "FR:Module_Ticket";
$page_name = "TicketSetup"; $page_name = "TicketSetup";
@@ -414,7 +416,7 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
} }
if (empty($conf->use_javascript_ajax)) { if (empty($conf->use_javascript_ajax)) {
print '<tr class="impair"><td colspan="3" align="center"><input type="submit" class="button button-save" value="'.$langs->trans("Save").'"></td>'; print '<tr><td colspan="3" align="center"><input type="submit" class="button button-save" value="'.$langs->trans("Save").'"></td>';
print '</tr>'; print '</tr>';
} }
@@ -458,9 +460,29 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help'); print $form->textwithpicto('', $langs->trans("TicketPublicInterfaceTextHelpMessageHelpAdmin"), 1, 'help');
print '</td></tr>'; print '</td></tr>';
// Add first contact id found in database from submitter email entered into public interface
// Feature disabled: This has a security trouble. The public interface is a no login interface, so being able to show the contact info from an
// email decided by the submiter allows anybody to get information on any contact (customer or supplier) in Dolibarr database.
// He can even check if contact exists by trying any email if this feature is enabled.
/*
print '<tr class="oddeven"><td>'.$langs->trans("TicketAssignContactToMessage").'</td>';
print '<td class="left">';
if ($conf->use_javascript_ajax) {
print ajax_constantonoff('TICKET_ASSIGN_CONTACT_TO_MESSAGE');
} else {
$arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes"));
print $formcategory->selectarray("TICKET_ASSIGN_CONTACT_TO_MESSAGE", $arrval, getDolGlobalString('TICKET_ASSIGN_CONTACT_TO_MESSAGE'));
}
print '</td>';
print '<td class="center">';
print $formcategory->textwithpicto('', $langs->trans("TicketAssignContactToMessageHelp"), 1, 'help');
print '</td>';
print '</tr>';
*/
// Url public interface // Url public interface
$url_interface = getDolGlobalString("TICKET_URL_PUBLIC_INTERFACE"); $url_interface = getDolGlobalString("TICKET_URL_PUBLIC_INTERFACE");
print '<tr><td>'.$langs->trans("UrlPublicInterfaceLabelAdmin").'</label>'; print '<tr class="oddeven"><td>'.$langs->trans("UrlPublicInterfaceLabelAdmin").'</label>';
print '</td><td>'; print '</td><td>';
print '<input type="text" class="minwidth500" name="TICKET_URL_PUBLIC_INTERFACE" value="'.$url_interface.'" placeholder="https://..."></td>'; print '<input type="text" class="minwidth500" name="TICKET_URL_PUBLIC_INTERFACE" value="'.$url_interface.'" placeholder="https://..."></td>';
print '</td>'; print '</td>';
@@ -470,15 +492,17 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
print '</table>'; print '</table>';
print '<br><br>'; print '<br><br>';
print load_fiche_titre($langs->trans("Emails")); print load_fiche_titre($langs->trans("Emails"));
print '<div class="div-table-responsive-no-min">'; print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">'; print '<table class="noborder centpercent">';
// Activate email creation to user // Activate email creation to user
print '<tr class="pair"><td>'; print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help'); print $form->textwithpicto($langs->trans("TicketsDisableCustomerEmail"), $langs->trans("TicketsDisableEmailHelp"), 1, 'help');
print '</td>'; print '</td>';
print '<td class="left">'; print '<td class="left">';
@@ -493,7 +517,7 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
// Text of email after creatio of a ticket // Text of email after creatio of a ticket
$mail_mesg_new = getDolGlobalString("TICKET_MESSAGE_MAIL_NEW", $langs->trans('TicketNewEmailBody')); $mail_mesg_new = getDolGlobalString("TICKET_MESSAGE_MAIL_NEW", $langs->trans('TicketNewEmailBody'));
print '<tr><td>'; print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help'); print $form->textwithpicto($langs->trans("TicketNewEmailBodyLabel"), $langs->trans("TicketNewEmailBodyHelp"), 1, 'help');
print '</label>'; print '</label>';
print '</td><td>'; print '</td><td>';
@@ -504,7 +528,7 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
print '</tr>'; print '</tr>';
// Activate email notification when a new message is added // Activate email notification when a new message is added
print '<tr class="pair"><td>'; print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("TicketsPublicNotificationNewMessage"), $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help'); print $form->textwithpicto($langs->trans("TicketsPublicNotificationNewMessage"), $langs->trans("TicketsPublicNotificationNewMessageHelp"), 1, 'help');
print '</td>'; print '</td>';
print '<td class="left">'; print '<td class="left">';
@@ -518,7 +542,7 @@ if (getDolGlobalInt('TICKET_ENABLE_PUBLIC_INTERFACE')) {
print '</tr>'; print '</tr>';
// Send notification when a new message is added to a email if a user is not assigned to the ticket // Send notification when a new message is added to a email if a user is not assigned to the ticket
print '<tr><td>'; print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help'); print $form->textwithpicto($langs->trans("TicketPublicNotificationNewMessageDefaultEmail"), $langs->trans("TicketPublicNotificationNewMessageDefaultEmailHelp"), 1, 'help');
print '</td><td>'; print '</td><td>';
print '<input type="text" name="TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL" value="'.getDolGlobalString("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL").'" size="40" ></td>'; print '<input type="text" name="TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL" value="'.getDolGlobalString("TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL").'" size="40" ></td>';

View File

@@ -234,6 +234,12 @@ $workflowcodes = array_filter(
} }
); );
if ($action == 'setvarworkflow') { // Test on permission already done
if (GETPOSTISSET('product_category_id')) {
$param_ticket_product_category = GETPOSTINT('product_category_id');
$res = dolibarr_set_const($db, 'TICKET_PRODUCT_CATEGORY', $param_ticket_product_category, 'chaine', 0, '', $conf->entity);
}
}
/* /*
@@ -261,22 +267,30 @@ if (count($workflowcodes) < 1) {
// Sort on position // Sort on position
$workflowcodes = dol_sort_array($workflowcodes, 'position'); $workflowcodes = dol_sort_array($workflowcodes, 'position');
print '<table class="noborder centpercent">'; print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" enctype="multipart/form-data" >';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="setvarworkflow">';
print '<input type="hidden" name="page_y" value="">';
$oldfamily = ''; $oldfamily = '';
$tableopen = 0;
$atleastoneline = 0;
foreach ($workflowcodes as $key => $params) { foreach ($workflowcodes as $key => $params) {
if ($params['family'] == 'separator') { if ($params['family'] == 'separator') {
print '</table>'; if ($atleastoneline) {
print '<br>'; print '</table>';
print '<br>';
print '<table class="noborder centpercent">';
$oldfamily = '';
$atleastoneline = 0;
}
continue; continue;
} }
$reg = array(); $reg = array();
if ($oldfamily != $params['family']) { if ($oldfamily != $params['family']) {
// New group
if ($params['family'] == 'create') { if ($params['family'] == 'create') {
$header = $langs->trans("AutomaticCreation"); $header = $langs->trans("AutomaticCreation");
} elseif (preg_match('/classify_(.*)/', $params['family'], $reg)) { } elseif (preg_match('/classify_(.*)/', $params['family'], $reg)) {
@@ -308,6 +322,9 @@ foreach ($workflowcodes as $key => $params) {
$header = $langs->trans("Description"); $header = $langs->trans("Description");
} }
print '<table class="noborder centpercent">';
$tableopen = 1;
print '<tr class="liste_titre">'; print '<tr class="liste_titre">';
print '<th>'.$header.'</th>'; print '<th>'.$header.'</th>';
print '<th class="right">'.$langs->trans("Status").'</th>'; print '<th class="right">'.$langs->trans("Status").'</th>';
@@ -316,6 +333,8 @@ foreach ($workflowcodes as $key => $params) {
$oldfamily = $params['family']; $oldfamily = $params['family'];
} }
$atleastoneline = 1;
print '<tr class="oddeven">'; print '<tr class="oddeven">';
print '<td>'; print '<td>';
print img_object('', $params['picto'], 'class="pictofixedwidth"'); print img_object('', $params['picto'], 'class="pictofixedwidth"');
@@ -328,6 +347,26 @@ foreach ($workflowcodes as $key => $params) {
print ' '.img_warning($langs->transnoentitiesnoconv("Deprecated")); print ' '.img_warning($langs->transnoentitiesnoconv("Deprecated"));
} }
if ($key == 'WORKFLOW_TICKET_LINK_CONTRACT' && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT')) {
require_once DOL_DOCUMENT_ROOT."/core/class/html.formcategory.class.php";
$formcategory = new FormCategory($db);
$htmlname = "product_category_id";
print '<br>';
print $formcategory->textwithpicto($langs->trans("TicketChooseProductCategory"), $langs->trans("TicketChooseProductCategoryHelp"), 1, 'help');
if (isModEnabled('category')) {
print ' &nbsp; '.img_picto('', 'category', 'class="pictofixedwidth"');
$formcategory->selectProductCategory(getDolGlobalInt('TICKET_PRODUCT_CATEGORY'), $htmlname, 1);
if ($conf->use_javascript_ajax) {
print ajax_combobox('select_'.$htmlname);
}
print '<input class="button smallpaddingimp" type="submit" value="'.$langs->trans("Save").'">';
} else {
print 'Module category must be enabled';
}
}
print '</td>'; print '</td>';
print '<td class="right">'; print '<td class="right">';
@@ -354,7 +393,12 @@ foreach ($workflowcodes as $key => $params) {
print '</tr>'; print '</tr>';
} }
print '</table>'; if ($tableopen) {
print '</table>';
}
print '</form>';
// End of page // End of page
llxFooter(); llxFooter();

View File

@@ -23,6 +23,7 @@
*/ */
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
/** /**
@@ -101,6 +102,8 @@ class FormCategory extends Form
/** /**
* Prints a select form for products categories * Prints a select form for products categories
* TODO Remove this. We should already have a generic method to get list of product category.
*
* @param int $selected Id category pre-selection * @param int $selected Id category pre-selection
* @param string $htmlname Name of HTML field * @param string $htmlname Name of HTML field
* @param int $showempty Add an empty field * @param int $showempty Add an empty field
@@ -108,15 +111,14 @@ class FormCategory extends Form
*/ */
public function selectProductCategory($selected = 0, $htmlname = 'product_category_id', $showempty = 0) public function selectProductCategory($selected = 0, $htmlname = 'product_category_id', $showempty = 0)
{ {
$sql = "SELECT cp.fk_categorie as cat_index, cat.label"; $sql = "SELECT cat.rowid, cat.label";
$sql .= " FROM ".MAIN_DB_PREFIX."categorie_product as cp"; $sql .= " FROM ".MAIN_DB_PREFIX."categorie as cat";
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."categorie as cat ON cat.rowid = cp.fk_categorie"; $sql .= " WHERE cat.type = 0";
$sql .= " GROUP BY cp.fk_categorie, cat.label";
dol_syslog(get_class($this)."::selectProductCategory", LOG_DEBUG); dol_syslog(get_class($this)."::selectProductCategory", LOG_DEBUG);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
if ($resql) { if ($resql) {
print '<select class="flat" id="select_'.$htmlname.'" name="'.$htmlname.'">'; print '<select class="flat minwidth100" id="select_'.$htmlname.'" name="'.$htmlname.'">';
if ($showempty) { if ($showempty) {
print '<option value="0">&nbsp;</option>'; print '<option value="0">&nbsp;</option>';
} }
@@ -125,10 +127,10 @@ class FormCategory extends Form
$num_rows = $this->db->num_rows($resql); $num_rows = $this->db->num_rows($resql);
while ($i < $num_rows) { while ($i < $num_rows) {
$category = $this->db->fetch_object($resql); $category = $this->db->fetch_object($resql);
if ($selected && $selected == $category->cat_index) { if ($selected && $selected == $category->rowid) {
print '<option value="'.$category->cat_index.'" selected>'.$category->label.'</option>'; print '<option value="'.$category->rowid.'" selected>'.$category->label.'</option>';
} else { } else {
print '<option value="'.$category->cat_index.'">'.$category->label.'</option>'; print '<option value="'.$category->rowid.'">'.$category->label.'</option>';
} }
$i++; $i++;
} }

View File

@@ -524,13 +524,13 @@ class FormOther
if (!empty($user->socid)) { if (!empty($user->socid)) {
$sql_usr .= " AND u.fk_soc = ".((int) $user->socid); $sql_usr .= " AND u.fk_soc = ".((int) $user->socid);
} }
if (getDolGlobalString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX')) { if (getDolUserString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX', getDolGlobalString('USER_HIDE_NONEMPLOYEE_IN_COMBOBOX'))) {
$sql_usr .= " AND u.employee <> 0"; $sql_usr .= " AND u.employee <> 0";
} }
if (getDolGlobalString('USER_HIDE_EXTERNAL_IN_COMBOBOX')) { if (getDolUserString('USER_HIDE_EXTERNAL_IN_COMBOBOX', getDolGlobalString('USER_HIDE_EXTERNAL_IN_COMBOBOX'))) {
$sql_usr .= " AND u.fk_soc IS NULL"; $sql_usr .= " AND u.fk_soc IS NULL";
} }
if (getDolGlobalString('USER_HIDE_INACTIVE_IN_COMBOBOX')) { if (getDolUserString('USER_HIDE_INACTIVE_IN_COMBOBOX', getDolGlobalString('USER_HIDE_INACTIVE_IN_COMBOBOX'))) { // Can be set in setup of module User.
$sql_usr .= " AND u.statut <> 0"; $sql_usr .= " AND u.statut <> 0";
} }

View File

@@ -263,7 +263,7 @@ function getDolUserString($key, $default = '', $tmpuser = null)
$tmpuser = $user; $tmpuser = $user;
} }
return (string) (empty($tmpuser->conf->$key) ? $default : $tmpuser->conf->$key); return (string) (isset($tmpuser->conf->$key) ? $tmpuser->conf->$key : $default);
} }
/** /**
@@ -281,7 +281,7 @@ function getDolUserInt($key, $default = 0, $tmpuser = null)
$tmpuser = $user; $tmpuser = $user;
} }
return (int) (empty($tmpuser->conf->$key) ? $default : $tmpuser->conf->$key); return (int) (isset($tmpuser->conf->$key) ? $tmpuser->conf->$key: $default);
} }
@@ -8413,7 +8413,7 @@ function dol_htmlwithnojs($stringtoencode, $nouseofiframesandbox = 0, $check = '
// Keep only some html tags and remove also some 'javascript:' strings // Keep only some html tags and remove also some 'javascript:' strings
if ($check == 'restricthtmlallowlinkscript') { if ($check == 'restricthtmlallowlinkscript') {
$out = dol_string_onlythesehtmltags($out, 0, 1, 0, 0, array(), 1, 1); $out = dol_string_onlythesehtmltags($out, 0, 1, 0, 0, array(), 1, 1);
} elseif ($check == 'restricthtmlallowclass') { } elseif ($check == 'restricthtmlallowclass' || $check == 'restricthtmlallowunvalid') {
$out = dol_string_onlythesehtmltags($out, 0, 0, 1); $out = dol_string_onlythesehtmltags($out, 0, 0, 1);
} else { } else {
$out = dol_string_onlythesehtmltags($out, 0, 1, 1); $out = dol_string_onlythesehtmltags($out, 0, 1, 1);

View File

@@ -107,13 +107,13 @@ class modSociete extends DolibarrModules
$r++; $r++;
/* /*
$this->const[$r][0] = "COMPANY_HIDE_INACTIVE_IN_COMBOBOX"; $this->const[$r][0] = "COMPANY_HIDE_INACTIVE_IN_COMBOBOX";
$this->const[$r][1] = "chaine"; $this->const[$r][1] = "chaine";
$this->const[$r][2] = "0"; $this->const[$r][2] = "0";
$this->const[$r][3] = "hide thirdparty customer inative in combobox"; $this->const[$r][3] = "hide thirdparty customer inative in combobox";
$this->const[$r][4] = 1; $this->const[$r][4] = 1;
$r++; $r++;
*/ */
$this->const[$r][0] = "SOCIETE_ADD_REF_IN_LIST"; $this->const[$r][0] = "SOCIETE_ADD_REF_IN_LIST";
$this->const[$r][1] = "yesno"; $this->const[$r][1] = "yesno";
@@ -144,21 +144,21 @@ class modSociete extends DolibarrModules
$this->rights[$r][4] = 'lire'; $this->rights[$r][4] = 'lire';
/*$r++; /*$r++;
$this->rights[$r][0] = 241; $this->rights[$r][0] = 241;
$this->rights[$r][1] = 'Read thirdparties customers'; $this->rights[$r][1] = 'Read thirdparties customers';
$this->rights[$r][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0; $this->rights[$r][3] = 0;
$this->rights[$r][4] = 'thirdparty_customer_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][4] = 'thirdparty_customer_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on
$this->rights[$r][5] = 'read'; $this->rights[$r][5] = 'read';
$r++; $r++;
$this->rights[$r][0] = 242; $this->rights[$r][0] = 242;
$this->rights[$r][1] = 'Read thirdparties suppliers'; $this->rights[$r][1] = 'Read thirdparties suppliers';
$this->rights[$r][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0; $this->rights[$r][3] = 0;
$this->rights[$r][4] = 'thirdparty_supplier_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][4] = 'thirdparty_supplier_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on
$this->rights[$r][5] = 'read'; $this->rights[$r][5] = 'read';
*/ */
$r++; $r++;
$this->rights[$r][0] = 122; // id de la permission $this->rights[$r][0] = 122; // id de la permission
@@ -168,21 +168,21 @@ class modSociete extends DolibarrModules
$this->rights[$r][4] = 'creer'; $this->rights[$r][4] = 'creer';
/* $r++; /* $r++;
$this->rights[$r][0] = 251; $this->rights[$r][0] = 251;
$this->rights[$r][1] = 'Create thirdparties customers'; $this->rights[$r][1] = 'Create thirdparties customers';
$this->rights[$r][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0; $this->rights[$r][3] = 0;
$this->rights[$r][4] = 'thirdparty_customer_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][4] = 'thirdparty_customer_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on
$this->rights[$r][5] = 'read'; $this->rights[$r][5] = 'read';
$r++; $r++;
$this->rights[$r][0] = 252; $this->rights[$r][0] = 252;
$this->rights[$r][1] = 'Create thirdparties suppliers'; $this->rights[$r][1] = 'Create thirdparties suppliers';
$this->rights[$r][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0; $this->rights[$r][3] = 0;
$this->rights[$r][4] = 'thirdparty_supplier_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][4] = 'thirdparty_supplier_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on
$this->rights[$r][5] = 'read'; $this->rights[$r][5] = 'read';
*/ */
$r++; $r++;
$this->rights[$r][0] = 125; // id de la permission $this->rights[$r][0] = 125; // id de la permission
@@ -215,14 +215,14 @@ class modSociete extends DolibarrModules
$this->rights[$r][5] = 'voir'; $this->rights[$r][5] = 'voir';
/* /*
$r++; $r++;
$this->rights[$r][0] = 263; $this->rights[$r][0] = 263;
$this->rights[$r][1] = 'Read all third parties (without their objects) by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).'; $this->rights[$r][1] = 'Read all third parties (without their objects) by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).';
$this->rights[$r][2] = 'r'; $this->rights[$r][2] = 'r';
$this->rights[$r][3] = 0; $this->rights[$r][3] = 0;
$this->rights[$r][4] = 'client'; $this->rights[$r][4] = 'client';
$this->rights[$r][5] = 'readallthirdparties_advance'; $this->rights[$r][5] = 'readallthirdparties_advance';
*/ */
$r++; $r++;
$this->rights[$r][0] = 281; // id de la permission $this->rights[$r][0] = 281; // id de la permission
@@ -411,6 +411,7 @@ class modSociete extends DolibarrModules
's.code_compta' => "company", 's.code_compta_fournisseur' => "company", 's.code_compta' => "company", 's.code_compta_fournisseur' => "company",
's.client' => "company", 's.fournisseur' => "company", 's.client' => "company", 's.fournisseur' => "company",
's.address' => "company", 's.zip' => "company", 's.town' => "company", 's.phone' => "company", 's.email' => "company", 's.address' => "company", 's.zip' => "company", 's.town' => "company", 's.phone' => "company", 's.email' => "company",
's.note_private' => 'company', 's.note_public' => "company",
't.code' => "company", 't.code' => "company",
's.entity' => 'company', 's.entity' => 'company',
); // We define here only fields that use another picto ); // We define here only fields that use another picto
@@ -685,24 +686,24 @@ class modSociete extends DolibarrModules
'table_element' => 'c_stcomm' 'table_element' => 'c_stcomm'
), ),
/* /*
's.fk_prospectlevel' => array( 's.fk_prospectlevel' => array(
'rule' => 'fetchidfromcodeid', 'rule' => 'fetchidfromcodeid',
'classfile' => '/core/class/cgenericdic.class.php', 'classfile' => '/core/class/cgenericdic.class.php',
'class' => 'CGenericDic', 'class' => 'CGenericDic',
'method' => 'fetch', 'method' => 'fetch',
'dict' => 'DictionaryProspectLevel', 'dict' => 'DictionaryProspectLevel',
'element' => 'c_prospectlevel', 'element' => 'c_prospectlevel',
'table_element' => 'c_prospectlevel' 'table_element' => 'c_prospectlevel'
),*/ ),*/
// TODO // TODO
// 's.fk_incoterms' => array( // 's.fk_incoterms' => array(
// 'rule' => 'fetchidfromcodeid', // 'rule' => 'fetchidfromcodeid',
// 'classfile' => '/core/class/cincoterm.class.php', // 'classfile' => '/core/class/cincoterm.class.php',
// 'class' => 'Cincoterm', // 'class' => 'Cincoterm',
// 'method' => 'fetch', // 'method' => 'fetch',
// 'dict' => 'IncotermLabel' // 'dict' => 'IncotermLabel'
// ) // )
); );
//$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t'); //$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
$this->import_regex_array[$r] = array(//field order as per structure of table llx_societe $this->import_regex_array[$r] = array(//field order as per structure of table llx_societe
's.status' => '^[0|1]', 's.status' => '^[0|1]',
@@ -981,7 +982,7 @@ class modSociete extends DolibarrModules
'sr.datec' => 'date used for creating direct debit UMR formatted as '.dol_print_date( 'sr.datec' => 'date used for creating direct debit UMR formatted as '.dol_print_date(
dol_now(), dol_now(),
'%Y-%m-%d' '%Y-%m-%d'
), ),
'sr.bank' => 'bank name eg: "ING-Direct"', 'sr.bank' => 'bank name eg: "ING-Direct"',
'sr.code_banque' => 'account sort code (GB)/Routing number (US) eg. "8456"', 'sr.code_banque' => 'account sort code (GB)/Routing number (US) eg. "8456"',
'sr.code_guichet' => "bank code for office/branch", 'sr.code_guichet' => "bank code for office/branch",
@@ -1008,8 +1009,8 @@ class modSociete extends DolibarrModules
$this->import_fields_array[$r] = array('sr.fk_soc' => "ThirdPartyName*", 'sr.fk_user' => "User*"); $this->import_fields_array[$r] = array('sr.fk_soc' => "ThirdPartyName*", 'sr.fk_user' => "User*");
$this->import_convertvalue_array[$r] = array( $this->import_convertvalue_array[$r] = array(
'sr.fk_soc' => array('rule' => 'fetchidfromref', 'classfile' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'), 'sr.fk_soc' => array('rule' => 'fetchidfromref', 'classfile' => '/societe/class/societe.class.php', 'class' => 'Societe', 'method' => 'fetch', 'element' => 'ThirdParty'),
'sr.fk_user' => array('rule' => 'fetchidfromref', 'classfile' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'User') 'sr.fk_user' => array('rule' => 'fetchidfromref', 'classfile' => '/user/class/user.class.php', 'class' => 'User', 'method' => 'fetch', 'element' => 'User')
); );
$this->import_examplevalues_array[$r] = array('sr.fk_soc' => "MyBigCompany", 'sr.fk_user' => "login"); $this->import_examplevalues_array[$r] = array('sr.fk_soc' => "MyBigCompany", 'sr.fk_user' => "login");
} }

View File

@@ -115,7 +115,7 @@ class modTicket extends DolibarrModules
5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0), 5 => array('TICKET_DELAY_BEFORE_FIRST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time before a first answer to a ticket (in hours). Display a warning in tickets list if not respected.', 0),
6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0), 6 => array('TICKET_DELAY_SINCE_LAST_RESPONSE', 'chaine', '0', 'Maximum wanted elapsed time between two answers on the same ticket (in hours). Display a warning in tickets list if not respected.', 0),
7 => array('TICKET_NOTIFY_AT_CLOSING', 'chaine', '0', 'Default notify contacts when closing a module', 0), 7 => array('TICKET_NOTIFY_AT_CLOSING', 'chaine', '0', 'Default notify contacts when closing a module', 0),
8 => array('TICKET_PRODUCT_CATEGORY', 'chaine', 0, 'The category of product that is being used for ticket accounting', 0), 8 => array('TICKET_PRODUCT_CATEGORY', 'chaine', 0, 'The category of product that is being used to find contract to link to created ticket', 0),
9 => array('TICKET_NOTIFICATION_EMAIL_FROM', 'chaine', getDolGlobalString('MAIN_MAIL_EMAIL_FROM'), 'Email to use by default as sender for messages sent from Dolibarr', 0), 9 => array('TICKET_NOTIFICATION_EMAIL_FROM', 'chaine', getDolGlobalString('MAIN_MAIL_EMAIL_FROM'), 'Email to use by default as sender for messages sent from Dolibarr', 0),
10 => array('TICKET_MESSAGE_MAIL_INTRO', 'chaine', $langs->trans('TicketMessageMailIntroText'), 'Introduction text of ticket replies sent from Dolibarr', 0), 10 => array('TICKET_MESSAGE_MAIL_INTRO', 'chaine', $langs->trans('TicketMessageMailIntroText'), 'Introduction text of ticket replies sent from Dolibarr', 0),
11 => array('TICKET_MESSAGE_MAIL_SIGNATURE', 'chaine', $default_footer, 'Signature to use by default for messages sent from Dolibarr', 0), 11 => array('TICKET_MESSAGE_MAIL_SIGNATURE', 'chaine', $default_footer, 'Signature to use by default for messages sent from Dolibarr', 0),

View File

@@ -2146,7 +2146,7 @@ COMPANY_DIGITARIA_CLEAN_REGEX=Regex filter to clean value (COMPANY_DIGITARIA_CLE
DuplicateForbidden=Duplicate forbidden DuplicateForbidden=Duplicate forbidden
RemoveSpecialWords=Clean certain words when generating sub-accounts for customers or suppliers RemoveSpecialWords=Clean certain words when generating sub-accounts for customers or suppliers
RemoveSpecialWordsHelp=Specify the words to be cleaned before calculating the customer or supplier account. Use a ";" between each word RemoveSpecialWordsHelp=Specify the words to be cleaned before calculating the customer or supplier account. Use a ";" between each word
GDPRContact=Data Protection Officer (DPO, Data Privacy or GDPR contact) GDPRContact=Data Protection Officer (DPO, Data Privacy or GDPR contact, ...)
GDPRContactDesc=If you store personal data in your Information System, you can name the contact who is responsible for the General Data Protection Regulation here GDPRContactDesc=If you store personal data in your Information System, you can name the contact who is responsible for the General Data Protection Regulation here
HelpOnTooltip=Help text to show on tooltip HelpOnTooltip=Help text to show on tooltip
HelpOnTooltipDesc=Put text or a translation key here for the text to show in a tooltip when this field appears in a form HelpOnTooltipDesc=Put text or a translation key here for the text to show in a tooltip when this field appears in a form

View File

@@ -134,7 +134,7 @@ TicketsAutoNotifyClose=Automatically notify the third party when closing a ticke
TicketsAutoNotifyCloseHelp=When closing a ticket, you will be proposed to send a message to one of third-party contacts. On mass closing, a message will be sent to one contact of the third party linked to the ticket. TicketsAutoNotifyCloseHelp=When closing a ticket, you will be proposed to send a message to one of third-party contacts. On mass closing, a message will be sent to one contact of the third party linked to the ticket.
TicketWrongContact=Provided contact is not part of current ticket contacts. Email not sent. TicketWrongContact=Provided contact is not part of current ticket contacts. Email not sent.
TicketChooseProductCategory=Product category for ticket support TicketChooseProductCategory=Product category for ticket support
TicketChooseProductCategoryHelp=Select the product category of ticket support. This will be used to automatically link a contract to a ticket. TicketChooseProductCategoryHelp=Select the product category for support. The category will be used to find all contracts that include a product in this category. All contracts found will be linked to the created ticket.
TicketUseCaptchaCode=Use graphical code (CAPTCHA) when creating a ticket TicketUseCaptchaCode=Use graphical code (CAPTCHA) when creating a ticket
TicketUseCaptchaCodeHelp=Adds CAPTCHA verification when creating a new ticket. TicketUseCaptchaCodeHelp=Adds CAPTCHA verification when creating a new ticket.
TicketsAllowClassificationModificationIfClosed=Allow to modify classification of closed tickets TicketsAllowClassificationModificationIfClosed=Allow to modify classification of closed tickets

View File

@@ -215,6 +215,9 @@ if (empty($reshook) && $action == 'add') { // Test on permission not required he
if (!$error) { if (!$error) {
$societe = new Societe($db); $societe = new Societe($db);
// TODO Support MAIN_SECURITY_MAX_POST_ON_PUBLIC_PAGES_BY_IP_ADDRESS
$societe->name = GETPOST('name', 'alphanohtml'); $societe->name = GETPOST('name', 'alphanohtml');
$societe->client = GETPOSTINT('client') ? GETPOSTINT('client') : $societe->client; $societe->client = GETPOSTINT('client') ? GETPOSTINT('client') : $societe->client;

View File

@@ -1859,7 +1859,10 @@ class Ticket extends CommonObject
$actioncomm->fk_element = $this->id; $actioncomm->fk_element = $this->id;
$actioncomm->fk_project = $this->fk_project; $actioncomm->fk_project = $this->fk_project;
// add contact id from author email on public interface // Add first contact id found in database from submitter email entered into public interface
// Feature disabled: This has a security trouble. The public interface is a no login interface, so being able to show the contact info from an
// email decided by the submiter allows anybody to get information on any contact (customer or supplier) in Dolibarr database.
// He can even check if contact exists by trying any email if this feature is enabled.
if ($public_area && !empty($this->origin_email) && getDolGlobalString('TICKET_ASSIGN_CONTACT_TO_MESSAGE')) { if ($public_area && !empty($this->origin_email) && getDolGlobalString('TICKET_ASSIGN_CONTACT_TO_MESSAGE')) {
$contacts = $this->searchContactByEmail($this->origin_email); $contacts = $this->searchContactByEmail($this->origin_email);
if (!empty($contacts)) { if (!empty($contacts)) {

View File

@@ -342,7 +342,7 @@ if (empty($sortfield)) {
} }
} }
$searchkey = GETPOST('searchstring', 'restricthtmlallowclass'); $searchkey = GETPOST('searchstring', 'restricthtmlallowunvalid'); // or 'none', must be same then $searchstring
if ($action == 'replacesite' || $mode == 'replacesite') { // Test on permission not required if ($action == 'replacesite' || $mode == 'replacesite') { // Test on permission not required
$containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : ''; $containertype = GETPOST('optioncontainertype', 'aZ09') != '-1' ? GETPOST('optioncontainertype', 'aZ09') : '';
@@ -583,7 +583,7 @@ if ($massaction == 'delcategory' && GETPOST('confirmmassaction', 'alpha') && $us
// Replacement of string into pages // Replacement of string into pages
if ($massaction == 'replace' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) { if ($massaction == 'replace' && GETPOST('confirmmassaction', 'alpha') && $usercanedit) {
$replacestring = GETPOST('replacestring', 'none'); $replacestring = GETPOST('replacestring', 'restricthtmlallowunvalid'); // or 'none', must be same then $searchstring
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT); $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
$allowimportsite = true; $allowimportsite = true;