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