Skip to content
Open
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [UNRELEASE]
## [unreleased]


161 changes: 112 additions & 49 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Config extends CommonDBTM
{
public $dohistory = true;
public static $rightname = 'config';
public const CONFIG_PARENT = \Entity::CONFIG_PARENT;
public static function getMenuName(): string
{
return __('More options', 'moreoptions');
Expand Down Expand Up @@ -104,11 +105,9 @@ public static function preItemUpdate(CommonDBTM $item): CommonDBTM
return $item;
}

foreach (self::getItilConfigFields() as $field) {
if (!isset($item->input[$field])) {
$item->input[$field] = 0;
} elseif ($item->input[$field] == 'on') {
$item->input[$field] = 1;
foreach (self::getAllConfigFields() as $field) {
if (isset($item->input[$field])) {
$item->input[$field] = (int) $item->input[$field];
}
}

Expand All @@ -121,7 +120,6 @@ public static function preItemUpdate(CommonDBTM $item): CommonDBTM
public static function getItilConfigFields(): array
{
return [
'use_parent_entity',
'take_item_group_ticket',
'take_item_group_change',
'take_item_group_problem',
Expand Down Expand Up @@ -153,9 +151,35 @@ public static function getItilConfigFields(): array
'mandatory_task_duration',
'mandatory_task_user',
'mandatory_task_group',
'assign_technician_from_task_ticket',
'assign_technician_from_task_change',
'assign_technician_from_task_problem',
];
}

/**
* @return array<string>
*/
private static function getActorGroupConfigFields(): array
{
return [
'take_requester_group_ticket',
'take_requester_group_change',
'take_requester_group_problem',
'take_technician_group_ticket',
'take_technician_group_change',
'take_technician_group_problem',
];
}

/**
* @return array<string>
*/
private static function getAllConfigFields(): array
{
return array_merge(self::getItilConfigFields(), self::getActorGroupConfigFields());
}

/**
* @return array<int, string>
*/
Expand All @@ -175,24 +199,24 @@ public static function showForEntity(Entity $item): void
'entities_id' => $item->getID(),
]);

// Get effective configuration to show which entity's config is actually used
$effectiveConfig = self::getConfig($item->getID(), true);
$parentEntityInfo = null;

if (($moconfig->fields['use_parent_entity'] ?? false) && ($effectiveConfig->fields['entities_id'] != $item->getID())) {
$parentEntity = new Entity();
if ($parentEntity->getFromDB($effectiveConfig->fields['entities_id'])) {
$parentEntityInfo = $parentEntity->getName();
$inheritance_labels = [];
if ($item->getID() > 0) {
$parentConfig = self::getConfig($item->fields['entities_id'], true);
foreach (self::getItilConfigFields() as $field) {
$inheritance_labels[$field] = self::getInheritedValueBadge($parentConfig->fields[$field] ?? 0);
}
foreach (self::getActorGroupConfigFields() as $field) {
$inheritance_labels[$field] = self::getInheritedValueBadgeForActorGroup($parentConfig->fields[$field] ?? 0);
Comment thread
Lainow marked this conversation as resolved.
}
}

TemplateRenderer::getInstance()->display(
'@moreoptions/config.html.twig',
[
'item' => $moconfig,
'dropdown_options' => self::getSelectableActorGroup(),
'parent_entity_info' => $parentEntityInfo,
'params' => [
'item' => $moconfig,
'dropdown_options' => self::getSelectableActorGroup(),
'inheritance_labels' => $inheritance_labels,
'params' => [
'canedit' => true,
],
],
Expand All @@ -204,13 +228,33 @@ public static function getIcon(): string
return "ti ti-send";
}

private static function getInheritedValueBadge(mixed $value): string
{
$text = match ((int) $value) {
1 => __('Yes'),
default => __('No'),
};
return Entity::inheritedValue(htmlescape($text), false, false);
}

private static function getInheritedValueBadgeForActorGroup(mixed $value): string
{
$options = self::getSelectableActorGroup();
$text = $options[(int) $value] ?? __('No');
return Entity::inheritedValue(htmlescape($text), false, false);
}

public static function addConfig(CommonDBTM $item): void
{
$moconfig = new self();
$moconfig->add([
'is_active' => 0,
'entities_id' => $item->getID(),
]);
$entity_id = $item->getID();
$data = ['entities_id' => $entity_id];
if ($entity_id > 0) {
foreach (self::getAllConfigFields() as $field) {
$data[$field] = self::CONFIG_PARENT;
}
}
$moconfig->add($data);
}

/**
Expand All @@ -222,7 +266,6 @@ public static function addConfig(CommonDBTM $item): void
*/
public static function getConfig(?int $entityId = null, bool $useInheritance = true): self
{
// Use current entity if not specified
if ($entityId === null) {
$entityId = Session::getActiveEntity();
}
Expand All @@ -232,12 +275,15 @@ public static function getConfig(?int $entityId = null, bool $useInheritance = t
'entities_id' => $entityId,
]);

// If inheritance is enabled, use_parent_entity is set, and we're not at root entity
if ($useInheritance && ($moconfig->fields['use_parent_entity'] ?? false) && $entityId > 0) {
if ($useInheritance && $entityId > 0) {
$entity = new Entity();
if ($entity->getFromDB($entityId)) {
$parentId = $entity->fields['entities_id'];
return self::getConfig($parentId, true);
$parentConfig = self::getConfig((int) $entity->fields['entities_id'], true);
foreach (self::getAllConfigFields() as $field) {
if (($moconfig->fields[$field] ?? 0) == self::CONFIG_PARENT) {
$moconfig->fields[$field] = $parentConfig->fields[$field] ?? 0;
}
}
}
}

Expand All @@ -253,18 +299,16 @@ public static function install(Migration $migration): void
$migration->displayMessage("Installing $table");
$query = "CREATE TABLE IF NOT EXISTS `$table` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`is_active` tinyint NOT NULL DEFAULT '1',
Comment thread
Rom1-B marked this conversation as resolved.
`entities_id` int unsigned NOT NULL DEFAULT '0',
`use_parent_entity` tinyint NOT NULL DEFAULT '0',
`take_item_group_ticket` tinyint NOT NULL DEFAULT '-2',
`take_item_group_ticket` tinyint NOT NULL DEFAULT '0',
`take_item_group_change` tinyint NOT NULL DEFAULT '0',
`take_item_group_problem` tinyint NOT NULL DEFAULT '0',
`take_requester_group_ticket` int unsigned NOT NULL DEFAULT '0',
`take_requester_group_change` int unsigned NOT NULL DEFAULT '0',
`take_requester_group_problem` int unsigned NOT NULL DEFAULT '0',
`take_technician_group_ticket` int unsigned NOT NULL DEFAULT '0',
`take_technician_group_change` int unsigned NOT NULL DEFAULT '0',
`take_technician_group_problem` int unsigned NOT NULL DEFAULT '0',
`take_requester_group_ticket` tinyint NOT NULL DEFAULT '0',
`take_requester_group_change` tinyint NOT NULL DEFAULT '0',
`take_requester_group_problem` tinyint NOT NULL DEFAULT '0',
`take_technician_group_ticket` tinyint NOT NULL DEFAULT '0',
`take_technician_group_change` tinyint NOT NULL DEFAULT '0',
`take_technician_group_problem` tinyint NOT NULL DEFAULT '0',
`prevent_closure_ticket` tinyint NOT NULL DEFAULT '0',
`prevent_closure_change` tinyint NOT NULL DEFAULT '0',
`prevent_closure_problem` tinyint NOT NULL DEFAULT '0',
Expand Down Expand Up @@ -293,30 +337,49 @@ public static function install(Migration $migration): void
`mandatory_task_duration` tinyint NOT NULL DEFAULT '0',
`mandatory_task_user` tinyint NOT NULL DEFAULT '0',
`mandatory_task_group` tinyint NOT NULL DEFAULT '0',
`assign_technician_from_task_ticket` tinyint NOT NULL DEFAULT '0',
`assign_technician_from_task_change` tinyint NOT NULL DEFAULT '0',
`assign_technician_from_task_problem` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `entities_id` (`entities_id`),
KEY `is_active` (`is_active`)
Comment thread
Rom1-B marked this conversation as resolved.
KEY `entities_id` (`entities_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC;
";
$DB->doQuery($query);
}

// Migration: Add use_parent_entity column if it doesn't exist
if (!$DB->fieldExists($table, 'use_parent_entity')) {
$migration->displayMessage("Adding use_parent_entity field to $table");
$migration->addField($table, 'use_parent_entity', 'tinyint', [
'after' => 'entities_id',
'value' => 0,
'nodefault' => false,
]);
foreach (self::getActorGroupConfigFields() as $field) {
if ($DB->fieldExists($table, $field)) {
$migration->changeField($table, $field, $field, 'bool', ['value' => '0']);
}
}

foreach (
[
'assign_technician_from_task_ticket',
'assign_technician_from_task_change',
'assign_technician_from_task_problem',
] as $field
) {
if (!$DB->fieldExists($table, $field)) {
$migration->addField($table, $field, 'bool', ['value' => '0']);
}
}

$migration->executeMigration();

$entities = new Entity();
foreach ($entities->find() as $entity) {
if (is_array($entity) && isset($entity['id'])) {
$data = [
'entities_id' => $entity['id'],
];
$entity_id = (int) $entity['id'];
if (countElementsInTable(self::getTable(), ['entities_id' => $entity_id]) > 0) {
continue;
}
$data = ['entities_id' => $entity_id];
if ($entity_id > 0) {
foreach (self::getAllConfigFields() as $field) {
$data[$field] = self::CONFIG_PARENT;
}
}
$DB->insert(
self::getTable(),
$data,
Expand Down
30 changes: 4 additions & 26 deletions src/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ public static function useConfig(CommonDBTM $item): void
}
$moconfig = Config::getConfig();

if ($moconfig->fields['is_active'] != 1) {
return;
}

switch ($item) {
case $item instanceof Ticket_User:
if ($item->fields['type'] == \CommonITILActor::REQUESTER) {
Expand Down Expand Up @@ -132,9 +128,6 @@ public static function useConfig(CommonDBTM $item): void
public static function addItemGroups(CommonDBTM $item): void
{
$conf = Config::getConfig();
if ($conf->fields['is_active'] != 1) {
return;
}

// Mapping of item types to their configuration fields and group classes
$itemMappings = [
Expand Down Expand Up @@ -311,9 +304,6 @@ public static function beforeCloseITILObject(CommonDBTM $item): void
public static function preventClosure(CommonDBTM $item): bool
{
$conf = Config::getConfig();
if ($conf->fields['is_active'] != 1) {
return true;
}

$tasks = [];

Expand Down Expand Up @@ -349,9 +339,6 @@ public static function preventClosure(CommonDBTM $item): bool
public static function requireFieldsToClose(CommonDBTM $item, bool $is_solution = false): bool
{
$conf = Config::getConfig();
if ($conf->fields['is_active'] != 1) {
return true;
}

$message = '';
$itemtype = get_class($item);
Expand Down Expand Up @@ -447,9 +434,6 @@ public static function requireFieldsToClose(CommonDBTM $item, bool $is_solution
public static function checkTaskRequirements(CommonDBTM $item): CommonDBTM
{
$conf = Config::getConfig();
if ($conf->fields['is_active'] != 1) {
return $item;
}

$message = '';
if ($conf->fields['mandatory_task_category'] == 1) {
Expand Down Expand Up @@ -488,9 +472,6 @@ public static function checkTaskRequirements(CommonDBTM $item): CommonDBTM
public static function updateItemActors(CommonITILObject $item): CommonITILObject
{
$conf = Config::getConfig();
if ($conf->fields['is_active'] != 1) {
return $item;
}

switch (get_class($item)) {
case 'Ticket':
Expand Down Expand Up @@ -556,10 +537,7 @@ public static function updateItemActors(CommonITILObject $item): CommonITILObjec
*/
public static function assignTechnicianFromTask(\CommonITILTask $item): void
Comment thread
Lainow marked this conversation as resolved.
{
$conf = Config::getConfig(Session::getActiveEntity());
if ($conf->fields['is_active'] != 1) {
return;
}
$conf = Config::getConfig();

// Check if a technician is assigned to the task
if (empty($item->fields['users_id_tech'])) {
Expand All @@ -571,7 +549,7 @@ public static function assignTechnicianFromTask(\CommonITILTask $item): void
// Determine the parent ITIL object and user link class based on task type
switch ($item::class) {
case TicketTask::class:
if (empty($item->fields['tickets_id'])) {
if ($conf->fields['assign_technician_from_task_ticket'] != 1 || empty($item->fields['tickets_id'])) {
return;
}
$itilObject = new Ticket();
Expand All @@ -581,7 +559,7 @@ public static function assignTechnicianFromTask(\CommonITILTask $item): void
break;

case ChangeTask::class:
if (empty($item->fields['changes_id'])) {
if ($conf->fields['assign_technician_from_task_change'] != 1 || empty($item->fields['changes_id'])) {
return;
}
$itilObject = new Change();
Expand All @@ -591,7 +569,7 @@ public static function assignTechnicianFromTask(\CommonITILTask $item): void
break;

case ProblemTask::class:
if (empty($item->fields['problems_id'])) {
if ($conf->fields['assign_technician_from_task_problem'] != 1 || empty($item->fields['problems_id'])) {
return;
}
$itilObject = new Problem();
Expand Down
Loading