xref: /webtrees/app/Http/RequestHandlers/ReportSetupPage.php (revision a9b613b19a7bebd6295716a08ffb33e94a76bd34)
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 Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Html;
24use Fisharebest\Webtrees\Http\ViewResponseTrait;
25use Fisharebest\Webtrees\I18N;
26use Fisharebest\Webtrees\Module\ModuleReportInterface;
27use Fisharebest\Webtrees\Registry;
28use Fisharebest\Webtrees\Report\ReportParserSetup;
29use Fisharebest\Webtrees\Services\ModuleService;
30use Fisharebest\Webtrees\Validator;
31use Psr\Http\Message\ResponseInterface;
32use Psr\Http\Message\ServerRequestInterface;
33use Psr\Http\Server\RequestHandlerInterface;
34
35use function redirect;
36use function route;
37
38/**
39 * Get parameters for a report.
40 */
41class ReportSetupPage implements RequestHandlerInterface
42{
43    use ViewResponseTrait;
44
45    private ModuleService $module_service;
46
47    /**
48     * @param ModuleService $module_service
49     */
50    public function __construct(ModuleService $module_service)
51    {
52        $this->module_service = $module_service;
53    }
54
55    /**
56     * @param ServerRequestInterface $request
57     *
58     * @return ResponseInterface
59     */
60    public function handle(ServerRequestInterface $request): ResponseInterface
61    {
62        $tree = Validator::attributes($request)->tree();
63        $user = Validator::attributes($request)->user();
64
65        $report = Validator::attributes($request)->string('report');
66        $module = $this->module_service->findByName($report);
67
68        if (!$module instanceof ModuleReportInterface) {
69            return redirect(route(ReportListPage::class, ['tree' => $tree->name()]));
70        }
71
72        Auth::checkComponentAccess($module, ModuleReportInterface::class, $tree, $user);
73
74        $xref = Validator::queryParams($request)->isXref()->string('xref', '');
75
76        $xml_filename = $module->resourcesFolder() . $module->xmlFilename();
77
78        $report_array = (new ReportParserSetup($xml_filename))->reportProperties();
79        $description  = $report_array['description'];
80        $title        = $report_array['title'];
81
82        $inputs = [];
83
84        foreach ($report_array['inputs'] ?? [] as $n => $input) {
85            $input += [
86                'type'    => 'text',
87                'default' => '',
88                'lookup'  => '',
89                'extra'   => '',
90            ];
91
92            $attributes = [
93                'id'    => 'input-' . $n,
94                'name'  => 'vars[' . $input['name'] . ']',
95                'class' => $input['type'] === 'checkbox' ? 'form-control-check' : 'form-control',
96            ];
97
98            switch ($input['lookup']) {
99                case 'INDI':
100                    $input['control'] = view('components/select-individual', [
101                        'id'         => 'input-' . $n,
102                        'name'       => 'vars[' . $input['name'] . ']',
103                        'individual' => Registry::individualFactory()->make($xref, $tree),
104                        'tree'       => $tree,
105                        'required'   => true,
106                    ]);
107                    break;
108
109                case 'FAM':
110                    $input['control'] = view('components/select-family', [
111                        'id'       => 'input-' . $n,
112                        'name'     => 'vars[' . $input['name'] . ']',
113                        'family'   => Registry::familyFactory()->make($xref, $tree),
114                        'tree'     => $tree,
115                        'required' => true,
116                    ]);
117                    break;
118
119                case 'SOUR':
120                    $input['control'] = view('components/select-source', [
121                        'id'       => 'input-' . $n,
122                        'name'     => 'vars[' . $input['name'] . ']',
123                        'family'   => Registry::sourceFactory()->make($xref, $tree),
124                        'tree'     => $tree,
125                        'required' => true,
126                    ]);
127                    break;
128
129                case 'DATE':
130                    // Need to know if the user prefers DMY/MDY/YMD so we can validate dates properly.
131                    $dmy = I18N::language()->dateOrder();
132
133                    $attributes += [
134                        'type'     => 'text',
135                        'value'    => $input['default'],
136                        'dir'      => 'ltr',
137                        'onchange' => 'webtrees.reformatDate(this, "' . $dmy . '")'
138                    ];
139                    $input['control'] = '<input ' . Html::attributes($attributes) . '>';
140                    $input['extra'] = view('edit/input-addon-calendar', ['id' => 'input-' . $n]);
141                    break;
142
143                default:
144                    switch ($input['type']) {
145                        case 'text':
146                            $attributes += [
147                                'type'  => 'text',
148                                'value' => $input['default'],
149                            ];
150                            $input['control'] = '<input ' . Html::attributes($attributes) . '>';
151                            break;
152
153                        case 'checkbox':
154                            $attributes += [
155                                'type'    => 'checkbox',
156                                'checked' => (bool) $input['default'],
157                            ];
158                            $input['control'] = '<input ' . Html::attributes($attributes) . '>';
159                            break;
160
161                        case 'select':
162                            $options = [];
163                            foreach (explode('|', $input['options']) as $option) {
164                                [$key, $value] = explode('=>', $option);
165                                if (preg_match('/^I18N::number\((.+?)(,([\d+]))?\)$/', $value, $match)) {
166                                    $number        = (float) $match[1];
167                                    $precision     = (int) ($match[3] ?? 0);
168                                    $options[$key] = I18N::number($number, $precision);
169                                } elseif (preg_match('/^I18N::translate\(\'(.+)\'\)$/', $value, $match)) {
170                                    $options[$key] = I18N::translate($match[1]);
171                                } elseif (preg_match('/^I18N::translateContext\(\'(.+)\', *\'(.+)\'\)$/', $value, $match)) {
172                                    $options[$key] = I18N::translateContext($match[1], $match[2]);
173                                }
174                            }
175                            $input['control'] = view('components/select', ['name' => 'vars[' . $input['name'] . ']', 'id' => 'input-' . $n, 'selected' => $input['default'], 'options' => $options]);
176                            break;
177                    }
178            }
179
180            $inputs[] = $input;
181        }
182
183        $destination = $user->getPreference('default-report-destination', 'view');
184        $format      = $user->getPreference('default-report-format', 'PDF');
185
186        return $this->viewResponse('report-setup-page', [
187            'description' => $description,
188            'destination' => $destination,
189            'format'      => $format,
190            'inputs'      => $inputs,
191            'report'      => $report,
192            'title'       => $title,
193            'tree'        => $tree,
194        ]);
195    }
196}
197