xref: /webtrees/app/Module/CensusAssistantModule.php (revision cfe766af61e4d860f17afd91dc1b2e538caffa79)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 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 */
16
17namespace Fisharebest\Webtrees\Module;
18
19use Fisharebest\Webtrees\Census\CensusInterface;
20use Fisharebest\Webtrees\I18N;
21use Fisharebest\Webtrees\Individual;
22use Fisharebest\Webtrees\Tree;
23use Symfony\Component\HttpFoundation\Request;
24use Symfony\Component\HttpFoundation\Response;
25
26/**
27 * Class CensusAssistantModule
28 */
29class CensusAssistantModule extends AbstractModule
30{
31    /** {@inheritdoc} */
32    public function getTitle(): string
33    {
34        /* I18N: Name of a module */
35        return I18N::translate('Census assistant');
36    }
37
38    /** {@inheritdoc} */
39    public function getDescription(): string
40    {
41        /* I18N: Description of the “Census assistant” module */
42        return I18N::translate('An alternative way to enter census transcripts and link them to individuals.');
43    }
44
45    /**
46     * @param Request $request
47     *
48     * @return Response
49     */
50    public function getCensusHeaderAction(Request $request): Response
51    {
52        $census = $request->get('census');
53
54        $html = $this->censusTableHeader(new $census());
55
56        return new Response($html);
57    }
58
59    /**
60     * @param Request $request
61     * @param Tree    $tree
62     *
63     * @return Response
64     */
65    public function getCensusIndividualAction(Request $request, Tree $tree): Response
66    {
67        $census = $request->get('census');
68
69        $individual = Individual::getInstance($request->get('xref'), $tree);
70        $head       = Individual::getInstance($request->get('head'), $tree);
71        $html       = $this->censusTableRow(new $census(), $individual, $head);
72
73        return new Response($html);
74    }
75
76    /**
77     * @param Individual $individual
78     *
79     * @return string
80     */
81    public function createCensusAssistant(Individual $individual): string
82    {
83        return view('modules/census-assistant', [
84            'individual' => $individual,
85        ]);
86    }
87
88    /**
89     * @param Request    $request
90     * @param Individual $individual
91     * @param string     $fact_id
92     * @param string     $newged
93     * @param bool       $keep_chan
94     *
95     * @return string
96     */
97    public function updateCensusAssistant(Request $request, Individual $individual, $fact_id, $newged, $keep_chan): string
98    {
99        $ca_title       = $request->get('ca_title', '');
100        $ca_place       = $request->get('ca_place', '');
101        $ca_citation    = $request->get('ca_citation', '');
102        $ca_individuals = (array) $request->get('ca_individuals');
103        $ca_notes       = $request->get('ca_notes', '');
104        $ca_census      = $request->get('ca_census', '');
105
106        if ($ca_census !== '' && !empty($ca_individuals)) {
107            $census = new $ca_census();
108
109            $note_text   = $this->createNoteText($census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes);
110            $note_gedcom = '0 @new@ NOTE ' . str_replace("\n", "\n1 CONT ", $note_text);
111            $note        = $individual->getTree()->createRecord($note_gedcom);
112
113            $newged .= "\n2 NOTE @" . $note->getXref() . '@';
114
115            // Add the census fact to the rest of the household
116            foreach (array_keys($ca_individuals) as $xref) {
117                if ($xref !== $individual->getXref()) {
118                    Individual::getInstance($xref, $individual->getTree())
119                        ->updateFact($fact_id, $newged, !$keep_chan);
120                }
121            }
122        }
123
124        return $newged;
125    }
126
127    /**
128     * @param CensusInterface $census
129     * @param string          $ca_title
130     * @param string          $ca_place
131     * @param string          $ca_citation
132     * @param string[][]      $ca_individuals
133     * @param string          $ca_notes
134     *
135     * @return string
136     */
137    private function createNoteText(CensusInterface $census, $ca_title, $ca_place, $ca_citation, $ca_individuals, $ca_notes): string
138    {
139        $text = $ca_title . "\n" . $ca_citation . "\n" . $ca_place . "\n\n";
140
141        foreach ($census->columns() as $n => $column) {
142            if ($n === 0) {
143                $text .= "\n";
144            } else {
145                $text .= ' | ';
146            }
147            $text .= $column->abbreviation();
148        }
149
150        foreach ($census->columns() as $n => $column) {
151            if ($n === 0) {
152                $text .= "\n";
153            } else {
154                $text .= ' | ';
155            }
156            $text .= '-----';
157        }
158
159        foreach ($ca_individuals as $xref => $columns) {
160            $text .= "\n" . implode(' | ', $columns);
161        }
162
163        return $text . "\n\n" . $ca_notes;
164    }
165
166    /**
167     * Generate an HTML row of data for the census header
168     * Add prefix cell (store XREF and drag/drop)
169     * Add suffix cell (delete button)
170     *
171     * @param CensusInterface $census
172     *
173     * @return string
174     */
175    protected function censusTableHeader(CensusInterface $census): string
176    {
177        $html = '';
178        foreach ($census->columns() as $column) {
179            $html .= '<th class="wt-census-assistant-field" title="' . $column->title() . '">' . $column->abbreviation() . '</th>';
180        }
181
182        return '<tr class="wt-census-assistant-row"><th hidden></th>' . $html . '<th></th></tr>';
183    }
184
185    /**
186     * Generate an HTML row of data for the census
187     * Add prefix cell (store XREF and drag/drop)
188     * Add suffix cell (delete button)
189     *
190     * @param CensusInterface $census
191     *
192     * @return string
193     */
194    public static function censusTableEmptyRow(CensusInterface $census): string
195    {
196        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>';
197    }
198
199    /**
200     * Generate an HTML row of data for the census
201     * Add prefix cell (store XREF and drag/drop)
202     * Add suffix cell (delete button)
203     *
204     * @param CensusInterface $census
205     * @param Individual      $individual
206     * @param Individual      $head
207     *
208     * @return string
209     */
210    public static function censusTableRow(CensusInterface $census, Individual $individual, Individual $head): string
211    {
212        $html = '';
213        foreach ($census->columns() as $column) {
214            $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->getXref() . '][]"></td>';
215        }
216
217        return '<tr class="wt-census-assistant-row"><td class="wt-census-assistant-field" hidden>' . $individual->getXref() . '</td>' . $html . '<td class="wt-census-assistant-field"><a class="icon-remove" href="#" title="' . I18N::translate('Remove') . '"></a></td></tr>';
218    }
219}
220