" . Dropdown::showYesNo($_POST['field'] . '[use_notification][]', $default_notif, -1, ['display' => false]) . "
diff --git a/ajax/viewsubitem.php b/ajax/viewsubitem.php
index 644410474a9..b226f1e185d 100644
--- a/ajax/viewsubitem.php
+++ b/ajax/viewsubitem.php
@@ -51,12 +51,11 @@
&& ($parent = getItemForItemtype($_POST['parenttype']))
) {
if (
- isset($_POST[$parent::getForeignKeyField()])
- && isset($_POST["id"])
+ isset($_POST[$parent::getForeignKeyField()], $_POST["id"])
&& $parent->getFromDB($_POST[$parent::getForeignKeyField()])
) {
$item->showForm($_POST["id"], ['parent' => $parent]);
} else {
- echo __('Access denied');
+ echo __s('Access denied');
}
}
diff --git a/ajax/visibility.php b/ajax/visibility.php
index 4761a285331..712388a8bc8 100644
--- a/ajax/visibility.php
+++ b/ajax/visibility.php
@@ -109,7 +109,7 @@
'entity_sons' => $_POST['is_recursive'] ?? false,
]);
echo "
";
- echo __('Child entities');
+ echo __s('Child entities');
echo " | ";
Dropdown::showYesNo($prefix . 'is_recursive' . $suffix);
echo " | ";
diff --git a/src/Contract.php b/src/Contract.php
index 294c43827f0..149f0ab5fc0 100644
--- a/src/Contract.php
+++ b/src/Contract.php
@@ -1599,7 +1599,7 @@ public static function getAlertName($val = null)
return $names;
}
// Default value for display
- $names[0] = ' ';
+ $names[0] = __('None');
if (isset($names[$val])) {
return $names[$val];
diff --git a/src/Entity.php b/src/Entity.php
index bd9d67d5c59..5f4489b8928 100644
--- a/src/Entity.php
+++ b/src/Entity.php
@@ -1658,48 +1658,25 @@ public static function showInventoryOptions(Entity $entity)
}
}
- $fn_get_inheritance_label = static function (string $field, ?string $strategy_field = null) use ($entity): ?string {
- $result = null;
- if ($entity->fields[$field] == self::CONFIG_PARENT) {
- if ($strategy_field === null) {
- $strategy_field = $field;
- }
- $inherited_strategy = self::getUsedConfig($strategy_field, $entity->fields['entities_id']);
- $inherited_value = $inherited_strategy === 0
- ? self::getUsedConfig($strategy_field, $entity->fields['entities_id'], $field)
- : $inherited_strategy;
- $result = self::inheritedValue(
- self::getSpecificValueToDisplay($field, $inherited_value),
- false,
- false
- );
- }
- return $result;
- };
-
$inheritance_labels = [
- 'entities_id_software' => $fn_get_inheritance_label('entities_id_software', 'entities_strategy_software'),
- 'transfers_id' => $fn_get_inheritance_label('transfers_id', 'transfers_strategy'),
- 'autofill_buy_date' => $fn_get_inheritance_label('autofill_buy_date'),
- 'autofill_order_date' => $fn_get_inheritance_label('autofill_order_date'),
- 'autofill_delivery_date' => $fn_get_inheritance_label('autofill_delivery_date'),
- 'autofill_use_date' => $fn_get_inheritance_label('autofill_use_date'),
- 'autofill_warranty_date' => $fn_get_inheritance_label('autofill_warranty_date'),
- 'autofill_decommission_date' => $fn_get_inheritance_label('autofill_decommission_date'),
- 'agent_base_url' => self::inheritedValue(
- self::getUsedConfig('agent_base_url', $ID, '', ''),
- false,
- false
- ),
+ 'entities_id_software' => $entity->getInheritedValueBadge('entities_id_software', 'entities_strategy_software'),
+ 'transfers_id' => $entity->getInheritedValueBadge('transfers_id', 'transfers_strategy'),
+ 'autofill_buy_date' => $entity->getInheritedValueBadge('autofill_buy_date'),
+ 'autofill_order_date' => $entity->getInheritedValueBadge('autofill_order_date'),
+ 'autofill_delivery_date' => $entity->getInheritedValueBadge('autofill_delivery_date'),
+ 'autofill_use_date' => $entity->getInheritedValueBadge('autofill_use_date'),
+ 'autofill_warranty_date' => $entity->getInheritedValueBadge('autofill_warranty_date'),
+ 'autofill_decommission_date' => $entity->getInheritedValueBadge('autofill_decommission_date'),
+ 'agent_base_url' => $entity->getInheritedValueBadge(field: 'agent_base_url', inherit_parent_value: null),
];
$fields = ["contact", "user", "group", "location"];
foreach ($fields as $field) {
- $inheritance_labels["is_{$field}_autoupdate"] = $fn_get_inheritance_label("is_{$field}_autoupdate");
- $inheritance_labels["is_{$field}_autoclean"] = $fn_get_inheritance_label("is_{$field}_autoclean");
+ $inheritance_labels["is_{$field}_autoupdate"] = $entity->getInheritedValueBadge("is_{$field}_autoupdate");
+ $inheritance_labels["is_{$field}_autoclean"] = $entity->getInheritedValueBadge("is_{$field}_autoclean");
}
- $inheritance_labels['state_autoupdate_mode'] = $fn_get_inheritance_label('state_autoupdate_mode');
- $inheritance_labels['state_autoclean_mode'] = $fn_get_inheritance_label('state_autoclean_mode');
+ $inheritance_labels['state_autoupdate_mode'] = $entity->getInheritedValueBadge('state_autoupdate_mode');
+ $inheritance_labels['state_autoclean_mode'] = $entity->getInheritedValueBadge('state_autoclean_mode');
TemplateRenderer::getInstance()->display('pages/admin/entity/assets.html.twig', [
'item' => $entity,
@@ -1733,58 +1710,41 @@ public static function showNotificationOptions(Entity $entity)
return false;
}
- $fn_get_inheritance_label = static function (string $field) use ($ID): string {
- return self::inheritedValue(
- self::getUsedConfig($field, $ID, '', ''),
- false,
- false
- );
- };
-
- $fn_get_specific_inheritance_label = static function (string $field) use ($entity): string {
- $tid = self::getUsedConfig($field, $entity->getField('entities_id'));
- return self::inheritedValue(
- self::getSpecificValueToDisplay($field, $tid),
- false,
- false
- );
- };
-
$inheritance_labels = [
- 'admin_email' => $fn_get_inheritance_label('admin_email'),
- 'admin_email_name' => $fn_get_inheritance_label('admin_email_name'),
- 'from_email' => $fn_get_inheritance_label('from_email'),
- 'from_email_name' => $fn_get_inheritance_label('from_email_name'),
- 'noreply_email' => $fn_get_inheritance_label('noreply_email'),
- 'noreply_email_name' => $fn_get_inheritance_label('noreply_email_name'),
- 'replyto_email' => $fn_get_inheritance_label('replyto_email'),
- 'replyto_email_name' => $fn_get_inheritance_label('replyto_email_name'),
- 'notification_subject_tag' => $fn_get_inheritance_label('notification_subject_tag'),
+ 'admin_email' => $entity->getInheritedValueBadge(field: 'admin_email', inherit_parent_value: null),
+ 'admin_email_name' => $entity->getInheritedValueBadge(field: 'admin_email_name', inherit_parent_value: null),
+ 'from_email' => $entity->getInheritedValueBadge(field: 'from_email', inherit_parent_value: null),
+ 'from_email_name' => $entity->getInheritedValueBadge(field: 'from_email_name', inherit_parent_value: null),
+ 'noreply_email' => $entity->getInheritedValueBadge(field: 'noreply_email', inherit_parent_value: null),
+ 'noreply_email_name' => $entity->getInheritedValueBadge(field: 'noreply_email_name', inherit_parent_value: null),
+ 'replyto_email' => $entity->getInheritedValueBadge(field: 'replyto_email', inherit_parent_value: null),
+ 'replyto_email_name' => $entity->getInheritedValueBadge(field: 'replyto_email_name', inherit_parent_value: null),
+ 'notification_subject_tag' => $entity->getInheritedValueBadge(field: 'notification_subject_tag', inherit_parent_value: null),
'delay_send_emails' => null,
'is_notif_enable_default' => null,
- 'mailing_signature' => $fn_get_inheritance_label('mailing_signature'),
- 'url_base' => $fn_get_inheritance_label('url_base'),
- 'cartridges_alert_repeat' => $fn_get_specific_inheritance_label('cartridges_alert_repeat'),
- 'default_cartridges_alarm_threshold' => $fn_get_specific_inheritance_label('default_cartridges_alarm_threshold'),
- 'consumables_alert_repeat' => $fn_get_specific_inheritance_label('consumables_alert_repeat'),
- 'default_consumables_alarm_threshold' => $fn_get_specific_inheritance_label('default_consumables_alarm_threshold'),
- 'use_contracts_alert' => $fn_get_specific_inheritance_label('use_contracts_alert'),
- 'default_contract_alert' => $fn_get_specific_inheritance_label('default_contract_alert'),
- 'send_contracts_alert_before_delay' => $fn_get_specific_inheritance_label('send_contracts_alert_before_delay'),
- 'use_infocoms_alert' => $fn_get_specific_inheritance_label('use_infocoms_alert'),
- 'default_infocom_alert' => $fn_get_specific_inheritance_label('default_infocom_alert'),
- 'send_infocoms_alert_before_delay' => $fn_get_specific_inheritance_label('send_infocoms_alert_before_delay'),
- 'use_licenses_alert' => $fn_get_specific_inheritance_label('use_licenses_alert'),
- 'send_licenses_alert_before_delay' => $fn_get_specific_inheritance_label('send_licenses_alert_before_delay'),
- 'use_certificates_alert' => $fn_get_specific_inheritance_label('use_certificates_alert'),
- 'send_certificates_alert_before_delay' => $fn_get_specific_inheritance_label('send_certificates_alert_before_delay'),
- 'certificates_alert_repeat_interval' => $fn_get_specific_inheritance_label('certificates_alert_repeat_interval'),
- 'use_reservations_alert' => $fn_get_specific_inheritance_label('use_reservations_alert'),
- 'notclosed_delay' => $fn_get_specific_inheritance_label('notclosed_delay'),
- 'use_domains_alert' => $fn_get_specific_inheritance_label('use_domains_alert'),
- 'send_domains_alert_close_expiries_delay' => $fn_get_specific_inheritance_label('send_domains_alert_close_expiries_delay'),
- 'send_domains_alert_expired_delay' => $fn_get_specific_inheritance_label('send_domains_alert_expired_delay'),
- 'approval_reminder_repeat_interval' => $fn_get_specific_inheritance_label('approval_reminder_repeat_interval'),
+ 'mailing_signature' => $entity->getInheritedValueBadge('mailing_signature', inherit_parent_value: null),
+ 'url_base' => $entity->getInheritedValueBadge('url_base', inherit_parent_value: null),
+ 'cartridges_alert_repeat' => $entity->getInheritedValueBadge('cartridges_alert_repeat'),
+ 'default_cartridges_alarm_threshold' => $entity->getInheritedValueBadge('default_cartridges_alarm_threshold'),
+ 'consumables_alert_repeat' => $entity->getInheritedValueBadge('consumables_alert_repeat'),
+ 'default_consumables_alarm_threshold' => $entity->getInheritedValueBadge('default_consumables_alarm_threshold'),
+ 'use_contracts_alert' => $entity->getInheritedValueBadge('use_contracts_alert'),
+ 'default_contract_alert' => $entity->getInheritedValueBadge('default_contract_alert'),
+ 'send_contracts_alert_before_delay' => $entity->getInheritedValueBadge('send_contracts_alert_before_delay'),
+ 'use_infocoms_alert' => $entity->getInheritedValueBadge('use_infocoms_alert'),
+ 'default_infocom_alert' => $entity->getInheritedValueBadge('default_infocom_alert'),
+ 'send_infocoms_alert_before_delay' => $entity->getInheritedValueBadge('send_infocoms_alert_before_delay'),
+ 'use_licenses_alert' => $entity->getInheritedValueBadge('use_licenses_alert'),
+ 'send_licenses_alert_before_delay' => $entity->getInheritedValueBadge('send_licenses_alert_before_delay'),
+ 'use_certificates_alert' => $entity->getInheritedValueBadge('use_certificates_alert'),
+ 'send_certificates_alert_before_delay' => $entity->getInheritedValueBadge('send_certificates_alert_before_delay'),
+ 'certificates_alert_repeat_interval' => $entity->getInheritedValueBadge('certificates_alert_repeat_interval'),
+ 'use_reservations_alert' => $entity->getInheritedValueBadge('use_reservations_alert'),
+ 'notclosed_delay' => $entity->getInheritedValueBadge('notclosed_delay'),
+ 'use_domains_alert' => $entity->getInheritedValueBadge('use_domains_alert'),
+ 'send_domains_alert_close_expiries_delay' => $entity->getInheritedValueBadge('send_domains_alert_close_expiries_delay'),
+ 'send_domains_alert_expired_delay' => $entity->getInheritedValueBadge('send_domains_alert_expired_delay'),
+ 'approval_reminder_repeat_interval' => $entity->getInheritedValueBadge('approval_reminder_repeat_interval'),
];
if ($entity->fields['delay_send_emails'] == self::CONFIG_PARENT) {
$tid = self::getUsedConfig('delay_send_emails', $entity->getField('entities_id'));
@@ -1904,7 +1864,8 @@ public static function showSecurityOptions(Entity $entity)
TemplateRenderer::getInstance()->display('pages/2fa/2fa_config.html.twig', [
'canedit' => $canedit,
'item' => $entity,
- 'action' => Toolbox::getItemTypeFormURL(__CLASS__)
+ 'action' => Toolbox::getItemTypeFormURL(__CLASS__),
+ 'inherited_value' => $entity->getInheritedValueBadge('2fa_enforcement_strategy', '2fa_enforcement_strategy'),
]);
}
@@ -2025,15 +1986,12 @@ public static function isEntityDirectoryConfigured($entities_id)
}
/**
+ * @param Entity $entity
+ * @return false|void
* @since 0.84 (before in entitydata.class)
- *
- * @param Entity $entity object
**/
public static function showHelpdeskOptions(Entity $entity)
{
- /** @var array $CFG_GLPI */
- global $CFG_GLPI;
-
$ID = $entity->getField('id');
if (
!$entity->can($ID, READ)
@@ -2047,500 +2005,43 @@ public static function showHelpdeskOptions(Entity $entity)
$canedit = (Session::haveRight(self::$rightname, self::UPDATEHELPDESK)
&& Session::haveAccessToEntity($ID));
- echo "
";
- if ($canedit) {
- echo "
";
-
- Ajax::updateItemOnSelectEvent(
- "dropdown_inquest_config$rand",
- "inquestconfig",
- $CFG_GLPI["root_doc"] . "/ajax/ticketsatisfaction.php",
- $params
- );
+ ]);
}
/**
@@ -2922,31 +2423,29 @@ public static function getSpecificValueToDisplay($field, $values, array $options
case 'use_domains_alert':
case 'use_infocoms_alert':
case 'is_notif_enable_default':
- if ($values[$field] == self::CONFIG_PARENT) {
+ case 'enable_custom_css':
+ case 'suppliers_as_private':
+ case 'display_users_initials':
+ case '2fa_enforcement_strategy':
+ if ($values[$field] === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
return Dropdown::getYesNo($values[$field]);
case 'use_reservations_alert':
- switch ($values[$field]) {
- case self::CONFIG_PARENT:
- return __('Inheritance of the parent entity');
-
- case 0:
- return __('Never');
- }
- return sprintf(_n('%d hour', '%d hours', $values[$field]), $values[$field]);
+ return match ($values[$field]) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ 0 => __('Never'),
+ default => sprintf(_n('%d hour', '%d hours', $values[$field]), $values[$field]),
+ };
case 'default_cartridges_alarm_threshold':
case 'default_consumables_alarm_threshold':
- switch ($values[$field]) {
- case self::CONFIG_PARENT:
- return __('Inheritance of the parent entity');
-
- case 0:
- return __('Never');
- }
- return $values[$field];
+ return match ($values[$field]) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ 0 => __('Never'),
+ default => $values[$field],
+ };
case 'send_contracts_alert_before_delay':
case 'send_infocoms_alert_before_delay':
@@ -2954,56 +2453,37 @@ public static function getSpecificValueToDisplay($field, $values, array $options
case 'send_certificates_alert_before_delay':
case 'send_domains_alert_close_expiries_delay':
case 'send_domains_alert_expired_delay':
- switch ($values[$field]) {
- case self::CONFIG_PARENT:
- return __('Inheritance of the parent entity');
-
- case 0:
- return __('No');
- }
- return sprintf(_n('%d day', '%d days', $values[$field]), $values[$field]);
+ return match ($values[$field]) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ 0 => __('No'),
+ default => sprintf(_n('%d day', '%d days', $values[$field]), $values[$field]),
+ };
case 'cartridges_alert_repeat':
case 'consumables_alert_repeat':
case 'approval_reminder_repeat_interval':
- switch ($values[$field]) {
- case self::CONFIG_PARENT:
- return __('Inheritance of the parent entity');
-
- case self::CONFIG_NEVER:
- case 0: // For compatibility issue
- return __('Never');
-
- case DAY_TIMESTAMP:
- return __('Each day');
-
- case WEEK_TIMESTAMP:
- return __('Each week');
-
- case MONTH_TIMESTAMP:
- return __('Each month');
-
- default:
- // Display value if not defined
- return $values[$field];
- }
- break;
+ case 'certificates_alert_repeat_interval':
+ return match ($values[$field]) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ self::CONFIG_NEVER, 0 => __('Never'),
+ DAY_TIMESTAMP => __('Each day'),
+ WEEK_TIMESTAMP => __('Each week'),
+ MONTH_TIMESTAMP => __('Each month'),
+ default => $values[$field],
+ };
case 'notclosed_delay': // 0 means never
- switch ($values[$field]) {
- case self::CONFIG_PARENT:
- return __('Inheritance of the parent entity');
-
- case 0:
- return __('Never');
- }
- return sprintf(_n('%d day', '%d days', $values[$field]), $values[$field]);
+ return match ($values[$field]) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ 0 => __('Never'),
+ default => sprintf(_n('%d day', '%d days', $values[$field]), $values[$field]),
+ };
case 'auto_assign_mode':
return self::getAutoAssignMode((int) $values[$field]);
case 'tickettype':
- if ($values[$field] == self::CONFIG_PARENT) {
+ if ($values[$field] === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
return Ticket::getTicketTypeName($values[$field]);
@@ -3031,13 +2511,13 @@ public static function getSpecificValueToDisplay($field, $values, array $options
return __('Copy the delivery date');
default:
- if (strstr($values[$field], '_')) {
- list($type,$sid) = explode('_', $values[$field], 2);
- if ($type == Infocom::ON_STATUS_CHANGE) {
+ if (str_contains($values[$field], '_')) {
+ [$type, $sid] = explode('_', $values[$field], 2);
+ if ($type === Infocom::ON_STATUS_CHANGE) {
// TRANS %s is the name of the state
return sprintf(
__('Fill when shifting to state %s'),
- Dropdown::getDropdownName('glpi_states', $sid)
+ Dropdown::getDropdownName(table: 'glpi_states', id: $sid, default: __('None'))
);
}
}
@@ -3046,10 +2526,41 @@ public static function getSpecificValueToDisplay($field, $values, array $options
case 'inquest_config':
case 'inquest_config_change':
- if ($values[$field] == self::CONFIG_PARENT) {
+ if ($values[$field] === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
- return CommonITILSatisfaction::getTypeInquestName($values[$field]);
+ $inherit = '';
+ $inquest_rate = self::getUsedConfig(
+ $field,
+ $options['entity']->fields['entities_id'],
+ str_replace('config', 'rate', $field)
+ );
+ $inherit .= '
';
+ if ($inquest_rate === 0) {
+ $inherit .= __('Disabled');
+ } else {
+ $inherit .= CommonITILSatisfaction::getTypeInquestName($values[$field]) . '
';
+ $inqconf = self::getUsedConfig(
+ $field,
+ $options['entity']->fields['entities_id'],
+ str_replace('config', 'delay', $field)
+ );
+
+ $inherit .= sprintf(_n('%d day', '%d days', $inqconf), $inqconf);
+ $inherit .= "
";
+ //TRANS: %d is the percentage. %% to display %
+ $inherit .= sprintf(__('%d%%'), $inquest_rate);
+
+ if ($values[$field] === 2) {
+ $inherit .= "
";
+ $inherit .= self::getUsedConfig(
+ $field,
+ $options['entity']->fields['entities_id'],
+ str_replace('config', 'URL', $field)
+ );
+ }
+ }
+ return $inherit;
case 'default_contract_alert':
return Contract::getAlertName($values[$field]);
@@ -3059,98 +2570,87 @@ public static function getSpecificValueToDisplay($field, $values, array $options
case 'entities_id_software':
$strategy = $values['entities_strategy_software'] ?? $values[$field];
- if ($strategy == self::CONFIG_NEVER) {
- return __('No change of entity');
- }
- if ($strategy == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- }
- return Dropdown::getDropdownName('glpi_entities', $values[$field]);
+ return match ($strategy) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ self::CONFIG_NEVER => __('No change of entity'),
+ default => Dropdown::getDropdownName(table: 'glpi_entities', id: $values[$field], default: __('None')),
+ };
case 'tickettemplates_id':
$strategy = $values['tickettemplates_strategy'] ?? $values[$field];
- if ($strategy == self::CONFIG_PARENT) {
+ if ($strategy === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
- return Dropdown::getDropdownName(TicketTemplate::getTable(), $values[$field]);
+ return Dropdown::getDropdownName(table: TicketTemplate::getTable(), id: $values[$field], default: __('None'));
case 'calendars_id':
$strategy = $values['calendars_strategy'] ?? $values[$field];
- if ($strategy == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- } elseif ($values[$field] == 0) {
- return __('24/7');
- }
- return Dropdown::getDropdownName('glpi_calendars', $values[$field]);
+ return match ($strategy) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ self::CONFIG_NEVER => __('24/7'),
+ default => Dropdown::getDropdownName(table: 'glpi_calendars', id: $values[$field], default: __('None')),
+ };
case 'transfers_id':
$strategy = $values['transfers_strategy'] ?? $values[$field];
- if ($strategy == self::CONFIG_NEVER) {
- return __('No automatic transfer');
- }
- if ($strategy == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- } elseif ($values[$field] == 0) {
- return __('No automatic transfer');
- }
- return Dropdown::getDropdownName('glpi_transfers', $values[$field]);
+ return match (true) {
+ $strategy === self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ $strategy === self::CONFIG_NEVER, $values[$field] === 0 => __('No automatic transfer'),
+ default => Dropdown::getDropdownName(table: 'glpi_transfers', id: $values[$field], default: __('None')),
+ };
case 'contracts_id_default':
$strategy = $values['contracts_strategy_default'] ?? $values[$field];
- if ($strategy === self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- }
- if ($strategy === self::CONFIG_AUTO) {
- return __('Contract in ticket entity');
- }
-
- return Dropdown::getDropdownName(Contract::getTable(), $values[$field]);
+ return match ($strategy) {
+ self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ self::CONFIG_AUTO => __('Contract in ticket entity'),
+ default => Dropdown::getDropdownName(table: 'glpi_contracts', id: $values[$field], default: __('None')),
+ };
case 'is_contact_autoupdate':
case 'is_user_autoupdate':
case 'is_group_autoupdate':
case 'is_location_autoupdate':
- if ($values[$field] == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- } elseif ($values[$field]) {
- return __('Copy');
- }
- return __('Do not copy');
+ return match (true) {
+ $values[$field] === self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ $values[$field] > 0 => __('Copy'),
+ default => __('Do not copy'),
+ };
case 'is_contact_autoclean':
case 'is_user_autoclean':
case 'is_group_autoclean':
case 'is_location_autoclean':
- if ($values[$field] == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- } elseif ($values[$field]) {
- return __('Clear');
- }
- return __('Do not delete');
+ return match (true) {
+ $values[$field] === self::CONFIG_PARENT => __('Inheritance of the parent entity'),
+ $values[$field] > 0 => __('Clear'),
+ default => __('Do not delete'),
+ };
case 'state_autoupdate_mode':
- if ($values[$field] == self::CONFIG_PARENT) {
+ if ($values[$field] === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
- $states = State::getBehaviours(
- __('Copy computer status'),
- );
+ $states = State::getBehaviours(__('Copy computer status'));
return $states[$values[$field]];
case 'state_autoclean_mode':
- if ($values[$field] == self::CONFIG_PARENT) {
- return __('Inheritance of the parent entity');
- }
- $states = State::getBehaviours(
- __('Clear status'),
- );
- return $states[$values[$field]];
- case 'enable_custom_css':
if ($values[$field] === self::CONFIG_PARENT) {
return __('Inheritance of the parent entity');
}
- return Dropdown::getYesNo($values[$field]);
+ $states = State::getBehaviours(__('Clear status'));
+ return $states[$values[$field]];
+ case 'anonymize_support_agents':
+ return self::getAnonymizeSupportAgentsValues()[$values[$field]] ?? $values[$field];
+ case 'autoclose_delay':
+ case 'autopurge_delay':
+ return match ($values[$field]) {
+ self::CONFIG_NEVER => __('Never'),
+ 0 => __('Immediately'),
+ default => sprintf(_n('%d day', '%d days', $values[$field]), $values[$field]),
+ };
+ default:
+ return $values[$field] ?? '';
}
- return parent::getSpecificValueToDisplay($field, $values, $options);
}
public static function getSpecificValueToSelect($field, $name = '', $values = '', array $options = [])
@@ -3296,7 +2796,6 @@ public static function inheritedValue($value = "", bool $inline = false, bool $d
return "";
}
- $value = htmlspecialchars($value);
$out = "
@@ -3312,6 +2811,68 @@ public static function inheritedValue($value = "", bool $inline = false, bool $d
return $out;
}
+ /**
+ * Get the badge HTML for a field that can be inherited
+ * @param string $field The field name
+ * @param string|null $strategy_field The field name of the strategy
+ * @param mixed $default_value
+ * @return string|null The badge HTML or null if the field is not inherited
+ */
+ public function getInheritedValueBadge(string $field, ?string $strategy_field = null, mixed $default_value = self::CONFIG_PARENT, mixed $inherit_parent_value = self::CONFIG_PARENT): ?string
+ {
+ if ($this->getID() <= 0) {
+ return null;
+ }
+ $result = null;
+ if ($this->fields[$field] == $inherit_parent_value) {
+ if ($strategy_field === null) {
+ $strategy_field = $field;
+ }
+ $inherited_strategy = self::getUsedConfig($strategy_field, $this->fields['entities_id']);
+ $inherited_value = $inherited_strategy === 0
+ ? self::getUsedConfig($strategy_field, $this->fields['entities_id'], $field, $default_value)
+ : $inherited_strategy;
+ if ($inherited_value === self::CONFIG_PARENT) {
+ return null;
+ }
+ $result = self::inheritedValue(
+ self::getSpecificValueToDisplay($field, $inherited_value, [
+ 'entity' => $this,
+ ]),
+ false,
+ false
+ );
+ }
+ return $result;
+ }
+
+ /**
+ * Get the badge HTML for a linked field that can be inherited
+ * @param class-string
$itemtype The item type
+ * @param string $empty_value The value to display when the field is empty
+ * @param string|null $field The field name
+ * @param int $default_value The default value
+ * @return string|null The badge HTML or null if the field is not inherited
+ */
+ public function getInheritedLinkedValueBadge(string $itemtype, string $empty_value = Dropdown::EMPTY_VALUE, ?string $field = null, int $default_value = 0): ?string
+ {
+ if ($this->getID() <= 0) {
+ return null;
+ }
+ $item = new $itemtype();
+ $field = $field ?? $item::getForeignKeyField();
+ if ($this->fields[$field] == self::CONFIG_PARENT) {
+ $tid = self::getUsedConfig(str_replace('_id', '_strategy', $field), $this->getID(), $field, $default_value);
+ if (!$tid) {
+ return self::inheritedValue(htmlspecialchars($empty_value), true, false);
+ }
+ if ($item->getFromDB($tid)) {
+ return self::inheritedValue($item->getLink(), true, false);
+ }
+ }
+ return null;
+ }
+
public static function getIcon()
{
return "ti ti-stack";
diff --git a/src/Glpi/DBAL/QueryFunction.php b/src/Glpi/DBAL/QueryFunction.php
index ae71e16f5dc..62957206db5 100644
--- a/src/Glpi/DBAL/QueryFunction.php
+++ b/src/Glpi/DBAL/QueryFunction.php
@@ -452,4 +452,15 @@ public static function locate(string|QueryExpression $substring, string|QueryExp
$substring = is_string($substring) ? new QueryExpression($DB::quoteValue($substring)) : $substring;
return self::getExpression('LOCATE', [$substring, $expression], $alias);
}
+
+ public static function concat_ws(string|QueryExpression $separator, array $params, ?string $alias = null): QueryExpression
+ {
+ /** @var \DBmysql $DB */
+ global $DB;
+ $params = array_map(static function ($p) use ($DB) {
+ return $p instanceof QueryExpression || $p === null ? $p : $DB::quoteName($p);
+ }, $params);
+ $separator = $separator instanceof QueryExpression ? $separator : $DB::quoteName($separator);
+ return new QueryExpression('CONCAT_WS(' . $separator . ', ' . implode(', ', $params) . ')', $alias);
+ }
}
diff --git a/src/Infocom.php b/src/Infocom.php
index 40799d57088..6d6a3e4f74c 100644
--- a/src/Infocom.php
+++ b/src/Infocom.php
@@ -639,7 +639,7 @@ public static function getAlertName($val = null)
return $tmp;
}
// Default value for display
- $tmp[0] = ' ';
+ $tmp[0] = __('None');
if (isset($tmp[$val])) {
return $tmp[$val];
diff --git a/templates/pages/2fa/2fa_config.html.twig b/templates/pages/2fa/2fa_config.html.twig
index d769d961d57..024ae892a11 100644
--- a/templates/pages/2fa/2fa_config.html.twig
+++ b/templates/pages/2fa/2fa_config.html.twig
@@ -62,6 +62,7 @@
'1': __('Yes'),
}, '', {
'no_label': true,
+ add_field_html: inherited_value
}) }}
{% else %}
{{ fields.dropdownYesNo('2fa_enforced', item.fields['2fa_enforced'], '', {
diff --git a/templates/pages/admin/entity/assets.html.twig b/templates/pages/admin/entity/assets.html.twig
index c0918c42997..1d5bbba350c 100644
--- a/templates/pages/admin/entity/assets.html.twig
+++ b/templates/pages/admin/entity/assets.html.twig
@@ -72,9 +72,9 @@
(constant('Entity::CONFIG_NEVER')): __('No change of entity')
} %}
{% if item.fields['id'] > 0 %}
- {% set to_add = to_add|merge({
+ {% set to_add = to_add + {
(constant('Entity::CONFIG_PARENT')): __('Inheritance of the parent entity')
- }) %}
+ } %}
{% endif %}
{{ fields.dropdownField(
'Entity',
@@ -91,12 +91,12 @@
{{ fields.largeTitle(__('Transfer')) }}
{% set to_add = {
- (constant('Entity::CONFIG_NEVER')): __('No automatic transfer')
+ (constant('Entity::CONFIG_NEVER')): __('No automatic transfer')
} %}
{% if item.fields['id'] > 0 %}
- {% set to_add = to_add|merge({
+ {% set to_add = to_add + {
(constant('Entity::CONFIG_PARENT')): __('Inheritance of the parent entity')
- }) %}
+ } %}
{% endif %}
{{ fields.dropdownField(
'Transfer',
@@ -106,7 +106,7 @@
{
toadd: to_add,
add_field_html: inheritance_labels['transfers_id']|default(null),
- display_emptychoice: false
+ display_emptychoice: false,
}
) }}
diff --git a/templates/pages/admin/entity/assistance.html.twig b/templates/pages/admin/entity/assistance.html.twig
new file mode 100644
index 00000000000..3f8412e5464
--- /dev/null
+++ b/templates/pages/admin/entity/assistance.html.twig
@@ -0,0 +1,175 @@
+{#
+ # ---------------------------------------------------------------------
+ #
+ # GLPI - Gestionnaire Libre de Parc Informatique
+ #
+ # http://glpi-project.org
+ #
+ # @copyright 2015-2024 Teclib' and contributors.
+ # @copyright 2003-2014 by the INDEPNET Development Team.
+ # @licence https://www.gnu.org/licenses/gpl-3.0.html
+ #
+ # ---------------------------------------------------------------------
+ #
+ # LICENSE
+ #
+ # This file is part of GLPI.
+ #
+ # 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 .
+ #
+ # ---------------------------------------------------------------------
+ #}
+
+{% extends "generic_show_form.html.twig" %}
+{% import 'components/form/fields_macros.html.twig' as fields %}
+
+{% block form_fields %}
+ {% set inheritable_params = {
+ full_width: true,
+ entity: item.getID(),
+ toadd: (item.getID() > 0 ? {
+ (constant('Entity::CONFIG_PARENT')): __('Inheritance of the parent entity')
+ } : {})
+ } %}
+
+ {{ fields.smallTitle(__('Templates configuration')) }}
+ {{ fields.dropdownField('TicketTemplate', 'tickettemplates_id', item.fields['tickettemplates_id'], 'TicketTemplate'|itemtype_name(1), {
+ add_field_html: inheritance_labels['tickettemplates_id']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownField('ChangeTemplate', 'changetemplates_id', item.fields['changetemplates_id'], 'ChangeTemplate'|itemtype_name(1), {
+ add_field_html: inheritance_labels['changetemplates_id']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownField('ProblemTemplate', 'problemtemplates_id', item.fields['problemtemplates_id'], 'ProblemTemplate'|itemtype_name(1), {
+ add_field_html: inheritance_labels['problemtemplates_id']|default(null)
+ } + inheritable_params) }}
+
+ {{ fields.smallTitle(__('Tickets configuration')) }}
+ {{ fields.dropdownField('Calendar', 'calendars_id', item.fields['calendars_id'], 'Calendar'|itemtype_name(1), {
+ emptylabel: __('24/7'),
+ add_field_html: inheritance_labels['calendars_id']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownArrayField('tickettype', item.fields['tickettype'], inheritable_params.toadd + {
+ (constant('Ticket::INCIDENT_TYPE')): __('Incident'),
+ (constant('Ticket::DEMAND_TYPE')): __('Request'),
+ }, __('Tickets default type'), {
+ add_field_html: inheritance_labels['tickettype']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownArrayField('auto_assign_mode', item.fields['auto_assign_mode'], inheritable_params.toadd + {
+ (constant('Entity::CONFIG_NEVER')): __('No'),
+ (constant('Entity::AUTO_ASSIGN_HARDWARE_CATEGORY')): __('Based on the item then the category'),
+ (constant('Entity::AUTO_ASSIGN_CATEGORY_HARDWARE')): __('Based on the category then the item'),
+ }, __('Automatic assignment of tickets, changes and problems'), {
+ add_field_html: inheritance_labels['auto_assign_mode']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownArrayField('suppliers_as_private', item.fields['suppliers_as_private'], inheritable_params.toadd + {
+ 0: __('No'),
+ 1: __('Yes'),
+ }, __('Mark followup added by a supplier though an email collector as private'), {
+ add_field_html: inheritance_labels['suppliers_as_private']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownArrayField('anonymize_support_agents', item.fields['anonymize_support_agents'], inheritable_params.toadd + {
+ (constant('Entity::ANONYMIZE_DISABLED')): __('Disabled'),
+ (constant('Entity::ANONYMIZE_USE_GENERIC')): __("Replace the agent and group name with a generic name"),
+ (constant('Entity::ANONYMIZE_USE_NICKNAME')): __("Replace the agent and group name with a customisable nickname"),
+ (constant('Entity::ANONYMIZE_USE_GENERIC_USER')): __("Replace the agent's name with a generic name"),
+ (constant('Entity::ANONYMIZE_USE_NICKNAME_USER')): __("Replace the agent's name with a customisable nickname"),
+ (constant('Entity::ANONYMIZE_USE_GENERIC_GROUP')): __("Replace the group's name with a generic name"),
+ }, __('Anonymize support agents'), {
+ add_field_html: inheritance_labels['anonymize_support_agents']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownArrayField('display_users_initials', item.fields['display_users_initials'], inheritable_params.toadd + {
+ 0: __('No'),
+ 1: __('Yes')
+ }, __('Display initials for users without pictures'), {
+ add_field_html: inheritance_labels['display_users_initials']|default(null)
+ } + inheritable_params) }}
+ {{ fields.dropdownField('Contract', 'contracts_id_default', item.fields['contracts_id_default'], __('Default contract'), {
+ full_width: true,
+ entity: item.getID(),
+ toadd: inheritable_params.toadd + {
+ (constant('Entity::CONFIG_AUTO')): __('Contract in ticket entity')
+ },
+ condition: {
+ is_template: 0,
+ is_deleted: 0
+ }|merge(call('Contract::getNotExpiredCriteria')),
+ add_field_html: inheritance_labels['contracts_id_default']|default(null)
+ }) }}
+
+ {{ fields.smallTitle(__('Automatic closing configuration')) }}
+ {% if closeticket_disabled or purgeticket_disabled %}
+
+
+
+ {{ closeticket_disabled ? __('Close ticket action is disabled.') : '' }}
+ {{ purgeticket_disabled ? __('Purge ticket action is disabled.') : '' }}
+
+
+ {% endif %}
+ {{ fields.dropdownNumberField('autoclose_delay', item.fields['autoclose_delay'], __('Automatic closing of solved tickets after'), {
+ full_width: true,
+ min: 1,
+ max: 99,
+ unit: 'day',
+ toadd: inheritable_params.toadd + {
+ (constant('Entity::CONFIG_NEVER')): __('Never'),
+ 0: __('Immediately'),
+ },
+ add_field_html: inheritance_labels['autoclose_delay']|default(null)
+ }) }}
+ {{ fields.dropdownNumberField('autopurge_delay', item.fields['autopurge_delay'], __('Automatic purge of closed tickets after'), {
+ full_width: true,
+ min: 1,
+ max: 3650,
+ unit: 'day',
+ toadd: inheritable_params.toadd + {
+ (constant('Entity::CONFIG_NEVER')): __('Never'),
+ },
+ add_field_html: inheritance_labels['autopurge_delay']|default(null)
+ }) }}
+
+ {% set inquest_types = {
+ 'Ticket': 'TicketSatisfaction',
+ 'Change': 'ChangeSatisfaction',
+ } %}
+ {% for itemtype, inquest_itemtype in inquest_types %}
+ {% set c_rand = random() %}
+ {% set config_suffix = itemtype == 'Ticket' ? '' : ('_' ~ itemtype|lower) %}
+ {{ fields.smallTitle(__('Configuring the satisfaction survey: %s')|format(itemtype|itemtype_name(get_plural_number()))) }}
+ {{ fields.dropdownArrayField('inquest_config' ~ config_suffix, item.fields['inquest_config' ~ config_suffix], inheritable_params.toadd + {
+ (constant('CommonITILSatisfaction::TYPE_INTERNAL')): __('Internal survey'),
+ (constant('CommonITILSatisfaction::TYPE_EXTERNAL')): __('External survey')
+ }, __('Configuring the satisfaction survey'), {
+ add_field_html: inheritance_labels['inquest_config' ~ config_suffix]|default(null),
+ rand: c_rand
+ } + inheritable_params) }}
+
+
+ {% endfor %}
+{% endblock %}
diff --git a/templates/pages/admin/entity/survey_config.html.twig b/templates/pages/admin/entity/survey_config.html.twig
new file mode 100644
index 00000000000..5489d4b5a47
--- /dev/null
+++ b/templates/pages/admin/entity/survey_config.html.twig
@@ -0,0 +1,146 @@
+{#
+ # ---------------------------------------------------------------------
+ #
+ # GLPI - Gestionnaire Libre de Parc Informatique
+ #
+ # http://glpi-project.org
+ #
+ # @copyright 2015-2024 Teclib' and contributors.
+ # @copyright 2003-2014 by the INDEPNET Development Team.
+ # @licence https://www.gnu.org/licenses/gpl-3.0.html
+ #
+ # ---------------------------------------------------------------------
+ #
+ # LICENSE
+ #
+ # This file is part of GLPI.
+ #
+ # 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 .
+ #
+ # ---------------------------------------------------------------------
+ #}
+
+{% import 'components/form/fields_macros.html.twig' as fields %}
+
+{{ fields.dropdownNumberField('inquest_delay' ~ config_suffix, inquest_delay, __('Create survey after'), {
+ full_width: true,
+ min: 1,
+ max: 90,
+ unit: 'day',
+ toadd: {
+ 0: __('As soon as possible'),
+ }
+}) }}
+
+{{ fields.dropdownNumberField('inquest_rate' ~ config_suffix, inquest_rate, __('Rate to trigger survey'), {
+ full_width: true,
+ min: 0,
+ max: 100,
+ step: 10,
+ unit: '%',
+ toadd: {
+ 0: __('Disabled')
+ }
+}) }}
+
+{{ fields.dropdownNumberField('inquest_duration' ~ config_suffix, inquest_duration, __('Duration of survey'), {
+ full_width: true,
+ min: 1,
+ max: 100,
+ unit: 'day',
+ toadd: {
+ 0: __('Unspecified')
+ }
+}) }}
+
+{{ fields.dropdownNumberField('inquest_max_rate' ~ config_suffix, inquest_max_rate, __('Max rate'), {
+ full_width: true,
+ min: 1,
+ max: 10,
+}) }}
+
+{{ fields.numberField('inquest_default_rate' ~ config_suffix, inquest_default_rate, __('Default rate'), {
+ full_width: true,
+ min: 1,
+ max: 10,
+}) }}
+
+{{ fields.numberField('inquest_mandatory_comment' ~ config_suffix, inquest_mandatory_comment, __('Comment required if score is <= to'), {
+ full_width: true,
+ min: 0,
+ max: 10,
+ toadd: {
+ 0: __('Disabled')
+ }
+}) }}
+
+{{ fields.datetimeField('max_closedate' ~ config_suffix, max_closedate, __('For %s closed after')|format(itemtype|itemtype_name(get_plural_number())), {
+ full_width: true,
+ maybeempty: true,
+ timestep: 1
+}) }}
+
+{% set tag_prefix = itemtype|upper %}
+{% set ticket_only_tags = " [REQUESTTYPE_ID] [REQUESTTYPE_NAME] [TICKETTYPE_NAME] [TICKETTYPE_ID] [SLA_TTO_ID] [SLA_TTO_NAME] [SLA_TTR_ID] [SLA_TTR_NAME] [SLALEVEL_ID] [SLALEVEL_NAME]" %}
+{% set tags = [
+ '[' ~ tag_prefix ~ '_ID]', '[' ~ tag_prefix ~ '_NAME]', '[' ~ tag_prefix ~ '_CREATEDATE]', '[' ~ tag_prefix ~ '_SOLVEDATE]',
+ '[' ~ tag_prefix ~ '_PRIORITY]', '[' ~ tag_prefix ~ '_PRIORITYNAME]', '[ITILCATEGORY_ID]', '[ITILCATEGORY_NAME]',
+ '[SOLUTIONTYPE_ID]', '[SOLUTIONTYPE_NAME]'
+]|join(' ') ~ (itemtype == 'Ticket' ? ticket_only_tags : '') %}
+{{ fields.htmlField('', tags|e, __('Valid tags'), {
+ full_width: true,
+ add_field_class: 'valid_tags'
+}) }}
+{{ fields.textField('inquest_URL' ~ config_suffix, inquest_URL, __('URL'), {
+ full_width: true,
+}) }}
+
+
diff --git a/tests/functional/Glpi/DBAL/QueryFunction.php b/tests/functional/Glpi/DBAL/QueryFunction.php
index fb9491ad3cc..a5a915ea0c6 100644
--- a/tests/functional/Glpi/DBAL/QueryFunction.php
+++ b/tests/functional/Glpi/DBAL/QueryFunction.php
@@ -100,6 +100,52 @@ public function testConcat($params, $alias, $expected)
$this->string((string) \Glpi\DBAL\QueryFunction::concat($params, $alias))->isIdenticalTo($expected);
}
+ protected function concatWSProvider()
+ {
+ return [
+ [
+ new QueryExpression("','"),
+ [
+ new QueryExpression("'A'"),
+ new QueryExpression("'B'"),
+ new QueryExpression("'C'")
+ ], null, "CONCAT_WS(',', 'A', 'B', 'C')"
+ ],
+ [
+ new QueryExpression("'-'"),
+ [
+ new QueryExpression("'A'"),
+ new QueryExpression("'B'"),
+ new QueryExpression("'C'")
+ ], 'concat_alias', "CONCAT_WS('-', 'A', 'B', 'C') AS `concat_alias`"
+ ],
+ [
+ new QueryExpression("','"),
+ [
+ new QueryExpression("'A'"),
+ 'glpi_computers.name',
+ new QueryExpression("'C'")
+ ], null, "CONCAT_WS(',', 'A', `glpi_computers`.`name`, 'C')"
+ ],
+ [
+ new QueryExpression("','"),
+ [
+ new QueryExpression("'A'"),
+ 'glpi_computers.name',
+ new QueryExpression("'C'")
+ ], 'concat_alias', "CONCAT_WS(',', 'A', `glpi_computers`.`name`, 'C') AS `concat_alias`"
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider concatWSProvider
+ */
+ public function testConcatWS($separator, $params, $alias, $expected)
+ {
+ $this->string((string) \Glpi\DBAL\QueryFunction::concat_ws($separator, $params, $alias))->isIdenticalTo($expected);
+ }
+
protected function ifProvider()
{
return [