summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Roach <fisharebest@gmail.com>2017-11-07 17:34:45 +0000
committerGreg Roach <fisharebest@gmail.com>2017-11-08 21:54:11 +0000
commit6d016c41a91f4141ccb644b40bc34cf7cead6d3d (patch)
treeaba69ee7ce4790238ff07566133f2c31457e9a48
parentd38f98bb6ed732e39c4f5acf3e54e84a00a4eff5 (diff)
downloadwebtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.tar.gz
webtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.tar.bz2
webtrees-6d016c41a91f4141ccb644b40bc34cf7cead6d3d.zip
Working on media fixup tool
-rwxr-xr-xadmin.php4
-rw-r--r--app/Controller/AdminController.php86
-rw-r--r--resources/views/admin/fix-level-0-media-action.php15
-rw-r--r--resources/views/admin/fix-level-0-media.php44
-rw-r--r--resources/views/layouts/administration.php11
5 files changed, 137 insertions, 23 deletions
diff --git a/admin.php b/admin.php
index bd76b141df..ef3f141975 100755
--- a/admin.php
+++ b/admin.php
@@ -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">&times;</span>
+ </button>
+ <?= $message->text ?>
+ </div>
+ <?php endforeach ?>
+
<?= $content ?>
<script src="<?= Html::escape(WT_JQUERY_JS_URL) ?>"></script>