diff --git a/hook.php b/hook.php index ec9c091..5e3715b 100644 --- a/hook.php +++ b/hook.php @@ -28,6 +28,8 @@ * ------------------------------------------------------------------------- */ +use Glpi\Api\HL\Doc as Doc; + // Plugin hook after *Uninstall* function plugin_uninstall_after_tag($item) { $tagitem = new PluginTagTagItem(); @@ -276,3 +278,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 0000000..b36ae78 --- /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 21bf9d1..79479a8 100644 --- a/setup.php +++ b/setup.php @@ -35,7 +35,7 @@ // Minimal GLPI version, inclusive define("PLUGIN_TAG_MIN_GLPI", "10.0.0"); // Maximum GLPI version, exclusive -define("PLUGIN_TAG_MAX_GLPI", "10.0.99"); +define("PLUGIN_TAG_MAX_GLPI", "10.1.99"); /** * Init hooks of the plugin. @@ -135,6 +135,11 @@ function plugin_init_tag() { $PLUGIN_HOOKS['add_javascript']['tag'][] = 'js/entity.js'; } + $PLUGIN_HOOKS[Hooks::REDEFINE_API_SCHEMAS]['tag'] = 'plugin_tag_redefine_api_schemas'; + $PLUGIN_HOOKS[Hooks::API_CONTROLLERS]['tag'] = [ + PluginTagApicontroller::class + ]; + Plugin::registerClass('PluginTagProfile', ['addtabon' => ['Profile']]); Plugin::registerClass('PluginTagConfig', ['addtabon' => 'Config']);