diff options
| author | Greg Roach <fisharebest@gmail.com> | 2017-11-07 17:34:45 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@gmail.com> | 2017-11-08 21:54:11 +0000 |
| commit | 6d016c41a91f4141ccb644b40bc34cf7cead6d3d (patch) | |
| tree | aba69ee7ce4790238ff07566133f2c31457e9a48 | |
| parent | d38f98bb6ed732e39c4f5acf3e54e84a00a4eff5 (diff) | |
| download | webtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.tar.gz webtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.tar.bz2 webtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.zip | |
Working on media fixup tool
| -rwxr-xr-x | admin.php | 4 | ||||
| -rw-r--r-- | app/Controller/AdminController.php | 86 | ||||
| -rw-r--r-- | resources/views/admin/fix-level-0-media-action.php | 15 | ||||
| -rw-r--r-- | resources/views/admin/fix-level-0-media.php | 44 | ||||
| -rw-r--r-- | resources/views/layouts/administration.php | 11 |
5 files changed, 137 insertions, 23 deletions
@@ -69,6 +69,10 @@ if (Auth::isAdmin()) { $response = ($controller = new AdminController)->fixLevel0Media(); break; + case 'POST:admin-fix-level-0-media-action': + $response = ($controller = new AdminController)->fixLevel0MediaAction($request); + break; + case 'GET:admin-fix-level-0-media-data': $response = ($controller = new AdminController)->fixLevel0MediaData($request); break; diff --git a/app/Controller/AdminController.php b/app/Controller/AdminController.php index f8bc77d314..251c96ff5b 100644 --- a/app/Controller/AdminController.php +++ b/app/Controller/AdminController.php @@ -640,22 +640,47 @@ class AdminController extends BaseController { * @return Response */ public function fixLevel0Media(): Response { - $records = Database::prepare( - "SELECT m.* from `##media` AS m" . - " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . - " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id" . - " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')" - )->execute([ - - ])->fetchAll(); - return $this->viewResponse('admin/fix-level-0-media', [ 'title' => I18N::translate('MEDIA FIXUP'), - 'records' => $records, ]); } /** + * Move a link to a media object from a level 0 record to a level 1 record. + * + * @param Request $request + * + * @return Response + */ + public function fixLevel0MediaAction(Request $request): Response { + $fact_id = $request->get('fact_id'); + $indi_xref = $request->get('indi_xref'); + $obje_xref = $request->get('obje_xref'); + $tree_id = $request->get('tree_id'); + + $tree = Tree::findById($tree_id); + if ($tree !== null) { + $individual = Individual::getInstance($indi_xref, $tree); + $media = Media::getInstance($obje_xref, $tree); + if ($individual !== null && $media !== null) { + foreach ($individual->getFacts() as $fact1) { + if ($fact1->getFactId() === $fact_id) { + $individual->updateFact($fact_id, $fact1->getGedcom() . "\n2 OBJE @" . $obje_xref . '@', false); + foreach ($individual->getFacts('OBJE') as $fact2) { + if ($fact2->getTarget() === $media) { + $individual->deleteFact($fact2->getFactId(), false); + } + } + break; + } + } + } + } + + return new Response; + } + + /** * If media objects are wronly linked to top-level records, reattach them * to facts/events. * @@ -664,7 +689,7 @@ class AdminController extends BaseController { * @return JsonResponse */ public function fixLevel0MediaData(Request $request): JsonResponse { - $ignore_facts = ['FAMC', 'FAMS', 'NAME', 'SEX', 'CHAN', 'NOTE', 'OBJE', 'SOUR']; + $ignore_facts = ['FAMC', 'FAMS', 'NAME', 'SEX', 'CHAN', 'NOTE', 'OBJE', 'SOUR', 'RESN']; $start = (int) $request->get('start', 0); $length = (int) $request->get('length', 20); @@ -678,7 +703,9 @@ class AdminController extends BaseController { " JOIN `##link` AS l ON m.m_file = l.l_file AND m.m_id = l.l_to" . " JOIN `##individuals` AS i ON l.l_file = i.i_file AND l.l_from = i.i_id"; + // Only records where the media object is at level 1 $where = " WHERE i.i_gedcom LIKE CONCAT('%\n1 OBJE @', m.m_id, '@%')"; + $args = []; if ($search) { $where .= " AND (m_title LIKE CONCAT('%', :search1, '%') OR (m_filename LIKE CONCAT('%', :search2, '%')"; @@ -690,29 +717,56 @@ class AdminController extends BaseController { $args['limit'] = $length; $args['offset'] = $start; + // Need a consistent order + $order_by = " ORDER BY i.i_file, i.i_id, m.m_id"; + $data = Database::prepare( - $select1 . $where . $limit + $select1 . $where . $order_by . $limit )->execute( $args )->fetchAll(); + // Turn each row from the query into a row for the table $data = array_map(function ($datum) use ($ignore_facts) { $tree = Tree::findById($datum->m_file); $media = Media::getInstance($datum->m_id, $tree, $datum->m_gedcom); $individual = Individual::getInstance($datum->i_id, $tree, $datum->i_gedcom); + $facts = $individual->getFacts(null, true); - $facts = array_filter($facts, function (Fact $fact) use ($ignore_facts) { return !in_array($fact->getTag(), $ignore_facts); }); - $facts = array_map(function (Fact $fact) { - $year = $fact->getDate()->display(false, '%Y'); - return '<a class="btn btn-primary btn-sm mb-2" href="#" data-confirm="TODO - move the link" onclick="return confirm(this.dataset.confirm) && false;">' . $fact->getLabel() . ' ' . $year . '</a>'; + $facts = array_filter($facts, function (Fact $fact) use ($ignore_facts) { return !$fact->isPendingDeletion() && !in_array($fact->getTag(), $ignore_facts); }); + + // The link to the media object may have been deleted in a pending change. + $deleted = true; + foreach ($individual->getFacts('OBJE') as $fact) { + if ($fact->getTarget() === $media && !$fact->isPendingDeletion()) { + $deleted = false; + } + } + if ($deleted) { + $facts = []; + } + + $facts = array_map(function (Fact $fact) use ($individual, $media, $tree) { + return View::make('admin/fix-level-0-media-action', [ + 'fact' => $fact, + 'individual' => $individual, + 'media' => $media, + 'tree' => $tree, + ]); }, $facts); + $citations = ['foo']; + foreach ($individual->getFacts() as $fact) { +// if (preg_match()) + } + return [ $tree->getName(), $media->displayImage(100, 100, 'fit', ['class' => 'img-thumbnail']), '<a href="' . Html::escape($media->getRawUrl()) . '">' . $media->getFullName() . '</a>', '<a href="' . Html::escape($individual->getRawUrl()) . '">' . $individual->getFullName() . '</a>', implode(' ', $facts), + implode(' ', $citations), ]; }, $data); diff --git a/resources/views/admin/fix-level-0-media-action.php b/resources/views/admin/fix-level-0-media-action.php new file mode 100644 index 0000000000..0d46728dd3 --- /dev/null +++ b/resources/views/admin/fix-level-0-media-action.php @@ -0,0 +1,15 @@ +<?php use Fisharebest\Webtrees\Html; ?> +<?php use Fisharebest\Webtrees\I18N; ?> + +<button + class="btn btn-primary btn-small mb-1 wt-fix-button" + data-confirm="<?= I18N::translate('Move the media object from the individual to the fact.') ?>" + data-fact-id="<?= Html::escape($fact->getFactId()) ?>" + data-tree-id="<?= Html::escape($tree->getTreeId()) ?>" + data-individual-xref="<?= Html::escape($individual->getXref()) ?>" + data-media-xref="<?= Html::escape($media->getXref()) ?>" + type="button" +> + <?= $fact->getLabel() ?> + <?= $fact->getDate()->display(false, '%Y', false) ?> +</button> diff --git a/resources/views/admin/fix-level-0-media.php b/resources/views/admin/fix-level-0-media.php index b1498d84d8..0bf7bc3e0c 100644 --- a/resources/views/admin/fix-level-0-media.php +++ b/resources/views/admin/fix-level-0-media.php @@ -1,6 +1,10 @@ -<?php use Fisharebest\Webtrees\Bootstrap4; ?> -<?php use Fisharebest\Webtrees\Html; ?> -<?php use Fisharebest\Webtrees\I18N; ?> +<?php use Fisharebest\Webtrees\Bootstrap4; +use Fisharebest\Webtrees\Html; +use Fisharebest\Webtrees\I18N; + +?> +<?php ?> +<?php ?> <?= Bootstrap4::breadcrumbs([Html::url('admin.php', ['route' => 'admin-control-panel']) => I18N::translate('Control panel')], $title) ?> @@ -10,17 +14,43 @@ <?= I18N::translate('If you have linked a media object to an individual, instead of linking it to one of the facts or events, then you can move it to the correct location.') ?> </p> -<table class="table table-bordered table-sm table-hover datatables" data-ajax="<?= HTML::escape(json_encode(['url' => Html::url('admin.php', ['route' => 'admin-fix-level-0-media-data'])])) ?>" data-state-save="true"> +<table class="table table-bordered table-sm table-hover table-responsive datatables wt-fix-table" data-ajax="<?= HTML::escape(json_encode(['url' => Html::url('admin.php', ['route' => 'admin-fix-level-0-media-data'])])) ?>" data-state-save="true"> <caption class="sr-only"> <?= I18N::translate('Media objects') ?> </caption> <thead class="thead-dark"> <tr> - <th><?= I18N::translate('Tree') ?></th> + <th data-sortable="false"><?= I18N::translate('Tree') ?></th> <th data-sortable="false"><?= I18N::translate('Media object') ?></th> - <th><?= I18N::translate('Title') ?></th> - <th><?= I18N::translate('Individual') ?></th> + <th data-sortable="false"><?= I18N::translate('Title') ?></th> + <th data-sortable="false"><?= I18N::translate('Individual') ?></th> <th data-sortable="false"><?= I18N::translate('Facts and events') ?></th> + <th data-sortable="false"><?= I18N::translate('Sources') ?></th> </tr> </thead> </table> + +<script> + // If we click on a button, post the request and reload the table + document.querySelector(".wt-fix-table").onclick = function (event) { + var element = event.target; + if (element.classList.contains("wt-fix-button")) { + event.stopPropagation(); + if (confirm(element.dataset.confirm)) { + $.ajax({ + data: { + "route": "admin-fix-level-0-media-action", + "fact_id": element.dataset.factId, + "indi_xref": element.dataset.individualXref, + "obje_xref": element.dataset.mediaXref, + "tree_id": element.dataset.treeId + }, + method: "POST", + url: "admin.php" + }).done(function () { + $(".wt-fix-table").DataTable().ajax.reload(null, false); + }); + } + } + }; +</script> diff --git a/resources/views/layouts/administration.php b/resources/views/layouts/administration.php index d244d77e81..8ffdb9b1cf 100644 --- a/resources/views/layouts/administration.php +++ b/resources/views/layouts/administration.php @@ -1,4 +1,5 @@ <?php use Fisharebest\Webtrees\Filter; ?> +<?php use Fisharebest\Webtrees\FlashMessages; ?> <?php use Fisharebest\Webtrees\Html; ?> <?php use Fisharebest\Webtrees\I18N; ?> <!DOCTYPE html> @@ -57,6 +58,16 @@ </header> <div id="content"></div> + + <?php foreach (FlashMessages::getMessages() as $message): ?> + <div class="alert alert-<?= $message->status ?> alert-dismissible" role="alert"> + <button type="button" class="close" data-dismiss="alert" aria-label="<?= I18N::translate('close') ?>"> + <span aria-hidden="true">×</span> + </button> + <?= $message->text ?> + </div> + <?php endforeach ?> + <?= $content ?> <script src="<?= Html::escape(WT_JQUERY_JS_URL) ?>"></script> |
