18c2e8227SGreg Roach<?php 23976b470SGreg Roach 38c2e8227SGreg Roach/** 48c2e8227SGreg Roach * webtrees: online genealogy 589f7189bSGreg Roach * Copyright (C) 2021 webtrees development team 68c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify 78c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by 88c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or 98c2e8227SGreg Roach * (at your option) any later version. 108c2e8227SGreg Roach * This program is distributed in the hope that it will be useful, 118c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 128c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 138c2e8227SGreg Roach * GNU General Public License for more details. 148c2e8227SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 168c2e8227SGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 2076692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module; 2176692c8bSGreg Roach 22de2aa325SGreg Roachuse Aura\Router\Route; 230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth; 240e62c4b8SGreg Roachuse Fisharebest\Webtrees\Family; 255a78cd34SGreg Roachuse Fisharebest\Webtrees\Gedcom; 260e62c4b8SGreg Roachuse Fisharebest\Webtrees\GedcomRecord; 27f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\FamilyPage; 28f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\IndividualPage; 29*e8ded2caSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\LocationPage; 30f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\MediaPage; 31f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\NotePage; 32f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\RepositoryPage; 33f95e0480SGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\SourcePage; 34d45701ccSGreg Roachuse Fisharebest\Webtrees\Http\RequestHandlers\SubmitterPage; 350e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N; 360e62c4b8SGreg Roachuse Fisharebest\Webtrees\Individual; 37*e8ded2caSGreg Roachuse Fisharebest\Webtrees\Location; 385a78cd34SGreg Roachuse Fisharebest\Webtrees\Media; 390e62c4b8SGreg Roachuse Fisharebest\Webtrees\Menu; 405a78cd34SGreg Roachuse Fisharebest\Webtrees\Note; 41d45701ccSGreg Roachuse Fisharebest\Webtrees\Registry; 425a78cd34SGreg Roachuse Fisharebest\Webtrees\Repository; 4369c05a6eSGreg Roachuse Fisharebest\Webtrees\Services\GedcomExportService; 44e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Services\UserService; 450e62c4b8SGreg Roachuse Fisharebest\Webtrees\Session; 465a78cd34SGreg Roachuse Fisharebest\Webtrees\Source; 47d45701ccSGreg Roachuse Fisharebest\Webtrees\Submitter; 48aee13b6dSGreg Roachuse Fisharebest\Webtrees\Tree; 4969c05a6eSGreg Roachuse Illuminate\Support\Collection; 505a78cd34SGreg Roachuse League\Flysystem\Filesystem; 515a78cd34SGreg Roachuse League\Flysystem\ZipArchive\ZipArchiveAdapter; 52bed27cedSGreg Roachuse Psr\Http\Message\ResponseFactoryInterface; 536ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface; 546ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 556ccdf4f0SGreg Roachuse Psr\Http\Message\StreamFactoryInterface; 5669c05a6eSGreg Roachuse RuntimeException; 573976b470SGreg Roach 58eb235819SGreg Roachuse function app; 59bf80ec58SGreg Roachuse function array_filter; 60bf80ec58SGreg Roachuse function array_keys; 61bf80ec58SGreg Roachuse function array_map; 62fa695506SGreg Roachuse function array_search; 635229eadeSGreg Roachuse function assert; 6469c05a6eSGreg Roachuse function fopen; 65bf80ec58SGreg Roachuse function in_array; 66ddeb3354SGreg Roachuse function is_string; 67bf80ec58SGreg Roachuse function preg_match_all; 68bf80ec58SGreg Roachuse function redirect; 6969c05a6eSGreg Roachuse function rewind; 70bf80ec58SGreg Roachuse function route; 71e5a6b4d4SGreg Roachuse function str_replace; 72fa695506SGreg Roachuse function stream_get_meta_data; 73fa695506SGreg Roachuse function tmpfile; 74fa695506SGreg Roachuse function uasort; 75d45701ccSGreg Roachuse function view; 76fa695506SGreg Roach 77fa695506SGreg Roachuse const PREG_SET_ORDER; 788c2e8227SGreg Roach 798c2e8227SGreg Roach/** 808c2e8227SGreg Roach * Class ClippingsCartModule 818c2e8227SGreg Roach */ 8237eb8894SGreg Roachclass ClippingsCartModule extends AbstractModule implements ModuleMenuInterface 83c1010edaSGreg Roach{ 8449a243cbSGreg Roach use ModuleMenuTrait; 8549a243cbSGreg Roach 865a78cd34SGreg Roach // Routes that have a record which can be added to the clipboard 8716d6367aSGreg Roach private const ROUTES_WITH_RECORDS = [ 88f95e0480SGreg Roach 'Family' => FamilyPage::class, 89f95e0480SGreg Roach 'Individual' => IndividualPage::class, 90f95e0480SGreg Roach 'Media' => MediaPage::class, 91*e8ded2caSGreg Roach 'Location' => LocationPage::class, 92f95e0480SGreg Roach 'Note' => NotePage::class, 93f95e0480SGreg Roach 'Repository' => RepositoryPage::class, 94f95e0480SGreg Roach 'Source' => SourcePage::class, 95d45701ccSGreg Roach 'Submitter' => SubmitterPage::class, 96c1010edaSGreg Roach ]; 975a78cd34SGreg Roach 9849a243cbSGreg Roach /** @var int The default access level for this module. It can be changed in the control panel. */ 9949a243cbSGreg Roach protected $access_level = Auth::PRIV_USER; 10049a243cbSGreg Roach 10169c05a6eSGreg Roach /** @var GedcomExportService */ 10269c05a6eSGreg Roach private $gedcom_export_service; 10369c05a6eSGreg Roach 10469c05a6eSGreg Roach /** @var UserService */ 105e5a6b4d4SGreg Roach private $user_service; 106e5a6b4d4SGreg Roach 107e5a6b4d4SGreg Roach /** 108e5a6b4d4SGreg Roach * ClippingsCartModule constructor. 109e5a6b4d4SGreg Roach * 11069c05a6eSGreg Roach * @param GedcomExportService $gedcom_export_service 111e5a6b4d4SGreg Roach * @param UserService $user_service 112e5a6b4d4SGreg Roach */ 11369c05a6eSGreg Roach public function __construct(GedcomExportService $gedcom_export_service, UserService $user_service) 114e5a6b4d4SGreg Roach { 11569c05a6eSGreg Roach $this->gedcom_export_service = $gedcom_export_service; 116e5a6b4d4SGreg Roach $this->user_service = $user_service; 117e5a6b4d4SGreg Roach } 118e5a6b4d4SGreg Roach 119e5a6b4d4SGreg Roach /** 120961ec755SGreg Roach * A sentence describing what this module does. 121961ec755SGreg Roach * 122961ec755SGreg Roach * @return string 123961ec755SGreg Roach */ 12449a243cbSGreg Roach public function description(): string 125c1010edaSGreg Roach { 126bbb76c12SGreg Roach /* I18N: Description of the “Clippings cart” module */ 127bbb76c12SGreg Roach return I18N::translate('Select records from your family tree and save them as a GEDCOM file.'); 1288c2e8227SGreg Roach } 1298c2e8227SGreg Roach 1300ee13198SGreg Roach /** 13149a243cbSGreg Roach * The default position for this menu. It can be changed in the control panel. 1320ee13198SGreg Roach * 1330ee13198SGreg Roach * @return int 1340ee13198SGreg Roach */ 1358f53f488SRico Sonntag public function defaultMenuOrder(): int 136c1010edaSGreg Roach { 137353b36abSGreg Roach return 6; 1388c2e8227SGreg Roach } 1398c2e8227SGreg Roach 1400ee13198SGreg Roach /** 1410ee13198SGreg Roach * A menu, to be added to the main application menu. 1420ee13198SGreg Roach * 143aee13b6dSGreg Roach * @param Tree $tree 144aee13b6dSGreg Roach * 1450ee13198SGreg Roach * @return Menu|null 1460ee13198SGreg Roach */ 14746295629SGreg Roach public function getMenu(Tree $tree): ?Menu 148c1010edaSGreg Roach { 149eb235819SGreg Roach /** @var ServerRequestInterface $request */ 1506ccdf4f0SGreg Roach $request = app(ServerRequestInterface::class); 1518c2e8227SGreg Roach 152f7ab47b1SGreg Roach $route = $request->getAttribute('route'); 153de2aa325SGreg Roach assert($route instanceof Route); 1545a78cd34SGreg Roach 155d45701ccSGreg Roach $cart = Session::get('cart', []); 156d45701ccSGreg Roach $count = count($cart[$tree->name()] ?? []); 157d45701ccSGreg Roach $badge = view('components/badge', ['count' => $count]); 158d45701ccSGreg Roach 1595a78cd34SGreg Roach $submenus = [ 160d45701ccSGreg Roach new Menu($this->title() . ' ' . $badge, route('module', [ 16126684e68SGreg Roach 'module' => $this->name(), 162c1010edaSGreg Roach 'action' => 'Show', 163d72b284aSGreg Roach 'tree' => $tree->name(), 164c1010edaSGreg Roach ]), 'menu-clippings-cart', ['rel' => 'nofollow']), 1655a78cd34SGreg Roach ]; 1665a78cd34SGreg Roach 1672b0d92b4SGreg Roach $action = array_search($route->name, self::ROUTES_WITH_RECORDS, true); 168f95e0480SGreg Roach if ($action !== false) { 1692b0d92b4SGreg Roach $xref = $route->attributes['xref']; 170ddeb3354SGreg Roach assert(is_string($xref)); 171ddeb3354SGreg Roach 172c1010edaSGreg Roach $add_route = route('module', [ 17326684e68SGreg Roach 'module' => $this->name(), 174f95e0480SGreg Roach 'action' => 'Add' . $action, 175c1010edaSGreg Roach 'xref' => $xref, 176d72b284aSGreg Roach 'tree' => $tree->name(), 177c1010edaSGreg Roach ]); 1785a78cd34SGreg Roach 17925b2dde3SGreg Roach $submenus[] = new Menu(I18N::translate('Add to the clippings cart'), $add_route, 'menu-clippings-add', ['rel' => 'nofollow']); 1808c2e8227SGreg Roach } 181cbc1590aSGreg Roach 1825a78cd34SGreg Roach if (!$this->isCartEmpty($tree)) { 183c1010edaSGreg Roach $submenus[] = new Menu(I18N::translate('Empty the clippings cart'), route('module', [ 18426684e68SGreg Roach 'module' => $this->name(), 185c1010edaSGreg Roach 'action' => 'Empty', 186d72b284aSGreg Roach 'tree' => $tree->name(), 187c1010edaSGreg Roach ]), 'menu-clippings-empty', ['rel' => 'nofollow']); 188f95e0480SGreg Roach 189c1010edaSGreg Roach $submenus[] = new Menu(I18N::translate('Download'), route('module', [ 19026684e68SGreg Roach 'module' => $this->name(), 191c1010edaSGreg Roach 'action' => 'DownloadForm', 192d72b284aSGreg Roach 'tree' => $tree->name(), 193c1010edaSGreg Roach ]), 'menu-clippings-download', ['rel' => 'nofollow']); 1945a78cd34SGreg Roach } 1955a78cd34SGreg Roach 19649a243cbSGreg Roach return new Menu($this->title(), '#', 'menu-clippings', ['rel' => 'nofollow'], $submenus); 1978c2e8227SGreg Roach } 1988c2e8227SGreg Roach 19976692c8bSGreg Roach /** 200d45701ccSGreg Roach * How should this module be identified in the control panel, etc.? 201d45701ccSGreg Roach * 202d45701ccSGreg Roach * @return string 203d45701ccSGreg Roach */ 204d45701ccSGreg Roach public function title(): string 205d45701ccSGreg Roach { 206d45701ccSGreg Roach /* I18N: Name of a module */ 207d45701ccSGreg Roach return I18N::translate('Clippings cart'); 208d45701ccSGreg Roach } 209d45701ccSGreg Roach 210d45701ccSGreg Roach /** 211d45701ccSGreg Roach * @param Tree $tree 212d45701ccSGreg Roach * 213d45701ccSGreg Roach * @return bool 214d45701ccSGreg Roach */ 215d45701ccSGreg Roach private function isCartEmpty(Tree $tree): bool 216d45701ccSGreg Roach { 217d45701ccSGreg Roach $cart = Session::get('cart', []); 218d45701ccSGreg Roach $contents = $cart[$tree->name()] ?? []; 219d45701ccSGreg Roach 220d45701ccSGreg Roach return $contents === []; 221d45701ccSGreg Roach } 222d45701ccSGreg Roach 223d45701ccSGreg Roach /** 224d45701ccSGreg Roach * @param ServerRequestInterface $request 225d45701ccSGreg Roach * 226d45701ccSGreg Roach * @return ResponseInterface 227d45701ccSGreg Roach */ 228d45701ccSGreg Roach public function getDownloadFormAction(ServerRequestInterface $request): ResponseInterface 229d45701ccSGreg Roach { 230d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 231d45701ccSGreg Roach assert($tree instanceof Tree); 232d45701ccSGreg Roach 233d45701ccSGreg Roach $user = $request->getAttribute('user'); 234d45701ccSGreg Roach $title = I18N::translate('Family tree clippings cart') . ' — ' . I18N::translate('Download'); 235d45701ccSGreg Roach 236d45701ccSGreg Roach return $this->viewResponse('modules/clippings/download', [ 237d45701ccSGreg Roach 'is_manager' => Auth::isManager($tree, $user), 238d45701ccSGreg Roach 'is_member' => Auth::isMember($tree, $user), 239d45701ccSGreg Roach 'module' => $this->name(), 240d45701ccSGreg Roach 'title' => $title, 241d45701ccSGreg Roach 'tree' => $tree, 242d45701ccSGreg Roach ]); 243d45701ccSGreg Roach } 244d45701ccSGreg Roach 245d45701ccSGreg Roach /** 2466ccdf4f0SGreg Roach * @param ServerRequestInterface $request 24776692c8bSGreg Roach * 2486ccdf4f0SGreg Roach * @return ResponseInterface 24976692c8bSGreg Roach */ 250f95e0480SGreg Roach public function postDownloadAction(ServerRequestInterface $request): ResponseInterface 251c1010edaSGreg Roach { 25257ab2231SGreg Roach $tree = $request->getAttribute('tree'); 2534ea62551SGreg Roach assert($tree instanceof Tree); 2544ea62551SGreg Roach 2556b9cb339SGreg Roach $data_filesystem = Registry::filesystem()->data(); 256a04bb9a2SGreg Roach 257b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 258b46c87bdSGreg Roach 259d45701ccSGreg Roach $privatize_export = $params['privatize_export'] ?? 'none'; 260e2ed7c79SGreg Roach 261e2ed7c79SGreg Roach if ($privatize_export === 'none' && !Auth::isManager($tree)) { 262e2ed7c79SGreg Roach $privatize_export = 'member'; 263e2ed7c79SGreg Roach } 264e2ed7c79SGreg Roach 265e2ed7c79SGreg Roach if ($privatize_export === 'gedadmin' && !Auth::isManager($tree)) { 266e2ed7c79SGreg Roach $privatize_export = 'member'; 267e2ed7c79SGreg Roach } 268e2ed7c79SGreg Roach 269e2ed7c79SGreg Roach if ($privatize_export === 'user' && !Auth::isMember($tree)) { 270e2ed7c79SGreg Roach $privatize_export = 'visitor'; 271e2ed7c79SGreg Roach } 272e2ed7c79SGreg Roach 273b46c87bdSGreg Roach $convert = (bool) ($params['convert'] ?? false); 2748c2e8227SGreg Roach 27513abd6f3SGreg Roach $cart = Session::get('cart', []); 2768c2e8227SGreg Roach 277aa6f03bbSGreg Roach $xrefs = array_keys($cart[$tree->name()] ?? []); 278c8846facSGreg Roach $xrefs = array_map('strval', $xrefs); // PHP converts numeric keys to integers. 2795a78cd34SGreg Roach 2805a78cd34SGreg Roach // Create a new/empty .ZIP file 281a00baf47SGreg Roach $temp_zip_file = stream_get_meta_data(tmpfile())['uri']; 2827f996f6eSGreg Roach $zip_adapter = new ZipArchiveAdapter($temp_zip_file); 2837f996f6eSGreg Roach $zip_filesystem = new Filesystem($zip_adapter); 2845a78cd34SGreg Roach 285fa695506SGreg Roach $media_filesystem = $tree->mediaFilesystem($data_filesystem); 28661bf91b2SGreg Roach 2875a78cd34SGreg Roach // Media file prefix 2885a78cd34SGreg Roach $path = $tree->getPreference('MEDIA_DIRECTORY'); 2895a78cd34SGreg Roach 29069c05a6eSGreg Roach $encoding = $convert ? 'ANSI' : 'UTF-8'; 29169c05a6eSGreg Roach 29269c05a6eSGreg Roach $records = new Collection(); 2935a78cd34SGreg Roach 2945a78cd34SGreg Roach switch ($privatize_export) { 2955a78cd34SGreg Roach case 'gedadmin': 2965a78cd34SGreg Roach $access_level = Auth::PRIV_NONE; 2975a78cd34SGreg Roach break; 2985a78cd34SGreg Roach case 'user': 2995a78cd34SGreg Roach $access_level = Auth::PRIV_USER; 3005a78cd34SGreg Roach break; 3015a78cd34SGreg Roach case 'visitor': 3025a78cd34SGreg Roach $access_level = Auth::PRIV_PRIVATE; 3035a78cd34SGreg Roach break; 3045a78cd34SGreg Roach case 'none': 3055a78cd34SGreg Roach default: 3065a78cd34SGreg Roach $access_level = Auth::PRIV_HIDE; 3075a78cd34SGreg Roach break; 3085a78cd34SGreg Roach } 3095a78cd34SGreg Roach 3105a78cd34SGreg Roach foreach ($xrefs as $xref) { 3116b9cb339SGreg Roach $object = Registry::gedcomRecordFactory()->make($xref, $tree); 3125a78cd34SGreg Roach // The object may have been deleted since we added it to the cart.... 313bed27cedSGreg Roach if ($object instanceof GedcomRecord) { 3145a78cd34SGreg Roach $record = $object->privatizeGedcom($access_level); 3155a78cd34SGreg Roach // Remove links to objects that aren't in the cart 3168d0ebef0SGreg Roach preg_match_all('/\n1 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[2-9].*)*/', $record, $matches, PREG_SET_ORDER); 3175a78cd34SGreg Roach foreach ($matches as $match) { 318bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3195a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3205a78cd34SGreg Roach } 3215a78cd34SGreg Roach } 3228d0ebef0SGreg Roach preg_match_all('/\n2 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[3-9].*)*/', $record, $matches, PREG_SET_ORDER); 3235a78cd34SGreg Roach foreach ($matches as $match) { 324bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3255a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3265a78cd34SGreg Roach } 3275a78cd34SGreg Roach } 3288d0ebef0SGreg Roach preg_match_all('/\n3 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[4-9].*)*/', $record, $matches, PREG_SET_ORDER); 3295a78cd34SGreg Roach foreach ($matches as $match) { 330bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3315a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3325a78cd34SGreg Roach } 3335a78cd34SGreg Roach } 3345a78cd34SGreg Roach 33555167344SGreg Roach if ($object instanceof Individual || $object instanceof Family) { 33669c05a6eSGreg Roach $records->add($record . "\n1 SOUR @WEBTREES@\n2 PAGE " . $object->url()); 33755167344SGreg Roach } elseif ($object instanceof Source) { 33869c05a6eSGreg Roach $records->add($record . "\n1 NOTE " . $object->url()); 33955167344SGreg Roach } elseif ($object instanceof Media) { 34055167344SGreg Roach // Add the media files to the archive 3415a78cd34SGreg Roach foreach ($object->mediaFiles() as $media_file) { 342fa695506SGreg Roach $from = $media_file->filename(); 343fa695506SGreg Roach $to = $path . $media_file->filename(); 344fa695506SGreg Roach if (!$media_file->isExternal() && $media_filesystem->has($from) && !$zip_filesystem->has($to)) { 345fa695506SGreg Roach $zip_filesystem->writeStream($to, $media_filesystem->readStream($from)); 3465a78cd34SGreg Roach } 3475a78cd34SGreg Roach } 34869c05a6eSGreg Roach $records->add($record); 34955167344SGreg Roach } else { 35069c05a6eSGreg Roach $records->add($record); 3518c2e8227SGreg Roach } 3528c2e8227SGreg Roach } 3538c2e8227SGreg Roach } 3548c2e8227SGreg Roach 3559b93b7c3SGreg Roach $base_url = $request->getAttribute('base_url'); 3569b93b7c3SGreg Roach 3575a78cd34SGreg Roach // Create a source, to indicate the source of the data. 35869c05a6eSGreg Roach $record = "0 @WEBTREES@ SOUR\n1 TITL " . $base_url; 359e5a6b4d4SGreg Roach $author = $this->user_service->find((int) $tree->getPreference('CONTACT_USER_ID')); 3605a78cd34SGreg Roach if ($author !== null) { 36169c05a6eSGreg Roach $record .= "\n1 AUTH " . $author->realName(); 3625a78cd34SGreg Roach } 36369c05a6eSGreg Roach $records->add($record); 3645a78cd34SGreg Roach 36569c05a6eSGreg Roach $stream = fopen('php://temp', 'wb+'); 3665a78cd34SGreg Roach 36769c05a6eSGreg Roach if ($stream === false) { 36869c05a6eSGreg Roach throw new RuntimeException('Failed to create temporary stream'); 3698c2e8227SGreg Roach } 370cbc1590aSGreg Roach 37169c05a6eSGreg Roach // We have already applied privacy filtering, so do not do it again. 37269c05a6eSGreg Roach $this->gedcom_export_service->export($tree, $stream, false, $encoding, Auth::PRIV_HIDE, $path, $records); 37369c05a6eSGreg Roach rewind($stream); 37469c05a6eSGreg Roach 3755a78cd34SGreg Roach // Finally add the GEDCOM file to the .ZIP file. 37669c05a6eSGreg Roach $zip_filesystem->writeStream('clippings.ged', $stream); 3775a78cd34SGreg Roach 37861bf91b2SGreg Roach // Need to force-close ZipArchive filesystems. 3797f996f6eSGreg Roach $zip_adapter->getArchive()->close(); 3805a78cd34SGreg Roach 3816ccdf4f0SGreg Roach // Use a stream, so that we do not have to load the entire file into memory. 3826ccdf4f0SGreg Roach $stream = app(StreamFactoryInterface::class)->createStreamFromFile($temp_zip_file); 3835a78cd34SGreg Roach 384bed27cedSGreg Roach /** @var ResponseFactoryInterface $response_factory */ 385bed27cedSGreg Roach $response_factory = app(ResponseFactoryInterface::class); 386bed27cedSGreg Roach 387bed27cedSGreg Roach return $response_factory->createResponse() 3886ccdf4f0SGreg Roach ->withBody($stream) 3891b3d4731SGreg Roach ->withHeader('Content-Type', 'application/zip') 390bed27cedSGreg Roach ->withHeader('Content-Disposition', 'attachment; filename="clippings.zip'); 3918c2e8227SGreg Roach } 3928c2e8227SGreg Roach 3938c2e8227SGreg Roach /** 39457ab2231SGreg Roach * @param ServerRequestInterface $request 39576692c8bSGreg Roach * 3966ccdf4f0SGreg Roach * @return ResponseInterface 3978c2e8227SGreg Roach */ 39857ab2231SGreg Roach public function getEmptyAction(ServerRequestInterface $request): ResponseInterface 399c1010edaSGreg Roach { 40057ab2231SGreg Roach $tree = $request->getAttribute('tree'); 4014ea62551SGreg Roach assert($tree instanceof Tree); 4024ea62551SGreg Roach 4035a78cd34SGreg Roach $cart = Session::get('cart', []); 404aa6f03bbSGreg Roach $cart[$tree->name()] = []; 4055a78cd34SGreg Roach Session::put('cart', $cart); 4068c2e8227SGreg Roach 407c1010edaSGreg Roach $url = route('module', [ 40826684e68SGreg Roach 'module' => $this->name(), 409c1010edaSGreg Roach 'action' => 'Show', 410d72b284aSGreg Roach 'tree' => $tree->name(), 411c1010edaSGreg Roach ]); 4125a78cd34SGreg Roach 4136ccdf4f0SGreg Roach return redirect($url); 4145a78cd34SGreg Roach } 4155a78cd34SGreg Roach 4165a78cd34SGreg Roach /** 4176ccdf4f0SGreg Roach * @param ServerRequestInterface $request 4185a78cd34SGreg Roach * 4196ccdf4f0SGreg Roach * @return ResponseInterface 4205a78cd34SGreg Roach */ 42157ab2231SGreg Roach public function postRemoveAction(ServerRequestInterface $request): ResponseInterface 422c1010edaSGreg Roach { 42357ab2231SGreg Roach $tree = $request->getAttribute('tree'); 42475964c75SGreg Roach assert($tree instanceof Tree); 4255229eadeSGreg Roach 426d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 4275a78cd34SGreg Roach 4285a78cd34SGreg Roach $cart = Session::get('cart', []); 429aa6f03bbSGreg Roach unset($cart[$tree->name()][$xref]); 4305a78cd34SGreg Roach Session::put('cart', $cart); 4315a78cd34SGreg Roach 432c1010edaSGreg Roach $url = route('module', [ 43326684e68SGreg Roach 'module' => $this->name(), 434c1010edaSGreg Roach 'action' => 'Show', 435d72b284aSGreg Roach 'tree' => $tree->name(), 436c1010edaSGreg Roach ]); 4375a78cd34SGreg Roach 4386ccdf4f0SGreg Roach return redirect($url); 4395a78cd34SGreg Roach } 4405a78cd34SGreg Roach 4415a78cd34SGreg Roach /** 44257ab2231SGreg Roach * @param ServerRequestInterface $request 4435a78cd34SGreg Roach * 4446ccdf4f0SGreg Roach * @return ResponseInterface 4455a78cd34SGreg Roach */ 44657ab2231SGreg Roach public function getShowAction(ServerRequestInterface $request): ResponseInterface 447c1010edaSGreg Roach { 44857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 44975964c75SGreg Roach assert($tree instanceof Tree); 45057ab2231SGreg Roach 4515a78cd34SGreg Roach return $this->viewResponse('modules/clippings/show', [ 45277b78a63SRichard Cissée 'module' => $this->name(), 4535a78cd34SGreg Roach 'records' => $this->allRecordsInCart($tree), 4545a78cd34SGreg Roach 'title' => I18N::translate('Family tree clippings cart'), 4555a78cd34SGreg Roach 'tree' => $tree, 4565a78cd34SGreg Roach ]); 4575a78cd34SGreg Roach } 4585a78cd34SGreg Roach 4595a78cd34SGreg Roach /** 460d45701ccSGreg Roach * Get all the records in the cart. 461d45701ccSGreg Roach * 462d45701ccSGreg Roach * @param Tree $tree 463d45701ccSGreg Roach * 464d45701ccSGreg Roach * @return GedcomRecord[] 465d45701ccSGreg Roach */ 466d45701ccSGreg Roach private function allRecordsInCart(Tree $tree): array 467d45701ccSGreg Roach { 468d45701ccSGreg Roach $cart = Session::get('cart', []); 469d45701ccSGreg Roach 470d45701ccSGreg Roach $xrefs = array_keys($cart[$tree->name()] ?? []); 471d45701ccSGreg Roach $xrefs = array_map('strval', $xrefs); // PHP converts numeric keys to integers. 472d45701ccSGreg Roach 473d45701ccSGreg Roach // Fetch all the records in the cart. 474d45701ccSGreg Roach $records = array_map(static function (string $xref) use ($tree): ?GedcomRecord { 475d45701ccSGreg Roach return Registry::gedcomRecordFactory()->make($xref, $tree); 476d45701ccSGreg Roach }, $xrefs); 477d45701ccSGreg Roach 478d45701ccSGreg Roach // Some records may have been deleted after they were added to the cart. 479d45701ccSGreg Roach $records = array_filter($records); 480d45701ccSGreg Roach 481d45701ccSGreg Roach // Group and sort. 482d45701ccSGreg Roach uasort($records, static function (GedcomRecord $x, GedcomRecord $y): int { 483d45701ccSGreg Roach return $x->tag() <=> $y->tag() ?: GedcomRecord::nameComparator()($x, $y); 484d45701ccSGreg Roach }); 485d45701ccSGreg Roach 486d45701ccSGreg Roach return $records; 487d45701ccSGreg Roach } 488d45701ccSGreg Roach 489d45701ccSGreg Roach /** 4906ccdf4f0SGreg Roach * @param ServerRequestInterface $request 4915a78cd34SGreg Roach * 4926ccdf4f0SGreg Roach * @return ResponseInterface 4935a78cd34SGreg Roach */ 49457ab2231SGreg Roach public function getAddFamilyAction(ServerRequestInterface $request): ResponseInterface 495c1010edaSGreg Roach { 49657ab2231SGreg Roach $tree = $request->getAttribute('tree'); 49775964c75SGreg Roach assert($tree instanceof Tree); 4985229eadeSGreg Roach 499d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 5005a78cd34SGreg Roach 5016b9cb339SGreg Roach $family = Registry::familyFactory()->make($xref, $tree); 502d45701ccSGreg Roach $family = Auth::checkFamilyAccess($family); 503d45701ccSGreg Roach $name = $family->fullName(); 5045a78cd34SGreg Roach 505d45701ccSGreg Roach $options = [ 506d45701ccSGreg Roach 'record' => $name, 507bbb76c12SGreg Roach /* I18N: %s is a family (husband + wife) */ 508bbb76c12SGreg Roach 'members' => I18N::translate('%s and their children', $name), 509bbb76c12SGreg Roach /* I18N: %s is a family (husband + wife) */ 510bbb76c12SGreg Roach 'descendants' => I18N::translate('%s and their descendants', $name), 5115a78cd34SGreg Roach ]; 512d45701ccSGreg Roach 513d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 514d45701ccSGreg Roach 515d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 516d45701ccSGreg Roach 'options' => $options, 517d45701ccSGreg Roach 'record' => $family, 518d45701ccSGreg Roach 'title' => $title, 519d45701ccSGreg Roach 'tree' => $tree, 520d45701ccSGreg Roach ]); 5215a78cd34SGreg Roach } 5225a78cd34SGreg Roach 5235a78cd34SGreg Roach /** 5246ccdf4f0SGreg Roach * @param ServerRequestInterface $request 5255a78cd34SGreg Roach * 5266ccdf4f0SGreg Roach * @return ResponseInterface 5275a78cd34SGreg Roach */ 52857ab2231SGreg Roach public function postAddFamilyAction(ServerRequestInterface $request): ResponseInterface 529c1010edaSGreg Roach { 53057ab2231SGreg Roach $tree = $request->getAttribute('tree'); 5314ea62551SGreg Roach assert($tree instanceof Tree); 5324ea62551SGreg Roach 533b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 534b46c87bdSGreg Roach 535d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 536d45701ccSGreg Roach $option = $params['option'] ?? ''; 5375a78cd34SGreg Roach 5386b9cb339SGreg Roach $family = Registry::familyFactory()->make($xref, $tree); 539d45701ccSGreg Roach $family = Auth::checkFamilyAccess($family); 5405a78cd34SGreg Roach 5415a78cd34SGreg Roach switch ($option) { 542d45701ccSGreg Roach case 'self': 5435a78cd34SGreg Roach $this->addFamilyToCart($family); 5445a78cd34SGreg Roach break; 5455a78cd34SGreg Roach 5465a78cd34SGreg Roach case 'members': 5475a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 5485a78cd34SGreg Roach break; 5495a78cd34SGreg Roach 5505a78cd34SGreg Roach case 'descendants': 5515a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($family); 5525a78cd34SGreg Roach break; 5535a78cd34SGreg Roach } 5545a78cd34SGreg Roach 5556ccdf4f0SGreg Roach return redirect($family->url()); 5565a78cd34SGreg Roach } 5575a78cd34SGreg Roach 5585a78cd34SGreg Roach 5595a78cd34SGreg Roach /** 5605a78cd34SGreg Roach * @param Family $family 56118d7a90dSGreg Roach * 56218d7a90dSGreg Roach * @return void 5635a78cd34SGreg Roach */ 564d45701ccSGreg Roach protected function addFamilyAndChildrenToCart(Family $family): void 565c1010edaSGreg Roach { 566d45701ccSGreg Roach $this->addFamilyToCart($family); 5675a78cd34SGreg Roach 56839ca88baSGreg Roach foreach ($family->children() as $child) { 569d45701ccSGreg Roach $this->addIndividualToCart($child); 5705a78cd34SGreg Roach } 5715a78cd34SGreg Roach } 5725a78cd34SGreg Roach 5735a78cd34SGreg Roach /** 5745a78cd34SGreg Roach * @param Family $family 57518d7a90dSGreg Roach * 57618d7a90dSGreg Roach * @return void 5775a78cd34SGreg Roach */ 578d45701ccSGreg Roach protected function addFamilyAndDescendantsToCart(Family $family): void 579c1010edaSGreg Roach { 580d45701ccSGreg Roach $this->addFamilyAndChildrenToCart($family); 5815a78cd34SGreg Roach 58239ca88baSGreg Roach foreach ($family->children() as $child) { 58339ca88baSGreg Roach foreach ($child->spouseFamilies() as $child_family) { 5845a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($child_family); 5855a78cd34SGreg Roach } 5865a78cd34SGreg Roach } 5875a78cd34SGreg Roach } 5885a78cd34SGreg Roach 5895a78cd34SGreg Roach /** 5906ccdf4f0SGreg Roach * @param ServerRequestInterface $request 5915a78cd34SGreg Roach * 5926ccdf4f0SGreg Roach * @return ResponseInterface 5935a78cd34SGreg Roach */ 59457ab2231SGreg Roach public function getAddIndividualAction(ServerRequestInterface $request): ResponseInterface 595c1010edaSGreg Roach { 59657ab2231SGreg Roach $tree = $request->getAttribute('tree'); 59775964c75SGreg Roach assert($tree instanceof Tree); 5985229eadeSGreg Roach 599d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 6005a78cd34SGreg Roach 6016b9cb339SGreg Roach $individual = Registry::individualFactory()->make($xref, $tree); 602d45701ccSGreg Roach $individual = Auth::checkIndividualAccess($individual); 603d45701ccSGreg Roach $name = $individual->fullName(); 6045a78cd34SGreg Roach 60539ca88baSGreg Roach if ($individual->sex() === 'F') { 606d45701ccSGreg Roach $options = [ 607d45701ccSGreg Roach 'record' => $name, 6085a78cd34SGreg Roach 'parents' => I18N::translate('%s, her parents and siblings', $name), 6095a78cd34SGreg Roach 'spouses' => I18N::translate('%s, her spouses and children', $name), 6105a78cd34SGreg Roach 'ancestors' => I18N::translate('%s and her ancestors', $name), 6115a78cd34SGreg Roach 'ancestor_families' => I18N::translate('%s, her ancestors and their families', $name), 6125a78cd34SGreg Roach 'descendants' => I18N::translate('%s, her spouses and descendants', $name), 6135a78cd34SGreg Roach ]; 614d45701ccSGreg Roach } else { 615d45701ccSGreg Roach $options = [ 616d45701ccSGreg Roach 'record' => $name, 6175a78cd34SGreg Roach 'parents' => I18N::translate('%s, his parents and siblings', $name), 6185a78cd34SGreg Roach 'spouses' => I18N::translate('%s, his spouses and children', $name), 6195a78cd34SGreg Roach 'ancestors' => I18N::translate('%s and his ancestors', $name), 6205a78cd34SGreg Roach 'ancestor_families' => I18N::translate('%s, his ancestors and their families', $name), 6215a78cd34SGreg Roach 'descendants' => I18N::translate('%s, his spouses and descendants', $name), 6225a78cd34SGreg Roach ]; 6235a78cd34SGreg Roach } 6245a78cd34SGreg Roach 625d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 626d45701ccSGreg Roach 627d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 628d45701ccSGreg Roach 'options' => $options, 629d45701ccSGreg Roach 'record' => $individual, 630d45701ccSGreg Roach 'title' => $title, 631d45701ccSGreg Roach 'tree' => $tree, 632d45701ccSGreg Roach ]); 633d45701ccSGreg Roach } 634d45701ccSGreg Roach 6355a78cd34SGreg Roach /** 6366ccdf4f0SGreg Roach * @param ServerRequestInterface $request 6375a78cd34SGreg Roach * 6386ccdf4f0SGreg Roach * @return ResponseInterface 6395a78cd34SGreg Roach */ 64057ab2231SGreg Roach public function postAddIndividualAction(ServerRequestInterface $request): ResponseInterface 641c1010edaSGreg Roach { 64257ab2231SGreg Roach $tree = $request->getAttribute('tree'); 6434ea62551SGreg Roach assert($tree instanceof Tree); 6444ea62551SGreg Roach 645b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 646b46c87bdSGreg Roach 647d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 648d45701ccSGreg Roach $option = $params['option'] ?? ''; 6495a78cd34SGreg Roach 6506b9cb339SGreg Roach $individual = Registry::individualFactory()->make($xref, $tree); 651d45701ccSGreg Roach $individual = Auth::checkIndividualAccess($individual); 6525a78cd34SGreg Roach 6535a78cd34SGreg Roach switch ($option) { 6545a78cd34SGreg Roach case 'self': 655d45701ccSGreg Roach $this->addIndividualToCart($individual); 6565a78cd34SGreg Roach break; 6575a78cd34SGreg Roach 6585a78cd34SGreg Roach case 'parents': 65939ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 6605a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 6615a78cd34SGreg Roach } 6625a78cd34SGreg Roach break; 6635a78cd34SGreg Roach 6645a78cd34SGreg Roach case 'spouses': 66539ca88baSGreg Roach foreach ($individual->spouseFamilies() as $family) { 6665a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 6675a78cd34SGreg Roach } 6685a78cd34SGreg Roach break; 6695a78cd34SGreg Roach 6705a78cd34SGreg Roach case 'ancestors': 6715a78cd34SGreg Roach $this->addAncestorsToCart($individual); 6725a78cd34SGreg Roach break; 6735a78cd34SGreg Roach 6745a78cd34SGreg Roach case 'ancestor_families': 6755a78cd34SGreg Roach $this->addAncestorFamiliesToCart($individual); 6765a78cd34SGreg Roach break; 6775a78cd34SGreg Roach 6785a78cd34SGreg Roach case 'descendants': 67939ca88baSGreg Roach foreach ($individual->spouseFamilies() as $family) { 6805a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($family); 6815a78cd34SGreg Roach } 6825a78cd34SGreg Roach break; 6835a78cd34SGreg Roach } 6845a78cd34SGreg Roach 6856ccdf4f0SGreg Roach return redirect($individual->url()); 6865a78cd34SGreg Roach } 6875a78cd34SGreg Roach 6885a78cd34SGreg Roach /** 6895a78cd34SGreg Roach * @param Individual $individual 69018d7a90dSGreg Roach * 69118d7a90dSGreg Roach * @return void 6925a78cd34SGreg Roach */ 693d45701ccSGreg Roach protected function addAncestorsToCart(Individual $individual): void 694c1010edaSGreg Roach { 695d45701ccSGreg Roach $this->addIndividualToCart($individual); 6965a78cd34SGreg Roach 69739ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 698d45701ccSGreg Roach $this->addFamilyToCart($family); 6998df4c68dSGreg Roach 70039ca88baSGreg Roach foreach ($family->spouses() as $parent) { 7015a78cd34SGreg Roach $this->addAncestorsToCart($parent); 7025a78cd34SGreg Roach } 7035a78cd34SGreg Roach } 7045a78cd34SGreg Roach } 7055a78cd34SGreg Roach 7065a78cd34SGreg Roach /** 7075a78cd34SGreg Roach * @param Individual $individual 70818d7a90dSGreg Roach * 70918d7a90dSGreg Roach * @return void 7105a78cd34SGreg Roach */ 711d45701ccSGreg Roach protected function addAncestorFamiliesToCart(Individual $individual): void 712c1010edaSGreg Roach { 71339ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 7145a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 7158df4c68dSGreg Roach 71639ca88baSGreg Roach foreach ($family->spouses() as $parent) { 717cad6d3f3SGreg Roach $this->addAncestorFamiliesToCart($parent); 7185a78cd34SGreg Roach } 7195a78cd34SGreg Roach } 7205a78cd34SGreg Roach } 7215a78cd34SGreg Roach 7225a78cd34SGreg Roach /** 7236ccdf4f0SGreg Roach * @param ServerRequestInterface $request 7245a78cd34SGreg Roach * 7256ccdf4f0SGreg Roach * @return ResponseInterface 7265a78cd34SGreg Roach */ 727*e8ded2caSGreg Roach public function getAddLocationAction(ServerRequestInterface $request): ResponseInterface 728*e8ded2caSGreg Roach { 729*e8ded2caSGreg Roach $tree = $request->getAttribute('tree'); 730*e8ded2caSGreg Roach assert($tree instanceof Tree); 731*e8ded2caSGreg Roach 732*e8ded2caSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 733*e8ded2caSGreg Roach 734*e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $tree); 735*e8ded2caSGreg Roach $location = Auth::checkLocationAccess($location); 736*e8ded2caSGreg Roach $name = $location->fullName(); 737*e8ded2caSGreg Roach 738*e8ded2caSGreg Roach $options = [ 739*e8ded2caSGreg Roach 'record' => $name, 740*e8ded2caSGreg Roach ]; 741*e8ded2caSGreg Roach 742*e8ded2caSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 743*e8ded2caSGreg Roach 744*e8ded2caSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 745*e8ded2caSGreg Roach 'options' => $options, 746*e8ded2caSGreg Roach 'record' => $location, 747*e8ded2caSGreg Roach 'title' => $title, 748*e8ded2caSGreg Roach 'tree' => $tree, 749*e8ded2caSGreg Roach ]); 750*e8ded2caSGreg Roach } 751*e8ded2caSGreg Roach 752*e8ded2caSGreg Roach /** 753*e8ded2caSGreg Roach * @param ServerRequestInterface $request 754*e8ded2caSGreg Roach * 755*e8ded2caSGreg Roach * @return ResponseInterface 756*e8ded2caSGreg Roach */ 757*e8ded2caSGreg Roach public function postAddLocationAction(ServerRequestInterface $request): ResponseInterface 758*e8ded2caSGreg Roach { 759*e8ded2caSGreg Roach $tree = $request->getAttribute('tree'); 760*e8ded2caSGreg Roach assert($tree instanceof Tree); 761*e8ded2caSGreg Roach 762*e8ded2caSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 763*e8ded2caSGreg Roach 764*e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $tree); 765*e8ded2caSGreg Roach $location = Auth::checkLocationAccess($location); 766*e8ded2caSGreg Roach 767*e8ded2caSGreg Roach $this->addLocationToCart($location); 768*e8ded2caSGreg Roach 769*e8ded2caSGreg Roach return redirect($location->url()); 770*e8ded2caSGreg Roach } 771*e8ded2caSGreg Roach 772*e8ded2caSGreg Roach /** 773*e8ded2caSGreg Roach * @param ServerRequestInterface $request 774*e8ded2caSGreg Roach * 775*e8ded2caSGreg Roach * @return ResponseInterface 776*e8ded2caSGreg Roach */ 77757ab2231SGreg Roach public function getAddMediaAction(ServerRequestInterface $request): ResponseInterface 778c1010edaSGreg Roach { 77957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 78075964c75SGreg Roach assert($tree instanceof Tree); 7815229eadeSGreg Roach 782d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 7835a78cd34SGreg Roach 7846b9cb339SGreg Roach $media = Registry::mediaFactory()->make($xref, $tree); 785d45701ccSGreg Roach $media = Auth::checkMediaAccess($media); 786d45701ccSGreg Roach $name = $media->fullName(); 7875a78cd34SGreg Roach 788d45701ccSGreg Roach $options = [ 789d45701ccSGreg Roach 'record' => $name, 790d45701ccSGreg Roach ]; 7915a78cd34SGreg Roach 792d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 7935a78cd34SGreg Roach 7945a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 7955a78cd34SGreg Roach 'options' => $options, 7965a78cd34SGreg Roach 'record' => $media, 7975a78cd34SGreg Roach 'title' => $title, 7985a78cd34SGreg Roach 'tree' => $tree, 7995a78cd34SGreg Roach ]); 8005a78cd34SGreg Roach } 8015a78cd34SGreg Roach 8025a78cd34SGreg Roach /** 8036ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8045a78cd34SGreg Roach * 8056ccdf4f0SGreg Roach * @return ResponseInterface 8065a78cd34SGreg Roach */ 80757ab2231SGreg Roach public function postAddMediaAction(ServerRequestInterface $request): ResponseInterface 808c1010edaSGreg Roach { 80957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 81075964c75SGreg Roach assert($tree instanceof Tree); 8115229eadeSGreg Roach 812d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8135a78cd34SGreg Roach 8146b9cb339SGreg Roach $media = Registry::mediaFactory()->make($xref, $tree); 815d45701ccSGreg Roach $media = Auth::checkMediaAccess($media); 8165a78cd34SGreg Roach 817d45701ccSGreg Roach $this->addMediaToCart($media); 8185a78cd34SGreg Roach 8196ccdf4f0SGreg Roach return redirect($media->url()); 8205a78cd34SGreg Roach } 8215a78cd34SGreg Roach 8225a78cd34SGreg Roach /** 8236ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8245a78cd34SGreg Roach * 8256ccdf4f0SGreg Roach * @return ResponseInterface 8265a78cd34SGreg Roach */ 82757ab2231SGreg Roach public function getAddNoteAction(ServerRequestInterface $request): ResponseInterface 828c1010edaSGreg Roach { 82957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 83075964c75SGreg Roach assert($tree instanceof Tree); 8315229eadeSGreg Roach 832d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8335a78cd34SGreg Roach 8346b9cb339SGreg Roach $note = Registry::noteFactory()->make($xref, $tree); 835d45701ccSGreg Roach $note = Auth::checkNoteAccess($note); 836d45701ccSGreg Roach $name = $note->fullName(); 8375a78cd34SGreg Roach 838d45701ccSGreg Roach $options = [ 839d45701ccSGreg Roach 'record' => $name, 840d45701ccSGreg Roach ]; 8415a78cd34SGreg Roach 842d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 8435a78cd34SGreg Roach 8445a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 8455a78cd34SGreg Roach 'options' => $options, 8465a78cd34SGreg Roach 'record' => $note, 8475a78cd34SGreg Roach 'title' => $title, 8485a78cd34SGreg Roach 'tree' => $tree, 8495a78cd34SGreg Roach ]); 8505a78cd34SGreg Roach } 8515a78cd34SGreg Roach 8525a78cd34SGreg Roach /** 8536ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8545a78cd34SGreg Roach * 8556ccdf4f0SGreg Roach * @return ResponseInterface 8565a78cd34SGreg Roach */ 85757ab2231SGreg Roach public function postAddNoteAction(ServerRequestInterface $request): ResponseInterface 858c1010edaSGreg Roach { 85957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 86075964c75SGreg Roach assert($tree instanceof Tree); 8615229eadeSGreg Roach 862d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8635a78cd34SGreg Roach 8646b9cb339SGreg Roach $note = Registry::noteFactory()->make($xref, $tree); 865d45701ccSGreg Roach $note = Auth::checkNoteAccess($note); 8665a78cd34SGreg Roach 867d45701ccSGreg Roach $this->addNoteToCart($note); 8685a78cd34SGreg Roach 8696ccdf4f0SGreg Roach return redirect($note->url()); 8705a78cd34SGreg Roach } 8715a78cd34SGreg Roach 8725a78cd34SGreg Roach /** 8736ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8745a78cd34SGreg Roach * 8756ccdf4f0SGreg Roach * @return ResponseInterface 8765a78cd34SGreg Roach */ 87757ab2231SGreg Roach public function getAddRepositoryAction(ServerRequestInterface $request): ResponseInterface 878c1010edaSGreg Roach { 87957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 88075964c75SGreg Roach assert($tree instanceof Tree); 8815229eadeSGreg Roach 882d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8835a78cd34SGreg Roach 8846b9cb339SGreg Roach $repository = Registry::repositoryFactory()->make($xref, $tree); 885d45701ccSGreg Roach $repository = Auth::checkRepositoryAccess($repository); 886d45701ccSGreg Roach $name = $repository->fullName(); 8875a78cd34SGreg Roach 888d45701ccSGreg Roach $options = [ 889d45701ccSGreg Roach 'record' => $name, 890d45701ccSGreg Roach ]; 8915a78cd34SGreg Roach 892d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 8935a78cd34SGreg Roach 8945a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 8955a78cd34SGreg Roach 'options' => $options, 8965a78cd34SGreg Roach 'record' => $repository, 8975a78cd34SGreg Roach 'title' => $title, 8985a78cd34SGreg Roach 'tree' => $tree, 8995a78cd34SGreg Roach ]); 9005a78cd34SGreg Roach } 9015a78cd34SGreg Roach 9025a78cd34SGreg Roach /** 9036ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9045a78cd34SGreg Roach * 9056ccdf4f0SGreg Roach * @return ResponseInterface 9065a78cd34SGreg Roach */ 90757ab2231SGreg Roach public function postAddRepositoryAction(ServerRequestInterface $request): ResponseInterface 908c1010edaSGreg Roach { 90957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 91075964c75SGreg Roach assert($tree instanceof Tree); 9115229eadeSGreg Roach 912d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 9135a78cd34SGreg Roach 9146b9cb339SGreg Roach $repository = Registry::repositoryFactory()->make($xref, $tree); 915d45701ccSGreg Roach $repository = Auth::checkRepositoryAccess($repository); 9165a78cd34SGreg Roach 917d45701ccSGreg Roach $this->addRepositoryToCart($repository); 918d45701ccSGreg Roach 919d45701ccSGreg Roach foreach ($repository->linkedSources('REPO') as $source) { 920d45701ccSGreg Roach $this->addSourceToCart($source); 9215a78cd34SGreg Roach } 9225a78cd34SGreg Roach 9236ccdf4f0SGreg Roach return redirect($repository->url()); 9245a78cd34SGreg Roach } 9255a78cd34SGreg Roach 9265a78cd34SGreg Roach /** 9276ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9285a78cd34SGreg Roach * 9296ccdf4f0SGreg Roach * @return ResponseInterface 9305a78cd34SGreg Roach */ 93157ab2231SGreg Roach public function getAddSourceAction(ServerRequestInterface $request): ResponseInterface 932c1010edaSGreg Roach { 93357ab2231SGreg Roach $tree = $request->getAttribute('tree'); 93475964c75SGreg Roach assert($tree instanceof Tree); 9355229eadeSGreg Roach 936d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 9375a78cd34SGreg Roach 9386b9cb339SGreg Roach $source = Registry::sourceFactory()->make($xref, $tree); 939d45701ccSGreg Roach $source = Auth::checkSourceAccess($source); 940d45701ccSGreg Roach $name = $source->fullName(); 9415a78cd34SGreg Roach 942d45701ccSGreg Roach $options = [ 943d45701ccSGreg Roach 'record' => $name, 944d45701ccSGreg Roach 'linked' => I18N::translate('%s and the individuals that reference it.', $name), 945d45701ccSGreg Roach ]; 9465a78cd34SGreg Roach 947d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 9485a78cd34SGreg Roach 9495a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 9505a78cd34SGreg Roach 'options' => $options, 9515a78cd34SGreg Roach 'record' => $source, 9525a78cd34SGreg Roach 'title' => $title, 9535a78cd34SGreg Roach 'tree' => $tree, 9545a78cd34SGreg Roach ]); 9555a78cd34SGreg Roach } 9565a78cd34SGreg Roach 9575a78cd34SGreg Roach /** 9586ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9595a78cd34SGreg Roach * 9606ccdf4f0SGreg Roach * @return ResponseInterface 9615a78cd34SGreg Roach */ 96257ab2231SGreg Roach public function postAddSourceAction(ServerRequestInterface $request): ResponseInterface 963c1010edaSGreg Roach { 96457ab2231SGreg Roach $tree = $request->getAttribute('tree'); 96575964c75SGreg Roach assert($tree instanceof Tree); 9665229eadeSGreg Roach 967b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 968b46c87bdSGreg Roach 969d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 970d45701ccSGreg Roach $option = $params['option'] ?? ''; 9715a78cd34SGreg Roach 9726b9cb339SGreg Roach $source = Registry::sourceFactory()->make($xref, $tree); 973d45701ccSGreg Roach $source = Auth::checkSourceAccess($source); 9745a78cd34SGreg Roach 975d45701ccSGreg Roach $this->addSourceToCart($source); 9765a78cd34SGreg Roach 9775a78cd34SGreg Roach if ($option === 'linked') { 9785a78cd34SGreg Roach foreach ($source->linkedIndividuals('SOUR') as $individual) { 979d45701ccSGreg Roach $this->addIndividualToCart($individual); 9805a78cd34SGreg Roach } 9815a78cd34SGreg Roach foreach ($source->linkedFamilies('SOUR') as $family) { 982d45701ccSGreg Roach $this->addFamilyToCart($family); 9835a78cd34SGreg Roach } 9845a78cd34SGreg Roach } 9855a78cd34SGreg Roach 9866ccdf4f0SGreg Roach return redirect($source->url()); 9875a78cd34SGreg Roach } 9885a78cd34SGreg Roach 9895a78cd34SGreg Roach /** 990d45701ccSGreg Roach * @param ServerRequestInterface $request 9915a78cd34SGreg Roach * 992d45701ccSGreg Roach * @return ResponseInterface 9935a78cd34SGreg Roach */ 994d45701ccSGreg Roach public function getAddSubmitterAction(ServerRequestInterface $request): ResponseInterface 995c1010edaSGreg Roach { 996d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 997d45701ccSGreg Roach assert($tree instanceof Tree); 9985a78cd34SGreg Roach 999d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 10005a78cd34SGreg Roach 1001d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $tree); 1002d45701ccSGreg Roach $submitter = Auth::checkSubmitterAccess($submitter); 1003d45701ccSGreg Roach $name = $submitter->fullName(); 10045a78cd34SGreg Roach 1005d45701ccSGreg Roach $options = [ 1006d45701ccSGreg Roach 'record' => $name, 1007d45701ccSGreg Roach ]; 10085a78cd34SGreg Roach 1009d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 10105a78cd34SGreg Roach 1011d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 1012d45701ccSGreg Roach 'options' => $options, 1013d45701ccSGreg Roach 'record' => $submitter, 1014d45701ccSGreg Roach 'title' => $title, 1015d45701ccSGreg Roach 'tree' => $tree, 1016d45701ccSGreg Roach ]); 10175a78cd34SGreg Roach } 10185a78cd34SGreg Roach 10195a78cd34SGreg Roach /** 1020d45701ccSGreg Roach * @param ServerRequestInterface $request 10215a78cd34SGreg Roach * 1022d45701ccSGreg Roach * @return ResponseInterface 10235a78cd34SGreg Roach */ 1024d45701ccSGreg Roach public function postAddSubmitterAction(ServerRequestInterface $request): ResponseInterface 1025d45701ccSGreg Roach { 1026d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 1027d45701ccSGreg Roach assert($tree instanceof Tree); 1028d45701ccSGreg Roach 1029d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 1030d45701ccSGreg Roach 1031d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $tree); 1032d45701ccSGreg Roach $submitter = Auth::checkSubmitterAccess($submitter); 1033d45701ccSGreg Roach 1034d45701ccSGreg Roach $this->addSubmitterToCart($submitter); 1035d45701ccSGreg Roach 1036d45701ccSGreg Roach return redirect($submitter->url()); 1037d45701ccSGreg Roach } 1038d45701ccSGreg Roach 1039d45701ccSGreg Roach /** 1040d45701ccSGreg Roach * @param Family $family 1041d45701ccSGreg Roach */ 1042d45701ccSGreg Roach protected function addFamilyToCart(Family $family): void 1043c1010edaSGreg Roach { 10445a78cd34SGreg Roach $cart = Session::get('cart', []); 1045d45701ccSGreg Roach $tree = $family->tree()->name(); 1046d45701ccSGreg Roach $xref = $family->xref(); 10475a78cd34SGreg Roach 1048d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1049d45701ccSGreg Roach $cart[$tree][$xref] = true; 10505a78cd34SGreg Roach 1051d45701ccSGreg Roach Session::put('cart', $cart); 10525a78cd34SGreg Roach 1053d45701ccSGreg Roach foreach ($family->spouses() as $spouse) { 1054d45701ccSGreg Roach $this->addIndividualToCart($spouse); 10555a78cd34SGreg Roach } 10565a78cd34SGreg Roach 1057*e8ded2caSGreg Roach $this->addLocationLinksToCart($family); 1058d45701ccSGreg Roach $this->addMediaLinksToCart($family); 1059d45701ccSGreg Roach $this->addNoteLinksToCart($family); 1060d45701ccSGreg Roach $this->addSourceLinksToCart($family); 1061d45701ccSGreg Roach $this->addSubmitterLinksToCart($family); 1062d45701ccSGreg Roach } 1063d45701ccSGreg Roach } 1064d45701ccSGreg Roach 1065d45701ccSGreg Roach /** 1066d45701ccSGreg Roach * @param Individual $individual 1067d45701ccSGreg Roach */ 1068d45701ccSGreg Roach protected function addIndividualToCart(Individual $individual): void 1069d45701ccSGreg Roach { 1070d45701ccSGreg Roach $cart = Session::get('cart', []); 1071d45701ccSGreg Roach $tree = $individual->tree()->name(); 1072d45701ccSGreg Roach $xref = $individual->xref(); 1073d45701ccSGreg Roach 1074d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1075d45701ccSGreg Roach $cart[$tree][$xref] = true; 1076d45701ccSGreg Roach 1077d45701ccSGreg Roach Session::put('cart', $cart); 1078d45701ccSGreg Roach 1079*e8ded2caSGreg Roach $this->addLocationLinksToCart($individual); 1080d45701ccSGreg Roach $this->addMediaLinksToCart($individual); 1081d45701ccSGreg Roach $this->addNoteLinksToCart($individual); 1082d45701ccSGreg Roach $this->addSourceLinksToCart($individual); 1083d45701ccSGreg Roach } 1084d45701ccSGreg Roach } 1085d45701ccSGreg Roach 1086d45701ccSGreg Roach /** 1087*e8ded2caSGreg Roach * @param Location $location 1088*e8ded2caSGreg Roach */ 1089*e8ded2caSGreg Roach protected function addLocationToCart(Location $location): void 1090*e8ded2caSGreg Roach { 1091*e8ded2caSGreg Roach $cart = Session::get('cart', []); 1092*e8ded2caSGreg Roach $tree = $location->tree()->name(); 1093*e8ded2caSGreg Roach $xref = $location->xref(); 1094*e8ded2caSGreg Roach 1095*e8ded2caSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1096*e8ded2caSGreg Roach $cart[$tree][$xref] = true; 1097*e8ded2caSGreg Roach 1098*e8ded2caSGreg Roach Session::put('cart', $cart); 1099*e8ded2caSGreg Roach 1100*e8ded2caSGreg Roach $this->addLocationLinksToCart($location); 1101*e8ded2caSGreg Roach $this->addMediaLinksToCart($location); 1102*e8ded2caSGreg Roach $this->addNoteLinksToCart($location); 1103*e8ded2caSGreg Roach $this->addSourceLinksToCart($location); 1104*e8ded2caSGreg Roach } 1105*e8ded2caSGreg Roach } 1106*e8ded2caSGreg Roach 1107*e8ded2caSGreg Roach /** 1108*e8ded2caSGreg Roach * @param GedcomRecord $record 1109*e8ded2caSGreg Roach */ 1110*e8ded2caSGreg Roach protected function addLocationLinksToCart(GedcomRecord $record): void 1111*e8ded2caSGreg Roach { 1112*e8ded2caSGreg Roach preg_match_all('/\n\d _LOC @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1113*e8ded2caSGreg Roach 1114*e8ded2caSGreg Roach foreach ($matches[1] as $xref) { 1115*e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $record->tree()); 1116*e8ded2caSGreg Roach 1117*e8ded2caSGreg Roach if ($location instanceof Location && $location->canShow()) { 1118*e8ded2caSGreg Roach $this->addLocationToCart($location); 1119*e8ded2caSGreg Roach } 1120*e8ded2caSGreg Roach } 1121*e8ded2caSGreg Roach } 1122*e8ded2caSGreg Roach 1123*e8ded2caSGreg Roach /** 1124d45701ccSGreg Roach * @param Media $media 1125d45701ccSGreg Roach */ 1126d45701ccSGreg Roach protected function addMediaToCart(Media $media): void 1127d45701ccSGreg Roach { 1128d45701ccSGreg Roach $cart = Session::get('cart', []); 1129d45701ccSGreg Roach $tree = $media->tree()->name(); 1130d45701ccSGreg Roach $xref = $media->xref(); 1131d45701ccSGreg Roach 1132d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1133d45701ccSGreg Roach $cart[$tree][$xref] = true; 1134d45701ccSGreg Roach 1135d45701ccSGreg Roach Session::put('cart', $cart); 1136d45701ccSGreg Roach 1137d45701ccSGreg Roach $this->addNoteLinksToCart($media); 1138d45701ccSGreg Roach } 1139d45701ccSGreg Roach } 1140d45701ccSGreg Roach 1141d45701ccSGreg Roach /** 1142d45701ccSGreg Roach * @param GedcomRecord $record 1143d45701ccSGreg Roach */ 1144d45701ccSGreg Roach protected function addMediaLinksToCart(GedcomRecord $record): void 1145d45701ccSGreg Roach { 1146d45701ccSGreg Roach preg_match_all('/\n\d OBJE @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1147d45701ccSGreg Roach 1148d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1149d45701ccSGreg Roach $media = Registry::mediaFactory()->make($xref, $record->tree()); 1150d45701ccSGreg Roach 1151d45701ccSGreg Roach if ($media instanceof Media && $media->canShow()) { 1152d45701ccSGreg Roach $this->addMediaToCart($media); 1153d45701ccSGreg Roach } 1154d45701ccSGreg Roach } 1155d45701ccSGreg Roach } 1156d45701ccSGreg Roach 1157d45701ccSGreg Roach /** 1158d45701ccSGreg Roach * @param Note $note 1159d45701ccSGreg Roach */ 1160d45701ccSGreg Roach protected function addNoteToCart(Note $note): void 1161d45701ccSGreg Roach { 1162d45701ccSGreg Roach $cart = Session::get('cart', []); 1163d45701ccSGreg Roach $tree = $note->tree()->name(); 1164d45701ccSGreg Roach $xref = $note->xref(); 1165d45701ccSGreg Roach 1166d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1167d45701ccSGreg Roach $cart[$tree][$xref] = true; 1168d45701ccSGreg Roach 11695a78cd34SGreg Roach Session::put('cart', $cart); 11705a78cd34SGreg Roach } 1171d45701ccSGreg Roach } 11725a78cd34SGreg Roach 11735a78cd34SGreg Roach /** 1174d45701ccSGreg Roach * @param GedcomRecord $record 11755a78cd34SGreg Roach */ 1176d45701ccSGreg Roach protected function addNoteLinksToCart(GedcomRecord $record): void 1177d45701ccSGreg Roach { 1178d45701ccSGreg Roach preg_match_all('/\n\d NOTE @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1179d45701ccSGreg Roach 1180d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1181d45701ccSGreg Roach $note = Registry::noteFactory()->make($xref, $record->tree()); 1182d45701ccSGreg Roach 1183d45701ccSGreg Roach if ($note instanceof Note && $note->canShow()) { 1184d45701ccSGreg Roach $this->addNoteToCart($note); 1185d45701ccSGreg Roach } 1186d45701ccSGreg Roach } 1187d45701ccSGreg Roach } 1188d45701ccSGreg Roach 1189d45701ccSGreg Roach /** 1190d45701ccSGreg Roach * @param Source $source 1191d45701ccSGreg Roach */ 1192d45701ccSGreg Roach protected function addSourceToCart(Source $source): void 1193c1010edaSGreg Roach { 11945a78cd34SGreg Roach $cart = Session::get('cart', []); 1195d45701ccSGreg Roach $tree = $source->tree()->name(); 1196d45701ccSGreg Roach $xref = $source->xref(); 11975a78cd34SGreg Roach 1198d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1199d45701ccSGreg Roach $cart[$tree][$xref] = true; 1200d45701ccSGreg Roach 1201d45701ccSGreg Roach Session::put('cart', $cart); 1202d45701ccSGreg Roach 1203d45701ccSGreg Roach $this->addNoteLinksToCart($source); 1204d45701ccSGreg Roach $this->addRepositoryLinksToCart($source); 1205d45701ccSGreg Roach } 1206d45701ccSGreg Roach } 1207d45701ccSGreg Roach 1208d45701ccSGreg Roach /** 1209d45701ccSGreg Roach * @param GedcomRecord $record 1210d45701ccSGreg Roach */ 1211d45701ccSGreg Roach protected function addSourceLinksToCart(GedcomRecord $record): void 1212d45701ccSGreg Roach { 1213d45701ccSGreg Roach preg_match_all('/\n\d SOUR @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1214d45701ccSGreg Roach 1215d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1216d45701ccSGreg Roach $source = Registry::sourceFactory()->make($xref, $record->tree()); 1217d45701ccSGreg Roach 1218d45701ccSGreg Roach if ($source instanceof Source && $source->canShow()) { 1219d45701ccSGreg Roach $this->addSourceToCart($source); 1220d45701ccSGreg Roach } 1221d45701ccSGreg Roach } 1222d45701ccSGreg Roach } 1223d45701ccSGreg Roach 1224d45701ccSGreg Roach /** 1225d45701ccSGreg Roach * @param Repository $repository 1226d45701ccSGreg Roach */ 1227d45701ccSGreg Roach protected function addRepositoryToCart(Repository $repository): void 1228d45701ccSGreg Roach { 1229d45701ccSGreg Roach $cart = Session::get('cart', []); 1230d45701ccSGreg Roach $tree = $repository->tree()->name(); 1231d45701ccSGreg Roach $xref = $repository->xref(); 1232d45701ccSGreg Roach 1233d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1234d45701ccSGreg Roach $cart[$tree][$xref] = true; 1235d45701ccSGreg Roach 1236d45701ccSGreg Roach Session::put('cart', $cart); 1237d45701ccSGreg Roach 1238d45701ccSGreg Roach $this->addNoteLinksToCart($repository); 1239d45701ccSGreg Roach } 1240d45701ccSGreg Roach } 1241d45701ccSGreg Roach 1242d45701ccSGreg Roach /** 1243d45701ccSGreg Roach * @param GedcomRecord $record 1244d45701ccSGreg Roach */ 1245d45701ccSGreg Roach protected function addRepositoryLinksToCart(GedcomRecord $record): void 1246d45701ccSGreg Roach { 1247d45701ccSGreg Roach preg_match_all('/\n\d REPO @(' . Gedcom::REGEX_XREF . '@)/', $record->gedcom(), $matches); 1248d45701ccSGreg Roach 1249d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1250d45701ccSGreg Roach $repository = Registry::repositoryFactory()->make($xref, $record->tree()); 1251d45701ccSGreg Roach 1252d45701ccSGreg Roach if ($repository instanceof Repository && $repository->canShow()) { 1253d45701ccSGreg Roach $this->addRepositoryToCart($repository); 1254d45701ccSGreg Roach } 1255d45701ccSGreg Roach } 1256d45701ccSGreg Roach } 1257d45701ccSGreg Roach 1258d45701ccSGreg Roach /** 1259d45701ccSGreg Roach * @param Submitter $submitter 1260d45701ccSGreg Roach */ 1261d45701ccSGreg Roach protected function addSubmitterToCart(Submitter $submitter): void 1262d45701ccSGreg Roach { 1263d45701ccSGreg Roach $cart = Session::get('cart', []); 1264d45701ccSGreg Roach $tree = $submitter->tree()->name(); 1265d45701ccSGreg Roach $xref = $submitter->xref(); 1266d45701ccSGreg Roach 1267d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1268d45701ccSGreg Roach $cart[$tree][$xref] = true; 1269d45701ccSGreg Roach 1270d45701ccSGreg Roach Session::put('cart', $cart); 1271d45701ccSGreg Roach 1272d45701ccSGreg Roach $this->addNoteLinksToCart($submitter); 1273d45701ccSGreg Roach } 1274d45701ccSGreg Roach } 1275d45701ccSGreg Roach 1276d45701ccSGreg Roach /** 1277d45701ccSGreg Roach * @param GedcomRecord $record 1278d45701ccSGreg Roach */ 1279d45701ccSGreg Roach protected function addSubmitterLinksToCart(GedcomRecord $record): void 1280d45701ccSGreg Roach { 1281d45701ccSGreg Roach preg_match_all('/\n\d SUBM @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1282d45701ccSGreg Roach 1283d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1284d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $record->tree()); 1285d45701ccSGreg Roach 1286d45701ccSGreg Roach if ($submitter instanceof Submitter && $submitter->canShow()) { 1287d45701ccSGreg Roach $this->addSubmitterToCart($submitter); 1288d45701ccSGreg Roach } 1289d45701ccSGreg Roach } 12905a78cd34SGreg Roach } 12918c2e8227SGreg Roach} 1292