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