diff options
| author | Greg Roach <fisharebest@webtrees.net> | 2018-12-14 09:36:19 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@webtrees.net> | 2018-12-14 09:36:19 +0000 |
| commit | c0dc1dc8776d0d9214741483e39305c5e08e2358 (patch) | |
| tree | 1ab8045b0041bb90346dd2704208cffbbfbbd9be | |
| parent | 1efebf18750c84c258e87e294e56bd7ef897b541 (diff) | |
| download | webtrees-c0dc1dc8776d0d9214741483e39305c5e08e2358.tar.gz webtrees-c0dc1dc8776d0d9214741483e39305c5e08e2358.tar.bz2 webtrees-c0dc1dc8776d0d9214741483e39305c5e08e2358.zip | |
Refactor clipboard functionality to a ClipboardService
| -rw-r--r-- | app/Functions/FunctionsPrint.php | 81 | ||||
| -rw-r--r-- | app/Http/Controllers/EditGedcomRecordController.php | 48 | ||||
| -rw-r--r-- | app/Services/ClipboardService.php | 115 | ||||
| -rw-r--r-- | resources/views/edit/add-fact-row.phtml | 50 | ||||
| -rw-r--r-- | resources/views/edit/paste-fact-row.phtml | 33 | ||||
| -rwxr-xr-x | themes/clouds/css-2.0.0/style.css | 5 | ||||
| -rwxr-xr-x | themes/colors/css-2.0.0/style.css | 5 | ||||
| -rwxr-xr-x | themes/fab/css-2.0.0/style.css | 5 | ||||
| -rwxr-xr-x | themes/minimal/css-2.0.0/style.css | 5 | ||||
| -rwxr-xr-x | themes/webtrees/css-2.0.0/style.css | 5 | ||||
| -rwxr-xr-x | themes/xenea/css-2.0.0/style.css | 5 |
11 files changed, 227 insertions, 130 deletions
diff --git a/app/Functions/FunctionsPrint.php b/app/Functions/FunctionsPrint.php index 6a2d7138b6..1e1c2aa3c9 100644 --- a/app/Functions/FunctionsPrint.php +++ b/app/Functions/FunctionsPrint.php @@ -32,6 +32,7 @@ use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Note; use Fisharebest\Webtrees\Place; +use Fisharebest\Webtrees\Services\ClipboardService; use Fisharebest\Webtrees\Session; use Fisharebest\Webtrees\Theme; use Fisharebest\Webtrees\Tree; @@ -479,42 +480,10 @@ class FunctionsPrint * * @return void */ - public static function printAddNewFact(GedcomRecord $record, $usedfacts, $type) + public static function printAddNewFact(GedcomRecord $record, $usedfacts, $type): void { $tree = $record->tree(); - // -- Add from clipboard - if (is_array(Session::get('clipboard'))) { - $newRow = true; - foreach (array_reverse(Session::get('clipboard'), true) as $fact_id => $fact) { - if ($fact['type'] == $type || $fact['type'] == 'all') { - if ($newRow) { - $newRow = false; - echo '<tr><th scope="row">'; - echo I18N::translate('Add from clipboard'), '</th>'; - echo '<td><form name="newFromClipboard" onsubmit="return false;">'; - echo '<select id="newClipboardFact">'; - } - echo '<option value="', e($fact_id), '">', GedcomTag::getLabel($fact['fact']); - // TODO use the event class to store/parse the clipboard events - if (preg_match('/^2 DATE (.+)/m', $fact['factrec'], $match)) { - $tmp = new Date($match[1]); - echo '; ', $tmp->minimumDate()->format('%Y'); - } - if (preg_match('/^2 PLAC ([^,\n]+)/m', $fact['factrec'], $match)) { - echo '; ', $match[1]; - } - echo '</option>'; - } - } - if (!$newRow) { - echo '</select>'; - /* I18N: A button label. */ - echo ' <input type="button" value="', I18N::translate('add'), '" onclick="return paste_fact(\'' . e($tree->name()) . '\',\'' . e($record->xref()) . '\', \'#newClipboardFact\');"> '; - echo '</form></td></tr>', "\n"; - } - } - // -- Add from pick list switch ($type) { case 'INDI': @@ -559,36 +528,20 @@ class FunctionsPrint uasort($translated_addfacts, function (string $x, string $y): int { return I18N::strcasecmp(I18N::translate($x), I18N::translate($y)); }); - echo '<tr><th scope="row">'; - echo I18N::translate('Fact or event'); - echo '</th>'; - echo '<td>'; - echo '<form onsubmit="if ($("#add-fact").val() === null) {event.preventDefault();}">'; - echo '<input type="hidden" name="route" value="add-fact">'; - echo '<input type="hidden" name="xref" value="' . e($record->xref()) . '">'; - echo '<input type="hidden" name="ged" value="' . e($tree->name()) . '">'; - echo '<select id="add-fact" name="fact">'; - echo '<option value="" disabled selected>' . I18N::translate('<select>') . '</option>'; - foreach ($translated_addfacts as $fact => $fact_name) { - echo '<option value="', $fact, '">', $fact_name, '</option>'; - } - if ($type == 'INDI' || $type == 'FAM') { - echo '<option value="FACT">', I18N::translate('Custom fact'), '</option>'; - echo '<option value="EVEN">', I18N::translate('Custom event'), '</option>'; - } - echo '</select>'; - /* I18N: A button label. */ - echo '<input type="submit" value="', I18N::translate('add'), '">'; - echo '</form>'; - echo '<span class="quickfacts">'; - foreach ($quickfacts as $fact) { - echo '<a href="' . e(route('add-fact', [ - 'fact' => $fact, - 'xref' => $record->xref(), - 'ged' => $tree->name(), - ])) . '">', GedcomTag::getLabel($fact), '</a>'; - } - echo '</span>'; - echo '</td></tr>'; + + $clipboard_service = new ClipboardService(); + + $pastable_facts = $clipboard_service->pastableFacts($record); + + echo view('edit/paste-fact-row', [ + 'facts' => $pastable_facts, + 'record' => $record, + ]); + + echo view('edit/add-fact-row', [ + 'add_facts' => $translated_addfacts, + 'quick_facts' => $quickfacts, + 'record' => $record, + ]); } } diff --git a/app/Http/Controllers/EditGedcomRecordController.php b/app/Http/Controllers/EditGedcomRecordController.php index 040c413c2e..7c265e4716 100644 --- a/app/Http/Controllers/EditGedcomRecordController.php +++ b/app/Http/Controllers/EditGedcomRecordController.php @@ -27,7 +27,7 @@ use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; use Fisharebest\Webtrees\Module; use Fisharebest\Webtrees\Module\CensusAssistantModule; -use Fisharebest\Webtrees\Session; +use Fisharebest\Webtrees\Services\ClipboardService; use Fisharebest\Webtrees\Tree; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -44,12 +44,13 @@ class EditGedcomRecordController extends AbstractEditController /** * Copy a fact to the clipboard. * - * @param Request $request - * @param Tree $tree + * @param Request $request + * @param Tree $tree + * @param ClipboardService $clipboard_service * * @return Response */ - public function copyFact(Request $request, Tree $tree): Response + public function copyFact(Request $request, Tree $tree, ClipboardService $clipboard_service): Response { $xref = $request->get('xref', ''); $fact_id = $request->get('fact_id'); @@ -59,31 +60,9 @@ class EditGedcomRecordController extends AbstractEditController $this->checkRecordAccess($record, true); foreach ($record->facts() as $fact) { - if ($fact->id() == $fact_id) { - switch ($fact->getTag()) { - case 'NOTE': - case 'SOUR': - case 'OBJE': - $type = 'all'; // paste this anywhere - break; - default: - $type = $record::RECORD_TYPE; // paste only to the same record type - break; - } - $clipboard = Session::get('clipboard'); - if (!is_array($clipboard)) { - $clipboard = []; - } - $clipboard[$fact_id] = [ - 'type' => $type, - 'factrec' => $fact->gedcom(), - 'fact' => $fact->getTag(), - ]; - - // The clipboard only holds 10 facts - $clipboard = array_slice($clipboard, -10); + if ($fact->id() === $fact_id) { + $clipboard_service->copyFact($fact); - Session::put('clipboard', $clipboard); FlashMessages::addMessage(I18N::translate('The record has been copied to the clipboard.')); break; } @@ -178,12 +157,13 @@ class EditGedcomRecordController extends AbstractEditController /** * Paste a fact from the clipboard into a record. * - * @param Request $request - * @param Tree $tree + * @param Request $request + * @param Tree $tree + * @param ClipboardService $clipboard_service * * @return Response */ - public function pasteFact(Request $request, Tree $tree): Response + public function pasteFact(Request $request, Tree $tree, ClipboardService $clipboard_service): Response { $xref = $request->get('xref', ''); $fact_id = $request->get('fact_id'); @@ -192,11 +172,7 @@ class EditGedcomRecordController extends AbstractEditController $this->checkRecordAccess($record, true); - $clipboard = Session::get('clipboard'); - - if (isset($clipboard[$fact_id])) { - $record->createFact($clipboard[$fact_id]['factrec'], true); - } + $clipboard_service->pasteFact($fact_id, $record); return new Response(); } diff --git a/app/Services/ClipboardService.php b/app/Services/ClipboardService.php new file mode 100644 index 0000000000..afe4b98e9b --- /dev/null +++ b/app/Services/ClipboardService.php @@ -0,0 +1,115 @@ +<?php +/** + * webtrees: online genealogy + * Copyright (C) 2018 webtrees development team + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +declare(strict_types=1); + +namespace Fisharebest\Webtrees\Services; + +use Fisharebest\Webtrees\Fact; +use Fisharebest\Webtrees\GedcomRecord; +use Fisharebest\Webtrees\Session; + +/** + * Copy and past facts between records. + */ +class ClipboardService +{ + // Maximum number of entries in the clipboard. + private const CLIPBOARD_SIZE = 10; + + /** + * Copy a fact to the clipboard. + * + * @param Fact $fact + */ + public function copyFact(Fact $fact): void { + $clipboard = Session::get('clipboard', []); + + switch ($fact->getTag()) { + case 'NOTE': + case 'SOUR': + case 'OBJE': + // paste this anywhere + $type = 'all'; + break; + default: + // paste only to the same record type + $type = $fact->record()::RECORD_TYPE; + break; + } + + // If we are copying the same fact twice, make sure the new one is at the top. + $fact_id = $fact->id(); + + unset($clipboard[$fact_id]); + + $clipboard[$fact_id] = [ + 'type' => $type, + 'factrec' => $fact->gedcom(), + 'fact' => $fact->getTag(), + ]; + + // The clipboard only holds a limited number of facts. + $clipboard = array_slice($clipboard, -self::CLIPBOARD_SIZE); + + Session::put('clipboard', $clipboard); + } + + /** + * Copy a fact from the clipboard to a record. + * + * @param string $fact_id + * @param GedcomRecord $record + * + * @return bool + */ + public function pasteFact(string $fact_id, GedcomRecord $record): bool { + $clipboard = Session::get('clipboard'); + + if (isset($clipboard[$fact_id])) { + $record->createFact($clipboard[$fact_id]['factrec'], true); + return true; + } + + return false; + } + + /** + * Createa a list of facts that can be pasted into a given record + * + * @param GedcomRecord $gedcom_record + * + * @return Fact[] + */ + public function pastableFacts(GedcomRecord $gedcom_record): array { + // The facts are stored in the session. + $clipboard = Session::get('clipboard', []); + + // Put the most recently copied fact at the top of the list. + $clipboard = array_reverse($clipboard); + + // Only include facts that can be pasted onto this record. + $clipboard = array_filter($clipboard, function(array $clipping) use ($gedcom_record): bool { + return $clipping['type'] == $gedcom_record::RECORD_TYPE || $clipping['type'] == 'all'; + }); + + // Create facts for the record. + $facts = array_map(function(array $clipping) use ($gedcom_record): Fact { + return new Fact($clipping['factrec'], $gedcom_record, md5($clipping['factrec'])); + }, $clipboard); + + return $facts; + } +} diff --git a/resources/views/edit/add-fact-row.phtml b/resources/views/edit/add-fact-row.phtml new file mode 100644 index 0000000000..4979054eef --- /dev/null +++ b/resources/views/edit/add-fact-row.phtml @@ -0,0 +1,50 @@ +<?php use Fisharebest\Webtrees\GedcomTag; ?> +<?php use Fisharebest\Webtrees\I18N; ?> + +<tr> + <th scope="row"> + <?= I18N::translate('Fact or event') ?> + </th> + <td> + <form onsubmit="if ($('#add-fact').val() === null) {event.preventDefault();}"> + <input type="hidden" name="route" value="add-fact"> + <input type="hidden" name="xref" value="<?= e($record->xref()) ?>"> + <input type="hidden" name="ged" value="<?= e($record->tree()->name()) ?>"> + <div class="input-group"> + <select class="form-control" id="add-fact" name="fact"> + <option value="" disabled selected> + <?= I18N::translate('<select>') ?> + </option> + <?php foreach ($add_facts as $fact => $fact_name) : ?> + <option value="<?= $fact ?>"><?= $fact_name ?></option> + <?php endforeach ?> + <?php if ($record::RECORD_TYPE === 'INDI' || $record::RECORD_TYPE === 'FAM') : ?> + <option value="FACT"> + <?= I18N::translate('Custom fact') ?> + </option> + <option value="EVEN"> + <?= I18N::translate('Custom event') ?> + </option> + <?php endif ?> + </select> + <div class="input-group-append"> + <button class="btn btn-light" type="submit"> + <?= /* I18N: A button label. */ I18N::translate('add') ?> + </button> + </div> + </div> + </form> + + <div class="wt-quick-facts"> + <?php foreach ($quick_facts as $fact) : ?> + <a class="btn btn-link btn-sm wt-quick-fact" href="<?= e(route('add-fact', [ + 'fact' => $fact, + 'xref' => $record->xref(), + 'ged' => $tree->name(), + ])) ?>"> + <?= GedcomTag::getLabel($fact) ?> + </a> + <?php endforeach ?> + </div> + </td> +</tr> diff --git a/resources/views/edit/paste-fact-row.phtml b/resources/views/edit/paste-fact-row.phtml new file mode 100644 index 0000000000..33521107fb --- /dev/null +++ b/resources/views/edit/paste-fact-row.phtml @@ -0,0 +1,33 @@ +<?php use Fisharebest\Webtrees\I18N; ?> + +<?php if (!empty($facts)) : ?> +<tr> + <th scope="row"> + <?= I18N::translate('Add from clipboard') ?> + </th> + <td> + <form name="newFromClipboard" onsubmit="return false;"> + <div class="input-group"> + <select class="form-control" id="newClipboardFact"> + <?php foreach ($facts as $fact) : ?> + <option value="<?= e($fact->id()) ?>"> + <?= $fact->label() ?> + <?php if ($fact->date()->isOK()) : ?> + – <?= $fact->date()->minimumDate()->format('%Y') ?> + <?php endif ?> + <?php if (!$fact->place()->isEmpty()) : ?> + – <?= $fact->place()->getShortName() ?> + <?php endif ?> + </option> + <?php endforeach ?> + </select> + <div class="input-group-append"> + <button class="btn btn-light" type="submit" onclick="return paste_fact('<?= e($tree->name()) ?>', '<?= e($record->xref()) ?>', '#newClipboardFact');"> + <?= /* I18N: A button label. */ I18N::translate('add') ?> + </button> + </div> + </div> + </form> + </td> +</tr> +<?php endif ?> diff --git a/themes/clouds/css-2.0.0/style.css b/themes/clouds/css-2.0.0/style.css index 209e895195..fdfa133a1d 100755 --- a/themes/clouds/css-2.0.0/style.css +++ b/themes/clouds/css-2.0.0/style.css @@ -1249,11 +1249,6 @@ div.fact_SHARED_NOTE { background-color: #fdd; } -.quickfacts a { - padding: 0 3px; - font-size: 9px; -} - .tabs_table { width: 99%; } diff --git a/themes/colors/css-2.0.0/style.css b/themes/colors/css-2.0.0/style.css index fef9ccb729..8a5d945a61 100755 --- a/themes/colors/css-2.0.0/style.css +++ b/themes/colors/css-2.0.0/style.css @@ -1151,11 +1151,6 @@ div.fact_SHARED_NOTE { background-color: #fdd; } -.quickfacts a { - padding: 0 3px; - font-size: 9px; -} - .tabs_table { width: 99%; } diff --git a/themes/fab/css-2.0.0/style.css b/themes/fab/css-2.0.0/style.css index 555e409ba7..032aa5d24d 100755 --- a/themes/fab/css-2.0.0/style.css +++ b/themes/fab/css-2.0.0/style.css @@ -691,11 +691,6 @@ div.fact_SHARED_NOTE { background-color: #fdd; } -.quickfacts a { - padding: 0 3px; - font-size: 9px; -} - .tabs_table { width: 99%; } diff --git a/themes/minimal/css-2.0.0/style.css b/themes/minimal/css-2.0.0/style.css index 7a25c66942..f48d0366d3 100755 --- a/themes/minimal/css-2.0.0/style.css +++ b/themes/minimal/css-2.0.0/style.css @@ -623,11 +623,6 @@ table { margin: 0 auto; } -.quickfacts a { - font-size: .75rem; - padding: 0 3px; -} - #reportengine-page .report-type { overflow: hidden; margin: auto; diff --git a/themes/webtrees/css-2.0.0/style.css b/themes/webtrees/css-2.0.0/style.css index cd80275a41..c827cd707d 100755 --- a/themes/webtrees/css-2.0.0/style.css +++ b/themes/webtrees/css-2.0.0/style.css @@ -1154,11 +1154,6 @@ div.fact_SHARED_NOTE { border-color: #ff2080; } -.quickfacts a { - padding: 0 3px; - font-size: 9px; -} - .tabs_table { width: 99%; } diff --git a/themes/xenea/css-2.0.0/style.css b/themes/xenea/css-2.0.0/style.css index 770a0fbfb9..31ca8ffd0e 100755 --- a/themes/xenea/css-2.0.0/style.css +++ b/themes/xenea/css-2.0.0/style.css @@ -1136,11 +1136,6 @@ div.fact_SHARED_NOTE { border-color: #ff2080; } -.quickfacts a { - padding: 0 3px; - font-size: 9px; -} - .tabs_table { width: 99%; } |
