From d65c59e534eeefe4321bfcd9a7fbf9240be471d5 Mon Sep 17 00:00:00 2001 From: MyuTsu Date: Mon, 28 Sep 2026 17:10:42 +0200 Subject: [PATCH 1/2] feat(group): add escalation links skeleton between groups --- hook.php | 3 + setup.php | 3 + src/Group_Link.php | 150 ++++++++++++++++++++++ src/LinkStrategy/AbstractLinkStrategy.php | 74 +++++++++++ src/LinkStrategy/BasicLink.php | 51 ++++++++ src/LinkStrategy/InheritedLink.php | 56 ++++++++ src/LinkStrategy/LinkStrategyEnum.php | 78 +++++++++++ src/LinkStrategy/NoneLink.php | 56 ++++++++ templates/group_link.html.twig | 30 +++++ 9 files changed, 501 insertions(+) create mode 100644 src/Group_Link.php create mode 100644 src/LinkStrategy/AbstractLinkStrategy.php create mode 100644 src/LinkStrategy/BasicLink.php create mode 100644 src/LinkStrategy/InheritedLink.php create mode 100644 src/LinkStrategy/LinkStrategyEnum.php create mode 100644 src/LinkStrategy/NoneLink.php create mode 100644 templates/group_link.html.twig diff --git a/hook.php b/hook.php index 676ccbb..0948759 100644 --- a/hook.php +++ b/hook.php @@ -35,6 +35,7 @@ use GlpiPlugin\Moreoptions\Config; use GlpiPlugin\Moreoptions\Escalation; +use GlpiPlugin\Moreoptions\Group_Link; function plugin_moreoptions_install(): bool { @@ -42,6 +43,7 @@ function plugin_moreoptions_install(): bool Config::install($migration); Escalation::install($migration); + Group_Link::install($migration); $migration->executeMigration(); return true; } @@ -52,6 +54,7 @@ function plugin_moreoptions_uninstall(): bool Config::uninstall($migration); Escalation::uninstall($migration); + Group_Link::uninstall($migration); return true; } diff --git a/setup.php b/setup.php index 96afaca..dd06f8c 100644 --- a/setup.php +++ b/setup.php @@ -37,6 +37,7 @@ use GlpiPlugin\Moreoptions\Config; use GlpiPlugin\Moreoptions\Controller; use GlpiPlugin\Moreoptions\Escalation; +use GlpiPlugin\Moreoptions\Group_Link; /** @phpstan-ignore theCodingMachineSafe.function (safe to assume this isn't already defined) */ define('PLUGIN_MOREOPTIONS_VERSION', '1.0.0-rc2'); @@ -67,6 +68,8 @@ function plugin_init_moreoptions(): void Plugin::registerClass(Config::class, ['addtabon' => 'Entity']); + Plugin::registerClass(Group_Link::class, ['addtabon' => 'Group']); + $PLUGIN_HOOKS[Hooks::ADD_CSS]['moreoptions'][] = 'css/moreoptions.scss'; $PLUGIN_HOOKS[Hooks::ITEM_ADD]['moreoptions'][Entity::class] = Config::addConfig(...); diff --git a/src/Group_Link.php b/src/Group_Link.php new file mode 100644 index 0000000..025c65f --- /dev/null +++ b/src/Group_Link.php @@ -0,0 +1,150 @@ +isNewItem()) { + return ''; + } + + return self::createTabEntry(self::getTypeName(), 0, $item::class, self::getIcon()); + } + + public static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0): bool + { + if ($item instanceof Group) { + self::showForGroup($item); + } + + return true; + } + + /** + * Renders the "Escalation" tab of the given group. + */ + public static function showForGroup(Group $group): void + { + TemplateRenderer::getInstance()->display('@moreoptions/group_link.html.twig'); + } + + /** + * The links applying in the given entity. For each pair of groups, the link of the closest + * entity wins, from the given entity up to the root entity: a LinkStrategyEnum::BASIC link + * only applies in its own entity, a LinkStrategyEnum::INHERITED one also in its sub-entities, + * and a LinkStrategyEnum::NONE one removes the inherited link from its entity and its + * sub-entities. + * + * @return array> + */ + public static function getLinksForEntity(int $entities_id): array + { + return []; + } + + public function getLinkStrategy(): LinkStrategyEnum + { + return LinkStrategyEnum::tryFrom((string) ($this->fields['link_type'] ?? '')) ?? LinkStrategyEnum::getDefault(); + } + + public static function install(Migration $migration): void + { + /** @var DBmysql $DB */ + global $DB; + + $table = self::getTable(); + if (!$DB->tableExists($table)) { + $migration->displayMessage('Installing ' . $table); + $default_charset = DBConnection::getDefaultCharset(); + $default_collation = DBConnection::getDefaultCollation(); + $default_key_sign = DBConnection::getDefaultPrimaryKeySignOption(); + + $DB->doQuery("CREATE TABLE `{$table}` ( + `id` int {$default_key_sign} NOT NULL AUTO_INCREMENT, + `groups_id_source` int {$default_key_sign} NOT NULL DEFAULT '0', + `groups_id_destination` int {$default_key_sign} NOT NULL DEFAULT '0', + `entities_id` int {$default_key_sign} NOT NULL DEFAULT '0', + `link_type` varchar(30) NOT NULL DEFAULT '', + `date_creation` timestamp NULL DEFAULT NULL, + `date_mod` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `unicity` (`entities_id`, `groups_id_source`, `groups_id_destination`), + KEY `groups_id_source` (`groups_id_source`), + KEY `groups_id_destination` (`groups_id_destination`), + KEY `date_creation` (`date_creation`), + KEY `date_mod` (`date_mod`) + ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC; + "); + } + } + + public static function uninstall(Migration $migration): void + { + $migration->dropTable(self::getTable()); + } +} diff --git a/src/LinkStrategy/AbstractLinkStrategy.php b/src/LinkStrategy/AbstractLinkStrategy.php new file mode 100644 index 0000000..487bec7 --- /dev/null +++ b/src/LinkStrategy/AbstractLinkStrategy.php @@ -0,0 +1,74 @@ + + */ + public function getArrowOptions(): array + { + return []; + } + + /** + * Whether the link is replicated in the sub-entities of its entity + */ + public function appliesToSubEntities(): bool + { + return false; + } + + /** + * Whether the link stops, from its entity, the replication of an inherited link + */ + public function blocksInheritance(): bool + { + return false; + } + + /** + * Get the label of the link strategy + */ + abstract public function getLabel(): string; + + /** + * Get the icon of the link strategy + */ + abstract public function getIcon(): string; +} diff --git a/src/LinkStrategy/BasicLink.php b/src/LinkStrategy/BasicLink.php new file mode 100644 index 0000000..a0d2f75 --- /dev/null +++ b/src/LinkStrategy/BasicLink.php @@ -0,0 +1,51 @@ + new NoneLink(), + self::BASIC => new BasicLink(), + self::INHERITED => new InheritedLink(), + }; + } + + /** + * Get the default strategy + */ + public static function getDefault(): self + { + return self::NONE; + } + + /** + * Get all available link strategies + * + * @return array + */ + public static function getAvailableStrategies(): array + { + $strategies = []; + + foreach (LinkStrategyEnum::cases() as $case) { + $strategies[$case->value] = $case->getStrategy(); + } + + return $strategies; + } +} diff --git a/src/LinkStrategy/NoneLink.php b/src/LinkStrategy/NoneLink.php new file mode 100644 index 0000000..50bdf08 --- /dev/null +++ b/src/LinkStrategy/NoneLink.php @@ -0,0 +1,56 @@ + Date: Mon, 28 Sep 2026 17:19:09 +0200 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ced93a..9019c5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ 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/). -## [unreleased] +## [Unreleased] ### Fixed