xref: /webtrees/app/Http/RequestHandlers/ReportGenerate.php (revision 7ef421a4290b6b468944b845497d6139b0eddd3f)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 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 <http://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\Contracts\UserInterface;
25use Fisharebest\Webtrees\Http\ViewResponseTrait;
26use Fisharebest\Webtrees\I18N;
27use Fisharebest\Webtrees\Module\ModuleReportInterface;
28use Fisharebest\Webtrees\Report\ReportHtml;
29use Fisharebest\Webtrees\Report\ReportParserGenerate;
30use Fisharebest\Webtrees\Report\ReportPdf;
31use Fisharebest\Webtrees\Services\ModuleService;
32use Fisharebest\Webtrees\Tree;
33use Psr\Http\Message\ResponseInterface;
34use Psr\Http\Message\ServerRequestInterface;
35use Psr\Http\Server\RequestHandlerInterface;
36
37use function addcslashes;
38use function assert;
39use function ob_get_clean;
40use function ob_start;
41use function redirect;
42use function response;
43use function route;
44
45/**
46 * Show all available reports.
47 */
48class ReportGenerate implements RequestHandlerInterface
49{
50    use ViewResponseTrait;
51
52    /**
53     * @var ModuleService
54     */
55    private $module_service;
56
57    /**
58     * ReportEngineController constructor.
59     *
60     * @param ModuleService $module_service
61     */
62    public function __construct(ModuleService $module_service)
63    {
64        $this->module_service = $module_service;
65    }
66
67    /**
68     * A list of available reports.
69     *
70     * @param ServerRequestInterface $request
71     *
72     * @return ResponseInterface
73     */
74    public function handle(ServerRequestInterface $request): ResponseInterface
75    {
76        $tree = $request->getAttribute('tree');
77        assert($tree instanceof Tree);
78
79        $user = $request->getAttribute('user');
80        assert($user instanceof UserInterface);
81
82        $report = $request->getAttribute('report');
83        $module = $this->module_service->findByName($report);
84
85        if (!$module instanceof ModuleReportInterface) {
86            return redirect(route(ReportListPage::class, ['tree' => $tree->name()]));
87        }
88
89        Auth::checkComponentAccess($module, 'report', $tree, $user);
90
91        $varnames  = $request->getQueryParams()['varnames'] ?? [];
92        $vars      = $request->getQueryParams()['vars'] ?? [];
93        $variables = [];
94
95        foreach ($varnames as $name) {
96            $variables[$name]['id'] = $vars[$name] ?? '';
97        }
98
99        $xml_filename = $module->resourcesFolder() . $module->xmlFilename();
100
101        $format      = $request->getQueryParams()['format'] ?? '';
102        $destination = $request->getQueryParams()['destination'] ?? '';
103
104        switch ($format) {
105            default:
106            case 'HTML':
107                ob_start();
108                new ReportParserGenerate($xml_filename, new ReportHtml(), $variables, $tree);
109                $html = ob_get_clean();
110
111                $this->layout = 'layouts/report';
112
113                $response = $this->viewResponse('report-page', [
114                    'content' => $html,
115                    'title'   => I18N::translate('Report'),
116                ]);
117
118                if ($destination === 'download') {
119                    $response = $response->withHeader('Content-Disposition', 'attachment; filename="' . addcslashes($report, '"') . '.html"');
120                }
121
122                return $response;
123
124            case 'PDF':
125                ob_start();
126                new ReportParserGenerate($xml_filename, new ReportPdf(), $variables, $tree);
127                $pdf = ob_get_clean();
128
129                $headers = ['Content-Type' => 'application/pdf'];
130
131                if ($destination === 'download') {
132                    $headers['Content-Disposition'] = 'attachment; filename="' . addcslashes($report, '"') . '.pdf"';
133                }
134
135                return response($pdf, StatusCodeInterface::STATUS_OK, $headers);
136        }
137    }
138}
139