allow to specify conditions, when the serial number get generated, use

value=<start/format>
<name>=<value>
This commit is contained in:
ralf 2024-04-03 21:12:31 +02:00
parent 9f2d952fdf
commit 1cc266467d
4 changed files with 60 additions and 29 deletions

View File

@ -379,16 +379,11 @@ class admin_customfields
if (!empty($content['cf_values']))
{
$values = array();
if ($content['cf_type'] === 'serial')
if ($content['cf_type'] === 'serial' && !str_starts_with($content['cf_values'], 'value='))
{
if (!preg_match(Api\Storage\Customfields::SERIAL_PREG, $content['cf_values']))
{
Api\Etemplate::set_validation_error('cf_values', lang('Invalid Format, must end in a group of digits e.g. %1 or %2', "'0000'", "'RE2024-0000'"));
break;
$content['cf_values'] = 'value=' . $content['cf_values'];
}
$values = $content['cf_values'];
}
elseif($content['cf_values'][0] === '@')
if($content['cf_values'][0] === '@')
{
$values['@'] = substr($content['cf_values'], $content['cf_values'][1] === '=' ? 2:1);
}
@ -416,6 +411,11 @@ class admin_customfields
$values[$var] = trim($value)==='' ? $var : $value;
}
}
if ($content['cf_type'] === 'serial' && !preg_match(Api\Storage\Customfields::SERIAL_PREG, $values['value']))
{
Api\Etemplate::set_validation_error('cf_values', lang('Invalid Format, must end in a group of digits e.g. %1 or %2', "'0000'", "'RE2024-0000'"));
break;
}
$content['cf_values'] = $values;
}
$update_content = array();
@ -559,6 +559,7 @@ class admin_customfields
'cf_id' => $cf_id,
'cf_app' => $this->appname,
'cf_name' => $content['cf_name'],
'cf_values' => $content['cf_values'],
'use_private' => $this->use_private,
), 2);
}

View File

@ -295,7 +295,7 @@ class Customfields extends Transformer
}
/**
* Instanciate (server-side) widget used to implement custom-field, to run its beforeSendToClient or validate method
* Instantiate (server-side) widget used to implement custom-field, to run its beforeSendToClient or validate method
*
* @param string $fname custom field name
* @param array $field custom field data
@ -546,12 +546,35 @@ class Customfields extends Transformer
}
//error_log(__METHOD__."() $field_name: ".array2string($value).' --> '.array2string($valid));
}
}
if ($this->type == 'customfields-types')
{
// Transformation doesn't handle validation
$valid =& self::get_array($validated, $this->id ? $form_name : $field, true);
if (true) $valid = $value_in;
//error_log(__METHOD__."() $form_name $field: ".array2string($value).' --> '.array2string($value));
}
else
{
// serials do NOT return a value, as they are always readonly
foreach(array_filter($customfields, static function($field)
{
return $field['type'] === 'serial';
}) as $field)
{
if (!empty($this->attrs['exclude']) && in_array($field['name'],
explode(',', self::expand_name($this->attrs['exclude'], 0, 0, 0, 0, self::$request->content))))
{
continue;
}
// check if we have condition(s) beside the value, and they are NOT meet --> do NOT generate the serial
if (is_array($field['values']) && array_filter($field['values'], static function($val, $name) use ($content)
{
return $name === 'value' ? false : $val != $content[$name];
}, ARRAY_FILTER_USE_BOTH))
{
continue;
}
$valid =& self::get_array($validated, self::$prefix.$field['name'], true);
if (empty($valid = self::$request->content[self::$prefix.$field['name']]))
{
@ -560,13 +583,7 @@ class Customfields extends Transformer
self::$request->content = $content;
}
}
}
elseif ($this->type == 'customfields-types')
{
// Transformation doesn't handle validation
$valid =& self::get_array($validated, $this->id ? $form_name : $field, true);
if (true) $valid = $value_in;
//error_log(__METHOD__."() $form_name $field: ".array2string($value).' --> '.array2string($value));
}
}
}

View File

@ -146,13 +146,12 @@ class Tabbox extends Etemplate\Widget
public function beforeSendToClient($cname, array $expand=null)
{
[$app] = explode('.', self::$request->template['name']);
// no need to run again for responses, or if we have no custom fields
if (!empty(self::$response) || empty($app) || !($cfs = Api\Storage\Customfields::get($app, false, null, null, true)))
// no need to run if we have no custom fields
if (empty($app) || !($cfs = Api\Storage\Customfields::get($app, false, null, null, true)))
{
return;
}
$form_name = self::form_name($cname, $this->id, $expand);
$extra_private_tab = self::expand_name(self::getElementAttribute($form_name, 'cfPrivateTab') ?? $this->attrs['cfPrivateTab'] ?? false,
$extra_private_tab = self::expand_name($this->attrs['cfPrivateTab'] ?? false,
0, 0, 0, 0, self::$request->content);
if (is_string($extra_private_tab) && $extra_private_tab[0] === '!')
{
@ -173,10 +172,10 @@ class Tabbox extends Etemplate\Widget
// check if template still contains a legacy customfield tab
$have_legacy_cf_tab = $this->haveLegacyCfTab();
$exclude = self::getElementAttribute($form_name, 'cfExclude') ?? $this->attrs['cfExclude'] ?? null;
$exclude = $this->attrs['cfExclude'] ?? null;
$exclude = $exclude ? explode(',', $exclude) : [];
$type_filter = self::expand_name(self::getElementAttribute($form_name, 'cfTypeFilter') ?? $this->attrs['cfTypeFilter'] ?? null,
$type_filter = self::expand_name($this->attrs['cfTypeFilter'] ?? null,
0, 0, 0, 0, self::$request->content);
$type_filter = $type_filter ? explode(',', $type_filter) : [];
@ -247,7 +246,11 @@ class Tabbox extends Etemplate\Widget
$content['cfExclude'] = implode(',', $exclude);
self::$request->content = $content;
}
// we must not add tabs again!
if (!empty(self::$response))
{
return;
}
// addTabs is default false (= replace tabs), we need a default of true
$add_tabs =& self::setElementAttribute($this->id, 'addTabs', null);
if (!isset($add_tabs)) $add_tabs = true;

View File

@ -669,20 +669,30 @@ class Customfields implements \IteratorAggregate
'cf_type' => 'serial',
], __LINE__, __FILE__, false, 'FOR UPDATE') as $row)
{
// we increment the last digit-group
if (empty($row['cf_values']) || !preg_match(self::SERIAL_PREG, $row['cf_values'], $matches))
if (!empty($row['cf_values']) && ($v = json_decode($row['cf_values'], true)))
{
$row['cf_values'] = 1;
$values = $v;
}
else
{
$row['cf_values'] = preg_replace(self::SERIAL_PREG, sprintf('%0'.strlen($matches[0]).'d', 1+(int)$matches[0]), $row['cf_values']);
$values = ['value' => $row['cf_values'] ?? null];
}
// we increment the last digit-group
if (empty($values['value']) || !preg_match(self::SERIAL_PREG, $values['value'], $matches))
{
$values['value'] = 1;
}
else
{
$values['value'] = preg_replace(self::SERIAL_PREG,
sprintf('%0'.strlen($matches[0]).'d', 1+(int)$matches[0]), $values['value']);
}
$row['cf_values'] = json_encode($values);
break;
}
if (isset($row) && self::$db->update(self::TABLE, $row, $where, __LINE__, __FILE__) && self::$db->transaction_commit())
{
return $row['cf_values'];
return $values['value'];
}
self::$db->transaction_abort();
throw new Api\Db\Exception("Could not generate serial number for custom-field #$id!");