diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index eeb2a7fbbf9..30b5af06b76 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -6704,7 +6704,7 @@ abstract class CommonObject { global $langs, $user; - if (getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED')) { + if (getDolGlobalString('MAIN_EXTRAFIELDS_DISABLED') || empty($this->array_options)) { return 0; } @@ -6714,349 +6714,318 @@ abstract class CommonObject $error = 0; - if (!empty($this->array_options)) { - // Check parameters - $langs->load('admin'); - require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; - $extrafields = new ExtraFields($this->db); - $target_extrafields = $extrafields->fetch_name_optionals_label($this->table_element); + // Check parameters + $langs->load('admin'); + require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + $extrafields = new ExtraFields($this->db); + $target_extrafields = $extrafields->fetch_name_optionals_label($this->table_element); - // Eliminate copied source object extra fields that do not exist in target object - $new_array_options = array(); - foreach ($this->array_options as $key => $value) { - if (in_array(substr($key, 8), array_keys($target_extrafields))) { // We remove the 'options_' from $key for test - $new_array_options[$key] = $value; - } elseif (in_array($key, array_keys($target_extrafields))) { // We test on $key that does not contain the 'options_' prefix - $new_array_options['options_'.$key] = $value; + // Eliminate copied source object extra fields that do not exist in target object + $new_array_options = array(); + foreach ($this->array_options as $key => $value) { + if (in_array(substr($key, 8), array_keys($target_extrafields))) { // We remove the 'options_' from $key for test + $new_array_options[$key] = $value; + } elseif (in_array($key, array_keys($target_extrafields))) { // We test on $key that does not contain the 'options_' prefix + $new_array_options['options_'.$key] = $value; + } + } + + foreach ($new_array_options as $key => $value) { + $attributeKey = substr($key, 8); // Remove 'options_' prefix + $attributeType = $extrafields->attributes[$this->table_element]['type'][$attributeKey]; + $attributeLabel = $langs->transnoentities($extrafields->attributes[$this->table_element]['label'][$attributeKey]); + $attributeParam = $extrafields->attributes[$this->table_element]['param'][$attributeKey]; + $attributeRequired = $extrafields->attributes[$this->table_element]['required'][$attributeKey]; + $attributeUnique = $extrafields->attributes[$this->table_element]['unique'][$attributeKey]; + $attrfieldcomputed = $extrafields->attributes[$this->table_element]['computed'][$attributeKey]; + + // If we clone, we have to clean unique extrafields to prevent duplicates. + // This behaviour can be prevented by external code by changing $this->context['createfromclone'] value in createFrom hook + if (!empty($this->context['createfromclone']) && $this->context['createfromclone'] == 'createfromclone' && !empty($attributeUnique)) { + $new_array_options[$key] = null; + } + + // If we create product combination, we have to clean unique extrafields to prevent duplicates. + // This behaviour can be prevented by external code by changing $this->context['createproductcombination'] value in hook + if (!empty($this->context['createproductcombination']) && $this->context['createproductcombination'] == 'createproductcombination' && !empty($attributeUnique)) { + $new_array_options[$key] = null; + } + + // Similar code than into insertExtraFields + if ($attributeRequired) { + $v = $this->array_options[$key]; + if (ExtraFields::isEmptyValue($v, $attributeType)) { + $langs->load("errors"); + dol_syslog("Mandatory field '".$key."' is empty during create and set to required into definition of extrafields"); + $this->errors[] = $langs->trans('ErrorFieldRequired', $attributeLabel); + return -1; } } - foreach ($new_array_options as $key => $value) { - $attributeKey = substr($key, 8); // Remove 'options_' prefix - $attributeType = $extrafields->attributes[$this->table_element]['type'][$attributeKey]; - $attributeLabel = $langs->transnoentities($extrafields->attributes[$this->table_element]['label'][$attributeKey]); - $attributeParam = $extrafields->attributes[$this->table_element]['param'][$attributeKey]; - $attributeRequired = $extrafields->attributes[$this->table_element]['required'][$attributeKey]; - $attributeUnique = $extrafields->attributes[$this->table_element]['unique'][$attributeKey]; - $attrfieldcomputed = $extrafields->attributes[$this->table_element]['computed'][$attributeKey]; - - // If we clone, we have to clean unique extrafields to prevent duplicates. - // This behaviour can be prevented by external code by changing $this->context['createfromclone'] value in createFrom hook - if (!empty($this->context['createfromclone']) && $this->context['createfromclone'] == 'createfromclone' && !empty($attributeUnique)) { + if (!empty($attrfieldcomputed)) { + if (getDolGlobalString('MAIN_STORE_COMPUTED_EXTRAFIELDS')) { + $value = dol_eval($attrfieldcomputed, 1, 0, '2'); + dol_syslog($langs->trans("Extrafieldcomputed")." on ".$attributeLabel."(".$value.")", LOG_DEBUG); + $new_array_options[$key] = $value; + } else { $new_array_options[$key] = null; } + } - // If we create product combination, we have to clean unique extrafields to prevent duplicates. - // This behaviour can be prevented by external code by changing $this->context['createproductcombination'] value in hook - if (!empty($this->context['createproductcombination']) && $this->context['createproductcombination'] == 'createproductcombination' && !empty($attributeUnique)) { - $new_array_options[$key] = null; - } - - // Similar code than into insertExtraFields - if ($attributeRequired) { - $v = $this->array_options[$key]; - if (ExtraFields::isEmptyValue($v, $attributeType)) { - $langs->load("errors"); - dol_syslog("Mandatory field '".$key."' is empty during create and set to required into definition of extrafields"); - $this->errors[] = $langs->trans('ErrorFieldRequired', $attributeLabel); + switch ($attributeType) { + case 'int': + if (!is_numeric($value) && $value != '') { + $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; - } - } - - //dol_syslog("attributeLabel=".$attributeLabel, LOG_DEBUG); - //dol_syslog("attributeType=".$attributeType, LOG_DEBUG); - - if (!empty($attrfieldcomputed)) { - if (getDolGlobalString('MAIN_STORE_COMPUTED_EXTRAFIELDS')) { - $value = dol_eval($attrfieldcomputed, 1, 0, '2'); - dol_syslog($langs->trans("Extrafieldcomputed")." on ".$attributeLabel."(".$value.")", LOG_DEBUG); - $new_array_options[$key] = $value; - } else { + } elseif ($value == '') { $new_array_options[$key] = null; } - } - - switch ($attributeType) { - case 'int': - if (!is_numeric($value) && $value != '') { - $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); - return -1; - } elseif ($value == '') { - $new_array_options[$key] = null; - } - break; - case 'price': - case 'double': - $value = price2num($value); - if (!is_numeric($value) && $value != '') { - dol_syslog($langs->trans("ExtraFieldHasWrongValue")." for ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); - $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); - return -1; - } elseif ($value == '') { - $value = null; - } - //dol_syslog("double value"." on ".$attributeLabel."(".$value." is '".$attributeType."')", LOG_DEBUG); - $new_array_options[$key] = $value; - break; - /*case 'select': // Not required, we chose value='0' for undefined values - if ($value=='-1') - { - $this->array_options[$key] = null; - } - break;*/ - case 'password': - $algo = ''; - if ($this->array_options[$key] != '' && is_array($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options'])) { - // If there is an encryption choice, we use it to encrypt data before insert - $tmparrays = array_keys($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options']); - $algo = reset($tmparrays); - if ($algo != '') { - //global $action; // $action may be 'create', 'update', 'update_extras'... - //var_dump($action); - //var_dump($this->oldcopy);exit; - if (is_object($this->oldcopy)) { // If this->oldcopy is not defined, we can't know if we change attribute or not, so we must keep value - //var_dump('algo='.$algo.' '.$this->oldcopy->array_options[$key].' -> '.$this->array_options[$key]); - if (isset($this->oldcopy->array_options[$key]) && $this->array_options[$key] == $this->oldcopy->array_options[$key]) { - // If old value encrypted in database is same than submitted new value, it means we don't change it, so we don't update. - if ($algo == 'dolcrypt') { // dolibarr reversible encryption - if (!preg_match('/^dolcrypt:/', $this->array_options[$key])) { - $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master - } else { - $new_array_options[$key] = $this->array_options[$key]; // Value is kept - } + break; + case 'price': + case 'double': + $value = price2num($value); + if (!is_numeric($value) && $value != '') { + dol_syslog($langs->trans("ExtraFieldHasWrongValue")." for ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); + $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); + return -1; + } elseif ($value == '') { + $value = null; + } + //dol_syslog("double value"." on ".$attributeLabel."(".$value." is '".$attributeType."')", LOG_DEBUG); + $new_array_options[$key] = $value; + break; + /*case 'select': // Not required, we chose value='0' for undefined values + if ($value=='-1') + { + $this->array_options[$key] = null; + } + break;*/ + case 'password': + $algo = ''; + if ($this->array_options[$key] != '' && is_array($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options'])) { + // If there is an encryption choice, we use it to encrypt data before insert + $tmparrays = array_keys($extrafields->attributes[$this->table_element]['param'][$attributeKey]['options']); + $algo = reset($tmparrays); + if ($algo != '') { + //global $action; // $action may be 'create', 'update', 'update_extras'... + //var_dump($action); + //var_dump($this->oldcopy);exit; + if (is_object($this->oldcopy)) { // If this->oldcopy is not defined, we can't know if we change attribute or not, so we must keep value + //var_dump('algo='.$algo.' '.$this->oldcopy->array_options[$key].' -> '.$this->array_options[$key]); + if (isset($this->oldcopy->array_options[$key]) && $this->array_options[$key] == $this->oldcopy->array_options[$key]) { + // If old value encrypted in database is same than submitted new value, it means we don't change it, so we don't update. + if ($algo == 'dolcrypt') { // dolibarr reversible encryption + if (!preg_match('/^dolcrypt:/', $this->array_options[$key])) { + $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master } else { $new_array_options[$key] = $this->array_options[$key]; // Value is kept } } else { - // If value has changed - if ($algo == 'dolcrypt') { // dolibarr reversible encryption - if (!preg_match('/^dolcrypt:/', $this->array_options[$key])) { - $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master - } else { - $new_array_options[$key] = $this->array_options[$key]; // Value is kept - } - } else { - $new_array_options[$key] = dol_hash($this->array_options[$key], $algo); - } + $new_array_options[$key] = $this->array_options[$key]; // Value is kept } } else { - //var_dump('jjj'.$algo.' '.$this->oldcopy->array_options[$key].' -> '.$this->array_options[$key]); - // If this->oldcopy is not defined, we can't know if we change attribute or not, so we must keep value - if ($algo == 'dolcrypt' && !preg_match('/^dolcrypt:/', $this->array_options[$key])) { // dolibarr reversible encryption - $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master + // If value has changed + if ($algo == 'dolcrypt') { // dolibarr reversible encryption + if (!preg_match('/^dolcrypt:/', $this->array_options[$key])) { + $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master + } else { + $new_array_options[$key] = $this->array_options[$key]; // Value is kept + } } else { - $new_array_options[$key] = $this->array_options[$key]; // Value is kept + $new_array_options[$key] = dol_hash($this->array_options[$key], $algo); } } } else { - // No encryption - $new_array_options[$key] = $this->array_options[$key]; // Value is kept + //var_dump('jjj'.$algo.' '.$this->oldcopy->array_options[$key].' -> '.$this->array_options[$key]); + // If this->oldcopy is not defined, we can't know if we change attribute or not, so we must keep value + if ($algo == 'dolcrypt' && !preg_match('/^dolcrypt:/', $this->array_options[$key])) { // dolibarr reversible encryption + $new_array_options[$key] = dolEncrypt($this->array_options[$key]); // warning, must be called when on the master + } else { + $new_array_options[$key] = $this->array_options[$key]; // Value is kept + } } - } else { // Common usage + } else { + // No encryption $new_array_options[$key] = $this->array_options[$key]; // Value is kept } - break; - case 'date': - case 'datetime': - // If data is a string instead of a timestamp, we convert it - if (!is_numeric($this->array_options[$key]) || $this->array_options[$key] != intval($this->array_options[$key])) { - $this->array_options[$key] = strtotime($this->array_options[$key]); - } - $new_array_options[$key] = $this->db->idate($this->array_options[$key]); - break; - case 'datetimegmt': - // If data is a string instead of a timestamp, we convert it - if (!is_numeric($this->array_options[$key]) || $this->array_options[$key] != intval($this->array_options[$key])) { - $this->array_options[$key] = strtotime($this->array_options[$key]); - } - $new_array_options[$key] = $this->db->idate($this->array_options[$key], 'gmt'); - break; - case 'link': - $param_list = array_keys($attributeParam['options']); - // 0 : ObjectName - // 1 : classPath - $InfoFieldList = explode(":", $param_list[0]); - dol_include_once($InfoFieldList[1]); - if ($InfoFieldList[0] && class_exists($InfoFieldList[0])) { - if ($value == '-1') { // -1 is key for no defined in combo list of objects - $new_array_options[$key] = ''; - } elseif ($value) { - $object = new $InfoFieldList[0]($this->db); - '@phan-var-force CommonObject $object'; + } else { // Common usage + $new_array_options[$key] = $this->array_options[$key]; // Value is kept + } + break; + case 'date': + case 'datetime': + // If data is a string instead of a timestamp, we convert it + if (!is_numeric($this->array_options[$key]) || $this->array_options[$key] != intval($this->array_options[$key])) { + $this->array_options[$key] = strtotime($this->array_options[$key]); + } + $new_array_options[$key] = $this->db->idate($this->array_options[$key]); + break; + case 'datetimegmt': + // If data is a string instead of a timestamp, we convert it + if (!is_numeric($this->array_options[$key]) || $this->array_options[$key] != intval($this->array_options[$key])) { + $this->array_options[$key] = strtotime($this->array_options[$key]); + } + $new_array_options[$key] = $this->db->idate($this->array_options[$key], 'gmt'); + break; + case 'link': + $param_list = array_keys($attributeParam['options']); + // 0 : ObjectName + // 1 : classPath + $InfoFieldList = explode(":", $param_list[0]); + dol_include_once($InfoFieldList[1]); + if ($InfoFieldList[0] && class_exists($InfoFieldList[0])) { + if ($value == '-1') { // -1 is key for no defined in combo list of objects + $new_array_options[$key] = ''; + } elseif ($value) { + $object = new $InfoFieldList[0]($this->db); + '@phan-var-force CommonObject $object'; - $objectId = 0; + $objectId = 0; - $sqlFetchObject = "SELECT rowid FROM ".$this->db->prefix().$object->table_element; - if (is_numeric($value)) { - $sqlFetchObject .= " WHERE rowid = " . (int) $value; - } else { - $sqlFetchObject .= " WHERE ref = '" . $this->db->escape($value) . "'"; - } - - $obj = $this->db->getRow($sqlFetchObject); - - if ($obj !== false) { - $objectId = $obj->rowid; - $res = 1; - } else { - $res = -1; - } - - if ($res > 0) { - $new_array_options[$key] = $objectId; - } else { - $this->error = "Id/Ref '".$value."' for object '".$object->element."' not found"; - return -1; - } + $sqlFetchObject = "SELECT rowid FROM ".$this->db->prefix().$object->table_element; + if (is_numeric($value)) { + $sqlFetchObject .= " WHERE rowid = " . (int) $value; + } else { + $sqlFetchObject .= " WHERE ref = '" . $this->db->escape($value) . "'"; + } + + $obj = $this->db->getRow($sqlFetchObject); + + if ($obj !== false) { + $objectId = $obj->rowid; + $res = 1; + } else { + $res = -1; + } + + if ($res > 0) { + $new_array_options[$key] = $objectId; + } else { + $this->error = "Id/Ref '".$value."' for object '".$object->element."' not found"; + return -1; } - } else { - dol_syslog('Error bad setup of extrafield', LOG_WARNING); } - break; - case 'checkbox': - case 'chkbxlst': - if (is_array($this->array_options[$key])) { - $new_array_options[$key] = implode(',', $this->array_options[$key]); - } else { - $new_array_options[$key] = $this->array_options[$key]; - } - break; + } else { + dol_syslog('Error bad setup of extrafield', LOG_WARNING); + } + break; + case 'checkbox': + case 'chkbxlst': + if (is_array($this->array_options[$key])) { + $new_array_options[$key] = implode(',', $this->array_options[$key]); + } else { + $new_array_options[$key] = $this->array_options[$key]; + } + break; + } + } + + $sqlColumnValues = ['fk_object' => (int) $this->id]; // key-value pairs for the SQL INSERT or UPDATE query + + foreach ($new_array_options as $key => $newValue) { + $attributeKey = substr($key, 8); // Remove 'options_' prefix + $attributeType = $extrafields->attributes[$this->table_element]['type'][$attributeKey]; + if ($attributeType === 'separate') { + // separator extrafields don't have data per object so they don't have a comlumn in the database + continue; + } + $geoDataType = ExtraFields::$geoDataTypes[$attributeType] ?? null; + // Add field of attribute + if (! $geoDataType) { + // not a geodata type + if ($newValue != '') { + $sqlColumnValues[$attributeKey] = "'".$this->db->escape($newValue)."'"; + } else { + $sqlColumnValues[$attributeKey] = 'null'; } + continue; + } + if (empty($newValue)) { + $sqlColumnValues[$attributeKey] = 'null'; + continue; + } + if (preg_match('/error/i', $newValue)) { + dol_syslog( + 'Bad syntax string for '.$geoDataType['shortname'].' '.$newValue.' to generate SQL request', + LOG_WARNING + ); + $sqlColumnValues[$attributeKey] = 'null'; + continue; } - $this->db->begin(); + // Geodata type: Text must be a WKT string. Examples: + // - point => "POINT(15 20)" + // - multipts => "MULTIPOINT(0 0, 20 20, 60 60)" + // - linestrg => "LINESTRING(0 0, 10 10, 20 25, 50 60)" + // - polygon => "POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))" + $sqlColumnValues[$key] = $geoDataType['ST_Function']."('".$this->db->escape($newValue)."')"; + } - $table_element = $this->table_element; - if ($table_element == 'categorie') { - $table_element = 'categories'; // For compatibility - } + $this->db->begin(); - dol_syslog(get_class($this)."::insertExtraFields delete then insert", LOG_DEBUG); + $table_element = $this->table_element; + if ($table_element == 'categorie') { + $table_element = 'categories'; // For compatibility + } + $extrafieldsTable = $this->db->prefix() . $table_element . '_extrafields'; - $sql_del = "DELETE FROM ".$this->db->prefix().$table_element."_extrafields WHERE fk_object = ".((int) $this->id); - $this->db->query($sql_del); + dol_syslog(get_class($this)."::insertExtraFields delete then insert", LOG_DEBUG); - $sql = "INSERT INTO ".$this->db->prefix().$table_element."_extrafields (fk_object"; - foreach ($new_array_options as $key => $value) { - $attributeKey = substr($key, 8); // Remove 'options_' prefix - // Add field of attribute - if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] != 'separate') { // Only for other type than separator - $sql .= ",".$attributeKey; - } - } + // if the extrafields row already exists for the object, we update it + if ($this->db->getRow("SELECT 1 FROM {$extrafieldsTable} WHERE fk_object = ".((int) $this->id))) { + array_shift($sqlColumnValues); // drop the 'fk_object' column because its value won't change + $sqlColumnValueString = implode( + ',', + /** + * @param string $key + * @return string + */ + array_map(function ($key) use ($sqlColumnValues) { + return "{$key} = {$sqlColumnValues[$key]}"; + }, array_keys($sqlColumnValues)) + ); + $sql = "UPDATE {$extrafieldsTable} SET {$sqlColumnValueString} WHERE fk_object = ".((int) $this->id); + } else { // We must insert a default value for fields for other entities that are mandatory to avoid not null error - if (!empty($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities']) && is_array($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'])) { - foreach ($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'] as $tmpkey => $tmpval) { - if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) { // If field not already added previously - $sql .= ",".$tmpkey; - } + $extrafieldsRequiredOnOtherEntities = $extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'] ?? array(); + foreach ($extrafieldsRequiredOnOtherEntities as $key => $extrafieldType) { + if (isset($sqlColumnValues[$key])) { + // extrafield value already provided: no need to add it + continue; + } + // default value: empty string, except for 'int', 'double' and 'price' + $sqlColumnValues[$key] = "''"; + if (in_array($extrafieldType, array('int', 'double', 'price'))) { + $sqlColumnValues[$key] = 0; } } - $sql .= ") VALUES (".$this->id; + $sqlColumns = implode(',', array_keys($sqlColumnValues)); + $sqlValues = implode(',', array_values($sqlColumnValues)); + $sql = "INSERT INTO {$extrafieldsTable} ({$sqlColumns}) VALUES ({$sqlValues})"; + } - foreach ($new_array_options as $key => $value) { - $attributeKey = substr($key, 8); // Remove 'options_' prefix - // Add field of attribute - if (!in_array($extrafields->attributes[$this->table_element]['type'][$attributeKey], ['separate', 'point', 'multipts', 'linestrg', 'polygon'])) { // Only for other type than separator) - if ($new_array_options[$key] != '' || $new_array_options[$key] == '0') { - $sql .= ",'".$this->db->escape($new_array_options[$key])."'"; - } else { - $sql .= ",null"; - } - } - if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'point') { // for point type - if (!empty($new_array_options[$key])) { - if (!preg_match('/error/i', $new_array_options[$key])) { - // Text must be a WKT string, so "POINT(15 20)" - $sql .= ",ST_PointFromText('".$this->db->escape($new_array_options[$key])."')"; - } else { - dol_syslog("Bad syntax string for point ".$new_array_options[$key]." to generate SQL request", LOG_WARNING); - $sql .= ",null"; - } - } else { - $sql .= ",null"; - } - } - if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'multipts') { // for point type - if (!empty($new_array_options[$key])) { - if (!preg_match('/error/i', $new_array_options[$key])) { - // Text must be a WKT string, so "MULTIPOINT(0 0, 20 20, 60 60)" - $sql .= ",ST_MultiPointFromText('".$this->db->escape($new_array_options[$key])."')"; - } else { - dol_syslog("Bad syntax string for multipoint ".$new_array_options[$key]." to generate SQL request", LOG_WARNING); - $sql .= ",null"; - } - } else { - $sql .= ",null"; - } - } - if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'linestrg') { // for linestring type - if (!empty($new_array_options[$key])) { - if (!preg_match('/error/i', $new_array_options[$key])) { - // Text must be a WKT string, so "LINESTRING(0 0, 10 10, 20 25, 50 60)" - $sql .= ",ST_LineFromText('".$this->db->escape($new_array_options[$key])."')"; - } else { - dol_syslog("Bad syntax string for line ".$new_array_options[$key]." to generate SQL request", LOG_WARNING); - $sql .= ",null"; - } - } else { - $sql .= ",null"; - } - } - if ($extrafields->attributes[$this->table_element]['type'][$attributeKey] == 'polygon') { // for polygon type - if (!empty($new_array_options[$key])) { - if (!preg_match('/error/i', $new_array_options[$key])) { - // Text must be a WKT string, so "POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))" - $sql .= ",ST_PolyFromText('".$this->db->escape($new_array_options[$key])."')"; - } else { - dol_syslog("Bad syntax string for polygon ".$new_array_options[$key]." to generate SQL request", LOG_WARNING); - $sql .= ",null"; - } - } else { - $sql .= ",null"; - } - } - } - // We must insert a default value for fields for other entities that are mandatory to avoid not null error - if (!empty($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities']) && is_array($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'])) { - foreach ($extrafields->attributes[$this->table_element]['mandatoryfieldsofotherentities'] as $tmpkey => $tmpval) { - if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) { // If field not already added previously - if (in_array($tmpval, array('int', 'double', 'price'))) { - $sql .= ", 0"; - } else { - $sql .= ", ''"; - } - } - } - } + $resql = $this->db->query($sql); + if (!$resql) { + $this->error = $this->db->lasterror(); + $error++; + } - $sql .= ")"; - - $resql = $this->db->query($sql); - if (!$resql) { - $this->error = $this->db->lasterror(); + if (!$error && $trigger) { + // Call trigger + $this->context = array('extrafieldaddupdate' => 1); + $result = $this->call_trigger($trigger, $userused); + if ($result < 0) { $error++; } + // End call trigger + } - if (!$error && $trigger) { - // Call trigger - $this->context = array('extrafieldaddupdate' => 1); - $result = $this->call_trigger($trigger, $userused); - if ($result < 0) { - $error++; - } - // End call trigger - } - - if ($error) { - $this->db->rollback(); - return -1; - } else { - $this->db->commit(); - return 1; - } + if ($error) { + $this->db->rollback(); + return -1; } else { - return 0; + $this->db->commit(); + return 1; } } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index d61eaaff2b3..a5908ae8f51 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -107,6 +107,26 @@ class ExtraFields 'stars' => 'ExtrafieldStars', ); + /** @var array> $geoDataTypes */ + public static $geoDataTypes = array( + 'point' => array( + 'ST_Function' => 'ST_PointFromText', + 'shortname' => 'point' + ), + 'multipts' => array( + 'ST_Function' => 'ST_MultiPointFromText', + 'shortname' => 'multipoint' + ), + 'linestrg' => array( + 'ST_Function' => 'ST_LineFromText', + 'shortname' => 'line' + ), + 'polygon' => array( + 'ST_Function' => 'ST_PolyFromText', + 'shortname' => 'polygon' + ) + ); + /** * Constructor *