xref: /webtrees/app/Http/RequestHandlers/SourcePage.php (revision 9b152ff9230017d2c03aa1bf603a98b18250446d)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2019 webtrees development team
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22use Fisharebest\Webtrees\Auth;
23use Fisharebest\Webtrees\Fact;
24use Fisharebest\Webtrees\Http\ViewResponseTrait;
25use Fisharebest\Webtrees\Services\ClipboardService;
26use Fisharebest\Webtrees\Source;
27use Fisharebest\Webtrees\Tree;
28use Illuminate\Support\Collection;
29use Psr\Http\Message\ResponseInterface;
30use Psr\Http\Message\ServerRequestInterface;
31use Psr\Http\Server\RequestHandlerInterface;
32
33use function array_search;
34use function assert;
35use function is_string;
36use function redirect;
37
38use const PHP_INT_MAX;
39
40/**
41 * Show a source's page.
42 */
43class SourcePage implements RequestHandlerInterface
44{
45    use ViewResponseTrait;
46
47    // Show the source's facts in this order:
48    private const FACT_ORDER = [
49        1 => 'TITL',
50        'ABBR',
51        'AUTH',
52        'DATA',
53        'PUBL',
54        'TEXT',
55        'REPO',
56        'NOTE',
57        'OBJE',
58        'REFN',
59        'RIN',
60        '_UID',
61        'CHAN',
62        'RESN',
63    ];
64
65    /** @var ClipboardService */
66    private $clipboard_service;
67
68    /**
69     * SourcePage constructor.
70     *
71     * @param ClipboardService $clipboard_service
72     */
73    public function __construct(ClipboardService $clipboard_service)
74    {
75        $this->clipboard_service = $clipboard_service;
76    }
77
78    /**
79     * @param ServerRequestInterface $request
80     *
81     * @return ResponseInterface
82     */
83    public function handle(ServerRequestInterface $request): ResponseInterface
84    {
85        $tree = $request->getAttribute('tree');
86        assert($tree instanceof Tree);
87
88        $xref = $request->getAttribute('xref');
89        assert(is_string($xref));
90
91        $source = Source::getInstance($xref, $tree);
92        $source = Auth::checkSourceAccess($source, false);
93
94        // Redirect to correct xref/slug
95        if ($source->xref() !== $xref || $request->getAttribute('slug') !== $source->slug()) {
96            return redirect($source->url());
97        }
98
99        return $this->viewResponse('source-page', [
100            'clipboard_facts' => $this->clipboard_service->pastableFacts($source, new Collection()),
101            'facts'           => $this->facts($source),
102            'families'        => $source->linkedFamilies('SOUR'),
103            'individuals'     => $source->linkedIndividuals('SOUR'),
104            'meta_robots'     => 'index,follow',
105            'notes'           => $source->linkedNotes('SOUR'),
106            'media_objects'   => $source->linkedMedia('SOUR'),
107            'source'          => $source,
108            'title'           => $source->fullName(),
109            'tree'            => $tree,
110        ]);
111    }
112
113    /**
114     * @param Source $record
115     *
116     * @return Collection
117     */
118    private function facts(Source $record): Collection
119    {
120        return $record->facts()
121            ->sort(static function (Fact $x, Fact $y): int {
122                $sort_x = array_search($x->getTag(), self::FACT_ORDER, true) ?: PHP_INT_MAX;
123                $sort_y = array_search($y->getTag(), self::FACT_ORDER, true) ?: PHP_INT_MAX;
124
125                return $sort_x <=> $sort_y;
126            });
127    }
128}
129