xref: /webtrees/app/Http/RequestHandlers/ReportGenerate.php (revision 3e9d1108c60ae9ef5529fec9d07b46f7d3ecbd94)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2023 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22use Fig\Http\Message\StatusCodeInterface;
23use Fisharebest\Webtrees\Auth;
24use Fisharebest\Webtrees\Http\ViewResponseTrait;
25use Fisharebest\Webtrees\I18N;
26use Fisharebest\Webtrees\Module\ModuleReportInterface;
27use Fisharebest\Webtrees\Report\HtmlRenderer;
28use Fisharebest\Webtrees\Report\PdfRenderer;
29use Fisharebest\Webtrees\Report\ReportParserGenerate;
30use Fisharebest\Webtrees\Services\ModuleService;
31use Fisharebest\Webtrees\Validator;
32use Psr\Http\Message\ResponseInterface;
33use Psr\Http\Message\ServerRequestInterface;
34use Psr\Http\Server\RequestHandlerInterface;
35
36use function addcslashes;
37use function ob_get_clean;
38use function ob_start;
39use function redirect;
40use function response;
41use function route;
42
43/**
44 * Show all available reports.
45 */
46class ReportGenerate implements RequestHandlerInterface
47{
48    use ViewResponseTrait;
49
50    private ModuleService $module_service;
51
52    /**
53     * ReportEngineController constructor.
54     *
55     * @param ModuleService $module_service
56     */
57    public function __construct(ModuleService $module_service)
58    {
59        $this->module_service = $module_service;
60    }
61
62    /**
63     * A list of available reports.
64     *
65     * @param ServerRequestInterface $request
66     *
67     * @return ResponseInterface
68     */
69    public function handle(ServerRequestInterface $request): ResponseInterface
70    {
71        $tree   = Validator::attributes($request)->tree();
72        $user   = Validator::attributes($request)->user();
73        $report = Validator::attributes($request)->string('report');
74        $module = $this->module_service->findByName($report);
75
76        if (!$module instanceof ModuleReportInterface) {
77            return redirect(route(ReportListPage::class, ['tree' => $tree->name()]));
78        }
79
80        Auth::checkComponentAccess($module, ModuleReportInterface::class, $tree, $user);
81
82        $varnames  = Validator::queryParams($request)->array('varnames');
83        $vars      = Validator::queryParams($request)->array('vars');
84        $variables = [];
85
86        foreach ($varnames as $name) {
87            $variables[$name]['id'] = $vars[$name] ?? '';
88        }
89
90        $xml_filename = $module->resourcesFolder() . $module->xmlFilename();
91        $format       = Validator::queryParams($request)->string('format');
92        $destination  = Validator::queryParams($request)->string('destination');
93
94        $user->setPreference('default-report-destination', $destination);
95        $user->setPreference('default-report-format', $format);
96
97        switch ($format) {
98            default:
99            case 'HTML':
100                ob_start();
101                new ReportParserGenerate($xml_filename, new HtmlRenderer(), $variables, $tree);
102                $html = ob_get_clean();
103
104                $this->layout = 'layouts/report';
105
106                $response = $this->viewResponse('report-page', [
107                    'content' => $html,
108                    'title'   => I18N::translate('Report'),
109                ]);
110
111                if ($destination === 'download') {
112                    $response = $response->withHeader('content-disposition', 'attachment; filename="' . addcslashes($report, '"') . '.html"');
113                }
114
115                return $response;
116
117            case 'PDF':
118                ob_start();
119                new ReportParserGenerate($xml_filename, new PdfRenderer(), $variables, $tree);
120                $pdf = ob_get_clean();
121
122                $headers = ['content-type' => 'application/pdf'];
123
124                if ($destination === 'download') {
125                    $headers['content-disposition'] = 'attachment; filename="' . addcslashes($report, '"') . '.pdf"';
126                }
127
128                return response($pdf, StatusCodeInterface::STATUS_OK, $headers);
129        }
130    }
131}
132