CVE-2023-4198: Missing Authorization (CWE-862)
value: Improper Access Control in Dolibarr ERP CRM <= v17.0.3 allows an unauthorized authenticated user to read a database table containing customer data
CWE description: The product does not perform an authorization check when an actor attempts to access a resource or perform an action.
CVSS v3 base score: 6.5
Published: 2023-11-01T09:15Z
Repository: https://github.com/Dolibarr/dolibarr
Language: PHP
Files changed: htdocs/categories/viewcat.php, htdocs/comm/propal/card.php, htdocs/comm/propal/stats/index.php, htdocs/commande/card.php, htdocs/commande/stats/index.php, htdocs/compta/deplacement/stats/index.php, htdocs/compta/facture/card.php, htdocs/compta/facture/stats/index.php, htdocs/compta/stats/cabyprodserv.php, htdocs/compta/stats/supplier_turnover_by_prodserv.php, htdocs/contact/card.php, htdocs/contrat/card.php, htdocs/core/class/html.form.class.php, htdocs/core/lib/functions.lib.php, htdocs/don/card.php, htdocs/fourn/commande/card.php, htdocs/fourn/facture/card.php, htdocs/margin/customerMargins.php, htdocs/product/fournisseurs.php, htdocs/product/price.php, htdocs/product/stock/replenish.php, htdocs/projet/card.php, htdocs/societe/ajax/ajaxcompanies.php, htdocs/societe/ajax/company.php, htdocs/societe/card.php, htdocs/supplier_proposal/card.php, htdocs/takepos/admin/terminal.php
Commit date: 2023-04-27 21:15:27 +0200
Commit message: Clean code
Diff: diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php
index 5999865232a38..84770acdaff07 100644
--- a/htdocs/categories/viewcat.php
+++ b/htdocs/categories/viewcat.php
@@ -588,11 +588,12 @@ if ($type == Categorie::TYPE_CUSTOMER) {
 				print '<input type="hidden" name="id" value="'.$object->id.'">';
 				print '<input type="hidden" name="action" value="addintocategory">';
 				print '<table class="noborder centpercent">';
 				print '<tr class="liste_titre"><td>';
 				print $langs->trans("AddCustomerIntoCategory").' &nbsp;';
-				print $form->select_company('', 'elemid', 's.client IN (1,3)');
+				$filter = 's.client IN (1,3)';
+				print $form->select_company('', 'elemid', $filter);
 				print '<input type="submit" class="button buttongen" value="'.$langs->trans("ClassifyInCategory").'"></td>';
 				print '</tr>';
 				print '</table>';
 				print '</form>';
 			}
@@ -668,11 +669,12 @@ if ($type == Categorie::TYPE_SUPPLIER) {
 				print '<input type="hidden" name="id" value="'.$object->id.'">';
 				print '<input type="hidden" name="action" value="addintocategory">';
 				print '<table class="noborder centpercent">';
 				print '<tr class="liste_titre"><td>';
 				print $langs->trans("AddSupplierIntoCategory").' &nbsp;';
-				print $form->select_company('', 'elemid', 's.fournisseur = 1');
+				$filter ='s.fournisseur = 1';
+				print $form->select_company('', 'elemid', $filter);
 				print '<input type="submit" class="button buttongen" value="'.$langs->trans("ClassifyInCategory").'"></td>';
 				print '</tr>';
 				print '</table>';
 				print '</form>';
 			}
diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php
index 3a3fdfe50a0f9..d28753632d2e0 100644
--- a/htdocs/comm/propal/card.php
+++ b/htdocs/comm/propal/card.php
@@ -1808,11 +1808,12 @@ if ($action == 'create') {
 			$shipping_method_id = $soc->shipping_method_id;
 		}
 		//$warehouse_id       = $soc->warehouse_id;
 	} else {
 		print '<td class="valuefieldcreate">';
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx');
+		$filter = '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx');
 		// reload page to retrieve customer informations
 		if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
 			print '<script>
 			$(document).ready(function() {
 				$("#socid").change(function() {
@@ -2131,14 +2132,15 @@ if ($action == 'create') {
 	$formconfirm = '';
 
 	// Clone confirmation
 	if ($action == 'clone') {
 		// Create an array for form
+		$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
 		$formquestion = array(
 			// 'text' => $langs->trans("ConfirmClone"),
 			// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
-			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300')),
+			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter, '', 0, 0, null, 0, 'maxwidth300')),
 			array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans('PuttingPricesUpToDate'), 'value' => 0),
 			array('type' => 'checkbox', 'name' => 'update_desc', 'label' => $langs->trans('PuttingDescUpToDate'), 'value' => 0),
 		);
 		if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY) && !empty($object->delivery_date)) {
 			$formquestion[] = array('type' => 'date', 'name' => 'date_delivery', 'label' => $langs->trans("DeliveryDate"), 'value' => $object->delivery_date);
diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php
index 9473ca3bcb5e0..d8279fdc64681 100644
--- a/htdocs/comm/propal/stats/index.php
+++ b/htdocs/comm/propal/stats/index.php
@@ -261,12 +261,12 @@ print '<input type="hidden" name="mode" value="'.$mode.'">';
 
 print '<table class="noborder centpercent">';
 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
 // Company
 print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
-$filter = 's.client IN (1,2,3)';
 print img_picto('', 'company', 'class="pictofixedwidth"');
+$filter = 's.client IN (1,2,3)';
 print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
 print '</td></tr>';
 // ThirdParty Type
 print '<tr><td>'.$langs->trans("ThirdPartyType").'</td><td>';
 $sortparam_typent = (empty($conf->global->SOCIETE_SORT_ON_TYPEENT) ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label.
diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php
index 4b491344c2f4e..d79cc54b90779 100644
--- a/htdocs/commande/card.php
+++ b/htdocs/commande/card.php
@@ -1786,11 +1786,12 @@ if ($action == 'create' && $usercancreate) {
 		print $soc->getNomUrl(1, 'customer');
 		print '<input type="hidden" name="socid" value="'.$soc->id.'">';
 		print '</td>';
 	} else {
 		print '<td>';
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
+		$filter = '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
 		// reload page to retrieve customer informations
 		if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
 			print '<script>
 			$(document).ready(function() {
 				$("#socid").change(function() {
@@ -2335,13 +2336,14 @@ if ($action == 'create' && $usercancreate) {
 			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 0, 1);
 		}
 
 		// Clone confirmation
 		if ($action == 'clone') {
+			$filter = '(s.client=1 OR s.client = 2 OR s.client=3)';
 			// Create an array for form
 			$formquestion = array(
-				array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client = 2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300'))
+				array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter, '', 0, 0, null, 0, 'maxwidth300'))
 			);
 			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
 		}
 
 		// Call Hook formConfirm
diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php
index 20fccd3f0000c..c4c0e5dbf41c8 100644
--- a/htdocs/commande/stats/index.php
+++ b/htdocs/commande/stats/index.php
@@ -293,10 +293,11 @@ print '<input type="hidden" name="mode" value="'.$mode.'">';
 
 print '<table class="noborder centpercent">';
 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
 // Company
 print '<tr><td class="left">'.$langs->trans("ThirdParty").'</td><td class="left">';
+$filter = '';
 if ($mode == 'customer') {
 	$filter = 's.client IN (1,2,3)';
 }
 if ($mode == 'supplier') {
 	$filter = 's.fournisseur = 1';
diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php
index 4cb75c526ef3e..38e00a2c68b93 100644
--- a/htdocs/compta/deplacement/stats/index.php
+++ b/htdocs/compta/deplacement/stats/index.php
@@ -240,13 +240,12 @@ print '<input type="hidden" name="mode" value="'.$mode.'">';
 
 print '<table class="border centpercent">';
 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
 // Company
 print '<tr><td>'.$langs->trans("ThirdParty").'</td><td>';
-$filter = '';
 print img_picto('', 'company', 'class="pictofixedwidth"');
-print $form->select_company($socid, 'socid', $filter, 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
+print $form->select_company($socid, 'socid', '', 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
 print '</td></tr>';
 // User
 print '<tr><td>'.$langs->trans("User").'</td><td>';
 $include = '';
 if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) {
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 901207a8d5834..fdf7549881167 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -3203,11 +3203,12 @@ if ($action == 'create') {
 		print '</td>';
 		print '</tr>'."\n";
 	} else {
 		print '<tr><td class="fieldrequired">'.$langs->trans('Customer').'</td>';
 		print '<td colspan="2">';
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
+		$filter = '((s.client = 1 OR s.client = 3) AND s.status = 1)';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
 		// Option to reload page to retrieve customer informations.
 		if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
 			print '<script>
 			$(document).ready(function() {
 				$("#socid").change(function() {
@@ -4317,13 +4318,14 @@ if ($action == 'create') {
 		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteProductLine'), $langs->trans('ConfirmDeleteProductLine'), 'confirm_deleteline', '', 'no', 1);
 	}
 
 	// Clone confirmation
 	if ($action == 'clone') {
+		$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
 		// Create an array for form
 		$formquestion = array(
-			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company($object->socid, 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', 1)),
+			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company($object->socid, 'socid', $filter, 1)),
 			array('type' => 'date', 'name' => 'newdate', 'label' => $langs->trans("Date"), 'value' => dol_now())
 		);
 		// Request confirmation to clone
 		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneInvoice', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 250);
 	}
diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php
index 5c23057b10b14..f8d0f1a9f4122 100644
--- a/htdocs/compta/facture/stats/index.php
+++ b/htdocs/compta/facture/stats/index.php
@@ -263,19 +263,10 @@ if ($mode == 'supplier') {
 
 complete_head_from_modules($conf, $langs, null, $head, $h, $type);
 
 print dol_get_fiche_head($head, 'byyear', $langs->trans("Statistics"), -1);
 
-// We use select_thirdparty_list instead of select_company so we can use $filter and share same code for customer and supplier.
-$filter = '';
-if ($mode == 'customer') {
-	$filter = 's.client in (1,2,3)';
-}
-if ($mode == 'supplier') {
-	$filter = 's.fournisseur = 1';
-}
-
 print '<div class="fichecenter"><div class="fichethirdleft">';
 
 
 // Show filter box
 print '<form name="stats" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
@@ -284,10 +275,17 @@ print '<input type="hidden" name="mode" value="'.$mode.'">';
 
 print '<table class="noborder centpercent">';
 print '<tr class="liste_titre"><td class="liste_titre" colspan="2">'.$langs->trans("Filter").'</td></tr>';
 // Company
 print '<tr><td>'.$langs->trans("ThirdParty").'</td><td>';
+$filter = '';
+if ($mode == 'customer') {
+	$filter = 's.client in (1,2,3)';
+}
+if ($mode == 'supplier') {
+	$filter = 's.fournisseur = 1';
+}
 print img_picto('', 'company', 'class="pictofixedwidth"');
 print $form->select_company($socid, 'socid', $filter, 1, 0, 0, array(), 0, 'widthcentpercentminusx maxwidth300');
 print '</td></tr>';
 
 // ThirdParty Type
diff --git a/htdocs/compta/stats/cabyprodserv.php b/htdocs/compta/stats/cabyprodserv.php
index e747c4380a4eb..27b5a5b2723b4 100644
--- a/htdocs/compta/stats/cabyprodserv.php
+++ b/htdocs/compta/stats/cabyprodserv.php
@@ -416,16 +416,13 @@ if ($modecompta == 'CREANCES-DETTES') {
 	print $form->select_thirdparty_list($selected_soc, 'search_soc', '', $langs->trans("ThirdParty"));
 	print '</td>';
 
 	print '<td colspan="5" class="right">';
 	print '<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"), 'search.png', '', '', 1).'"  value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
+	print '</td>';
 
-	$parameters = array();
-	$reshook = $hookmanager->executeHooks('printFieldListeTitle', $parameters);
-	print $hookmanager->resPrint;
-
-	print '</td></tr>';
+	print '</tr>';
 
 	// Array header
 	print "<tr class=\"liste_titre\">";
 	print_liste_field_titre(
 		$langs->trans("Product"),
diff --git a/htdocs/compta/stats/supplier_turnover_by_prodserv.php b/htdocs/compta/stats/supplier_turnover_by_prodserv.php
index d641a513e54b8..d04ad4c42598c 100644
--- a/htdocs/compta/stats/supplier_turnover_by_prodserv.php
+++ b/htdocs/compta/stats/supplier_turnover_by_prodserv.php
@@ -375,11 +375,11 @@ if ($modecompta == 'CREANCES-DETTES') {
 	print '<td colspan="5" class="right">';
 	print '<input type="image" class="liste_titre" name="button_search" src="'.img_picto($langs->trans("Search"), 'search.png', '', '', 1).'"  value="'.dol_escape_htmltag($langs->trans("Search")).'" title="'.dol_escape_htmltag($langs->trans("Search")).'">';
 	print '</td></tr>';
 
 	// Array header
-	print "<tr class=\"liste_titre\">";
+	print '<tr class="liste_titre">';
 	print_liste_field_titre(
 		$langs->trans("Product"),
 		$_SERVER["PHP_SELF"],
 		"ref",
 		"",
diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php
index cbdce0c5d040b..739c4145db8e6 100644
--- a/htdocs/contact/card.php
+++ b/htdocs/contact/card.php
@@ -994,11 +994,11 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 
 			// Company
 			if (empty($conf->global->SOCIETE_DISABLE_CONTACTS)) {
 				print '<tr><td><label for="socid">'.$langs->trans("ThirdParty").'</label></td>';
 				print '<td colspan="3" class="maxwidthonsmartphone">';
-				print img_picto('', 'company').$form->select_company(GETPOST('socid', 'int') ?GETPOST('socid', 'int') : ($object->socid ? $object->socid : -1), 'socid', '', $langs->trans("SelectThirdParty"));
+				print img_picto('', 'company').$form->select_company(GETPOST('socid', 'int') ? GETPOST('socid', 'int') : ($object->socid ? $object->socid : -1), 'socid', '', $langs->trans("SelectThirdParty"));
 				print '</td>';
 				print '</tr>';
 			}
 
 			// Civility
diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php
index e5ab9664e0996..0430f937d1d35 100644
--- a/htdocs/contrat/card.php
+++ b/htdocs/contrat/card.php
@@ -1330,12 +1330,13 @@ if ($action == 'create') {
 				array('type' => 'date', 'name' => 'd_end', 'label' => $langs->trans("DateEndPlanned"), /*'value' => $form->selectDate('', "end", $usehm, $usehm, '', "active", 1, 0),*/ '', ''),
 				array('type' => 'text', 'name' => 'comment', 'label' => $langs->trans("Comment"), 'value' => '', '', '', 'class' => 'minwidth300', 'moreattr'=>'autofocus')
 			);
 			$formconfirm = $form->formconfirm($_SERVER['PHP_SELF']."?id=".$object->id, $langs->trans("ActivateAllOnContract"), $langs->trans("ConfirmActivateAllOnContract"), "confirm_activate", $formquestion, 'yes', 1, 280);
 		} elseif ($action == 'clone') {
+			$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
 			// Clone confirmation
-			$formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
+			$formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter)));
 			$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneContract', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
 		}
 
 
 		// Call Hook formConfirm
diff --git a/htdocs/core/ajax/ajaxcompanies.php b/htdocs/core/ajax/ajaxcompanies.php
deleted file mode 100644
index 086d20e796726..0000000000000
--- a/htdocs/core/ajax/ajaxcompanies.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-/* Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
- * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@inodbox.com>
- * Copyright (C) 2007-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
- * Copyright (C) 2010      Cyrille de Lambert   <info@auguria.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-/**
- *       \file       htdocs/core/ajax/ajaxcompanies.php
- *       \brief      File to return Ajax response on third parties request
- */
-
-if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', 1); // Disables token renewal
-if (!defined('NOREQUIREMENU'))  define('NOREQUIREMENU', '1');
-if (!defined('NOREQUIREHTML'))  define('NOREQUIREHTML', '1');
-if (!defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX', '1');
-if (!defined('NOREQUIRESOC'))   define('NOREQUIRESOC', '1');
-
-// Load Dolibarr environment
-require '../../main.inc.php';
-require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
-
-$object = new Societe($db);
-
-$usesublevelpermission = '';
-
-// Security check
-restrictedArea($user, $object->module, $object, $object->table_element, $usesublevelpermission);
-
-
-/*
- * View
- */
-
-// Ajout directives pour resoudre bug IE
-//header('Cache-Control: Public, must-revalidate');
-//header('Pragma: public');
-
-//top_htmlhead("", "", 1);  // Replaced with top_httphead. An ajax page does not need html header.
-top_httphead();
-
-//print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
-
-dol_syslog(join(',', $_GET));
-
-
-// Generation liste des societes
-if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn')) {
-	$return_arr = array();
-
-	// Define filter on text typed
-	$socid = GETPOST('newcompany');
-	if (!$socid) $socid = GETPOST('socid');
-	if (!$socid) $socid = GETPOST('id_fourn');
-
-	$sql = "SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.address, s.zip, s.town, s.email, s.siren, s.siret, s.ape, s.idprof4, s.client, s.fournisseur, s.datec, s.logo";
-	$sql .= " , c.label as country, d.nom as departement";
-	$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
-	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays";
-	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON d.rowid = s.fk_departement";
-	$sql .= " WHERE s.entity IN (".getEntity('societe').")";
-	if ($socid) {
-		$sql .= " AND (";
-		// Add criteria on name/code
-		if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
-			$sql .= "s.nom LIKE '".$db->escape($db->escapeforlike($socid))."%'";
-			$sql .= " OR s.code_client LIKE '".$db->escape($db->escapeforlike($socid))."%'";
-			$sql .= " OR s.code_fournisseur LIKE '".$db->escape($db->escapeforlike($socid))."%'";
-		} else {
-			$sql .= "s.nom LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
-			$sql .= " OR s.code_client LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
-			$sql .= " OR s.code_fournisseur LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
-		}
-		if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
-			$sql .= " OR s.rowid = ".((int) $socid);
-		}
-		$sql .= ")";
-	}
-	if ($user->socid > 0) {
-		$sql .= " AND s.rowid = ".((int) $user->socid);
-	}
-	//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
-	$sql .= " ORDER BY s.nom ASC";
-
-	//dol_syslog("ajaxcompanies", LOG_DEBUG);
-	$resql = $db->query($sql);
-
-	if ($resql) {
-		while ($row = $db->fetch_array($resql)) {
-			$label = $row['nom'];
-			if ($socid) $label = $label;
-			$row_array['label'] = $label;
-			$row_array['value'] = $row['nom'];
-			$row_array['key'] = $row['rowid'];
-			$row_array['name_alias'] = $row['name_alias'];
-			$row_array['code_client'] = $row['code_client'];
-			$row_array['code_fournisseur'] = $row['code_fournisseur'];
-			$row_array['address'] = $row['address'];
-			$row_array['zip'] = $row['zip'];
-			$row_array['town'] = $row['town'];
-			$row_array['email'] = $row['email'];
-			$row_array['siren'] = $row['siren'];
-			$row_array['siret'] = $row['siret'];
-			$row_array['ape'] = $row['ape'];
-			$row_array['idprof4'] = $row['idprof4'];
-			$row_array['client'] = $row['client'];
-			$row_array['fournisseur'] = $row['fournisseur'];
-			$row_array['datec'] = $row['datec'];
-			$row_array['logo'] = $row['logo'];
-			$row_array['country'] = $row['country'];
-			$row_array['departement'] = $row['departement'];
-
-			array_push($return_arr, $row_array);
-		}
-
-		echo json_encode($return_arr);
-	} else {
-		echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
-	}
-} else {
-	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
-}
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 8f11af63f4a80..527dba8eb3d50 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -1288,27 +1288,27 @@ class Form
 	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
 
 	/**
 	 *  Output html form to select a third party
 	 *
-	 * @param string $selected Preselected type
-	 * @param string $htmlname Name of field in form
-	 * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)')
-	 * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
-	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
-	 * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
-	 * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
-	 * @param int $limit Maximum number of elements
-	 * @param string $morecss Add more css styles to the SELECT component
-	 * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
-	 * @param string $selected_input_value Value of preselected input text (for use with ajax)
-	 * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
-	 * @param array $ajaxoptions Options for ajax_autocompleter
-	 * @param bool $multiple add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
-	 * @param array $excludeids Exclude IDs from the select combo
-	 * @param int $showcode Show code
-	 * @return    string                            HTML string with select box for thirdparty.
+	 * @param string 	$selected 			Preselected type
+	 * @param string 	$htmlname 			Name of field in form
+	 * @param string 	$filter 			Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
+	 * @param string 	$showempty 			Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
+	 * @param int 		$showtype 			Show third party type in combolist (customer, prospect or supplier)
+	 * @param int 		$forcecombo 		Force to load all values and output a standard combobox (with no beautification)
+	 * @param array 	$events 			Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
+	 * @param int 		$limit 				Maximum number of elements
+	 * @param string 	$morecss 			Add more css styles to the SELECT component
+	 * @param string 	$moreparam 			Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
+	 * @param string 	$selected_input_value 	Value of preselected input text (for use with ajax)
+	 * @param int 		$hidelabel 			Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
+	 * @param array 	$ajaxoptions 		Options for ajax_autocompleter
+	 * @param bool 		$multiple 			add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
+	 * @param array 	$excludeids 		Exclude IDs from the select combo
+	 * @param int 		$showcode 			Show code
+	 * @return string  		                HTML string with select box for thirdparty.
 	 */
 	public function select_company($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $limit = 0, $morecss = 'minwidth100', $moreparam = '', $selected_input_value = '', $hidelabel = 1, $ajaxoptions = array(), $multiple = false, $excludeids = array(), $showcode = 0)
 	{
 		// phpcs:enable
 		global $conf, $user, $langs;
@@ -1364,26 +1364,26 @@ class Form
 
 	/**
 	 *  Output html form to select a third party.
 	 *  Note, you must use the select_company to get the component to select a third party. This function must only be called by select_company.
 	 *
-	 * @param string $selected Preselected type
-	 * @param string $htmlname Name of field in form
-	 * @param string $filter Optional filters criteras (example: 's.rowid NOT IN (x)', 's.client IN (1,3)'). Do not use a filter coming from input of users.
-	 * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
-	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
-	 * @param int $forcecombo Force to use standard HTML select component without beautification
-	 * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
-	 * @param string $filterkey Filter on key value
-	 * @param int $outputmode 0=HTML select string, 1=Array
-	 * @param int $limit Limit number of answers
-	 * @param string $morecss Add more css styles to the SELECT component
-	 * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
-	 * @param bool $multiple add [] in the name of element and add 'multiple' attribut
-	 * @param array $excludeids Exclude IDs from the select combo
-	 * @param int $showcode Show code in list
-	 * @return    array|string            HTML string with
+	 * @param string 	$selected 		Preselected type
+	 * @param string 	$htmlname 		Name of field in form
+	 * @param string 	$filter 		Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
+	 * @param string 	$showempty 		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
+	 * @param int 		$showtype 		Show third party type in combolist (customer, prospect or supplier)
+	 * @param int 		$forcecombo 	Force to use standard HTML select component without beautification
+	 * @param array 	$events 		Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
+	 * @param string 	$filterkey 		Filter on key value
+	 * @param int 		$outputmode 	0=HTML select string, 1=Array
+	 * @param int 		$limit 			Limit number of answers
+	 * @param string 	$morecss 		Add more css styles to the SELECT component
+	 * @param string 	$moreparam 		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
+	 * @param bool 		$multiple 		add [] in the name of element and add 'multiple' attribut
+	 * @param array 	$excludeids 	Exclude IDs from the select combo
+	 * @param int 		$showcode 		Show code in list
+	 * @return array|string            	HTML string with
 	 */
 	public function select_thirdparty_list($selected = '', $htmlname = 'socid', $filter = '', $showempty = '', $showtype = 0, $forcecombo = 0, $events = array(), $filterkey = '', $outputmode = 0, $limit = 0, $morecss = 'minwidth100', $moreparam = '', $multiple = false, $excludeids = array(), $showcode = 0)
 	{
 		// phpcs:enable
 		global $conf, $user, $langs;
@@ -1401,13 +1401,17 @@ class Form
 
 		// Clean $filter that may contains sql conditions so sql code
 		if (function_exists('testSqlAndScriptInject')) {
 			if (testSqlAndScriptInject($filter, 3) > 0) {
 				$filter = '';
+				return 'SQLInjectionTryDetected';
 			}
 		}
 
+		//$errormsg = '';
+		//$filter = forgeSQLFromUniversalSearchCriteria($filter, $errormsg);
+
 		// We search companies
 		$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.tva_intra, s.client, s.fournisseur, s.code_client, s.code_fournisseur";
 		if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
 			$sql .= ", s.address, s.zip, s.town";
 			$sql .= ", dictp.code as country_code";
@@ -1468,11 +1472,11 @@ class Form
 		}
 		$sql .= $this->db->order("nom", "ASC");
 		$sql .= $this->db->plimit($limit, 0);
 
 		// Build output string
-		dol_syslog(get_class($this) . "::select_thirdparty_list", LOG_DEBUG);
+		dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
 		$resql = $this->db->query($sql);
 		if ($resql) {
 			if (!$forcecombo) {
 				include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
 				$out .= ajax_combobox($htmlname, $events, getDolGlobalString("COMPANY_USE_SEARCH_TO_SELECT"));
@@ -6068,22 +6072,22 @@ class Form
 	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
 
 	/**
 	 *  Output html select to select thirdparty
 	 *
-	 * @param string $page Page
-	 * @param string $selected Id preselected
-	 * @param string $htmlname Name of HTML select
-	 * @param string $filter Optional filters criteras. Do not use a filter coming from input of users.
-	 * @param int $showempty Add an empty field
-	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
-	 * @param int $forcecombo Force to use combo box
-	 * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
-	 * @param int $nooutput No print output. Return it only.
-	 * @param array $excludeids Exclude IDs from the select combo
-	 * @param string $textifnothirdparty Text to show if no thirdparty
-	 * @return    string                            HTML output or ''
+	 * @param string 	$page 					Page
+	 * @param string 	$selected 				Id preselected
+	 * @param string 	$htmlname 				Name of HTML select
+	 * @param string	$filter 				Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
+	 * @param int 		$showempty 				Add an empty field
+	 * @param int 		$showtype 				Show third party type in combolist (customer, prospect or supplier)
+	 * @param int 		$forcecombo 			Force to use combo box
+	 * @param array 	$events 				Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
+	 * @param int 		$nooutput 				No print output. Return it only.
+	 * @param array 	$excludeids 			Exclude IDs from the select combo
+	 * @param string 	$textifnothirdparty 	Text to show if no thirdparty
+	 * @return    string                        HTML output or ''
 	 */
 	public function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0, $excludeids = array(), $textifnothirdparty = '')
 	{
 		// phpcs:enable
 		global $langs;
@@ -7823,23 +7827,23 @@ class Form
 	/**
 	 * Generic method to select a component from a combo list.
 	 * Can use autocomplete with ajax after x key pressed or a full combo, depending on setup.
 	 * This is the generic method that will replace all specific existing methods.
 	 *
-	 * @param string $objectdesc ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]
-	 * @param string $htmlname Name of HTML select component
-	 * @param int $preselectedvalue Preselected value (ID of element)
-	 * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
-	 * @param string $searchkey Search criteria
-	 * @param string $placeholder Place holder
-	 * @param string $morecss More CSS
-	 * @param string $moreparams More params provided to ajax call
-	 * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
-	 * @param int $disabled 1=Html component is disabled
-	 * @param string $selected_input_value Value of preselected input text (for use with ajax)
-	 * @return    string                                Return HTML string
-	 * @see selectForFormsList() select_thirdparty_list()
+	 * @param 	string 	$objectdesc 		ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]
+	 * @param 	string 	$htmlname 			Name of HTML select component
+	 * @param 	int 	$preselectedvalue 	Preselected value (ID of element)
+	 * @param 	string 	$showempty 			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
+	 * @param 	string 	$searchkey 			Search criteria
+	 * @param 	string 	$placeholder 		Place holder
+	 * @param 	string 	$morecss 			More CSS
+	 * @param 	string 	$moreparams 		More params provided to ajax call
+	 * @param 	int 	$forcecombo 		Force to load all values and output a standard combobox (with no beautification)
+	 * @param 	int 	$disabled 			1=Html component is disabled
+	 * @param 	string 	$selected_input_value Value of preselected input text (for use with ajax)
+	 * @return  string                      Return HTML string
+	 * @see selectForFormsList(), select_thirdparty_list()
 	 */
 	public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0, $selected_input_value = '')
 	{
 		global $conf, $user;
 
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 2afd7e15fe9ce..fad1f6266c311 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -11783,11 +11783,13 @@ function jsonOrUnserialize($stringtodecode)
 
 
 /**
  * forgeSQLFromUniversalSearchCriteria
  *
- * @param 	string		$filter		String with universal search string. Must be  (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'.
+ * @param 	string		$filter		String with universal search string. Must be  (aaa:bbb:...) with
+ * 									aaa is a field name (with alias or not) and
+ * 									bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'.
  * @param	string		$error		Error message
  * @return	string					Return forged SQL string
  */
 function forgeSQLFromUniversalSearchCriteria($filter, &$error = '')
 {
diff --git a/htdocs/don/card.php b/htdocs/don/card.php
index 2c3e3ec6e119f..f396b5d386f59 100644
--- a/htdocs/don/card.php
+++ b/htdocs/don/card.php
@@ -438,11 +438,12 @@ if ($action == 'create') {
 			print ')';
 			print '</td>';
 		} else {
 			print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
 			print '<td>';
-			print $form->select_company($soc->id, 'socid', '(s.client = 1 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
+			$filter = '(s.client = 1 OR s.client = 3) AND status=1';
+			print $form->select_company($soc->id, 'socid', $filter, 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
 			// Option to reload page to retrieve customer informations. Note, this clear other input
 			if (!empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) {
 				print '<script type="text/javascript">
 				$(document).ready(function() {
 					$("#socid").change(function() {
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index dff3ed9885890..ed89b13bd77a7 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -1692,11 +1692,12 @@ if ($action == 'create') {
 
 	if (!empty($societe->id) && $societe->id > 0) {
 		print $societe->getNomUrl(1, 'supplier');
 		print '<input type="hidden" name="socid" value="'.$societe->id.'">';
 	} else {
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', '(s.fournisseur=1 AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
+		$filter = '(s.fournisseur=1 AND s.status=1)';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
 		// reload page to retrieve customer informations
 		if (empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED)) {
 			print '<script>
 			$(document).ready(function() {
 				$("#socid").change(function() {
@@ -1896,13 +1897,14 @@ if ($action == 'create') {
 		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteOrder'), $langs->trans('ConfirmDeleteOrder'), 'confirm_delete', '', 0, 2);
 	}
 
 	// Clone confirmation
 	if ($action == 'clone') {
+		$filter = '(s.fournisseur=1)';
 		// Create an array for form
 		$formquestion = array(
-			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.fournisseur=1)'))
+			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter))
 		);
 		// Paiement incomplet. On demande si motif = escompte ou autre
 		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneOrder', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
 	}
 
@@ -2032,11 +2034,12 @@ if ($action == 'create') {
 	$morehtmlref .= '<br>';
 	if (!empty($conf->global->MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER) && !empty($usercancreate) && $action == 'edit_thirdparty') {
 		$morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
 		$morehtmlref .= '<input type="hidden" name="action" value="set_thirdparty">';
 		$morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
-		$morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', 's.fournisseur=1', '', 0, 0, array(), 0, 'minwidth300');
+		$filter = 's.fournisseur=1';
+		$morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', $filter, '', 0, 0, array(), 0, 'minwidth300');
 		$morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
 		$morehtmlref .= '</form>';
 	}
 	if (empty($conf->global->MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER) || $action != 'edit_thirdparty') {
 		if (!empty($conf->global->MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER) && $object->statut == CommandeFournisseur::STATUS_DRAFT) {
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index bfd0f1a184a7e..29eb57d47bdc7 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -2197,11 +2197,12 @@ if ($action == 'create') {
 	if (!empty($societe->id) && $societe->id > 0 && ($fac_recid <= 0 || !empty($invoice_predefined->frequency))) {
 		$absolute_discount = $societe->getAvailableDiscounts('', '', 0, 1);
 		print $societe->getNomUrl(1, 'supplier');
 		print '<input type="hidden" name="socid" value="'.$societe->id.'">';
 	} else {
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', '(s.fournisseur = 1 AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
+		$filter = '(s.fournisseur = 1 AND s.status = 1)';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
 		// reload page to retrieve supplier informations
 		if (empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE_DISABLED)) {
 			print '<script type="text/javascript">
 				$(document).ready(function() {
 					$("#socid").change(function() {
diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php
index d6ace40ad1604..d9cff92462242 100644
--- a/htdocs/margin/customerMargins.php
+++ b/htdocs/margin/customerMargins.php
@@ -108,11 +108,12 @@ if ($socid > 0) {
 	$soc->fetch($socid);
 
 	if ($soc->client) {
 		print '<tr><td class="titlefield">'.$langs->trans('ThirdPartyName').'</td>';
 		print '<td class="maxwidthonsmartphone" colspan="4">';
-		print img_picto('', 'company').$form->select_company($socid, 'socid', '(client=1 OR client=3)', 1, 0, 0);
+		$filter = '(client=1 OR client=3)';
+		print img_picto('', 'company').$form->select_company($socid, 'socid', $filter, 1, 0, 0);
 		print '</td></tr>';
 
 		$client = true;
 		if (!$sortorder) {
 			$sortorder = "DESC";
diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php
index 58c98f791cfb9..779ee68d5a5c6 100644
--- a/htdocs/product/fournisseurs.php
+++ b/htdocs/product/fournisseurs.php
@@ -499,11 +499,12 @@ if ($id > 0 || $ref) {
 					print '<input type="hidden" name="rowid" value="'.$rowid.'">';
 					print '<input type="hidden" name="socid" value="'.$socid.'">';
 				} else {
 					$events = array();
 					$events[] = array('method' => 'getVatRates', 'url' => dol_buildpath('/core/ajax/vatrates.php', 1), 'htmlname' => 'tva_tx', 'params' => array());
-					print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', 'fournisseur=1', 'SelectThirdParty', 0, 0, $events);
+					$filter = 'fournisseur=1';
+					print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', $filter, 'SelectThirdParty', 0, 0, $events);
 
 					$parameters = array('filtre'=>"fournisseur=1", 'html_name'=>'id_fourn', 'selected'=>GETPOST("id_fourn"), 'showempty'=>1, 'prod_id'=>$object->id);
 					$reshook = $hookmanager->executeHooks('formCreateThirdpartyOptions', $parameters, $object, $action);
 					if (empty($reshook)) {
 						if (empty($form->result)) {
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index d62760611c278..0a47a0768344e 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -1942,11 +1942,12 @@ if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
 
 		print '<table class="border centpercent">';
 		print '<tr>';
 		print '<td class="fieldrequired">'.$langs->trans('ThirdParty').'</td>';
 		print '<td>';
-		print img_picto('', 'company').$form->select_company('', 'socid', 's.client IN (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
+		$filter = 's.client IN (1,2,3)';
+		print img_picto('', 'company').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
 		print '</td>';
 		print '</tr>';
 
 		// Ref. Customer
 		print '<tr><td>' . $langs->trans('RefCustomer') . '</td>';
diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php
index c5f35eb7864eb..7dfbf3c238588 100644
--- a/htdocs/product/stock/replenish.php
+++ b/htdocs/product/stock/replenish.php
@@ -613,11 +613,12 @@ if (!empty($conf->global->STOCK_ALLOW_ADD_LIMIT_STOCK_BY_WAREHOUSE)) {
 	print '<div class="inline-block valignmiddle" style="padding-right: 20px;">';
 	print $langs->trans('Warehouse').' '.$formproduct->selectWarehouses($fk_entrepot, 'fk_entrepot', '', 1);
 	print '</div>';
 }
 print '<div class="inline-block valignmiddle" style="padding-right: 20px;">';
-print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', 'fournisseur=1', 1);
+$filter = 'fournisseur=1';
+print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', $filter, 1);
 print '</div>';
 
 $parameters = array();
 $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook
 if (empty($reshook)) {
diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php
index 2b0ffd51b436c..43c31a2377691 100644
--- a/htdocs/projet/card.php
+++ b/htdocs/projet/card.php
@@ -696,15 +696,15 @@ if ($action == 'create' && $user->rights->projet->creer) {
 		print '<tr><td>';
 		print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '<span class="fieldrequired">');
 		print $langs->trans("ThirdParty");
 		print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '</span>');
 		print '</td><td class="maxwidthonsmartphone">';
-		$filteronlist = '';
+		$filter = '';
 		if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) {
-			$filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
+			$filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
 		}
-		$text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
+		$text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
 		if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) {
 			$texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
 			print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1);
 		} else {
 			print $text;
@@ -908,11 +908,11 @@ if ($action == 'create' && $user->rights->projet->creer) {
 
 	// Clone confirmation
 	if ($action == 'clone') {
 		$formquestion = array(
 			'text' => $langs->trans("ConfirmClone"),
-			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ?GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')),
+			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ? GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')),
 			array('type' => 'checkbox', 'name' => 'clone_contacts', 'label' => $langs->trans("CloneContacts"), 'value' => true),
 			array('type' => 'checkbox', 'name' => 'clone_tasks', 'label' => $langs->trans("CloneTasks"), 'value' => true),
 			array('type' => 'checkbox', 'name' => 'move_date', 'label' => $langs->trans("CloneMoveDate"), 'value' => true),
 			array('type' => 'checkbox', 'name' => 'clone_notes', 'label' => $langs->trans("CloneNotes"), 'value' => true),
 			array('type' => 'checkbox', 'name' => 'clone_project_files', 'label' => $langs->trans("CloneProjectFiles"), 'value' => false),
@@ -1075,16 +1075,16 @@ if ($action == 'create' && $user->rights->projet->creer) {
 			print '<tr><td>';
 			print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '<span class="fieldrequired">');
 			print $langs->trans("ThirdParty");
 			print (empty($conf->global->PROJECT_THIRDPARTY_REQUIRED) ? '' : '</span>');
 			print '</td><td>';
-			$filteronlist = '';
+			$filter = '';
 			if (!empty($conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST)) {
-				$filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
+				$filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
 			}
 			$text = img_picto('', 'company', 'class="pictofixedwidth"');
-			$text .= $form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300');
+			$text .= $form->select_company($object->thirdparty->id, 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300');
 			if (empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS) && empty($conf->dol_use_jmobile)) {
 				$texthelp = $langs->trans("IfNeedToUseOtherObjectKeepEmpty");
 				print $form->textwithtooltip($text.' '.img_help(), $texthelp, 1, 0, '', '', 2);
 			} else {
 				print $text;
diff --git a/htdocs/societe/ajax/ajaxcompanies.php b/htdocs/societe/ajax/ajaxcompanies.php
index 08d914d562ab2..aca9a4eaddba3 100644
--- a/htdocs/societe/ajax/ajaxcompanies.php
+++ b/htdocs/societe/ajax/ajaxcompanies.php
@@ -18,11 +18,11 @@
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**
  *       \file       htdocs/societe/ajax/ajaxcompanies.php
- *       \brief      File to return Ajax response on third parties request
+ *       \brief      File to return Ajax response on third parties request. Search is done on name|name_alias|code_client|code_fournisseur
  */
 
 if (!defined('NOTOKENRENEWAL')) {
 	define('NOTOKENRENEWAL', 1); // Disables token renewal
 }
@@ -51,109 +51,129 @@ if ($id > 0) {
 }
 
 // Security check
 if ($user->socid > 0) {
 	$socid = $user->socid;
-	$object->id = $socid;
+	if ($object->socid && $socid != $object->socid) {
+		accessforbidden('Not allowed to access thirdparty id '.$id.' with an external user on id '.$socid);
+	}
 }
-restrictedArea($user, 'societe', $object->id, '&societe');
+restrictedArea($user, 'societe', $object, '&societe');
 
 
 /*
  * View
  */
 
-// Ajout directives pour resoudre bug IE
-//header('Cache-Control: Public, must-revalidate');
-//header('Pragma: public');
-
 //top_htmlhead("", "", 1);  // Replaced with top_httphead. An ajax page does not need html header.
-top_httphead();
+top_httphead('application/json');
 
 //print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
 
 
-// Generate list of companies
-if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn', 'int')) {
-	$return_arr = array();
+$return_arr = array();
 
-	// Define filter on text typed
-	$socid = GETPOST('newcompany');
-	if (!$socid) {
-		$socid = GETPOST('socid', 'int');
-	}
-	if (!$socid) {
-		$socid = GETPOST('id_fourn', 'int');
-	}
+// Define filter on text typed
+$socid = GETPOST('newcompany');
+if (!$socid) {
+	$socid = GETPOST('socid', 'int');
+}
+if (!$socid) {
+	$socid = GETPOST('id_fourn', 'int');
+}
 
-	$sql = "SELECT s.rowid, s.nom";
-	if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
-		$sql .= ", s.client, s.fournisseur, s.code_client, s.code_fournisseur";
-	}
-	if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
-		$sql .= ", s.address, s.zip, s.town";
-		$sql .= ", dictp.code as country_code";
-	}
-	$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
-	if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
-		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as dictp ON dictp.rowid = s.fk_pays";
+// Generate list of companies
+if (! $socid) {
+	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
+	exit;
+}
+
+$sql = "SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.address, s.zip, s.town, s.email, s.siren, s.siret, s.ape, s.idprof4, s.idprof5, s.idprof6, s.client, s.fournisseur, s.datec, s.logo";
+if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
+	$sql .= ", dictp.code as country_code";
+}
+$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
+if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
+	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as dictp ON dictp.rowid = s.fk_pays";
+}
+$sql .= " WHERE s.entity IN (".getEntity('societe').")";
+if ($socid) {
+	$sql .= " AND (";
+	// Add criteria on name/code
+	if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
+		$sql .= "s.nom LIKE '".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.name_alias LIKE '".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.code_client LIKE '".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.code_fournisseur LIKE '".$db->escape($db->escapeforlike($socid))."%'";
+	} else {
+		$sql .= "s.nom LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.name_alias LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.code_client LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
+		$sql .= " OR s.code_fournisseur LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
 	}
-	$sql .= " WHERE s.entity IN (".getEntity('societe').")";
-	if ($socid) {
-		$sql .= " AND (";
-		// Add criteria on name/code
-		if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
-			$sql .= "nom LIKE '".$db->escape($socid)."%'";
-			$sql .= " OR code_client LIKE '".$db->escape($socid)."%'";
-			$sql .= " OR code_fournisseur LIKE '".$db->escape($socid)."%'";
-		} else {
-			$sql .= "nom LIKE '%".$db->escape($socid)."%'";
-			$sql .= " OR code_client LIKE '%".$db->escape($socid)."%'";
-			$sql .= " OR code_fournisseur LIKE '%".$db->escape($socid)."%'";
-		}
-		if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
-			$sql .= " OR rowid = ".((int) $socid);
-		}
-		$sql .= ")";
+	if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
+		$sql .= " OR s.rowid = ".((int) $socid);
 	}
-	//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
-	$sql .= " ORDER BY nom ASC";
-
-	//dol_syslog("ajaxcompanies", LOG_DEBUG);
-	$resql = $db->query($sql);
-	if ($resql) {
-		while ($row = $db->fetch_array($resql)) {
-			$label = '';
-			if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
-				if (($row['client']) && (!empty($row['code_client']))) {
-					$label = $row['code_client'].' - ';
-				}
-				if (($row['fournisseur']) && (!empty($row['code_fournisseur']))) {
-					$label .= $row['code_fournisseur'].' - ';
-				}
+	$sql .= ")";
+}
+// Protection for external user access
+if ($user->socid > 0) {
+	$sql .= " AND s.rowid = ".((int) $user->socid);
+}
+//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
+$sql .= " ORDER BY s.nom ASC";
+
+//dol_syslog("ajaxcompanies", LOG_DEBUG);
+$resql = $db->query($sql);
+if ($resql) {
+	while ($row = $db->fetch_array($resql)) {
+		$label = '';
+		if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
+			if (($row['client']) && (!empty($row['code_client']))) {
+				$label = $row['code_client'].' - ';
 			}
+			if (($row['fournisseur']) && (!empty($row['code_fournisseur']))) {
+				$label .= $row['code_fournisseur'].' - ';
+			}
+		}
 
-			$label .= $row['nom'];
+		$label .= $row['nom'];
 
-			if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
-				$label .= ($row['address'] ? ' - '.$row['address'] : '').($row['zip'] ? ' - '.$row['zip'] : '').($row['town'] ? ' '.$row['town'] : '');
-				if (!empty($row['country_code'])) {
-					$label .= ', '.$langs->trans('Country'.$row['country_code']);
-				}
+		if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
+			$label .= ($row['address'] ? ' - '.$row['address'] : '').($row['zip'] ? ' - '.$row['zip'] : '').($row['town'] ? ' '.$row['town'] : '');
+			if (!empty($row['country_code'])) {
+				$label .= ', '.$langs->trans('Country'.$row['country_code']);
 			}
-			if ($socid) {
-				$label = preg_replace('/('.preg_quote($socid, '/').')/i', '<strong>$1</strong>', $label, 1);
-			}
-			$row_array['label'] = $label;
-			$row_array['value'] = $row['nom'];
-			$row_array['key'] = $row['rowid'];
-
-			array_push($return_arr, $row_array);
 		}
-
-		echo json_encode($return_arr);
-	} else {
-		echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
+		if ($socid) {
+			$label = preg_replace('/('.preg_quote($socid, '/').')/i', '<strong>$1</strong>', $label, 1);
+		}
+		$row_array['label'] = $label;
+
+		$row_array['value'] = $row['nom'];
+		$row_array['key'] = $row['rowid'];
+
+		$row_array['name_alias'] = $row['name_alias'];
+		$row_array['client'] = $row['client'];
+		$row_array['fournisseur'] = $row['fournisseur'];
+		$row_array['code_client'] = $row['code_client'];
+		$row_array['code_fournisseur'] = $row['code_fournisseur'];
+		$row_array['address'] = $row['address'];
+		$row_array['zip'] = $row['zip'];
+		$row_array['town'] = $row['town'];
+		$row_array['email'] = $row['email'];
+		$row_array['siren'] = $row['siren'];
+		$row_array['siret'] = $row['siret'];
+		$row_array['ape'] = $row['ape'];
+		$row_array['idprof4'] = $row['idprof4'];
+		$row_array['idprof5'] = $row['idprof5'];
+		$row_array['idprof6'] = $row['idprof6'];
+		$row_array['datec'] = $row['datec'];
+		$row_array['logo'] = $row['logo'];
+
+		array_push($return_arr, $row_array);
 	}
+
+	echo json_encode($return_arr);
 } else {
-	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
+	echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
 }
diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php
index 7bdfe6e0e3467..f625b94bed706 100644
--- a/htdocs/societe/ajax/company.php
+++ b/htdocs/societe/ajax/company.php
@@ -17,11 +17,12 @@
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
 
 /**
  *       \file       htdocs/societe/ajax/company.php
- *       \brief      File to return Ajax response on thirdparty list request
+ *       \brief      File to return Ajax response on thirdparty list request. Used by the combo list of thirdparties.
+ *       			 Search done on name, name_alias, barcode, tva_intra, ...
  */
 
 if (!defined('NOTOKENRENEWAL')) {
 	define('NOTOKENRENEWAL', 1); // Disables token renewal
 }
@@ -46,12 +47,12 @@ $htmlname = GETPOST('htmlname', 'aZ09');
 $filter = GETPOST('filter', 'alpha');
 $outjson = (GETPOST('outjson', 'int') ? GETPOST('outjson', 'int') : 0);
 $action = GETPOST('action', 'aZ09');
 $id = GETPOST('id', 'int');
 $excludeids = GETPOST('excludeids', 'intcomma');
-$showtype = GETPOSTINT('showtype');
-$showcode = GETPOSTINT('showcode');
+$showtype = GETPOSTINT('showtype', 'alpha');
+$showcode = GETPOSTINT('showcode', 'alpha');
 
 $object = new Societe($db);
 if ($id > 0) {
 	$object->fetch($id);
 }
@@ -67,10 +68,12 @@ restrictedArea($user, 'societe', $object->id, '&societe');
 
 /*
  * View
  */
 
+top_httphead('application/json');
+
 //print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";
 //print_r($_GET);
 
 if (!empty($action) && $action == 'fetch' && !empty($id)) {
 	require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
@@ -88,14 +91,10 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) {
 
 	echo json_encode($outjson);
 } else {
 	require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
 
-	$langs->load("companies");
-
-	top_httphead();
-
 	if (empty($htmlname)) {
 		return;
 	}
 
 	// Filter on the company to search can be:
@@ -122,11 +121,11 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) {
 		$excludeids = array();
 	}
 
 	$arrayresult = $form->select_thirdparty_list(0, $htmlname, $filter, 1, $showtype, 0, null, $searchkey, $outjson, 0, 'minwidth100', '', false, $excludeids, $showcode);
 
-	$db->close();
-
 	if ($outjson) {
 		print json_encode($arrayresult);
 	}
 }
+
+$db->close();
diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php
index 6cc50d51399f9..a6d904ae3598a 100644
--- a/htdocs/societe/card.php
+++ b/htdocs/societe/card.php
@@ -1366,14 +1366,13 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
 			print '<span id="TypeName" class="fieldrequired">'.$form->editfieldkey('ThirdPartyName', 'name', '', $object, 0).'</span>';
 		}
 		print '</td><td'.(empty($conf->global->SOCIETE_USEPREFIX) ? ' colspan="3"' : '').'>';
 
 		print '<input type="text" class="minwidth300" maxlength="128" name="name" id="name" value="'.dol_escape_htmltag($object->name).'" autofocus="autofocus">';
-		print $form->widgetForTranslation("name", $object, $permissiontoadd, 'string', 'alpahnohtml', 'minwidth300');
-		/* Disabled. Must be implenteted by keeping the input text but calling ajax on a keydown of the input and output
-		   data of duplicate into a div under the input. We need to keep the widgetForTranslation also for some countries.
-		 */
+		print $form->widgetForTranslation("name", $object, $permissiontoadd, 'string', 'alpahnohtml', 'minwidth300');	// For some countries that need the company name in 2 languages
+		// This implementation of the feature to search already existing company has been disabled. It must be implemented by keeping the "input text" and we must call the search ajax societe/ajax/ajaxcompanies.php
+		// on a keydown of the input. We should show data about a duplicate found if we found less than 5 answers into a div under the input.
 		/*
 		print '<select class="name" name="name" id="name" style="min-width:500px"></select>';
 		print "\n".'<script type="text/javascript">';
 		print '$(document).ready(function () {
 			$("#name").select2({
diff --git a/htdocs/supplier_proposal/card.php b/htdocs/supplier_proposal/card.php
index 8f66ba035c459..0a0578e599030 100644
--- a/htdocs/supplier_proposal/card.php
+++ b/htdocs/supplier_proposal/card.php
@@ -1271,11 +1271,12 @@ if ($action == 'create') {
 		print $soc->getNomUrl(1, 'supplier');
 		print '<input type="hidden" name="socid" value="'.$soc->id.'">';
 		print '</td>';
 	} else {
 		print '<td colspan="2">';
-		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
+		$filter = 's.fournisseur=1';
+		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
 		// reload page to retrieve customer informations
 		if (!empty($conf->global->RELOAD_PAGE_ON_SUPPLIER_CHANGE)) {
 			print '<script>
 			$(document).ready(function() {
 				$("#socid").change(function() {
@@ -1523,21 +1524,22 @@ if ($action == 'create') {
 
 	$formconfirm = '';
 
 	// Clone confirmation
 	if ($action == 'clone') {
+		$filter = 's.fournisseur=1';
 		// Create an array for form
 		$formquestion = array(
 			// 'text' => $langs->trans("ConfirmClone"),
 			// array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
 			// array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' =>
 			// 1),
 			array(
 				'type' => 'other',
 				'name' => 'socid',
 				'label' => $langs->trans("SelectThirdParty"),
-				'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', 's.fournisseur=1'))
+				'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter))
 			);
 		// Paiement incomplet. On demande si motif = escompte ou autre
 		$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneAsk', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
 	} elseif ($action == 'delete') {
 		// Confirm delete
diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php
index dbbe7cfe46a34..9fc4df7e66279 100644
--- a/htdocs/takepos/admin/terminal.php
+++ b/htdocs/takepos/admin/terminal.php
@@ -157,11 +157,12 @@ print '<td>';
 print '<input type="text" name="terminalname'.$terminal.'" value="'.getDolGlobalString("TAKEPOS_TERMINAL_NAME_".$terminal, $langs->trans("TerminalName", $terminal)).'" >';
 print '</td></tr>';
 
 print '<tr class="oddeven"><td class="fieldrequired">'.$langs->trans("CashDeskThirdPartyForSell").'</td>';
 print '<td>';
-print $form->select_company(getDolGlobalInt('CASHDESK_ID_THIRDPARTY'.$terminaltouse), 'socid', '(s.client IN (1, 3) AND s.status = 1)', 1, 0, 0, array(), 0);
+$filter = '(s.client IN (1, 3) AND s.status = 1)';
+print $form->select_company(getDolGlobalInt('CASHDESK_ID_THIRDPARTY'.$terminaltouse), 'socid', $filter, 1, 0, 0, array(), 0);
 print '</td></tr>';
 
 $atleastonefound = 0;
 if (isModEnabled("banque")) {
 	print '<tr class="oddeven"><td>'.$langs->trans("CashDeskBankAccountForSell").'</td>';

Vulnerable code: 				print $form->select_company('', 'elemid', 's.client IN (1,3)');
				print $form->select_company('', 'elemid', 's.fournisseur = 1');
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx');
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300')),
$filter = 's.client IN (1,2,3)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
				array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client = 2 OR s.client=3)', '', 0, 0, null, 0, 'maxwidth300'))
$filter = '';
print $form->select_company($socid, 'socid', $filter, 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', '((s.client = 1 OR s.client = 3) AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company($object->socid, 'socid', '(s.client=1 OR s.client=2 OR s.client=3)', 1)),
// We use select_thirdparty_list instead of select_company so we can use $filter and share same code for customer and supplier.
$filter = '';
if ($mode == 'customer') {
	$filter = 's.client in (1,2,3)';
}
if ($mode == 'supplier') {
	$filter = 's.fournisseur = 1';
}

	$parameters = array();
	$reshook = $hookmanager->executeHooks('printFieldListeTitle', $parameters);
	print $hookmanager->resPrint;

	print '</td></tr>';
	print "<tr class=\"liste_titre\">";
				print img_picto('', 'company').$form->select_company(GETPOST('socid', 'int') ?GETPOST('socid', 'int') : ($object->socid ? $object->socid : -1), 'socid', '', $langs->trans("SelectThirdParty"));
			$formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.client=1 OR s.client=2 OR s.client=3)')));
<?php
/* Copyright (C) 2006      Andre Cianfarani     <acianfa@free.fr>
 * Copyright (C) 2005-2009 Regis Houssin        <regis.houssin@inodbox.com>
 * Copyright (C) 2007-2010 Laurent Destailleur  <eldy@users.sourceforge.net>
 * Copyright (C) 2010      Cyrille de Lambert   <info@auguria.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

/**
 *       \file       htdocs/core/ajax/ajaxcompanies.php
 *       \brief      File to return Ajax response on third parties request
 */

if (!defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', 1); // Disables token renewal
if (!defined('NOREQUIREMENU'))  define('NOREQUIREMENU', '1');
if (!defined('NOREQUIREHTML'))  define('NOREQUIREHTML', '1');
if (!defined('NOREQUIREAJAX'))  define('NOREQUIREAJAX', '1');
if (!defined('NOREQUIRESOC'))   define('NOREQUIRESOC', '1');

// Load Dolibarr environment
require '../../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';

$object = new Societe($db);

$usesublevelpermission = '';

// Security check
restrictedArea($user, $object->module, $object, $object->table_element, $usesublevelpermission);


/*
 * View
 */

// Ajout directives pour resoudre bug IE
//header('Cache-Control: Public, must-revalidate');
//header('Pragma: public');

//top_htmlhead("", "", 1);  // Replaced with top_httphead. An ajax page does not need html header.
top_httphead();

//print '<!-- Ajax page called with url '.dol_escape_htmltag($_SERVER["PHP_SELF"]).'?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]).' -->'."\n";

dol_syslog(join(',', $_GET));


// Generation liste des societes
if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn')) {
	$return_arr = array();

	// Define filter on text typed
	$socid = GETPOST('newcompany');
	if (!$socid) $socid = GETPOST('socid');
	if (!$socid) $socid = GETPOST('id_fourn');

	$sql = "SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.address, s.zip, s.town, s.email, s.siren, s.siret, s.ape, s.idprof4, s.client, s.fournisseur, s.datec, s.logo";
	$sql .= " , c.label as country, d.nom as departement";
	$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON c.rowid = s.fk_pays";
	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON d.rowid = s.fk_departement";
	$sql .= " WHERE s.entity IN (".getEntity('societe').")";
	if ($socid) {
		$sql .= " AND (";
		// Add criteria on name/code
		if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
			$sql .= "s.nom LIKE '".$db->escape($db->escapeforlike($socid))."%'";
			$sql .= " OR s.code_client LIKE '".$db->escape($db->escapeforlike($socid))."%'";
			$sql .= " OR s.code_fournisseur LIKE '".$db->escape($db->escapeforlike($socid))."%'";
		} else {
			$sql .= "s.nom LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
			$sql .= " OR s.code_client LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
			$sql .= " OR s.code_fournisseur LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
		}
		if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
			$sql .= " OR s.rowid = ".((int) $socid);
		}
		$sql .= ")";
	}
	if ($user->socid > 0) {
		$sql .= " AND s.rowid = ".((int) $user->socid);
	}
	//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
	$sql .= " ORDER BY s.nom ASC";

	//dol_syslog("ajaxcompanies", LOG_DEBUG);
	$resql = $db->query($sql);

	if ($resql) {
		while ($row = $db->fetch_array($resql)) {
			$label = $row['nom'];
			if ($socid) $label = $label;
			$row_array['label'] = $label;
			$row_array['value'] = $row['nom'];
			$row_array['key'] = $row['rowid'];
			$row_array['name_alias'] = $row['name_alias'];
			$row_array['code_client'] = $row['code_client'];
			$row_array['code_fournisseur'] = $row['code_fournisseur'];
			$row_array['address'] = $row['address'];
			$row_array['zip'] = $row['zip'];
			$row_array['town'] = $row['town'];
			$row_array['email'] = $row['email'];
			$row_array['siren'] = $row['siren'];
			$row_array['siret'] = $row['siret'];
			$row_array['ape'] = $row['ape'];
			$row_array['idprof4'] = $row['idprof4'];
			$row_array['client'] = $row['client'];
			$row_array['fournisseur'] = $row['fournisseur'];
			$row_array['datec'] = $row['datec'];
			$row_array['logo'] = $row['logo'];
			$row_array['country'] = $row['country'];
			$row_array['departement'] = $row['departement'];

			array_push($return_arr, $row_array);
		}

		echo json_encode($return_arr);
	} else {
		echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
	}
} else {
	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
}
	 * @param string $selected Preselected type
	 * @param string $htmlname Name of field in form
	 * @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)')
	 * @param string $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
	 * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
	 * @param array $events Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param int $limit Maximum number of elements
	 * @param string $morecss Add more css styles to the SELECT component
	 * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
	 * @param string $selected_input_value Value of preselected input text (for use with ajax)
	 * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
	 * @param array $ajaxoptions Options for ajax_autocompleter
	 * @param bool $multiple add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
	 * @param array $excludeids Exclude IDs from the select combo
	 * @param int $showcode Show code
	 * @return    string                            HTML string with select box for thirdparty.
	 * @param string $selected Preselected type
	 * @param string $htmlname Name of field in form
	 * @param string $filter Optional filters criteras (example: 's.rowid NOT IN (x)', 's.client IN (1,3)'). Do not use a filter coming from input of users.
	 * @param string $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
	 * @param int $forcecombo Force to use standard HTML select component without beautification
	 * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param string $filterkey Filter on key value
	 * @param int $outputmode 0=HTML select string, 1=Array
	 * @param int $limit Limit number of answers
	 * @param string $morecss Add more css styles to the SELECT component
	 * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
	 * @param bool $multiple add [] in the name of element and add 'multiple' attribut
	 * @param array $excludeids Exclude IDs from the select combo
	 * @param int $showcode Show code in list
	 * @return    array|string            HTML string with
		dol_syslog(get_class($this) . "::select_thirdparty_list", LOG_DEBUG);
	 * @param string $page Page
	 * @param string $selected Id preselected
	 * @param string $htmlname Name of HTML select
	 * @param string $filter Optional filters criteras. Do not use a filter coming from input of users.
	 * @param int $showempty Add an empty field
	 * @param int $showtype Show third party type in combolist (customer, prospect or supplier)
	 * @param int $forcecombo Force to use combo box
	 * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param int $nooutput No print output. Return it only.
	 * @param array $excludeids Exclude IDs from the select combo
	 * @param string $textifnothirdparty Text to show if no thirdparty
	 * @return    string                            HTML output or ''
	 * @param string $objectdesc ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]
	 * @param string $htmlname Name of HTML select component
	 * @param int $preselectedvalue Preselected value (ID of element)
	 * @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
	 * @param string $searchkey Search criteria
	 * @param string $placeholder Place holder
	 * @param string $morecss More CSS
	 * @param string $moreparams More params provided to ajax call
	 * @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
	 * @param int $disabled 1=Html component is disabled
	 * @param string $selected_input_value Value of preselected input text (for use with ajax)
	 * @return    string                                Return HTML string
	 * @see selectForFormsList() select_thirdparty_list()
 * @param 	string		$filter		String with universal search string. Must be  (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'.
			print $form->select_company($soc->id, 'socid', '(s.client = 1 OR s.client = 3) AND status=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', '(s.fournisseur=1 AND s.status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', '(s.fournisseur=1)'))
		$morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', 's.fournisseur=1', '', 0, 0, array(), 0, 'minwidth300');
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', '(s.fournisseur = 1 AND s.status = 1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
		print img_picto('', 'company').$form->select_company($socid, 'socid', '(client=1 OR client=3)', 1, 0, 0);
					print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', 'fournisseur=1', 'SelectThirdParty', 0, 0, $events);
		print img_picto('', 'company').$form->select_company('', 'socid', 's.client IN (1,2,3)', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', 'fournisseur=1', 1);
		$filteronlist = '';
			$filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
		$text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filteronlist, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ?GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')),
			$filteronlist = '';
				$filteronlist = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
			$text .= $form->select_company($object->thirdparty->id, 'socid', $filteronlist, 'None', 1, 0, array(), 0, 'minwidth300');
 *       \brief      File to return Ajax response on third parties request
	$object->id = $socid;
restrictedArea($user, 'societe', $object->id, '&societe');
// Ajout directives pour resoudre bug IE
//header('Cache-Control: Public, must-revalidate');
//header('Pragma: public');

top_httphead();
// Generate list of companies
if (GETPOST('newcompany') || GETPOST('socid', 'int') || GETPOST('id_fourn', 'int')) {
	$return_arr = array();
	// Define filter on text typed
	$socid = GETPOST('newcompany');
	if (!$socid) {
		$socid = GETPOST('socid', 'int');
	}
	if (!$socid) {
		$socid = GETPOST('id_fourn', 'int');
	}
	$sql = "SELECT s.rowid, s.nom";
	if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
		$sql .= ", s.client, s.fournisseur, s.code_client, s.code_fournisseur";
	}
	if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
		$sql .= ", s.address, s.zip, s.town";
		$sql .= ", dictp.code as country_code";
	}
	$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
	if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as dictp ON dictp.rowid = s.fk_pays";
	$sql .= " WHERE s.entity IN (".getEntity('societe').")";
	if ($socid) {
		$sql .= " AND (";
		// Add criteria on name/code
		if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
			$sql .= "nom LIKE '".$db->escape($socid)."%'";
			$sql .= " OR code_client LIKE '".$db->escape($socid)."%'";
			$sql .= " OR code_fournisseur LIKE '".$db->escape($socid)."%'";
		} else {
			$sql .= "nom LIKE '%".$db->escape($socid)."%'";
			$sql .= " OR code_client LIKE '%".$db->escape($socid)."%'";
			$sql .= " OR code_fournisseur LIKE '%".$db->escape($socid)."%'";
		}
		if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
			$sql .= " OR rowid = ".((int) $socid);
		}
		$sql .= ")";
	//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
	$sql .= " ORDER BY nom ASC";

	//dol_syslog("ajaxcompanies", LOG_DEBUG);
	$resql = $db->query($sql);
	if ($resql) {
		while ($row = $db->fetch_array($resql)) {
			$label = '';
			if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
				if (($row['client']) && (!empty($row['code_client']))) {
					$label = $row['code_client'].' - ';
				}
				if (($row['fournisseur']) && (!empty($row['code_fournisseur']))) {
					$label .= $row['code_fournisseur'].' - ';
				}
			$label .= $row['nom'];
			if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
				$label .= ($row['address'] ? ' - '.$row['address'] : '').($row['zip'] ? ' - '.$row['zip'] : '').($row['town'] ? ' '.$row['town'] : '');
				if (!empty($row['country_code'])) {
					$label .= ', '.$langs->trans('Country'.$row['country_code']);
				}
			if ($socid) {
				$label = preg_replace('/('.preg_quote($socid, '/').')/i', '<strong>$1</strong>', $label, 1);
			}
			$row_array['label'] = $label;
			$row_array['value'] = $row['nom'];
			$row_array['key'] = $row['rowid'];

			array_push($return_arr, $row_array);

		echo json_encode($return_arr);
	} else {
		echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
 *       \brief      File to return Ajax response on thirdparty list request
$showtype = GETPOSTINT('showtype');
$showcode = GETPOSTINT('showcode');
	$langs->load("companies");

	top_httphead();

	$db->close();

		print $form->widgetForTranslation("name", $object, $permissiontoadd, 'string', 'alpahnohtml', 'minwidth300');
		/* Disabled. Must be implenteted by keeping the input text but calling ajax on a keydown of the input and output
		   data of duplicate into a div under the input. We need to keep the widgetForTranslation also for some countries.
		 */
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', 's.fournisseur=1', 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
				'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', 's.fournisseur=1'))
print $form->select_company(getDolGlobalInt('CASHDESK_ID_THIRDPARTY'.$terminaltouse), 'socid', '(s.client IN (1, 3) AND s.status = 1)', 1, 0, 0, array(), 0);
Fixed code: 				$filter = 's.client IN (1,3)';
				print $form->select_company('', 'elemid', $filter);
				$filter ='s.fournisseur = 1';
				print $form->select_company('', 'elemid', $filter);
		$filter = '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx');
		$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter, '', 0, 0, null, 0, 'maxwidth300')),
$filter = 's.client IN (1,2,3)';
		$filter = '((s.client = 1 OR s.client = 2 OR s.client = 3) AND s.status=1)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
			$filter = '(s.client=1 OR s.client = 2 OR s.client=3)';
				array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter, '', 0, 0, null, 0, 'maxwidth300'))
$filter = '';
print $form->select_company($socid, 'socid', '', 1, 1, 0, array(), 0, 'widthcentpercentminusx maxwidth300', '');
		$filter = '((s.client = 1 OR s.client = 3) AND s.status = 1)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company($soc->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
		$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company($object->socid, 'socid', $filter, 1)),
$filter = '';
if ($mode == 'customer') {
	$filter = 's.client in (1,2,3)';
}
if ($mode == 'supplier') {
	$filter = 's.fournisseur = 1';
}
	print '</td>';
	print '</tr>';
	print '<tr class="liste_titre">';
				print img_picto('', 'company').$form->select_company(GETPOST('socid', 'int') ? GETPOST('socid', 'int') : ($object->socid ? $object->socid : -1), 'socid', '', $langs->trans("SelectThirdParty"));
			$filter = '(s.client=1 OR s.client=2 OR s.client=3)';
			$formquestion = array(array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter)));
	 * @param string 	$selected 			Preselected type
	 * @param string 	$htmlname 			Name of field in form
	 * @param string 	$filter 			Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
	 * @param string 	$showempty 			Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
	 * @param int 		$showtype 			Show third party type in combolist (customer, prospect or supplier)
	 * @param int 		$forcecombo 		Force to load all values and output a standard combobox (with no beautification)
	 * @param array 	$events 			Ajax event options to run on change. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param int 		$limit 				Maximum number of elements
	 * @param string 	$morecss 			Add more css styles to the SELECT component
	 * @param string 	$moreparam 			Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
	 * @param string 	$selected_input_value 	Value of preselected input text (for use with ajax)
	 * @param int 		$hidelabel 			Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after)
	 * @param array 	$ajaxoptions 		Options for ajax_autocompleter
	 * @param bool 		$multiple 			add [] in the name of element and add 'multiple' attribut (not working with ajax_autocompleter)
	 * @param array 	$excludeids 		Exclude IDs from the select combo
	 * @param int 		$showcode 			Show code
	 * @return string  		                HTML string with select box for thirdparty.
	 * @param string 	$selected 		Preselected type
	 * @param string 	$htmlname 		Name of field in form
	 * @param string 	$filter 		Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
	 * @param string 	$showempty 		Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
	 * @param int 		$showtype 		Show third party type in combolist (customer, prospect or supplier)
	 * @param int 		$forcecombo 	Force to use standard HTML select component without beautification
	 * @param array 	$events 		Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param string 	$filterkey 		Filter on key value
	 * @param int 		$outputmode 	0=HTML select string, 1=Array
	 * @param int 		$limit 			Limit number of answers
	 * @param string 	$morecss 		Add more css styles to the SELECT component
	 * @param string 	$moreparam 		Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
	 * @param bool 		$multiple 		add [] in the name of element and add 'multiple' attribut
	 * @param array 	$excludeids 	Exclude IDs from the select combo
	 * @param int 		$showcode 		Show code in list
	 * @return array|string            	HTML string with
				return 'SQLInjectionTryDetected';
		//$errormsg = '';
		//$filter = forgeSQLFromUniversalSearchCriteria($filter, $errormsg);

		dol_syslog(get_class($this)."::select_thirdparty_list", LOG_DEBUG);
	 * @param string 	$page 					Page
	 * @param string 	$selected 				Id preselected
	 * @param string 	$htmlname 				Name of HTML select
	 * @param string	$filter 				Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
	 * @param int 		$showempty 				Add an empty field
	 * @param int 		$showtype 				Show third party type in combolist (customer, prospect or supplier)
	 * @param int 		$forcecombo 			Force to use combo box
	 * @param array 	$events 				Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled')))
	 * @param int 		$nooutput 				No print output. Return it only.
	 * @param array 	$excludeids 			Exclude IDs from the select combo
	 * @param string 	$textifnothirdparty 	Text to show if no thirdparty
	 * @return    string                        HTML output or ''
	 * @param 	string 	$objectdesc 		ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]
	 * @param 	string 	$htmlname 			Name of HTML select component
	 * @param 	int 	$preselectedvalue 	Preselected value (ID of element)
	 * @param 	string 	$showempty 			''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
	 * @param 	string 	$searchkey 			Search criteria
	 * @param 	string 	$placeholder 		Place holder
	 * @param 	string 	$morecss 			More CSS
	 * @param 	string 	$moreparams 		More params provided to ajax call
	 * @param 	int 	$forcecombo 		Force to load all values and output a standard combobox (with no beautification)
	 * @param 	int 	$disabled 			1=Html component is disabled
	 * @param 	string 	$selected_input_value Value of preselected input text (for use with ajax)
	 * @return  string                      Return HTML string
	 * @see selectForFormsList(), select_thirdparty_list()
 * @param 	string		$filter		String with universal search string. Must be  (aaa:bbb:...) with
 * 									aaa is a field name (with alias or not) and
 * 									bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'.
			$filter = '(s.client = 1 OR s.client = 3) AND status=1';
			print $form->select_company($soc->id, 'socid', $filter, 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
		$filter = '(s.fournisseur=1 AND s.status=1)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company((empty($socid) ? '' : $socid), 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 maxwidth500 widthcentpercentminusxx');
		$filter = '(s.fournisseur=1)';
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter))
		$filter = 's.fournisseur=1';
		$morehtmlref .= $form->select_company($object->thirdparty->id, 'new_socid', $filter, '', 0, 0, array(), 0, 'minwidth300');
		$filter = '(s.fournisseur = 1 AND s.status = 1)';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(empty($societe->id) ? 0 : $societe->id, 'socid', $filter, 'SelectThirdParty', 1, 0, null, 0, 'minwidth175 widthcentpercentminusxx maxwidth500');
		$filter = '(client=1 OR client=3)';
		print img_picto('', 'company').$form->select_company($socid, 'socid', $filter, 1, 0, 0);
					$filter = 'fournisseur=1';
					print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company(GETPOST("id_fourn", 'alpha'), 'id_fourn', $filter, 'SelectThirdParty', 0, 0, $events);
		$filter = 's.client IN (1,2,3)';
		print img_picto('', 'company').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 0, 0, array(), 0, 'minwidth300');
$filter = 'fournisseur=1';
print $langs->trans('Supplier').' '.$form->select_company($fk_supplier, 'fk_supplier', $filter, 1);
		$filter = '';
			$filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
		$text = img_picto('', 'company').$form->select_company(GETPOST('socid', 'int'), 'socid', $filter, 'SelectThirdParty', 1, 0, array(), 0, 'minwidth300 widthcentpercentminusxx maxwidth500');
			array('type' => 'other', 'name' => 'socid', 'label' => $langs->trans("SelectThirdParty"), 'value' => $form->select_company(GETPOST('socid', 'int') > 0 ? GETPOST('socid', 'int') : $object->socid, 'socid', '', "None", 0, 0, null, 0, 'minwidth200 maxwidth250')),
			$filter = '';
				$filter = $conf->global->PROJECT_FILTER_FOR_THIRDPARTY_LIST;
			$text .= $form->select_company($object->thirdparty->id, 'socid', $filter, 'None', 1, 0, array(), 0, 'minwidth300');
 *       \brief      File to return Ajax response on third parties request. Search is done on name|name_alias|code_client|code_fournisseur
	if ($object->socid && $socid != $object->socid) {
		accessforbidden('Not allowed to access thirdparty id '.$id.' with an external user on id '.$socid);
	}
restrictedArea($user, 'societe', $object, '&societe');
top_httphead('application/json');
$return_arr = array();
// Define filter on text typed
$socid = GETPOST('newcompany');
if (!$socid) {
	$socid = GETPOST('socid', 'int');
}
if (!$socid) {
	$socid = GETPOST('id_fourn', 'int');
}
// Generate list of companies
if (! $socid) {
	echo json_encode(array('nom'=>'ErrorBadParameter', 'label'=>'ErrorBadParameter', 'key'=>'ErrorBadParameter', 'value'=>'ErrorBadParameter'));
	exit;
}

$sql = "SELECT s.rowid, s.nom, s.name_alias, s.code_client, s.code_fournisseur, s.address, s.zip, s.town, s.email, s.siren, s.siret, s.ape, s.idprof4, s.idprof5, s.idprof6, s.client, s.fournisseur, s.datec, s.logo";
if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
	$sql .= ", dictp.code as country_code";
}
$sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as dictp ON dictp.rowid = s.fk_pays";
}
$sql .= " WHERE s.entity IN (".getEntity('societe').")";
if ($socid) {
	$sql .= " AND (";
	// Add criteria on name/code
	if (!empty($conf->global->COMPANY_DONOTSEARCH_ANYWHERE)) {   // Can use index
		$sql .= "s.nom LIKE '".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.name_alias LIKE '".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.code_client LIKE '".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.code_fournisseur LIKE '".$db->escape($db->escapeforlike($socid))."%'";
	} else {
		$sql .= "s.nom LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.name_alias LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.code_client LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
		$sql .= " OR s.code_fournisseur LIKE '%".$db->escape($db->escapeforlike($socid))."%'";
	if (!empty($conf->global->SOCIETE_ALLOW_SEARCH_ON_ROWID)) {
		$sql .= " OR s.rowid = ".((int) $socid);
	$sql .= ")";
}
// Protection for external user access
if ($user->socid > 0) {
	$sql .= " AND s.rowid = ".((int) $user->socid);
}
//if (GETPOST("filter")) $sql.= " AND (".GETPOST("filter", "alpha").")"; // Add other filters
$sql .= " ORDER BY s.nom ASC";

//dol_syslog("ajaxcompanies", LOG_DEBUG);
$resql = $db->query($sql);
if ($resql) {
	while ($row = $db->fetch_array($resql)) {
		$label = '';
		if (!empty($conf->global->SOCIETE_ADD_REF_IN_LIST)) {
			if (($row['client']) && (!empty($row['code_client']))) {
				$label = $row['code_client'].' - ';
			if (($row['fournisseur']) && (!empty($row['code_fournisseur']))) {
				$label .= $row['code_fournisseur'].' - ';
			}
		}
		$label .= $row['nom'];
		if (!empty($conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST)) {
			$label .= ($row['address'] ? ' - '.$row['address'] : '').($row['zip'] ? ' - '.$row['zip'] : '').($row['town'] ? ' '.$row['town'] : '');
			if (!empty($row['country_code'])) {
				$label .= ', '.$langs->trans('Country'.$row['country_code']);
		if ($socid) {
			$label = preg_replace('/('.preg_quote($socid, '/').')/i', '<strong>$1</strong>', $label, 1);
		}
		$row_array['label'] = $label;

		$row_array['value'] = $row['nom'];
		$row_array['key'] = $row['rowid'];

		$row_array['name_alias'] = $row['name_alias'];
		$row_array['client'] = $row['client'];
		$row_array['fournisseur'] = $row['fournisseur'];
		$row_array['code_client'] = $row['code_client'];
		$row_array['code_fournisseur'] = $row['code_fournisseur'];
		$row_array['address'] = $row['address'];
		$row_array['zip'] = $row['zip'];
		$row_array['town'] = $row['town'];
		$row_array['email'] = $row['email'];
		$row_array['siren'] = $row['siren'];
		$row_array['siret'] = $row['siret'];
		$row_array['ape'] = $row['ape'];
		$row_array['idprof4'] = $row['idprof4'];
		$row_array['idprof5'] = $row['idprof5'];
		$row_array['idprof6'] = $row['idprof6'];
		$row_array['datec'] = $row['datec'];
		$row_array['logo'] = $row['logo'];

		array_push($return_arr, $row_array);

	echo json_encode($return_arr);
	echo json_encode(array('nom'=>'Error', 'label'=>'Error', 'key'=>'Error', 'value'=>'Error'));
 *       \brief      File to return Ajax response on thirdparty list request. Used by the combo list of thirdparties.
 *       			 Search done on name, name_alias, barcode, tva_intra, ...
$showtype = GETPOSTINT('showtype', 'alpha');
$showcode = GETPOSTINT('showcode', 'alpha');
top_httphead('application/json');


$db->close();
		print $form->widgetForTranslation("name", $object, $permissiontoadd, 'string', 'alpahnohtml', 'minwidth300');	// For some countries that need the company name in 2 languages
		// This implementation of the feature to search already existing company has been disabled. It must be implemented by keeping the "input text" and we must call the search ajax societe/ajax/ajaxcompanies.php
		// on a keydown of the input. We should show data about a duplicate found if we found less than 5 answers into a div under the input.
		$filter = 's.fournisseur=1';
		print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', $filter, 'SelectThirdParty', 0, 0, null, 0, 'minwidth300');
		$filter = 's.fournisseur=1';
				'value' => $form->select_company(GETPOST('socid', 'int'), 'socid', $filter))
$filter = '(s.client IN (1, 3) AND s.status = 1)';
print $form->select_company(getDolGlobalInt('CASHDESK_ID_THIRDPARTY'.$terminaltouse), 'socid', $filter, 1, 0, 0, array(), 0);