diff --git a/hook.php b/hook.php index 43ad830..751c561 100644 --- a/hook.php +++ b/hook.php @@ -61,6 +61,8 @@ * ------------------------------------------------------------------------- */ +use Glpi\Api\HL\Doc as Doc; + // Plugin hook after *Uninstall* function plugin_uninstall_after_tag($item) { @@ -374,3 +376,48 @@ function plugin_tag_getRuleActions($params = []) return $actions; } + +function plugin_tag_redefine_api_schemas(array $data): array { + foreach ($data['schemas'] as &$schema) { + if (!isset($schema['x-itemtype'])) { + continue; + } + if (PluginTagTag::canItemtype($schema['x-itemtype'])) { + $schema['properties']['tags'] = [ + 'type' => Doc\Schema::TYPE_ARRAY, + 'description' => 'Tags', + 'items' => [ + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-full-schema' => 'PluginTag', + 'x-join' => [ + // This is the join with the desired data + 'table' => PluginTagTag::getTable(), + 'fkey' => 'plugin_tag_tags_id', + 'field' => 'id', + 'ref-join' => [ + // This is the linking join between the main item and the data needed + 'table' => PluginTagTagItem::getTable(), + 'fkey' => 'id', // ID field on the main join table + 'field' => 'items_id', // items_id field on the linking join table + // Join params becomes tags_ref.items_id=_.id + 'condition' => [ + 'itemtype' => $schema['x-itemtype'] + ], + ] + ], + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'description' => 'ID', + ], + 'name' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Name', + ], + ] + ] + ]; + } + } + return $data; +} diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php new file mode 100644 index 0000000..1c00872 --- /dev/null +++ b/inc/apicontroller.class.php @@ -0,0 +1,120 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2014-2026 by Teclib'. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/tag + * ------------------------------------------------------------------------- + */ + +use Glpi\Api\HL\Controller\AbstractController; +use Glpi\Api\HL\Doc as Doc; +use Glpi\Api\HL\ResourceAccessor; +use Glpi\Api\HL\Route; +use Glpi\Api\HL\RouteVersion; +use Glpi\Http\Request; +use Glpi\Http\Response; + +#[Route(path: '/Plugin/Tag', priority: 1, tags: ['PluginTag'])] +final class PluginTagApicontroller extends AbstractController +{ + protected static function getRawKnownSchemas(): array + { + return [ + 'PluginTag' => [ + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-itemtype' => PluginTagTag::class, + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'format' => Doc\Schema::FORMAT_INTEGER_INT64, + 'x-readonly' => true, + ], + 'name' => ['type' => Doc\Schema::TYPE_STRING], + 'comment' => ['type' => Doc\Schema::TYPE_STRING], + ] + ] + ]; + } + + #[Route(path: '/', methods: ['GET'])] + #[RouteVersion('2.3.0')] + #[Doc\SearchRoute('PluginTag')] + public function getTags(Request $request): Response + { + return ResourceAccessor::searchBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getParameters() + ); + } + + #[Route(path: '/{id}', methods: ['GET'], requirements: ['id' => '\d+'])] + #[RouteVersion('2.3.0')] + #[Doc\GetRoute('PluginTag')] + public function getTag(Request $request, int $id): Response + { + return ResourceAccessor::getOneBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + $id + ); + } + + #[Route(path: '/', methods: ['POST'])] + #[RouteVersion('2.3.0')] + #[Doc\CreateRoute('PluginTag')] + public function createTag(Request $request): Response + { + return ResourceAccessor::createBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getParameters(), + [self::class, 'getTag'] + ); + } + + #[Route(path: '/{id}', methods: ['PATCH'], requirements: ['id' => '\d+'])] + #[RouteVersion('2.3.0')] + #[Doc\UpdateRoute('PluginTag')] + public function updateTag(Request $request, int $id): Response + { + return ResourceAccessor::updateBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + ); + } + + #[Route(path: '/{id}', methods: ['DELETE'], requirements: ['id' => '\d+'])] + #[Doc\DeleteRoute('PluginTag')] + public function deleteTag(Request $request, int $id): Response + { + return ResourceAccessor::deleteBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + $id + ); + } +} diff --git a/setup.php b/setup.php index 70155ef..a7b56df 100644 --- a/setup.php +++ b/setup.php @@ -153,6 +153,11 @@ function plugin_init_tag() // plugin datainjection $PLUGIN_HOOKS['plugin_datainjection_populate']['tag'] = "plugin_datainjection_populate_tag"; + $PLUGIN_HOOKS[Hooks::REDEFINE_API_SCHEMAS]['tag'] = 'plugin_tag_redefine_api_schemas'; + $PLUGIN_HOOKS[Hooks::API_CONTROLLERS]['tag'] = [ + PluginTagApicontroller::class + ]; + // add needed javascript & css files $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['tag'][] = 'js/common.js'; $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['tag'][] = 'js/kanban.js';