xref: /webtrees/app/Module/CensusAssistantModule.php (revision 4947e7089adb08f24bf1eef67994a106a8df60aa)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18
19namespace Fisharebest\Webtrees\Module;
20
21use Fisharebest\Webtrees\Census\CensusInterface;
22use Fisharebest\Webtrees\I18N;
23use Fisharebest\Webtrees\Individual;
24use Fisharebest\Webtrees\Tree;
25use Symfony\Component\HttpFoundation\Request;
26use Symfony\Component\HttpFoundation\Response;
27use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
29/**
30 * Class CensusAssistantModule
31 */
32class CensusAssistantModule extends AbstractModule implements ModuleInterface
33{
34    /**
35     * How should this module be labelled on tabs, menus, etc.?
36     *
37     * @return string
38     */
39    public function title(): string
40    {
41        /* I18N: Name of a module */
42        return I18N::translate('Census assistant');
43    }
44
45    /**
46     * A sentence describing what this module does.
47     *
48     * @return string
49     */
50    public function description(): string
51    {
52        /* I18N: Description of the “Census assistant” module */
53        return I18N::translate('An alternative way to enter census transcripts and link them to individuals.');
54    }
55
56    /**
57     * @param Request $request
58     *
59     * @return Response
60     */
61    public function getCensusHeaderAction(Request $request): Response
62    {
63        $census = $request->get('census');
64
65        $html = $this->censusTableHeader(new $census());
66
67        return new Response($html);
68    }
69
70    /**
71     * @param Request $request
72     * @param Tree    $tree
73     *
74     * @return Response
75     */
76    public function getCensusIndividualAction(Request $request, Tree $tree): Response
77    {
78        $census = $request->get('census', '');
79
80        $individual = Individual::getInstance($request->get('xref', ''), $tree);
81        $head       = Individual::getInstance($request->get('head', ''), $tree);
82
83        if ($individual instanceof Individual && $head instanceof Individual) {
84            $html = $this->censusTableRow(new $census(), $individual, $head);
85
86            return new Response($html);
87        } else {
88            throw new NotFoundHttpException();
89        }
90    }
91
92    /**
93     * @param Individual $individual
94     *
95     * @return string
96     */
97    public function createCensusAssistant(Individual $individual): string
98    {
99        return view('modules/census-assistant', [
100            'individual' => $individual,
101        ]);
102    }
103
104    /**
105     * @param Request    $request
106     * @param Individual $individual
107     * @param string     $fact_id
108     * @param string     $newged
109     * @param bool       $keep_chan
110     *
111     * @return string
112     */
113    public function updateCensusAssistant(Request $request, Individual $individual, $fact_id, $newged, $keep_chan): string
114    {
115        $ca_title       = $request->get('ca_title', '');
116        $ca_place       = $request->get('ca_place', '');
117        $ca_citation    = $request->get('ca_citation', '');
118        $ca_individuals = (array) $request->get('ca_individuals');
119        $ca_notes       = $request->get('ca_notes', '');
120        $ca_census      = $request->get('ca_census', '');
121
122        if ($ca_census !== '' && !empty($ca_individuals)) {
123            $census = new $ca_census();
124
125            $note_text   = $this->createNoteText($census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes);
126            $note_gedcom = '0 @@ NOTE ' . str_replace("\n", "\n1 CONT ", $note_text);
127            $note        = $individual->tree()->createRecord($note_gedcom);
128
129            $newged .= "\n2 NOTE @" . $note->xref() . '@';
130
131            // Add the census fact to the rest of the household
132            foreach (array_keys($ca_individuals) as $xref) {
133                if ($xref !== $individual->xref()) {
134                    Individual::getInstance($xref, $individual->tree())
135                        ->updateFact($fact_id, $newged, !$keep_chan);
136                }
137            }
138        }
139
140        return $newged;
141    }
142
143    /**
144     * @param CensusInterface $census
145     * @param string          $ca_title
146     * @param string          $ca_place
147     * @param string          $ca_citation
148     * @param string[][]      $ca_individuals
149     * @param string          $ca_notes
150     *
151     * @return string
152     */
153    private function createNoteText(CensusInterface $census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes): string
154    {
155        $text = $ca_title . "\n" . $ca_citation . "\n" . $ca_place . "\n\n";
156
157        foreach ($census->columns() as $n => $column) {
158            if ($n === 0) {
159                $text .= "\n";
160            } else {
161                $text .= ' | ';
162            }
163            $text .= $column->abbreviation();
164        }
165
166        foreach ($census->columns() as $n => $column) {
167            if ($n === 0) {
168                $text .= "\n";
169            } else {
170                $text .= ' | ';
171            }
172            $text .= '-----';
173        }
174
175        foreach ($ca_individuals as $xref => $columns) {
176            $text .= "\n" . implode(' | ', $columns);
177        }
178
179        return $text . "\n\n" . $ca_notes;
180    }
181
182    /**
183     * Generate an HTML row of data for the census header
184     * Add prefix cell (store XREF and drag/drop)
185     * Add suffix cell (delete button)
186     *
187     * @param CensusInterface $census
188     *
189     * @return string
190     */
191    protected function censusTableHeader(CensusInterface $census): string
192    {
193        $html = '';
194        foreach ($census->columns() as $column) {
195            $html .= '<th class="wt-census-assistant-field" title="' . $column->title() . '">' . $column->abbreviation() . '</th>';
196        }
197
198        return '<tr class="wt-census-assistant-row"><th hidden></th>' . $html . '<th></th></tr>';
199    }
200
201    /**
202     * Generate an HTML row of data for the census
203     * Add prefix cell (store XREF and drag/drop)
204     * Add suffix cell (delete button)
205     *
206     * @param CensusInterface $census
207     *
208     * @return string
209     */
210    public static function censusTableEmptyRow(CensusInterface $census): string
211    {
212        return '<tr class="wt-census-assistant-row"><td hidden></td>' . str_repeat('<td class="wt-census-assistant-field"><input type="text" class="form-control wt-census-assistant-form-control"></td>', count($census->columns())) . '<td><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>';
213    }
214
215    /**
216     * Generate an HTML row of data for the census
217     * Add prefix cell (store XREF and drag/drop)
218     * Add suffix cell (delete button)
219     *
220     * @param CensusInterface $census
221     * @param Individual      $individual
222     * @param Individual      $head
223     *
224     * @return string
225     */
226    public static function censusTableRow(CensusInterface $census, Individual $individual, Individual $head): string
227    {
228        $html = '';
229        foreach ($census->columns() as $column) {
230            $html .= '<td class="wt-census-assistant-field"><input class="form-control wt-census-assistant-form-control" type="text" value="' . $column->generate($individual, $head) . '" name="ca_individuals[' . $individual->xref() . '][]"></td>';
231        }
232
233        return '<tr class="wt-census-assistant-row"><td class="wt-census-assistant-field" hidden>' . $individual->xref() . '</td>' . $html . '<td class="wt-census-assistant-field"><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>';
234    }
235}
236