From 1c4194079cd7475f157e9f69a806e51c9a1cee44 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Thu, 22 Dec 2022 06:08:05 -0500 Subject: [PATCH 1/3] HL API integration --- hook.php | 50 +++++++++++++ inc/apicontroller.class.php | 141 ++++++++++++++++++++++++++++++++++++ setup.php | 5 ++ 3 files changed, 196 insertions(+) create mode 100644 inc/apicontroller.class.php diff --git a/hook.php b/hook.php index 43ad830d..385aa4fa 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,51 @@ 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-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', + ], + 'comment' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Comment', + ], + ] + ] + ]; + } + } + return $data; +} diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php new file mode 100644 index 00000000..b36ae783 --- /dev/null +++ b/inc/apicontroller.class.php @@ -0,0 +1,141 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2014-2022 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\Route; +use Glpi\Http\Request; +use Glpi\Http\Response; + +#[Route(path: '/Tag', priority: 1, tags: ['Tag'])] +final class PluginTagApicontroller extends AbstractController +{ + protected static function getRawKnownSchemas(): array + { + return [ + 'Tag' => [ + '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'])] + #[Doc\Route( + description: 'List or search tags' + )] + public function getTags(Request $request): Response + { + return \Glpi\Api\HL\Search::searchBySchema($this->getKnownSchema('Tag'), $request->getParameters()); + } + + #[Route(path: '/{id}', methods: ['GET'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Get a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ] + ] + )] + public function getTag(Request $request, int $id): Response + { + return \Glpi\Api\HL\Search::getOneBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } + + #[Route(path: '/', methods: ['POST'])] + #[Doc\Route(description: 'Create a new tag', parameters: [ + [ + 'name' => '_', + 'location' => Doc\Parameter::LOCATION_BODY, + 'type' => Doc\Schema::TYPE_OBJECT, + 'schema' => 'Tag', + ] + ])] + public function createTag(Request $request): Response + { + return \Glpi\Api\HL\Search::createBySchema($this->getKnownSchema('Tag'), $request->getParameters(), 'getTag'); + } + + #[Route(path: '/{id}', methods: ['PATCH'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Update a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ], + [ + 'name' => '_', + 'location' => Doc\Parameter::LOCATION_BODY, + 'type' => Doc\Schema::TYPE_OBJECT, + 'schema' => 'Tag', + ] + ], + responses: [ + ['schema' => 'Tag'] + ] + )] + public function updateTag(Request $request, int $id): Response + { + return \Glpi\Api\HL\Search::updateBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } + + #[Route(path: '/{id}', methods: ['DELETE'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Delete a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ] + ] + )] + public function deleteTag(Request $request, int $id): Response + { + return \Glpi\Api\HL\Search::deleteBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } +} diff --git a/setup.php b/setup.php index 70155ef9..a7b56df1 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'; From 52143f914ab38512472f507dd692b8f26283c5b1 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Wed, 22 Apr 2026 17:11:42 -0400 Subject: [PATCH 2/3] update for new api code --- hook.php | 5 +- inc/apicontroller.class.php | 99 +++++++++++++++---------------------- 2 files changed, 40 insertions(+), 64 deletions(-) diff --git a/hook.php b/hook.php index 385aa4fa..751c561d 100644 --- a/hook.php +++ b/hook.php @@ -388,6 +388,7 @@ function plugin_tag_redefine_api_schemas(array $data): 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(), @@ -413,10 +414,6 @@ function plugin_tag_redefine_api_schemas(array $data): array { 'type' => Doc\Schema::TYPE_STRING, 'description' => 'Name', ], - 'comment' => [ - 'type' => Doc\Schema::TYPE_STRING, - 'description' => 'Comment', - ], ] ] ]; diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php index b36ae783..e0b6d624 100644 --- a/inc/apicontroller.class.php +++ b/inc/apicontroller.class.php @@ -30,17 +30,19 @@ 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: '/Tag', priority: 1, tags: ['Tag'])] +#[Route(path: '/Plugin/Tag', priority: 1, tags: ['PluginTag'])] final class PluginTagApicontroller extends AbstractController { protected static function getRawKnownSchemas(): array { return [ - 'Tag' => [ + 'PluginTag' => [ 'type' => Doc\Schema::TYPE_OBJECT, 'x-itemtype' => PluginTagTag::class, 'properties' => [ @@ -57,85 +59,62 @@ protected static function getRawKnownSchemas(): array } #[Route(path: '/', methods: ['GET'])] - #[Doc\Route( - description: 'List or search tags' - )] + #[RouteVersion('2.3.0')] + #[Doc\SearchRoute('PluginTag')] public function getTags(Request $request): Response { - return \Glpi\Api\HL\Search::searchBySchema($this->getKnownSchema('Tag'), $request->getParameters()); + return ResourceAccessor::searchBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getParameters() + ); } #[Route(path: '/{id}', methods: ['GET'], requirements: ['id' => '\d+'])] - #[Doc\Route( - description: 'Get a tag by ID', - parameters: [ - [ - 'name' => 'id', - 'description' => 'The ID of the tag', - 'location' => Doc\Parameter::LOCATION_PATH, - 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] - ] - ] - )] + #[RouteVersion('2.3.0')] + #[Doc\GetRoute('PluginTag')] public function getTag(Request $request, int $id): Response { - return \Glpi\Api\HL\Search::getOneBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return ResourceAccessor::getOneBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + $id + ); } #[Route(path: '/', methods: ['POST'])] - #[Doc\Route(description: 'Create a new tag', parameters: [ - [ - 'name' => '_', - 'location' => Doc\Parameter::LOCATION_BODY, - 'type' => Doc\Schema::TYPE_OBJECT, - 'schema' => 'Tag', - ] - ])] + #[RouteVersion('2.3.0')] + #[Doc\CreateRoute('PluginTag')] public function createTag(Request $request): Response { - return \Glpi\Api\HL\Search::createBySchema($this->getKnownSchema('Tag'), $request->getParameters(), 'getTag'); + return ResourceAccessor::createBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getParameters(), + [self::class, 'getTag'] + ); } #[Route(path: '/{id}', methods: ['PATCH'], requirements: ['id' => '\d+'])] - #[Doc\Route( - description: 'Update a tag by ID', - parameters: [ - [ - 'name' => 'id', - 'description' => 'The ID of the tag', - 'location' => Doc\Parameter::LOCATION_PATH, - 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] - ], - [ - 'name' => '_', - 'location' => Doc\Parameter::LOCATION_BODY, - 'type' => Doc\Schema::TYPE_OBJECT, - 'schema' => 'Tag', - ] - ], - responses: [ - ['schema' => 'Tag'] - ] - )] + #[RouteVersion('2.3.0')] + #[Doc\UpdateRoute('PluginTag')] public function updateTag(Request $request, int $id): Response { - return \Glpi\Api\HL\Search::updateBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return ResourceAccessor::updateBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + ); } #[Route(path: '/{id}', methods: ['DELETE'], requirements: ['id' => '\d+'])] - #[Doc\Route( - description: 'Delete a tag by ID', - parameters: [ - [ - 'name' => 'id', - 'description' => 'The ID of the tag', - 'location' => Doc\Parameter::LOCATION_PATH, - 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] - ] - ] - )] + #[Doc\DeleteRoute('PluginTag')] public function deleteTag(Request $request, int $id): Response { - return \Glpi\Api\HL\Search::deleteBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return ResourceAccessor::deleteBySchema( + $this->getKnownSchema('PluginTag', $this->getAPIVersion($request)), + $request->getAttributes(), + $request->getParameters(), + $id + ); } } From 3fd624362140e0991be438a4017263d15238a651 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Wed, 22 Apr 2026 17:12:23 -0400 Subject: [PATCH 3/3] update header --- inc/apicontroller.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php index e0b6d624..1c008720 100644 --- a/inc/apicontroller.class.php +++ b/inc/apicontroller.class.php @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with Tag. If not, see . * ------------------------------------------------------------------------- - * @copyright Copyright (C) 2014-2022 by Teclib'. + * @copyright Copyright (C) 2014-2026 by Teclib'. * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html * @link https://github.com/pluginsGLPI/tag * -------------------------------------------------------------------------