diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php
index 13332b5c277..e18e65e47a0 100644
--- a/htdocs/admin/modulehelp.php
+++ b/htdocs/admin/modulehelp.php
@@ -384,15 +384,16 @@ if ($mode == 'feature') {
$text .= '
';
$text .= '
'.$langs->trans("AddDataTables").': ';
- $sqlfiles = dol_dir_list(dol_buildpath($moduledir.'/sql/'), 'files', 0, 'llx.*\.sql', array('\.key\.sql', '\.sql\.back'));
+ $listofsqlfiles1 = dol_dir_list(DOL_DOCUMENT_ROOT.'/install/mysql/tables/', 'files', 0, 'llx.*-'.$moduledir.'\.sql', array('\.key\.sql', '\.sql\.back'));
+ $listofsqlfiles2 = dol_dir_list(dol_buildpath($moduledir.'/sql/'), 'files', 0, 'llx.*\.sql', array('\.key\.sql', '\.sql\.back'));
+ $sqlfiles = array_merge($listofsqlfiles1, $listofsqlfiles2);
+
if (count($sqlfiles) > 0) {
- $text .= $langs->trans("Yes").' (';
$i = 0;
foreach ($sqlfiles as $val) {
- $text .= ($i ? ', ' : '').preg_replace('/\.sql$/', '', preg_replace('/llx_/', '', $val['name']));
+ $text .= ($i ? ', ' : '').preg_replace('/\-'.$moduledir.'$/', '', preg_replace('/\.sql$/', '', preg_replace('/llx_/', '', $val['name'])));
$i++;
}
- $text .= ')';
} else {
$text .= $langs->trans("No");
}
@@ -415,7 +416,7 @@ if ($mode == 'feature') {
$text .= '
'.$langs->trans("AddData").': ';
$filedata = dol_buildpath($moduledir.'/sql/data.sql');
if (dol_is_file($filedata)) {
- $text .= $langs->trans("Yes").' ('.$moduledir.'/sql/data.sql)';
+ $text .= $langs->trans("Yes").' ('.$moduledir.'/sql/data.sql)';
} else {
$text .= $langs->trans("No");
}
diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php
index 1d24b058614..faff7ff5172 100644
--- a/htdocs/core/db/Database.interface.php
+++ b/htdocs/core/db/Database.interface.php
@@ -182,9 +182,18 @@ interface Database
*
* @param string $stringtoencode String to escape
* @return string String escaped
+ * @deprecated
*/
public function escapeunderscore($stringtoencode);
+ /**
+ * Escape a string to insert data into a like
+ *
+ * @param string $stringtoencode String to escape
+ * @return string String escaped
+ */
+ public function escapeforlike($stringtoencode);
+
/**
* Sanitize a string for SQL forging
*
diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php
index 1fe4ce77414..9393f10489f 100644
--- a/htdocs/core/db/mysqli.class.php
+++ b/htdocs/core/db/mysqli.class.php
@@ -479,12 +479,24 @@ class DoliDBMysqli extends DoliDB
*
* @param string $stringtoencode String to escape
* @return string String escaped
+ * @deprecated
*/
public function escapeunderscore($stringtoencode)
{
return str_replace('_', '\_', (string) $stringtoencode);
}
+ /**
+ * Escape a string to insert data into a like
+ *
+ * @param string $stringtoencode String to escape
+ * @return string String escaped
+ */
+ public function escapeforlike($stringtoencode)
+ {
+ return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
+ }
+
/**
* Return generic error code of last operation.
*
diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php
index d33affec476..0515a043fd1 100644
--- a/htdocs/core/db/pgsql.class.php
+++ b/htdocs/core/db/pgsql.class.php
@@ -726,10 +726,22 @@ class DoliDBPgsql extends DoliDB
*
* @param string $stringtoencode String to escape
* @return string String escaped
+ * @deprecated
*/
public function escapeunderscore($stringtoencode)
{
- return str_replace('_', '\_', $stringtoencode);
+ return str_replace('_', '\_', (string) $stringtoencode);
+ }
+
+ /**
+ * Escape a string to insert data into a like
+ *
+ * @param string $stringtoencode String to escape
+ * @return string String escaped
+ */
+ public function escapeforlike($stringtoencode)
+ {
+ return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
}
/**
diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php
index 8d0141e8ca6..e31eeffe457 100644
--- a/htdocs/core/db/sqlite3.class.php
+++ b/htdocs/core/db/sqlite3.class.php
@@ -654,10 +654,22 @@ class DoliDBSqlite3 extends DoliDB
*
* @param string $stringtoencode String to escape
* @return string String escaped
+ * @deprecated
*/
public function escapeunderscore($stringtoencode)
{
- return str_replace('_', '\_', $stringtoencode);
+ return str_replace('_', '\_', (string) $stringtoencode);
+ }
+
+ /**
+ * Escape a string to insert data into a like
+ *
+ * @param string $stringtoencode String to escape
+ * @return string String escaped
+ */
+ public function escapeforlike($stringtoencode)
+ {
+ return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
}
/**
diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php
index 18bd7226400..4b43230adda 100644
--- a/htdocs/core/lib/website.lib.php
+++ b/htdocs/core/lib/website.lib.php
@@ -996,11 +996,11 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25, $so
$sql .= " AND (";
$searchalgo = '';
if (preg_match('/meta/', $algo)) {
- $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'";
- $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeunderscore($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeunderscore($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeforlike($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeforlike($db->escape($searchstring))."%'";
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeforlike($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeforlike($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords
}
if (preg_match('/content/', $algo)) {
- $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'";
+ $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeforlike($db->escape($searchstring))."%'";
}
$sql .= $searchalgo;
if (is_array($otherfilters) && !empty($otherfilters['category'])) {
diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php
index 426a582c3f4..9f5a31109a8 100644
--- a/htdocs/core/modules/import/import_csv.modules.php
+++ b/htdocs/core/modules/import/import_csv.modules.php
@@ -835,8 +835,8 @@ class ImportCsv extends ModeleImports
$sqlSelect = "SELECT ".$fname." FROM ".$tablename;
$data = array_combine($listfields, $listvalues);
- $where = array();
- $filters = array();
+ $where = array(); // filters to forge SQL request
+ $filters = array(); // filters to forge output error message
foreach ($updatekeys as $key) {
$col = $objimport->array_import_updatekeys[0][$key];
$key = preg_replace('/^.*\./i', '', $key);
@@ -846,8 +846,12 @@ class ImportCsv extends ModeleImports
$socialnetwork = $tmp[1];
$jsondata = $data[$key];
$json = json_decode($jsondata);
- $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'";
- $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'";
+ $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork);
+ //var_dump($stringtosearch);
+ //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like)
+ $where[] = $key." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'";
+ $filters[] = $col." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'";
+ //var_dump($where[1]); // This provide a value for sql string inside a like
} else {
$where[] = $key.' = '.$data[$key];
$filters[] = $col.' = '.$data[$key];
diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php
index 6b2c02de197..3637ce105c1 100644
--- a/htdocs/core/modules/import/import_xlsx.modules.php
+++ b/htdocs/core/modules/import/import_xlsx.modules.php
@@ -892,8 +892,12 @@ class ImportXlsx extends ModeleImports
$socialnetwork = $tmp[1];
$jsondata = $data[$key];
$json = json_decode($jsondata);
- $where[] = $key." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'";
- $filters[] = $col." LIKE '%\"".$socialnetwork."\":\"".$this->db->escape($json->$socialnetwork)."\"%'";
+ $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork);
+ //var_dump($stringtosearch);
+ //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like)
+ $where[] = $key." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'";
+ $filters[] = $col." LIKE '%".$this->db->escapeforlike($this->db->escape($stringtosearch))."%'";
+ //var_dump($where[1]); // This provide a value for sql string inside a like
} else {
$where[] = $key.' = '.$data[$key];
$filters[] = $col.' = '.$data[$key];
diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php
index 5e30978693e..737d2831db6 100644
--- a/htdocs/core/modules/modAccounting.class.php
+++ b/htdocs/core/modules/modAccounting.class.php
@@ -272,6 +272,24 @@ class modAccounting extends DolibarrModules
//--------
$r = 0;
+ // Chart of accounts
+ $r++;
+ $this->import_code[$r] = $this->rights_class.'_'.$r;
+ $this->import_label[$r] = "Chartofaccounts"; // Translation key
+ $this->import_icon[$r] = $this->picto;
+ $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
+ $this->import_tables_array[$r] = array('aa'=>MAIN_DB_PREFIX.'accounting_account');
+ $this->import_tables_creator_array[$r] = array('aa'=>'fk_user_author'); // Fields to store import user id
+ $this->import_fields_array[$r] = array('aa.fk_pcg_version'=>"Chartofaccounts*", 'aa.account_number'=>"AccountAccounting*", 'aa.label'=>"Label*", 'aa.account_parent'=>"Accountparent", "aa.fk_accounting_category"=>"AccountingCategory", "aa.pcg_type"=>"Pcgtype*", 'aa.active'=>'Status*', 'aa.datec'=>"DateCreation");
+ $this->import_regex_array[$r] = array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system', 'aa.account_number'=>'^.{1,32}$', 'aa.label'=>'^.{1,255}$', 'aa.account_parent'=>'^.{0,32}$', 'aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category', 'aa.pcg_type'=>'^.{1,20}$', 'aa.active'=>'^0|1$', 'aa.datec'=>'^\d{4}-\d{2}-\d{2}$');
+ $this->import_convertvalue_array[$r] = array(
+ 'aa.account_number'=>array('rule'=>'accountingaccount'),
+ 'aa.account_parent'=>array('rule'=>'fetchidfromref', 'classfile'=>'/accountancy/class/accountingaccount.class.php', 'class'=>'AccountingAccount', 'method'=>'fetch', 'element'=>'AccountingAccount'),
+ 'aa.fk_accounting_category'=>array('rule'=>'fetchidfromcodeorlabel', 'classfile'=>'/accountancy/class/accountancycategory.class.php', 'class'=>'AccountancyCategory', 'method'=>'fetch', 'dict'=>'DictionaryAccountancyCategory'),
+ );
+ $this->import_examplevalues_array[$r] = array('aa.fk_pcg_version'=>"PCG99-ABREGE", 'aa.account_number'=>"707", 'aa.label'=>"Product sales", 'aa.account_parent'=>"ref:7 or id:1407", "aa.fk_accounting_category"=>"", "aa.pcg_type"=>"PROD", 'aa.active'=>'1', 'aa.datec'=>"2017-04-28");
+ $this->import_updatekeys_array[$r] = array('aa.fk_pcg_version'=>'Chartofaccounts', 'aa.account_number'=>'AccountAccounting');
+
// General ledger
$r++;
$this->import_code[$r] = $this->rights_class.'_'.$r;
@@ -393,23 +411,5 @@ class modAccounting extends DolibarrModules
'b.multicurrency_amount'=>"90 (Necessary if devise is different than EUR)",
'b.multicurrency_code'=>"US (Necessary if devise is different than EUR)",
);
-
- // Chart of accounts
- $r++;
- $this->import_code[$r] = $this->rights_class.'_'.$r;
- $this->import_label[$r] = "Chartofaccounts"; // Translation key
- $this->import_icon[$r] = $this->picto;
- $this->import_entities_array[$r] = array(); // We define here only fields that use another icon that the one defined into import_icon
- $this->import_tables_array[$r] = array('aa'=>MAIN_DB_PREFIX.'accounting_account');
- $this->import_tables_creator_array[$r] = array('aa'=>'fk_user_author'); // Fields to store import user id
- $this->import_fields_array[$r] = array('aa.fk_pcg_version'=>"Chartofaccounts*", 'aa.account_number'=>"AccountAccounting*", 'aa.label'=>"Label*", 'aa.account_parent'=>"Accountparent", "aa.fk_accounting_category"=>"AccountingCategory", "aa.pcg_type"=>"Pcgtype*", 'aa.active'=>'Status*', 'aa.datec'=>"DateCreation");
- $this->import_regex_array[$r] = array('aa.fk_pcg_version'=>'pcg_version@'.MAIN_DB_PREFIX.'accounting_system', 'aa.account_number'=>'^.{1,32}$', 'aa.label'=>'^.{1,255}$', 'aa.account_parent'=>'^.{0,32}$', 'aa.fk_accounting_category'=>'rowid@'.MAIN_DB_PREFIX.'c_accounting_category', 'aa.pcg_type'=>'^.{1,20}$', 'aa.active'=>'^0|1$', 'aa.datec'=>'^\d{4}-\d{2}-\d{2}$');
- $this->import_convertvalue_array[$r] = array(
- 'aa.account_number'=>array('rule'=>'accountingaccount'),
- 'aa.account_parent'=>array('rule'=>'fetchidfromref', 'classfile'=>'/accountancy/class/accountingaccount.class.php', 'class'=>'AccountingAccount', 'method'=>'fetch', 'element'=>'AccountingAccount'),
- 'aa.fk_accounting_category'=>array('rule'=>'fetchidfromcodeorlabel', 'classfile'=>'/accountancy/class/accountancycategory.class.php', 'class'=>'AccountancyCategory', 'method'=>'fetch', 'dict'=>'DictionaryAccountancyCategory'),
- );
- $this->import_examplevalues_array[$r] = array('aa.fk_pcg_version'=>"PCG99-ABREGE", 'aa.account_number'=>"707", 'aa.label'=>"Product sales", 'aa.account_parent'=>"ref:7 or id:1407", "aa.fk_accounting_category"=>"", "aa.pcg_type"=>"PROD", 'aa.active'=>'1', 'aa.datec'=>"2017-04-28");
- $this->import_updatekeys_array[$r] = array('aa.fk_pcg_version'=>'Chartofaccounts', 'aa.account_number'=>'AccountAccounting');
}
}
diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php
index 5f898584ba4..5bc5c7da6cf 100644
--- a/htdocs/core/modules/modSociete.class.php
+++ b/htdocs/core/modules/modSociete.class.php
@@ -747,7 +747,7 @@ class modSociete extends DolibarrModules
's.fk_departement' => "StateCode",
's.fk_pays' => "CountryCode",
's.birthday' => "DateOfBirth",
- 's.poste' => "Role",
+ 's.poste' => "PostOrFunction",
's.phone' => "Phone",
's.phone_perso' => "PhonePerso",
's.phone_mobile' => "PhoneMobile",
diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php
index 082e45e4f43..785af37fc94 100644
--- a/htdocs/debugbar/class/TraceableDB.php
+++ b/htdocs/debugbar/class/TraceableDB.php
@@ -255,12 +255,24 @@ class TraceableDB extends DoliDB
*
* @param string $stringtoencode String to escape
* @return string String escaped
+ * @deprecated
*/
public function escapeunderscore($stringtoencode)
{
return $this->db->escapeunderscore($stringtoencode);
}
+ /**
+ * Escape a string to insert data into a like
+ *
+ * @param string $stringtoencode String to escape
+ * @return string String escaped
+ */
+ public function escapeforlike($stringtoencode)
+ {
+ return str_replace(array('_', '\\', '%'), array('\_', '\\\\', '\%'), (string) $stringtoencode);
+ }
+
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Get last ID after an insert INSERT
diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php
index 2c85007c086..ab5223697e6 100644
--- a/htdocs/imports/import.php
+++ b/htdocs/imports/import.php
@@ -235,6 +235,7 @@ if ($action == 'add_import_model') {
$result = $objimport->create($user);
if ($result >= 0) {
setEventMessages($langs->trans("ImportModelSaved", $objimport->model_name), null, 'mesgs');
+ $import_name = '';
} else {
$langs->load("errors");
if ($objimport->errno == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
@@ -1286,7 +1287,7 @@ if ($step == 4 && $datatoimport) {
print '';
// Lines for remark
- print '