From 8995174d00573a86a7ed0ff06a124e803e253c3f Mon Sep 17 00:00:00 2001 From: Alex Rock Ancelet Date: Fri, 11 Oct 2024 17:37:22 +0200 Subject: [PATCH] First draft of generic asset controller --- src/CommonGLPI.php | 14 +++ src/Glpi/Controller/GenericListcontroller.php | 101 ++++++++++++++++++ src/Software.php | 5 + templates/search/generic_list.html.twig | 39 +++++++ 4 files changed, 159 insertions(+) create mode 100644 src/Glpi/Controller/GenericListcontroller.php create mode 100644 templates/search/generic_list.html.twig diff --git a/src/CommonGLPI.php b/src/CommonGLPI.php index 27bb9dd05ea..3ef7d48b631 100644 --- a/src/CommonGLPI.php +++ b/src/CommonGLPI.php @@ -590,6 +590,20 @@ public function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) return ''; } + public static function getSectorizedDetails(): array + { + return []; + } + + public static function getHeaderParameters(): array + { + return [ + static::getTypeName(\Session::getPluralNumber()), + $_SERVER['PHP_SELF'], + ...static::getSectorizedDetails(), + ]; + } + /** * show Tab content * diff --git a/src/Glpi/Controller/GenericListcontroller.php b/src/Glpi/Controller/GenericListcontroller.php new file mode 100644 index 00000000000..4dca692ec17 --- /dev/null +++ b/src/Glpi/Controller/GenericListcontroller.php @@ -0,0 +1,101 @@ +. + * + * --------------------------------------------------------------------- + */ + +namespace Glpi\Controller; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\Routing\Attribute\Route; + +final class GenericListcontroller extends AbstractController +{ + #[Route("/{type}/search", name: "generic_list")] + public function __invoke(Request $request): Response + { + $type = $request->attributes->getString('type'); + + $class = $this->getClassFromType($type); + + if (!$class) { + throw new NotFoundHttpException(\sprintf('No class found for type "%s".', $type)); + } + + if (!$class::canView()) { + throw new AccessDeniedHttpException(); + } + + return $this->render('search/generic_list.html.twig', [ + 'object_class' => $class, + ]); + } + + /** + * @return class-string<\CommonDBTM>|null + */ + private function getClassFromType(string $type): ?string + { + $class = (new \DbUtils())->fixItemtypeCase($type); + + if ( + $class + && \class_exists($class) + && \is_subclass_of($class, \CommonDBTM::class) + ) { + return $this->normalizeClass($class); + } + + $namespacedClass = \preg_replace_callback('~\\\([a-z])~Uu', static fn($i) => '\\' . \ucfirst($i[1]), 'Glpi\\' . \str_replace('/', '\\', $class)); + + if ( + $namespacedClass + && \class_exists($namespacedClass) + && \is_subclass_of($namespacedClass, \CommonDBTM::class) + ) { + return $this->normalizeClass($namespacedClass); + } + + return null; + } + + private function normalizeClass(string $class): string + { + if (!\class_exists($class)) { + throw new \RuntimeException('Class "$class" does not exist.'); + } + + return (new \ReflectionClass($class))->getName(); + } +} diff --git a/src/Software.php b/src/Software.php index 78da974827e..0cfc904926e 100644 --- a/src/Software.php +++ b/src/Software.php @@ -252,6 +252,11 @@ public function getSpecificMassiveActions($checkitem = null) return $actions; } + public static function getSectorizedDetails(): array + { + return ['assets', 'software']; + } + public static function processMassiveActionsForOneItemtype( MassiveAction $ma, CommonDBTM $item, diff --git a/templates/search/generic_list.html.twig b/templates/search/generic_list.html.twig new file mode 100644 index 00000000000..3720b47152e --- /dev/null +++ b/templates/search/generic_list.html.twig @@ -0,0 +1,39 @@ +{# + # --------------------------------------------------------------------- + # + # GLPI - Gestionnaire Libre de Parc Informatique + # + # http://glpi-project.org + # + # @copyright 2015-2024 Teclib' and contributors. + # @licence https://www.gnu.org/licenses/gpl-3.0.html + # + # --------------------------------------------------------------------- + # + # LICENSE + # + # This file is part of GLPI. + # + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + # + # --------------------------------------------------------------------- + #} + +{% set header_params = call(object_class ~ '::getHeaderParameters') %} + +{{ call('Html::header', header_params) }} + +{{ call('Glpi\\Search\\SearchEngine::show', [object_class]) }} + +{{ call('Html::footer') }}