diff --git a/src/Glpi/Controller/AbstractController.php b/src/Glpi/Controller/AbstractController.php new file mode 100644 index 00000000000..cd010b51579 --- /dev/null +++ b/src/Glpi/Controller/AbstractController.php @@ -0,0 +1,78 @@ +. + * + * --------------------------------------------------------------------- + */ + +namespace Glpi\Controller; + +use Glpi\Application\View\TemplateRenderer; +use Glpi\DependencyInjection\PublicService; +use Symfony\Component\HttpFoundation\Response; + +abstract class AbstractController implements PublicService +{ + /** + * Helper method to get a response containing the content of a rendered + * twig template. + * + * @param string $view Path to a twig template, which will be looked for in + * the "templates" folder. + * For example, "my_template.html.twig" will be resolved to `templates/my_template.html.twig`. + * For plugins, you must use the "@my_plugin_name" prefix. + * For example, "@formcreator/my_template.html.twig will resolve to + * `(plugins|marketplace)/formcreator/templates/my_template.html.twig`. + * @param array $parameters The expected parameters of the twig template. + * @param Response $response Optional parameter which serves as the "base" + * response into which the renderer twig content will be inserted. + * You should only use it if you need to set some specific headers into the + * response or to set an http return code different than 200. + * + * @return Response + */ + final protected function render( + string $view, + array $parameters = [], + Response $response = new Response(), + ): Response { + $twig = TemplateRenderer::getInstance(); + + // We must use output buffering here as Html::header() and Html::footer() + // output content directly. + // TODO: fix header() and footer() methods and remove output buffering + ob_start(); + $twig->display($view, $parameters); + $content = ob_get_clean(); + + $response->setContent($content); + return $response; + } +} diff --git a/src/Glpi/Controller/ApiController.php b/src/Glpi/Controller/ApiController.php index 9b36771ff83..cd22c20b6bb 100644 --- a/src/Glpi/Controller/ApiController.php +++ b/src/Glpi/Controller/ApiController.php @@ -34,7 +34,7 @@ namespace Glpi\Controller; -use Glpi\Api\HL\Controller\AbstractController; +use Glpi\Api\HL\Controller\AbstractController as ApiAbstractController; use Glpi\Api\HL\Router; use Glpi\Application\ErrorHandler; use Glpi\Http\JSONResponse; @@ -46,7 +46,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Attribute\Route; -final readonly class ApiController implements Controller +final class ApiController extends AbstractController { #[Route( "/api.php{request_parameters}", @@ -105,8 +105,8 @@ private function call(): void $response->send(); } catch (\InvalidArgumentException $e) { $response = new JSONResponse( - AbstractController::getErrorResponseBody( - AbstractController::ERROR_INVALID_PARAMETER, + ApiAbstractController::getErrorResponseBody( + ApiAbstractController::ERROR_INVALID_PARAMETER, $e->getMessage() ), 400 diff --git a/src/Glpi/Controller/ApiRestController.php b/src/Glpi/Controller/ApiRestController.php index dfbc613acc4..6541d35aeb7 100644 --- a/src/Glpi/Controller/ApiRestController.php +++ b/src/Glpi/Controller/ApiRestController.php @@ -42,7 +42,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Attribute\Route; -final readonly class ApiRestController implements Controller +final class ApiRestController extends AbstractController { #[Route( "/apirest.php{request_parameters}", diff --git a/src/Glpi/Controller/CaldavController.php b/src/Glpi/Controller/CaldavController.php index 594b76c2ab2..d34e36f70cb 100644 --- a/src/Glpi/Controller/CaldavController.php +++ b/src/Glpi/Controller/CaldavController.php @@ -40,7 +40,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Attribute\Route; -final readonly class CaldavController implements Controller +final class CaldavController extends AbstractController { #[Route( "/caldav.php{request_parameters}", diff --git a/src/Glpi/Controller/Controller.php b/src/Glpi/Controller/Controller.php deleted file mode 100644 index 46b4161a141..00000000000 --- a/src/Glpi/Controller/Controller.php +++ /dev/null @@ -1,44 +0,0 @@ -. - * - * --------------------------------------------------------------------- - */ - -namespace Glpi\Controller; - -use Glpi\DependencyInjection\PublicService; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -interface Controller extends PublicService -{ - public function __invoke(Request $request): Response; -} diff --git a/src/Glpi/Controller/ErrorController.php b/src/Glpi/Controller/ErrorController.php index 03d18c1cdae..a901102572c 100644 --- a/src/Glpi/Controller/ErrorController.php +++ b/src/Glpi/Controller/ErrorController.php @@ -43,7 +43,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; -class ErrorController implements Controller +class ErrorController extends AbstractController { public function __invoke(Request $request, ?\Throwable $exception = null): Response { diff --git a/src/Glpi/Controller/Form/TagListController.php b/src/Glpi/Controller/Form/TagListController.php index 92cf396685a..ea3c645a55b 100644 --- a/src/Glpi/Controller/Form/TagListController.php +++ b/src/Glpi/Controller/Form/TagListController.php @@ -34,7 +34,7 @@ namespace Glpi\Controller\Form; -use Glpi\Controller\Controller; +use Glpi\Controller\AbstractController; use Glpi\Form\Form; use Glpi\Form\Tag\FormTagsManager; use Symfony\Component\HttpFoundation\JsonResponse; @@ -45,7 +45,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Attribute\Route; -final class TagListController implements Controller +final class TagListController extends AbstractController { #[Route( "/Form/TagList", diff --git a/src/Glpi/Controller/IndexController.php b/src/Glpi/Controller/IndexController.php index 1c0e44ef8e9..bfdb4768476 100644 --- a/src/Glpi/Controller/IndexController.php +++ b/src/Glpi/Controller/IndexController.php @@ -48,7 +48,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Attribute\Route; -final readonly class IndexController implements Controller +final class IndexController extends AbstractController { #[Route( [ diff --git a/src/Glpi/Controller/StatusController.php b/src/Glpi/Controller/StatusController.php index be97245bd27..e17c795cdd8 100644 --- a/src/Glpi/Controller/StatusController.php +++ b/src/Glpi/Controller/StatusController.php @@ -44,7 +44,7 @@ use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\Routing\Attribute\Route; -final readonly class StatusController implements Controller +final class StatusController extends AbstractController { #[Route( "/status.php", diff --git a/templates/layout/page_skeleton.html.twig b/templates/layout/page_skeleton.html.twig new file mode 100644 index 00000000000..d2f1ac77746 --- /dev/null +++ b/templates/layout/page_skeleton.html.twig @@ -0,0 +1,43 @@ +{# + # --------------------------------------------------------------------- + # + # 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 . + # + # --------------------------------------------------------------------- + #} + +{% do call(['Html', 'header'], { + title: title, + sector: menu[0] ?? 'none', + item : menu[1] ?? 'none', + option: menu[2] ?? '', +}) %} + +{% block content %} +{% endblock content %} + +{% do call(['Html', 'footer']) %} diff --git a/templates/layout/page_without_tabs.html.twig b/templates/layout/page_without_tabs.html.twig new file mode 100644 index 00000000000..7cf3e615175 --- /dev/null +++ b/templates/layout/page_without_tabs.html.twig @@ -0,0 +1,50 @@ +{# + # --------------------------------------------------------------------- + # + # 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 . + # + # --------------------------------------------------------------------- + #} + +{% extends "layout/page_skeleton.html.twig" %} + +{% block content %} + +
+
+ {% block content_body %} + {% endblock content_body %} +
+
+{% endblock content %}