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