Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW: API setup update extrafields from name, elementtype and json #29273

Merged
merged 15 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions htdocs/api/class/api_setup.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,91 @@ public function deleteExtrafieldsFromNames($attrname, $elementtype)
);
}

/**
* Update Extrafield object
*
* @param string $attrname extrafield attrname
* @param string $elementtype extrafield elementtype
* @param array $request_data Request datas
* @return int ID of extrafield
*
* @url PUT extrafields/{elementtype}/{attrname}
*
* @suppress PhanPluginUnknownArrayMethodParamType Luracast limitation
*
*/
public function updateExtrafields($attrname, $elementtype, $request_data = null)
{
if (!DolibarrApiAccess::$user->admin) {
throw new RestException(403, 'Only an admin user can create an extrafield');
}

$extrafields = new ExtraFields($this->db);

$result = $extrafields->fetch_name_optionals_label($elementtype, false, $attrname);
if (!$result) {
throw new RestException(404, 'Extrafield not found from attrname and elementtype');
}

foreach ($request_data as $field => $value) {
$extrafields->$field = $this->_checkValForAPI($field, $value, $extrafields);
}

// built in validation
$enabled = 1; // hardcoded because it seems to always be 1 in every row in the database
if ($request_data['entity']) {
$entity = $request_data['entity'];
} else {
throw new RestException(400, "Entity field absent");
}
if ($request_data['label']) {
$label = $request_data['label'];
} else {
throw new RestException(400, "label field absent");
}

$alwayseditable = $request_data['alwayseditable'];
$default_value = $request_data['default_value'];
$totalizable = $request_data['totalizable'];
$printable = $request_data['printable'];
$required = $request_data['required'];
$langfile = $request_data['langfile'];
$computed = $request_data['computed'];
$unique = $request_data['unique'];
$param = $request_data['param'];
$perms = $request_data['perms'];
$size = $request_data['size'];
$type = $request_data['type'];
$list = $request_data['list'];
$help = $request_data['help'];
$pos = $request_data['pos'];
$moreparams = array();

dol_syslog(get_class($this).'::updateExtraField', LOG_DEBUG);
if ( 0 > $extrafields->updateExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $default_value, $param, $alwayseditable, $perms, $list, $help, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams)) {
throw new RestException(500, 'Error updating extrafield', array_merge(array($extrafields->errno), $extrafields->errors));
}

$sql = "SELECT t.rowid as id";
$sql .= " FROM ".MAIN_DB_PREFIX."extrafields as t";
$sql .= " WHERE elementtype = '".$this->db->escape($elementtype)."'";
$sql .= " AND name = '".$this->db->escape($attrname)."'";

$resql = $this->db->query($sql);
if ($resql) {
if ($this->db->num_rows($resql)) {
$tab = $this->db->fetch_object($resql);
$id = (int) $tab->id;
} else {
$id = (int) -1;
}
} else {
$id = (int) -2;
}

return $id;
}

/**
* Get the list of towns.
*
Expand Down
84 changes: 81 additions & 3 deletions htdocs/core/class/extrafields.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,78 @@ public function addExtraField($attrname, $label, $type, $pos, $size, $elementtyp
}
}

/**
* Update an existing extra field parameter
*
* @param string $attrname Code of attribute
* @param string $label label of attribute
* @param string $type Type of attribute ('boolean','int','varchar','text','html','date','datetime','price', 'pricecy', 'phone','mail','password','url','select','checkbox','separate',...)
* @param int $pos Position of attribute
* @param string $size Size/length definition of attribute ('5', '24,8', ...). For float, it contains 2 numeric separated with a comma.
* @param string $elementtype Element type. Same value than object->table_element (Example 'member', 'product', 'thirdparty', ...)
* @param int $unique Is field unique or not
* @param int $required Is field required or not
* @param string $default_value Defaulted value (In database. use the default_value feature for default value on screen. Example: '', '0', 'null', 'avalue')
* @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
* @param int $alwayseditable Is attribute always editable regardless of the document status
* @param string $perms Permission to check
* @param string $list Visibility ('0'=never visible, '1'=visible on list+forms, '2'=list only, '3'=form only or 'eval string')
* @param string $help Text with help tooltip
* @param string $computed Computed value
* @param string $entity Entity of extrafields (for multicompany modules)
* @param string $langfile Language file
* @param string $enabled Condition to have the field enabled or not
* @param int $totalizable Is a measure. Must show a total on lists
* @param int $printable Is extrafield displayed on PDF
* @param array $moreparams More parameters. Example: array('css'=>, 'csslist'=>Css on list, 'cssview'=>...)
* @return int Return integer <=0 if KO, >0 if OK
*/
public function updateExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
{
if (empty($attrname)) {
return -1;
}
if (empty($label)) {
return -1;
}

$result = 0;

if ($type == 'separator' || $type == 'separate') {
$type = 'separate';
$unique = 0;
$required = 0;
} // Force unique and not required if this is a separator field to avoid troubles.
if ($elementtype == 'thirdparty') {
$elementtype = 'societe';
}
if ($elementtype == 'contact') {
$elementtype = 'socpeople';
}

// Create field into database except for separator type which is not stored in database
if ($type != 'separate') {
dol_syslog(get_class($this).'::thisupdate', LOG_DEBUG);
$result = $this->update($attrname, $label, $type, $size, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
}
$err1 = $this->errno;
if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') {
// Add declaration of field into table
dol_syslog(get_class($this).'::thislabel', LOG_DEBUG);
$result2 = $this->update_label($attrname, $label, $type, $size, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
$err2 = $this->errno;
if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) {
$this->error = '';
$this->errno = '0';
return 1;
} else {
return -2;
}
} else {
return -1;
}
}

/**
* Add a new optional attribute.
* This is a private method. For public method, use addExtraField.
Expand Down Expand Up @@ -418,10 +490,11 @@ private function create_label($attrname, $label = '', $type = '', $pos = 0, $siz
$sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null");
$sql .= ')';

dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
if ($this->db->query($sql)) {
dol_syslog(get_class($this)."::create_label_success", LOG_DEBUG);
return 1;
} else {
dol_syslog(get_class($this)."::create_label_error", LOG_DEBUG);
$this->error = $this->db->lasterror();
$this->errno = $this->db->lasterrno();
return -1;
Expand Down Expand Up @@ -617,19 +690,23 @@ public function update($attrname, $label, $type, $length, $elementtype, $unique
}
}

dol_syslog(get_class($this).'::DDLUpdateField', LOG_DEBUG);
if ($type != 'separate') { // No table update when separate type
$result = $this->db->DDLUpdateField($this->db->prefix().$table, $attrname, $field_desc);
}
if ($result > 0 || $type == 'separate') {
if ($label) {
dol_syslog(get_class($this).'::update_label', LOG_DEBUG);
$result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
}
if ($result > 0) {
$sql = '';
if ($unique) {
$sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
dol_syslog(get_class($this).'::update_unique', LOG_DEBUG);
JonBendtsen marked this conversation as resolved.
Show resolved Hide resolved
$sql = "ALTER TABLE ".$this->db->prefix().$table." ADD UNIQUE INDEX uk_".$table."_".$this->db->sanitize($attrname)." (".$this->db->sanitize($attrname).")";
} else {
$sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX IF EXISTS uk_".$table."_".$attrname;
dol_syslog(get_class($this).'::update_common', LOG_DEBUG);
$sql = "ALTER TABLE ".$this->db->prefix().$table." DROP INDEX IF EXISTS uk_".$table."_".$this->db->sanitize($attrname);
}
dol_syslog(get_class($this).'::update', LOG_DEBUG);
$resql = $this->db->query($sql, 1, 'dml');
Expand All @@ -654,6 +731,7 @@ public function update($attrname, $label, $type, $length, $elementtype, $unique
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Modify description of personalized attribute
* This is a private method. For public method, use updateExtraField.
*
* @param string $attrname Name of attribute
* @param string $label Label of attribute
Expand Down
Loading