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; 29e8ded2caSGreg 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; 37e8ded2caSGreg 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; 51*f32d77e6SGreg Roachuse League\Flysystem\ZipArchive\FilesystemZipArchiveProvider; 525a78cd34SGreg Roachuse League\Flysystem\ZipArchive\ZipArchiveAdapter; 53bed27cedSGreg Roachuse Psr\Http\Message\ResponseFactoryInterface; 546ccdf4f0SGreg Roachuse Psr\Http\Message\ResponseInterface; 556ccdf4f0SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 566ccdf4f0SGreg Roachuse Psr\Http\Message\StreamFactoryInterface; 5769c05a6eSGreg Roachuse RuntimeException; 583976b470SGreg Roach 59eb235819SGreg Roachuse function app; 60bf80ec58SGreg Roachuse function array_filter; 61bf80ec58SGreg Roachuse function array_keys; 62bf80ec58SGreg Roachuse function array_map; 63fa695506SGreg Roachuse function array_search; 645229eadeSGreg Roachuse function assert; 6569c05a6eSGreg Roachuse function fopen; 66bf80ec58SGreg Roachuse function in_array; 67ddeb3354SGreg Roachuse function is_string; 68bf80ec58SGreg Roachuse function preg_match_all; 69bf80ec58SGreg Roachuse function redirect; 7069c05a6eSGreg Roachuse function rewind; 71bf80ec58SGreg Roachuse function route; 72e5a6b4d4SGreg Roachuse function str_replace; 73fa695506SGreg Roachuse function stream_get_meta_data; 74fa695506SGreg Roachuse function tmpfile; 75fa695506SGreg Roachuse function uasort; 76d45701ccSGreg Roachuse function view; 77fa695506SGreg Roach 78fa695506SGreg Roachuse const PREG_SET_ORDER; 798c2e8227SGreg Roach 808c2e8227SGreg Roach/** 818c2e8227SGreg Roach * Class ClippingsCartModule 828c2e8227SGreg Roach */ 8337eb8894SGreg Roachclass ClippingsCartModule extends AbstractModule implements ModuleMenuInterface 84c1010edaSGreg Roach{ 8549a243cbSGreg Roach use ModuleMenuTrait; 8649a243cbSGreg Roach 875a78cd34SGreg Roach // Routes that have a record which can be added to the clipboard 8816d6367aSGreg Roach private const ROUTES_WITH_RECORDS = [ 89f95e0480SGreg Roach 'Family' => FamilyPage::class, 90f95e0480SGreg Roach 'Individual' => IndividualPage::class, 91f95e0480SGreg Roach 'Media' => MediaPage::class, 92e8ded2caSGreg Roach 'Location' => LocationPage::class, 93f95e0480SGreg Roach 'Note' => NotePage::class, 94f95e0480SGreg Roach 'Repository' => RepositoryPage::class, 95f95e0480SGreg Roach 'Source' => SourcePage::class, 96d45701ccSGreg Roach 'Submitter' => SubmitterPage::class, 97c1010edaSGreg Roach ]; 985a78cd34SGreg Roach 9949a243cbSGreg Roach /** @var int The default access level for this module. It can be changed in the control panel. */ 10049a243cbSGreg Roach protected $access_level = Auth::PRIV_USER; 10149a243cbSGreg Roach 10269c05a6eSGreg Roach /** @var GedcomExportService */ 10369c05a6eSGreg Roach private $gedcom_export_service; 10469c05a6eSGreg Roach 10569c05a6eSGreg Roach /** @var UserService */ 106e5a6b4d4SGreg Roach private $user_service; 107e5a6b4d4SGreg Roach 108e5a6b4d4SGreg Roach /** 109e5a6b4d4SGreg Roach * ClippingsCartModule constructor. 110e5a6b4d4SGreg Roach * 11169c05a6eSGreg Roach * @param GedcomExportService $gedcom_export_service 112e5a6b4d4SGreg Roach * @param UserService $user_service 113e5a6b4d4SGreg Roach */ 11469c05a6eSGreg Roach public function __construct(GedcomExportService $gedcom_export_service, UserService $user_service) 115e5a6b4d4SGreg Roach { 11669c05a6eSGreg Roach $this->gedcom_export_service = $gedcom_export_service; 117e5a6b4d4SGreg Roach $this->user_service = $user_service; 118e5a6b4d4SGreg Roach } 119e5a6b4d4SGreg Roach 120e5a6b4d4SGreg Roach /** 121961ec755SGreg Roach * A sentence describing what this module does. 122961ec755SGreg Roach * 123961ec755SGreg Roach * @return string 124961ec755SGreg Roach */ 12549a243cbSGreg Roach public function description(): string 126c1010edaSGreg Roach { 127bbb76c12SGreg Roach /* I18N: Description of the “Clippings cart” module */ 128bbb76c12SGreg Roach return I18N::translate('Select records from your family tree and save them as a GEDCOM file.'); 1298c2e8227SGreg Roach } 1308c2e8227SGreg Roach 1310ee13198SGreg Roach /** 13249a243cbSGreg Roach * The default position for this menu. It can be changed in the control panel. 1330ee13198SGreg Roach * 1340ee13198SGreg Roach * @return int 1350ee13198SGreg Roach */ 1368f53f488SRico Sonntag public function defaultMenuOrder(): int 137c1010edaSGreg Roach { 138353b36abSGreg Roach return 6; 1398c2e8227SGreg Roach } 1408c2e8227SGreg Roach 1410ee13198SGreg Roach /** 1420ee13198SGreg Roach * A menu, to be added to the main application menu. 1430ee13198SGreg Roach * 144aee13b6dSGreg Roach * @param Tree $tree 145aee13b6dSGreg Roach * 1460ee13198SGreg Roach * @return Menu|null 1470ee13198SGreg Roach */ 14846295629SGreg Roach public function getMenu(Tree $tree): ?Menu 149c1010edaSGreg Roach { 150eb235819SGreg Roach /** @var ServerRequestInterface $request */ 1516ccdf4f0SGreg Roach $request = app(ServerRequestInterface::class); 1528c2e8227SGreg Roach 153f7ab47b1SGreg Roach $route = $request->getAttribute('route'); 154de2aa325SGreg Roach assert($route instanceof Route); 1555a78cd34SGreg Roach 156d45701ccSGreg Roach $cart = Session::get('cart', []); 157d45701ccSGreg Roach $count = count($cart[$tree->name()] ?? []); 158d45701ccSGreg Roach $badge = view('components/badge', ['count' => $count]); 159d45701ccSGreg Roach 1605a78cd34SGreg Roach $submenus = [ 161d45701ccSGreg Roach new Menu($this->title() . ' ' . $badge, route('module', [ 16226684e68SGreg Roach 'module' => $this->name(), 163c1010edaSGreg Roach 'action' => 'Show', 164d72b284aSGreg Roach 'tree' => $tree->name(), 165c1010edaSGreg Roach ]), 'menu-clippings-cart', ['rel' => 'nofollow']), 1665a78cd34SGreg Roach ]; 1675a78cd34SGreg Roach 1682b0d92b4SGreg Roach $action = array_search($route->name, self::ROUTES_WITH_RECORDS, true); 169f95e0480SGreg Roach if ($action !== false) { 1702b0d92b4SGreg Roach $xref = $route->attributes['xref']; 171ddeb3354SGreg Roach assert(is_string($xref)); 172ddeb3354SGreg Roach 173c1010edaSGreg Roach $add_route = route('module', [ 17426684e68SGreg Roach 'module' => $this->name(), 175f95e0480SGreg Roach 'action' => 'Add' . $action, 176c1010edaSGreg Roach 'xref' => $xref, 177d72b284aSGreg Roach 'tree' => $tree->name(), 178c1010edaSGreg Roach ]); 1795a78cd34SGreg Roach 18025b2dde3SGreg Roach $submenus[] = new Menu(I18N::translate('Add to the clippings cart'), $add_route, 'menu-clippings-add', ['rel' => 'nofollow']); 1818c2e8227SGreg Roach } 182cbc1590aSGreg Roach 1835a78cd34SGreg Roach if (!$this->isCartEmpty($tree)) { 184c1010edaSGreg Roach $submenus[] = new Menu(I18N::translate('Empty the clippings cart'), route('module', [ 18526684e68SGreg Roach 'module' => $this->name(), 186c1010edaSGreg Roach 'action' => 'Empty', 187d72b284aSGreg Roach 'tree' => $tree->name(), 188c1010edaSGreg Roach ]), 'menu-clippings-empty', ['rel' => 'nofollow']); 189f95e0480SGreg Roach 190c1010edaSGreg Roach $submenus[] = new Menu(I18N::translate('Download'), route('module', [ 19126684e68SGreg Roach 'module' => $this->name(), 192c1010edaSGreg Roach 'action' => 'DownloadForm', 193d72b284aSGreg Roach 'tree' => $tree->name(), 194c1010edaSGreg Roach ]), 'menu-clippings-download', ['rel' => 'nofollow']); 1955a78cd34SGreg Roach } 1965a78cd34SGreg Roach 19749a243cbSGreg Roach return new Menu($this->title(), '#', 'menu-clippings', ['rel' => 'nofollow'], $submenus); 1988c2e8227SGreg Roach } 1998c2e8227SGreg Roach 20076692c8bSGreg Roach /** 201d45701ccSGreg Roach * How should this module be identified in the control panel, etc.? 202d45701ccSGreg Roach * 203d45701ccSGreg Roach * @return string 204d45701ccSGreg Roach */ 205d45701ccSGreg Roach public function title(): string 206d45701ccSGreg Roach { 207d45701ccSGreg Roach /* I18N: Name of a module */ 208d45701ccSGreg Roach return I18N::translate('Clippings cart'); 209d45701ccSGreg Roach } 210d45701ccSGreg Roach 211d45701ccSGreg Roach /** 212d45701ccSGreg Roach * @param Tree $tree 213d45701ccSGreg Roach * 214d45701ccSGreg Roach * @return bool 215d45701ccSGreg Roach */ 216d45701ccSGreg Roach private function isCartEmpty(Tree $tree): bool 217d45701ccSGreg Roach { 218d45701ccSGreg Roach $cart = Session::get('cart', []); 219d45701ccSGreg Roach $contents = $cart[$tree->name()] ?? []; 220d45701ccSGreg Roach 221d45701ccSGreg Roach return $contents === []; 222d45701ccSGreg Roach } 223d45701ccSGreg Roach 224d45701ccSGreg Roach /** 225d45701ccSGreg Roach * @param ServerRequestInterface $request 226d45701ccSGreg Roach * 227d45701ccSGreg Roach * @return ResponseInterface 228d45701ccSGreg Roach */ 229d45701ccSGreg Roach public function getDownloadFormAction(ServerRequestInterface $request): ResponseInterface 230d45701ccSGreg Roach { 231d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 232d45701ccSGreg Roach assert($tree instanceof Tree); 233d45701ccSGreg Roach 234d45701ccSGreg Roach $user = $request->getAttribute('user'); 235d45701ccSGreg Roach $title = I18N::translate('Family tree clippings cart') . ' — ' . I18N::translate('Download'); 236d45701ccSGreg Roach 237d45701ccSGreg Roach return $this->viewResponse('modules/clippings/download', [ 238d45701ccSGreg Roach 'is_manager' => Auth::isManager($tree, $user), 239d45701ccSGreg Roach 'is_member' => Auth::isMember($tree, $user), 240d45701ccSGreg Roach 'module' => $this->name(), 241d45701ccSGreg Roach 'title' => $title, 242d45701ccSGreg Roach 'tree' => $tree, 243d45701ccSGreg Roach ]); 244d45701ccSGreg Roach } 245d45701ccSGreg Roach 246d45701ccSGreg Roach /** 2476ccdf4f0SGreg Roach * @param ServerRequestInterface $request 24876692c8bSGreg Roach * 2496ccdf4f0SGreg Roach * @return ResponseInterface 25076692c8bSGreg Roach */ 251f95e0480SGreg Roach public function postDownloadAction(ServerRequestInterface $request): ResponseInterface 252c1010edaSGreg Roach { 25357ab2231SGreg Roach $tree = $request->getAttribute('tree'); 2544ea62551SGreg Roach assert($tree instanceof Tree); 2554ea62551SGreg Roach 2566b9cb339SGreg Roach $data_filesystem = Registry::filesystem()->data(); 257a04bb9a2SGreg Roach 258b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 259b46c87bdSGreg Roach 260d45701ccSGreg Roach $privatize_export = $params['privatize_export'] ?? 'none'; 261e2ed7c79SGreg Roach 262e2ed7c79SGreg Roach if ($privatize_export === 'none' && !Auth::isManager($tree)) { 263e2ed7c79SGreg Roach $privatize_export = 'member'; 264e2ed7c79SGreg Roach } 265e2ed7c79SGreg Roach 266e2ed7c79SGreg Roach if ($privatize_export === 'gedadmin' && !Auth::isManager($tree)) { 267e2ed7c79SGreg Roach $privatize_export = 'member'; 268e2ed7c79SGreg Roach } 269e2ed7c79SGreg Roach 270e2ed7c79SGreg Roach if ($privatize_export === 'user' && !Auth::isMember($tree)) { 271e2ed7c79SGreg Roach $privatize_export = 'visitor'; 272e2ed7c79SGreg Roach } 273e2ed7c79SGreg Roach 274b46c87bdSGreg Roach $convert = (bool) ($params['convert'] ?? false); 2758c2e8227SGreg Roach 27613abd6f3SGreg Roach $cart = Session::get('cart', []); 2778c2e8227SGreg Roach 278aa6f03bbSGreg Roach $xrefs = array_keys($cart[$tree->name()] ?? []); 279c8846facSGreg Roach $xrefs = array_map('strval', $xrefs); // PHP converts numeric keys to integers. 2805a78cd34SGreg Roach 2815a78cd34SGreg Roach // Create a new/empty .ZIP file 282a00baf47SGreg Roach $temp_zip_file = stream_get_meta_data(tmpfile())['uri']; 283*f32d77e6SGreg Roach $zip_provider = new FilesystemZipArchiveProvider($temp_zip_file, 0755); 284*f32d77e6SGreg Roach $zip_adapter = new ZipArchiveAdapter($zip_provider); 2857f996f6eSGreg Roach $zip_filesystem = new Filesystem($zip_adapter); 2865a78cd34SGreg Roach 287fa695506SGreg Roach $media_filesystem = $tree->mediaFilesystem($data_filesystem); 28861bf91b2SGreg Roach 2895a78cd34SGreg Roach // Media file prefix 2905a78cd34SGreg Roach $path = $tree->getPreference('MEDIA_DIRECTORY'); 2915a78cd34SGreg Roach 29269c05a6eSGreg Roach $encoding = $convert ? 'ANSI' : 'UTF-8'; 29369c05a6eSGreg Roach 29469c05a6eSGreg Roach $records = new Collection(); 2955a78cd34SGreg Roach 2965a78cd34SGreg Roach switch ($privatize_export) { 2975a78cd34SGreg Roach case 'gedadmin': 2985a78cd34SGreg Roach $access_level = Auth::PRIV_NONE; 2995a78cd34SGreg Roach break; 3005a78cd34SGreg Roach case 'user': 3015a78cd34SGreg Roach $access_level = Auth::PRIV_USER; 3025a78cd34SGreg Roach break; 3035a78cd34SGreg Roach case 'visitor': 3045a78cd34SGreg Roach $access_level = Auth::PRIV_PRIVATE; 3055a78cd34SGreg Roach break; 3065a78cd34SGreg Roach case 'none': 3075a78cd34SGreg Roach default: 3085a78cd34SGreg Roach $access_level = Auth::PRIV_HIDE; 3095a78cd34SGreg Roach break; 3105a78cd34SGreg Roach } 3115a78cd34SGreg Roach 3125a78cd34SGreg Roach foreach ($xrefs as $xref) { 3136b9cb339SGreg Roach $object = Registry::gedcomRecordFactory()->make($xref, $tree); 3145a78cd34SGreg Roach // The object may have been deleted since we added it to the cart.... 315bed27cedSGreg Roach if ($object instanceof GedcomRecord) { 3165a78cd34SGreg Roach $record = $object->privatizeGedcom($access_level); 3175a78cd34SGreg Roach // Remove links to objects that aren't in the cart 3188d0ebef0SGreg Roach preg_match_all('/\n1 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[2-9].*)*/', $record, $matches, PREG_SET_ORDER); 3195a78cd34SGreg Roach foreach ($matches as $match) { 320bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3215a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3225a78cd34SGreg Roach } 3235a78cd34SGreg Roach } 3248d0ebef0SGreg Roach preg_match_all('/\n2 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[3-9].*)*/', $record, $matches, PREG_SET_ORDER); 3255a78cd34SGreg Roach foreach ($matches as $match) { 326bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3275a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3285a78cd34SGreg Roach } 3295a78cd34SGreg Roach } 3308d0ebef0SGreg Roach preg_match_all('/\n3 ' . Gedcom::REGEX_TAG . ' @(' . Gedcom::REGEX_XREF . ')@(\n[4-9].*)*/', $record, $matches, PREG_SET_ORDER); 3315a78cd34SGreg Roach foreach ($matches as $match) { 332bf80ec58SGreg Roach if (!in_array($match[1], $xrefs, true)) { 3335a78cd34SGreg Roach $record = str_replace($match[0], '', $record); 3345a78cd34SGreg Roach } 3355a78cd34SGreg Roach } 3365a78cd34SGreg Roach 33755167344SGreg Roach if ($object instanceof Individual || $object instanceof Family) { 33869c05a6eSGreg Roach $records->add($record . "\n1 SOUR @WEBTREES@\n2 PAGE " . $object->url()); 33955167344SGreg Roach } elseif ($object instanceof Source) { 34069c05a6eSGreg Roach $records->add($record . "\n1 NOTE " . $object->url()); 34155167344SGreg Roach } elseif ($object instanceof Media) { 34255167344SGreg Roach // Add the media files to the archive 3435a78cd34SGreg Roach foreach ($object->mediaFiles() as $media_file) { 344fa695506SGreg Roach $from = $media_file->filename(); 345fa695506SGreg Roach $to = $path . $media_file->filename(); 346f7cf8a15SGreg Roach if (!$media_file->isExternal() && $media_filesystem->fileExists($from) && !$zip_filesystem->fileExists($to)) { 347fa695506SGreg Roach $zip_filesystem->writeStream($to, $media_filesystem->readStream($from)); 3485a78cd34SGreg Roach } 3495a78cd34SGreg Roach } 35069c05a6eSGreg Roach $records->add($record); 35155167344SGreg Roach } else { 35269c05a6eSGreg Roach $records->add($record); 3538c2e8227SGreg Roach } 3548c2e8227SGreg Roach } 3558c2e8227SGreg Roach } 3568c2e8227SGreg Roach 3579b93b7c3SGreg Roach $base_url = $request->getAttribute('base_url'); 3589b93b7c3SGreg Roach 3595a78cd34SGreg Roach // Create a source, to indicate the source of the data. 36069c05a6eSGreg Roach $record = "0 @WEBTREES@ SOUR\n1 TITL " . $base_url; 361e5a6b4d4SGreg Roach $author = $this->user_service->find((int) $tree->getPreference('CONTACT_USER_ID')); 3625a78cd34SGreg Roach if ($author !== null) { 36369c05a6eSGreg Roach $record .= "\n1 AUTH " . $author->realName(); 3645a78cd34SGreg Roach } 36569c05a6eSGreg Roach $records->add($record); 3665a78cd34SGreg Roach 36769c05a6eSGreg Roach $stream = fopen('php://temp', 'wb+'); 3685a78cd34SGreg Roach 36969c05a6eSGreg Roach if ($stream === false) { 37069c05a6eSGreg Roach throw new RuntimeException('Failed to create temporary stream'); 3718c2e8227SGreg Roach } 372cbc1590aSGreg Roach 37369c05a6eSGreg Roach // We have already applied privacy filtering, so do not do it again. 37469c05a6eSGreg Roach $this->gedcom_export_service->export($tree, $stream, false, $encoding, Auth::PRIV_HIDE, $path, $records); 37569c05a6eSGreg Roach rewind($stream); 37669c05a6eSGreg Roach 3775a78cd34SGreg Roach // Finally add the GEDCOM file to the .ZIP file. 37869c05a6eSGreg Roach $zip_filesystem->writeStream('clippings.ged', $stream); 3795a78cd34SGreg Roach 3806ccdf4f0SGreg Roach // Use a stream, so that we do not have to load the entire file into memory. 3816ccdf4f0SGreg Roach $stream = app(StreamFactoryInterface::class)->createStreamFromFile($temp_zip_file); 3825a78cd34SGreg Roach 383bed27cedSGreg Roach /** @var ResponseFactoryInterface $response_factory */ 384bed27cedSGreg Roach $response_factory = app(ResponseFactoryInterface::class); 385bed27cedSGreg Roach 386bed27cedSGreg Roach return $response_factory->createResponse() 3876ccdf4f0SGreg Roach ->withBody($stream) 3881b3d4731SGreg Roach ->withHeader('Content-Type', 'application/zip') 389bed27cedSGreg Roach ->withHeader('Content-Disposition', 'attachment; filename="clippings.zip'); 3908c2e8227SGreg Roach } 3918c2e8227SGreg Roach 3928c2e8227SGreg Roach /** 39357ab2231SGreg Roach * @param ServerRequestInterface $request 39476692c8bSGreg Roach * 3956ccdf4f0SGreg Roach * @return ResponseInterface 3968c2e8227SGreg Roach */ 39757ab2231SGreg Roach public function getEmptyAction(ServerRequestInterface $request): ResponseInterface 398c1010edaSGreg Roach { 39957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 4004ea62551SGreg Roach assert($tree instanceof Tree); 4014ea62551SGreg Roach 4025a78cd34SGreg Roach $cart = Session::get('cart', []); 403aa6f03bbSGreg Roach $cart[$tree->name()] = []; 4045a78cd34SGreg Roach Session::put('cart', $cart); 4058c2e8227SGreg Roach 406c1010edaSGreg Roach $url = route('module', [ 40726684e68SGreg Roach 'module' => $this->name(), 408c1010edaSGreg Roach 'action' => 'Show', 409d72b284aSGreg Roach 'tree' => $tree->name(), 410c1010edaSGreg Roach ]); 4115a78cd34SGreg Roach 4126ccdf4f0SGreg Roach return redirect($url); 4135a78cd34SGreg Roach } 4145a78cd34SGreg Roach 4155a78cd34SGreg Roach /** 4166ccdf4f0SGreg Roach * @param ServerRequestInterface $request 4175a78cd34SGreg Roach * 4186ccdf4f0SGreg Roach * @return ResponseInterface 4195a78cd34SGreg Roach */ 42057ab2231SGreg Roach public function postRemoveAction(ServerRequestInterface $request): ResponseInterface 421c1010edaSGreg Roach { 42257ab2231SGreg Roach $tree = $request->getAttribute('tree'); 42375964c75SGreg Roach assert($tree instanceof Tree); 4245229eadeSGreg Roach 425d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 4265a78cd34SGreg Roach 4275a78cd34SGreg Roach $cart = Session::get('cart', []); 428aa6f03bbSGreg Roach unset($cart[$tree->name()][$xref]); 4295a78cd34SGreg Roach Session::put('cart', $cart); 4305a78cd34SGreg Roach 431c1010edaSGreg Roach $url = route('module', [ 43226684e68SGreg Roach 'module' => $this->name(), 433c1010edaSGreg Roach 'action' => 'Show', 434d72b284aSGreg Roach 'tree' => $tree->name(), 435c1010edaSGreg Roach ]); 4365a78cd34SGreg Roach 4376ccdf4f0SGreg Roach return redirect($url); 4385a78cd34SGreg Roach } 4395a78cd34SGreg Roach 4405a78cd34SGreg Roach /** 44157ab2231SGreg Roach * @param ServerRequestInterface $request 4425a78cd34SGreg Roach * 4436ccdf4f0SGreg Roach * @return ResponseInterface 4445a78cd34SGreg Roach */ 44557ab2231SGreg Roach public function getShowAction(ServerRequestInterface $request): ResponseInterface 446c1010edaSGreg Roach { 44757ab2231SGreg Roach $tree = $request->getAttribute('tree'); 44875964c75SGreg Roach assert($tree instanceof Tree); 44957ab2231SGreg Roach 4505a78cd34SGreg Roach return $this->viewResponse('modules/clippings/show', [ 45177b78a63SRichard Cissée 'module' => $this->name(), 4525a78cd34SGreg Roach 'records' => $this->allRecordsInCart($tree), 4535a78cd34SGreg Roach 'title' => I18N::translate('Family tree clippings cart'), 4545a78cd34SGreg Roach 'tree' => $tree, 4555a78cd34SGreg Roach ]); 4565a78cd34SGreg Roach } 4575a78cd34SGreg Roach 4585a78cd34SGreg Roach /** 459d45701ccSGreg Roach * Get all the records in the cart. 460d45701ccSGreg Roach * 461d45701ccSGreg Roach * @param Tree $tree 462d45701ccSGreg Roach * 463d45701ccSGreg Roach * @return GedcomRecord[] 464d45701ccSGreg Roach */ 465d45701ccSGreg Roach private function allRecordsInCart(Tree $tree): array 466d45701ccSGreg Roach { 467d45701ccSGreg Roach $cart = Session::get('cart', []); 468d45701ccSGreg Roach 469d45701ccSGreg Roach $xrefs = array_keys($cart[$tree->name()] ?? []); 470d45701ccSGreg Roach $xrefs = array_map('strval', $xrefs); // PHP converts numeric keys to integers. 471d45701ccSGreg Roach 472d45701ccSGreg Roach // Fetch all the records in the cart. 473d45701ccSGreg Roach $records = array_map(static function (string $xref) use ($tree): ?GedcomRecord { 474d45701ccSGreg Roach return Registry::gedcomRecordFactory()->make($xref, $tree); 475d45701ccSGreg Roach }, $xrefs); 476d45701ccSGreg Roach 477d45701ccSGreg Roach // Some records may have been deleted after they were added to the cart. 478d45701ccSGreg Roach $records = array_filter($records); 479d45701ccSGreg Roach 480d45701ccSGreg Roach // Group and sort. 481d45701ccSGreg Roach uasort($records, static function (GedcomRecord $x, GedcomRecord $y): int { 482d45701ccSGreg Roach return $x->tag() <=> $y->tag() ?: GedcomRecord::nameComparator()($x, $y); 483d45701ccSGreg Roach }); 484d45701ccSGreg Roach 485d45701ccSGreg Roach return $records; 486d45701ccSGreg Roach } 487d45701ccSGreg Roach 488d45701ccSGreg Roach /** 4896ccdf4f0SGreg Roach * @param ServerRequestInterface $request 4905a78cd34SGreg Roach * 4916ccdf4f0SGreg Roach * @return ResponseInterface 4925a78cd34SGreg Roach */ 49357ab2231SGreg Roach public function getAddFamilyAction(ServerRequestInterface $request): ResponseInterface 494c1010edaSGreg Roach { 49557ab2231SGreg Roach $tree = $request->getAttribute('tree'); 49675964c75SGreg Roach assert($tree instanceof Tree); 4975229eadeSGreg Roach 498d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 4995a78cd34SGreg Roach 5006b9cb339SGreg Roach $family = Registry::familyFactory()->make($xref, $tree); 501d45701ccSGreg Roach $family = Auth::checkFamilyAccess($family); 502d45701ccSGreg Roach $name = $family->fullName(); 5035a78cd34SGreg Roach 504d45701ccSGreg Roach $options = [ 505d45701ccSGreg Roach 'record' => $name, 506bbb76c12SGreg Roach /* I18N: %s is a family (husband + wife) */ 507bbb76c12SGreg Roach 'members' => I18N::translate('%s and their children', $name), 508bbb76c12SGreg Roach /* I18N: %s is a family (husband + wife) */ 509bbb76c12SGreg Roach 'descendants' => I18N::translate('%s and their descendants', $name), 5105a78cd34SGreg Roach ]; 511d45701ccSGreg Roach 512d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 513d45701ccSGreg Roach 514d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 515d45701ccSGreg Roach 'options' => $options, 516d45701ccSGreg Roach 'record' => $family, 517d45701ccSGreg Roach 'title' => $title, 518d45701ccSGreg Roach 'tree' => $tree, 519d45701ccSGreg Roach ]); 5205a78cd34SGreg Roach } 5215a78cd34SGreg Roach 5225a78cd34SGreg Roach /** 5236ccdf4f0SGreg Roach * @param ServerRequestInterface $request 5245a78cd34SGreg Roach * 5256ccdf4f0SGreg Roach * @return ResponseInterface 5265a78cd34SGreg Roach */ 52757ab2231SGreg Roach public function postAddFamilyAction(ServerRequestInterface $request): ResponseInterface 528c1010edaSGreg Roach { 52957ab2231SGreg Roach $tree = $request->getAttribute('tree'); 5304ea62551SGreg Roach assert($tree instanceof Tree); 5314ea62551SGreg Roach 532b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 533b46c87bdSGreg Roach 534d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 535d45701ccSGreg Roach $option = $params['option'] ?? ''; 5365a78cd34SGreg Roach 5376b9cb339SGreg Roach $family = Registry::familyFactory()->make($xref, $tree); 538d45701ccSGreg Roach $family = Auth::checkFamilyAccess($family); 5395a78cd34SGreg Roach 5405a78cd34SGreg Roach switch ($option) { 541d45701ccSGreg Roach case 'self': 5425a78cd34SGreg Roach $this->addFamilyToCart($family); 5435a78cd34SGreg Roach break; 5445a78cd34SGreg Roach 5455a78cd34SGreg Roach case 'members': 5465a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 5475a78cd34SGreg Roach break; 5485a78cd34SGreg Roach 5495a78cd34SGreg Roach case 'descendants': 5505a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($family); 5515a78cd34SGreg Roach break; 5525a78cd34SGreg Roach } 5535a78cd34SGreg Roach 5546ccdf4f0SGreg Roach return redirect($family->url()); 5555a78cd34SGreg Roach } 5565a78cd34SGreg Roach 5575a78cd34SGreg Roach 5585a78cd34SGreg Roach /** 5595a78cd34SGreg Roach * @param Family $family 56018d7a90dSGreg Roach * 56118d7a90dSGreg Roach * @return void 5625a78cd34SGreg Roach */ 563d45701ccSGreg Roach protected function addFamilyAndChildrenToCart(Family $family): void 564c1010edaSGreg Roach { 565d45701ccSGreg Roach $this->addFamilyToCart($family); 5665a78cd34SGreg Roach 56739ca88baSGreg Roach foreach ($family->children() as $child) { 568d45701ccSGreg Roach $this->addIndividualToCart($child); 5695a78cd34SGreg Roach } 5705a78cd34SGreg Roach } 5715a78cd34SGreg Roach 5725a78cd34SGreg Roach /** 5735a78cd34SGreg Roach * @param Family $family 57418d7a90dSGreg Roach * 57518d7a90dSGreg Roach * @return void 5765a78cd34SGreg Roach */ 577d45701ccSGreg Roach protected function addFamilyAndDescendantsToCart(Family $family): void 578c1010edaSGreg Roach { 579d45701ccSGreg Roach $this->addFamilyAndChildrenToCart($family); 5805a78cd34SGreg Roach 58139ca88baSGreg Roach foreach ($family->children() as $child) { 58239ca88baSGreg Roach foreach ($child->spouseFamilies() as $child_family) { 5835a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($child_family); 5845a78cd34SGreg Roach } 5855a78cd34SGreg Roach } 5865a78cd34SGreg Roach } 5875a78cd34SGreg Roach 5885a78cd34SGreg Roach /** 5896ccdf4f0SGreg Roach * @param ServerRequestInterface $request 5905a78cd34SGreg Roach * 5916ccdf4f0SGreg Roach * @return ResponseInterface 5925a78cd34SGreg Roach */ 59357ab2231SGreg Roach public function getAddIndividualAction(ServerRequestInterface $request): ResponseInterface 594c1010edaSGreg Roach { 59557ab2231SGreg Roach $tree = $request->getAttribute('tree'); 59675964c75SGreg Roach assert($tree instanceof Tree); 5975229eadeSGreg Roach 598d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 5995a78cd34SGreg Roach 6006b9cb339SGreg Roach $individual = Registry::individualFactory()->make($xref, $tree); 601d45701ccSGreg Roach $individual = Auth::checkIndividualAccess($individual); 602d45701ccSGreg Roach $name = $individual->fullName(); 6035a78cd34SGreg Roach 60439ca88baSGreg Roach if ($individual->sex() === 'F') { 605d45701ccSGreg Roach $options = [ 606d45701ccSGreg Roach 'record' => $name, 6075a78cd34SGreg Roach 'parents' => I18N::translate('%s, her parents and siblings', $name), 6085a78cd34SGreg Roach 'spouses' => I18N::translate('%s, her spouses and children', $name), 6095a78cd34SGreg Roach 'ancestors' => I18N::translate('%s and her ancestors', $name), 6105a78cd34SGreg Roach 'ancestor_families' => I18N::translate('%s, her ancestors and their families', $name), 6115a78cd34SGreg Roach 'descendants' => I18N::translate('%s, her spouses and descendants', $name), 6125a78cd34SGreg Roach ]; 613d45701ccSGreg Roach } else { 614d45701ccSGreg Roach $options = [ 615d45701ccSGreg Roach 'record' => $name, 6165a78cd34SGreg Roach 'parents' => I18N::translate('%s, his parents and siblings', $name), 6175a78cd34SGreg Roach 'spouses' => I18N::translate('%s, his spouses and children', $name), 6185a78cd34SGreg Roach 'ancestors' => I18N::translate('%s and his ancestors', $name), 6195a78cd34SGreg Roach 'ancestor_families' => I18N::translate('%s, his ancestors and their families', $name), 6205a78cd34SGreg Roach 'descendants' => I18N::translate('%s, his spouses and descendants', $name), 6215a78cd34SGreg Roach ]; 6225a78cd34SGreg Roach } 6235a78cd34SGreg Roach 624d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 625d45701ccSGreg Roach 626d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 627d45701ccSGreg Roach 'options' => $options, 628d45701ccSGreg Roach 'record' => $individual, 629d45701ccSGreg Roach 'title' => $title, 630d45701ccSGreg Roach 'tree' => $tree, 631d45701ccSGreg Roach ]); 632d45701ccSGreg Roach } 633d45701ccSGreg Roach 6345a78cd34SGreg Roach /** 6356ccdf4f0SGreg Roach * @param ServerRequestInterface $request 6365a78cd34SGreg Roach * 6376ccdf4f0SGreg Roach * @return ResponseInterface 6385a78cd34SGreg Roach */ 63957ab2231SGreg Roach public function postAddIndividualAction(ServerRequestInterface $request): ResponseInterface 640c1010edaSGreg Roach { 64157ab2231SGreg Roach $tree = $request->getAttribute('tree'); 6424ea62551SGreg Roach assert($tree instanceof Tree); 6434ea62551SGreg Roach 644b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 645b46c87bdSGreg Roach 646d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 647d45701ccSGreg Roach $option = $params['option'] ?? ''; 6485a78cd34SGreg Roach 6496b9cb339SGreg Roach $individual = Registry::individualFactory()->make($xref, $tree); 650d45701ccSGreg Roach $individual = Auth::checkIndividualAccess($individual); 6515a78cd34SGreg Roach 6525a78cd34SGreg Roach switch ($option) { 6535a78cd34SGreg Roach case 'self': 654d45701ccSGreg Roach $this->addIndividualToCart($individual); 6555a78cd34SGreg Roach break; 6565a78cd34SGreg Roach 6575a78cd34SGreg Roach case 'parents': 65839ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 6595a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 6605a78cd34SGreg Roach } 6615a78cd34SGreg Roach break; 6625a78cd34SGreg Roach 6635a78cd34SGreg Roach case 'spouses': 66439ca88baSGreg Roach foreach ($individual->spouseFamilies() as $family) { 6655a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 6665a78cd34SGreg Roach } 6675a78cd34SGreg Roach break; 6685a78cd34SGreg Roach 6695a78cd34SGreg Roach case 'ancestors': 6705a78cd34SGreg Roach $this->addAncestorsToCart($individual); 6715a78cd34SGreg Roach break; 6725a78cd34SGreg Roach 6735a78cd34SGreg Roach case 'ancestor_families': 6745a78cd34SGreg Roach $this->addAncestorFamiliesToCart($individual); 6755a78cd34SGreg Roach break; 6765a78cd34SGreg Roach 6775a78cd34SGreg Roach case 'descendants': 67839ca88baSGreg Roach foreach ($individual->spouseFamilies() as $family) { 6795a78cd34SGreg Roach $this->addFamilyAndDescendantsToCart($family); 6805a78cd34SGreg Roach } 6815a78cd34SGreg Roach break; 6825a78cd34SGreg Roach } 6835a78cd34SGreg Roach 6846ccdf4f0SGreg Roach return redirect($individual->url()); 6855a78cd34SGreg Roach } 6865a78cd34SGreg Roach 6875a78cd34SGreg Roach /** 6885a78cd34SGreg Roach * @param Individual $individual 68918d7a90dSGreg Roach * 69018d7a90dSGreg Roach * @return void 6915a78cd34SGreg Roach */ 692d45701ccSGreg Roach protected function addAncestorsToCart(Individual $individual): void 693c1010edaSGreg Roach { 694d45701ccSGreg Roach $this->addIndividualToCart($individual); 6955a78cd34SGreg Roach 69639ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 697d45701ccSGreg Roach $this->addFamilyToCart($family); 6988df4c68dSGreg Roach 69939ca88baSGreg Roach foreach ($family->spouses() as $parent) { 7005a78cd34SGreg Roach $this->addAncestorsToCart($parent); 7015a78cd34SGreg Roach } 7025a78cd34SGreg Roach } 7035a78cd34SGreg Roach } 7045a78cd34SGreg Roach 7055a78cd34SGreg Roach /** 7065a78cd34SGreg Roach * @param Individual $individual 70718d7a90dSGreg Roach * 70818d7a90dSGreg Roach * @return void 7095a78cd34SGreg Roach */ 710d45701ccSGreg Roach protected function addAncestorFamiliesToCart(Individual $individual): void 711c1010edaSGreg Roach { 71239ca88baSGreg Roach foreach ($individual->childFamilies() as $family) { 7135a78cd34SGreg Roach $this->addFamilyAndChildrenToCart($family); 7148df4c68dSGreg Roach 71539ca88baSGreg Roach foreach ($family->spouses() as $parent) { 716cad6d3f3SGreg Roach $this->addAncestorFamiliesToCart($parent); 7175a78cd34SGreg Roach } 7185a78cd34SGreg Roach } 7195a78cd34SGreg Roach } 7205a78cd34SGreg Roach 7215a78cd34SGreg Roach /** 7226ccdf4f0SGreg Roach * @param ServerRequestInterface $request 7235a78cd34SGreg Roach * 7246ccdf4f0SGreg Roach * @return ResponseInterface 7255a78cd34SGreg Roach */ 726e8ded2caSGreg Roach public function getAddLocationAction(ServerRequestInterface $request): ResponseInterface 727e8ded2caSGreg Roach { 728e8ded2caSGreg Roach $tree = $request->getAttribute('tree'); 729e8ded2caSGreg Roach assert($tree instanceof Tree); 730e8ded2caSGreg Roach 731e8ded2caSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 732e8ded2caSGreg Roach 733e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $tree); 734e8ded2caSGreg Roach $location = Auth::checkLocationAccess($location); 735e8ded2caSGreg Roach $name = $location->fullName(); 736e8ded2caSGreg Roach 737e8ded2caSGreg Roach $options = [ 738e8ded2caSGreg Roach 'record' => $name, 739e8ded2caSGreg Roach ]; 740e8ded2caSGreg Roach 741e8ded2caSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 742e8ded2caSGreg Roach 743e8ded2caSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 744e8ded2caSGreg Roach 'options' => $options, 745e8ded2caSGreg Roach 'record' => $location, 746e8ded2caSGreg Roach 'title' => $title, 747e8ded2caSGreg Roach 'tree' => $tree, 748e8ded2caSGreg Roach ]); 749e8ded2caSGreg Roach } 750e8ded2caSGreg Roach 751e8ded2caSGreg Roach /** 752e8ded2caSGreg Roach * @param ServerRequestInterface $request 753e8ded2caSGreg Roach * 754e8ded2caSGreg Roach * @return ResponseInterface 755e8ded2caSGreg Roach */ 756e8ded2caSGreg Roach public function postAddLocationAction(ServerRequestInterface $request): ResponseInterface 757e8ded2caSGreg Roach { 758e8ded2caSGreg Roach $tree = $request->getAttribute('tree'); 759e8ded2caSGreg Roach assert($tree instanceof Tree); 760e8ded2caSGreg Roach 761e8ded2caSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 762e8ded2caSGreg Roach 763e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $tree); 764e8ded2caSGreg Roach $location = Auth::checkLocationAccess($location); 765e8ded2caSGreg Roach 766e8ded2caSGreg Roach $this->addLocationToCart($location); 767e8ded2caSGreg Roach 768e8ded2caSGreg Roach return redirect($location->url()); 769e8ded2caSGreg Roach } 770e8ded2caSGreg Roach 771e8ded2caSGreg Roach /** 772e8ded2caSGreg Roach * @param ServerRequestInterface $request 773e8ded2caSGreg Roach * 774e8ded2caSGreg Roach * @return ResponseInterface 775e8ded2caSGreg Roach */ 77657ab2231SGreg Roach public function getAddMediaAction(ServerRequestInterface $request): ResponseInterface 777c1010edaSGreg Roach { 77857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 77975964c75SGreg Roach assert($tree instanceof Tree); 7805229eadeSGreg Roach 781d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 7825a78cd34SGreg Roach 7836b9cb339SGreg Roach $media = Registry::mediaFactory()->make($xref, $tree); 784d45701ccSGreg Roach $media = Auth::checkMediaAccess($media); 785d45701ccSGreg Roach $name = $media->fullName(); 7865a78cd34SGreg Roach 787d45701ccSGreg Roach $options = [ 788d45701ccSGreg Roach 'record' => $name, 789d45701ccSGreg Roach ]; 7905a78cd34SGreg Roach 791d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 7925a78cd34SGreg Roach 7935a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 7945a78cd34SGreg Roach 'options' => $options, 7955a78cd34SGreg Roach 'record' => $media, 7965a78cd34SGreg Roach 'title' => $title, 7975a78cd34SGreg Roach 'tree' => $tree, 7985a78cd34SGreg Roach ]); 7995a78cd34SGreg Roach } 8005a78cd34SGreg Roach 8015a78cd34SGreg Roach /** 8026ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8035a78cd34SGreg Roach * 8046ccdf4f0SGreg Roach * @return ResponseInterface 8055a78cd34SGreg Roach */ 80657ab2231SGreg Roach public function postAddMediaAction(ServerRequestInterface $request): ResponseInterface 807c1010edaSGreg Roach { 80857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 80975964c75SGreg Roach assert($tree instanceof Tree); 8105229eadeSGreg Roach 811d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8125a78cd34SGreg Roach 8136b9cb339SGreg Roach $media = Registry::mediaFactory()->make($xref, $tree); 814d45701ccSGreg Roach $media = Auth::checkMediaAccess($media); 8155a78cd34SGreg Roach 816d45701ccSGreg Roach $this->addMediaToCart($media); 8175a78cd34SGreg Roach 8186ccdf4f0SGreg Roach return redirect($media->url()); 8195a78cd34SGreg Roach } 8205a78cd34SGreg Roach 8215a78cd34SGreg Roach /** 8226ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8235a78cd34SGreg Roach * 8246ccdf4f0SGreg Roach * @return ResponseInterface 8255a78cd34SGreg Roach */ 82657ab2231SGreg Roach public function getAddNoteAction(ServerRequestInterface $request): ResponseInterface 827c1010edaSGreg Roach { 82857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 82975964c75SGreg Roach assert($tree instanceof Tree); 8305229eadeSGreg Roach 831d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8325a78cd34SGreg Roach 8336b9cb339SGreg Roach $note = Registry::noteFactory()->make($xref, $tree); 834d45701ccSGreg Roach $note = Auth::checkNoteAccess($note); 835d45701ccSGreg Roach $name = $note->fullName(); 8365a78cd34SGreg Roach 837d45701ccSGreg Roach $options = [ 838d45701ccSGreg Roach 'record' => $name, 839d45701ccSGreg Roach ]; 8405a78cd34SGreg Roach 841d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 8425a78cd34SGreg Roach 8435a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 8445a78cd34SGreg Roach 'options' => $options, 8455a78cd34SGreg Roach 'record' => $note, 8465a78cd34SGreg Roach 'title' => $title, 8475a78cd34SGreg Roach 'tree' => $tree, 8485a78cd34SGreg Roach ]); 8495a78cd34SGreg Roach } 8505a78cd34SGreg Roach 8515a78cd34SGreg Roach /** 8526ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8535a78cd34SGreg Roach * 8546ccdf4f0SGreg Roach * @return ResponseInterface 8555a78cd34SGreg Roach */ 85657ab2231SGreg Roach public function postAddNoteAction(ServerRequestInterface $request): ResponseInterface 857c1010edaSGreg Roach { 85857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 85975964c75SGreg Roach assert($tree instanceof Tree); 8605229eadeSGreg Roach 861d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8625a78cd34SGreg Roach 8636b9cb339SGreg Roach $note = Registry::noteFactory()->make($xref, $tree); 864d45701ccSGreg Roach $note = Auth::checkNoteAccess($note); 8655a78cd34SGreg Roach 866d45701ccSGreg Roach $this->addNoteToCart($note); 8675a78cd34SGreg Roach 8686ccdf4f0SGreg Roach return redirect($note->url()); 8695a78cd34SGreg Roach } 8705a78cd34SGreg Roach 8715a78cd34SGreg Roach /** 8726ccdf4f0SGreg Roach * @param ServerRequestInterface $request 8735a78cd34SGreg Roach * 8746ccdf4f0SGreg Roach * @return ResponseInterface 8755a78cd34SGreg Roach */ 87657ab2231SGreg Roach public function getAddRepositoryAction(ServerRequestInterface $request): ResponseInterface 877c1010edaSGreg Roach { 87857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 87975964c75SGreg Roach assert($tree instanceof Tree); 8805229eadeSGreg Roach 881d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 8825a78cd34SGreg Roach 8836b9cb339SGreg Roach $repository = Registry::repositoryFactory()->make($xref, $tree); 884d45701ccSGreg Roach $repository = Auth::checkRepositoryAccess($repository); 885d45701ccSGreg Roach $name = $repository->fullName(); 8865a78cd34SGreg Roach 887d45701ccSGreg Roach $options = [ 888d45701ccSGreg Roach 'record' => $name, 889d45701ccSGreg Roach ]; 8905a78cd34SGreg Roach 891d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 8925a78cd34SGreg Roach 8935a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 8945a78cd34SGreg Roach 'options' => $options, 8955a78cd34SGreg Roach 'record' => $repository, 8965a78cd34SGreg Roach 'title' => $title, 8975a78cd34SGreg Roach 'tree' => $tree, 8985a78cd34SGreg Roach ]); 8995a78cd34SGreg Roach } 9005a78cd34SGreg Roach 9015a78cd34SGreg Roach /** 9026ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9035a78cd34SGreg Roach * 9046ccdf4f0SGreg Roach * @return ResponseInterface 9055a78cd34SGreg Roach */ 90657ab2231SGreg Roach public function postAddRepositoryAction(ServerRequestInterface $request): ResponseInterface 907c1010edaSGreg Roach { 90857ab2231SGreg Roach $tree = $request->getAttribute('tree'); 90975964c75SGreg Roach assert($tree instanceof Tree); 9105229eadeSGreg Roach 911d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 9125a78cd34SGreg Roach 9136b9cb339SGreg Roach $repository = Registry::repositoryFactory()->make($xref, $tree); 914d45701ccSGreg Roach $repository = Auth::checkRepositoryAccess($repository); 9155a78cd34SGreg Roach 916d45701ccSGreg Roach $this->addRepositoryToCart($repository); 917d45701ccSGreg Roach 918d45701ccSGreg Roach foreach ($repository->linkedSources('REPO') as $source) { 919d45701ccSGreg Roach $this->addSourceToCart($source); 9205a78cd34SGreg Roach } 9215a78cd34SGreg Roach 9226ccdf4f0SGreg Roach return redirect($repository->url()); 9235a78cd34SGreg Roach } 9245a78cd34SGreg Roach 9255a78cd34SGreg Roach /** 9266ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9275a78cd34SGreg Roach * 9286ccdf4f0SGreg Roach * @return ResponseInterface 9295a78cd34SGreg Roach */ 93057ab2231SGreg Roach public function getAddSourceAction(ServerRequestInterface $request): ResponseInterface 931c1010edaSGreg Roach { 93257ab2231SGreg Roach $tree = $request->getAttribute('tree'); 93375964c75SGreg Roach assert($tree instanceof Tree); 9345229eadeSGreg Roach 935d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 9365a78cd34SGreg Roach 9376b9cb339SGreg Roach $source = Registry::sourceFactory()->make($xref, $tree); 938d45701ccSGreg Roach $source = Auth::checkSourceAccess($source); 939d45701ccSGreg Roach $name = $source->fullName(); 9405a78cd34SGreg Roach 941d45701ccSGreg Roach $options = [ 942d45701ccSGreg Roach 'record' => $name, 943d45701ccSGreg Roach 'linked' => I18N::translate('%s and the individuals that reference it.', $name), 944d45701ccSGreg Roach ]; 9455a78cd34SGreg Roach 946d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 9475a78cd34SGreg Roach 9485a78cd34SGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 9495a78cd34SGreg Roach 'options' => $options, 9505a78cd34SGreg Roach 'record' => $source, 9515a78cd34SGreg Roach 'title' => $title, 9525a78cd34SGreg Roach 'tree' => $tree, 9535a78cd34SGreg Roach ]); 9545a78cd34SGreg Roach } 9555a78cd34SGreg Roach 9565a78cd34SGreg Roach /** 9576ccdf4f0SGreg Roach * @param ServerRequestInterface $request 9585a78cd34SGreg Roach * 9596ccdf4f0SGreg Roach * @return ResponseInterface 9605a78cd34SGreg Roach */ 96157ab2231SGreg Roach public function postAddSourceAction(ServerRequestInterface $request): ResponseInterface 962c1010edaSGreg Roach { 96357ab2231SGreg Roach $tree = $request->getAttribute('tree'); 96475964c75SGreg Roach assert($tree instanceof Tree); 9655229eadeSGreg Roach 966b46c87bdSGreg Roach $params = (array) $request->getParsedBody(); 967b46c87bdSGreg Roach 968d45701ccSGreg Roach $xref = $params['xref'] ?? ''; 969d45701ccSGreg Roach $option = $params['option'] ?? ''; 9705a78cd34SGreg Roach 9716b9cb339SGreg Roach $source = Registry::sourceFactory()->make($xref, $tree); 972d45701ccSGreg Roach $source = Auth::checkSourceAccess($source); 9735a78cd34SGreg Roach 974d45701ccSGreg Roach $this->addSourceToCart($source); 9755a78cd34SGreg Roach 9765a78cd34SGreg Roach if ($option === 'linked') { 9775a78cd34SGreg Roach foreach ($source->linkedIndividuals('SOUR') as $individual) { 978d45701ccSGreg Roach $this->addIndividualToCart($individual); 9795a78cd34SGreg Roach } 9805a78cd34SGreg Roach foreach ($source->linkedFamilies('SOUR') as $family) { 981d45701ccSGreg Roach $this->addFamilyToCart($family); 9825a78cd34SGreg Roach } 9835a78cd34SGreg Roach } 9845a78cd34SGreg Roach 9856ccdf4f0SGreg Roach return redirect($source->url()); 9865a78cd34SGreg Roach } 9875a78cd34SGreg Roach 9885a78cd34SGreg Roach /** 989d45701ccSGreg Roach * @param ServerRequestInterface $request 9905a78cd34SGreg Roach * 991d45701ccSGreg Roach * @return ResponseInterface 9925a78cd34SGreg Roach */ 993d45701ccSGreg Roach public function getAddSubmitterAction(ServerRequestInterface $request): ResponseInterface 994c1010edaSGreg Roach { 995d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 996d45701ccSGreg Roach assert($tree instanceof Tree); 9975a78cd34SGreg Roach 998d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 9995a78cd34SGreg Roach 1000d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $tree); 1001d45701ccSGreg Roach $submitter = Auth::checkSubmitterAccess($submitter); 1002d45701ccSGreg Roach $name = $submitter->fullName(); 10035a78cd34SGreg Roach 1004d45701ccSGreg Roach $options = [ 1005d45701ccSGreg Roach 'record' => $name, 1006d45701ccSGreg Roach ]; 10075a78cd34SGreg Roach 1008d45701ccSGreg Roach $title = I18N::translate('Add %s to the clippings cart', $name); 10095a78cd34SGreg Roach 1010d45701ccSGreg Roach return $this->viewResponse('modules/clippings/add-options', [ 1011d45701ccSGreg Roach 'options' => $options, 1012d45701ccSGreg Roach 'record' => $submitter, 1013d45701ccSGreg Roach 'title' => $title, 1014d45701ccSGreg Roach 'tree' => $tree, 1015d45701ccSGreg Roach ]); 10165a78cd34SGreg Roach } 10175a78cd34SGreg Roach 10185a78cd34SGreg Roach /** 1019d45701ccSGreg Roach * @param ServerRequestInterface $request 10205a78cd34SGreg Roach * 1021d45701ccSGreg Roach * @return ResponseInterface 10225a78cd34SGreg Roach */ 1023d45701ccSGreg Roach public function postAddSubmitterAction(ServerRequestInterface $request): ResponseInterface 1024d45701ccSGreg Roach { 1025d45701ccSGreg Roach $tree = $request->getAttribute('tree'); 1026d45701ccSGreg Roach assert($tree instanceof Tree); 1027d45701ccSGreg Roach 1028d45701ccSGreg Roach $xref = $request->getQueryParams()['xref'] ?? ''; 1029d45701ccSGreg Roach 1030d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $tree); 1031d45701ccSGreg Roach $submitter = Auth::checkSubmitterAccess($submitter); 1032d45701ccSGreg Roach 1033d45701ccSGreg Roach $this->addSubmitterToCart($submitter); 1034d45701ccSGreg Roach 1035d45701ccSGreg Roach return redirect($submitter->url()); 1036d45701ccSGreg Roach } 1037d45701ccSGreg Roach 1038d45701ccSGreg Roach /** 1039d45701ccSGreg Roach * @param Family $family 1040d45701ccSGreg Roach */ 1041d45701ccSGreg Roach protected function addFamilyToCart(Family $family): void 1042c1010edaSGreg Roach { 10435a78cd34SGreg Roach $cart = Session::get('cart', []); 1044d45701ccSGreg Roach $tree = $family->tree()->name(); 1045d45701ccSGreg Roach $xref = $family->xref(); 10465a78cd34SGreg Roach 1047d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1048d45701ccSGreg Roach $cart[$tree][$xref] = true; 10495a78cd34SGreg Roach 1050d45701ccSGreg Roach Session::put('cart', $cart); 10515a78cd34SGreg Roach 1052d45701ccSGreg Roach foreach ($family->spouses() as $spouse) { 1053d45701ccSGreg Roach $this->addIndividualToCart($spouse); 10545a78cd34SGreg Roach } 10555a78cd34SGreg Roach 1056e8ded2caSGreg Roach $this->addLocationLinksToCart($family); 1057d45701ccSGreg Roach $this->addMediaLinksToCart($family); 1058d45701ccSGreg Roach $this->addNoteLinksToCart($family); 1059d45701ccSGreg Roach $this->addSourceLinksToCart($family); 1060d45701ccSGreg Roach $this->addSubmitterLinksToCart($family); 1061d45701ccSGreg Roach } 1062d45701ccSGreg Roach } 1063d45701ccSGreg Roach 1064d45701ccSGreg Roach /** 1065d45701ccSGreg Roach * @param Individual $individual 1066d45701ccSGreg Roach */ 1067d45701ccSGreg Roach protected function addIndividualToCart(Individual $individual): void 1068d45701ccSGreg Roach { 1069d45701ccSGreg Roach $cart = Session::get('cart', []); 1070d45701ccSGreg Roach $tree = $individual->tree()->name(); 1071d45701ccSGreg Roach $xref = $individual->xref(); 1072d45701ccSGreg Roach 1073d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1074d45701ccSGreg Roach $cart[$tree][$xref] = true; 1075d45701ccSGreg Roach 1076d45701ccSGreg Roach Session::put('cart', $cart); 1077d45701ccSGreg Roach 1078e8ded2caSGreg Roach $this->addLocationLinksToCart($individual); 1079d45701ccSGreg Roach $this->addMediaLinksToCart($individual); 1080d45701ccSGreg Roach $this->addNoteLinksToCart($individual); 1081d45701ccSGreg Roach $this->addSourceLinksToCart($individual); 1082d45701ccSGreg Roach } 1083d45701ccSGreg Roach } 1084d45701ccSGreg Roach 1085d45701ccSGreg Roach /** 1086e8ded2caSGreg Roach * @param Location $location 1087e8ded2caSGreg Roach */ 1088e8ded2caSGreg Roach protected function addLocationToCart(Location $location): void 1089e8ded2caSGreg Roach { 1090e8ded2caSGreg Roach $cart = Session::get('cart', []); 1091e8ded2caSGreg Roach $tree = $location->tree()->name(); 1092e8ded2caSGreg Roach $xref = $location->xref(); 1093e8ded2caSGreg Roach 1094e8ded2caSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1095e8ded2caSGreg Roach $cart[$tree][$xref] = true; 1096e8ded2caSGreg Roach 1097e8ded2caSGreg Roach Session::put('cart', $cart); 1098e8ded2caSGreg Roach 1099e8ded2caSGreg Roach $this->addLocationLinksToCart($location); 1100e8ded2caSGreg Roach $this->addMediaLinksToCart($location); 1101e8ded2caSGreg Roach $this->addNoteLinksToCart($location); 1102e8ded2caSGreg Roach $this->addSourceLinksToCart($location); 1103e8ded2caSGreg Roach } 1104e8ded2caSGreg Roach } 1105e8ded2caSGreg Roach 1106e8ded2caSGreg Roach /** 1107e8ded2caSGreg Roach * @param GedcomRecord $record 1108e8ded2caSGreg Roach */ 1109e8ded2caSGreg Roach protected function addLocationLinksToCart(GedcomRecord $record): void 1110e8ded2caSGreg Roach { 1111e8ded2caSGreg Roach preg_match_all('/\n\d _LOC @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1112e8ded2caSGreg Roach 1113e8ded2caSGreg Roach foreach ($matches[1] as $xref) { 1114e8ded2caSGreg Roach $location = Registry::locationFactory()->make($xref, $record->tree()); 1115e8ded2caSGreg Roach 1116e8ded2caSGreg Roach if ($location instanceof Location && $location->canShow()) { 1117e8ded2caSGreg Roach $this->addLocationToCart($location); 1118e8ded2caSGreg Roach } 1119e8ded2caSGreg Roach } 1120e8ded2caSGreg Roach } 1121e8ded2caSGreg Roach 1122e8ded2caSGreg Roach /** 1123d45701ccSGreg Roach * @param Media $media 1124d45701ccSGreg Roach */ 1125d45701ccSGreg Roach protected function addMediaToCart(Media $media): void 1126d45701ccSGreg Roach { 1127d45701ccSGreg Roach $cart = Session::get('cart', []); 1128d45701ccSGreg Roach $tree = $media->tree()->name(); 1129d45701ccSGreg Roach $xref = $media->xref(); 1130d45701ccSGreg Roach 1131d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1132d45701ccSGreg Roach $cart[$tree][$xref] = true; 1133d45701ccSGreg Roach 1134d45701ccSGreg Roach Session::put('cart', $cart); 1135d45701ccSGreg Roach 1136d45701ccSGreg Roach $this->addNoteLinksToCart($media); 1137d45701ccSGreg Roach } 1138d45701ccSGreg Roach } 1139d45701ccSGreg Roach 1140d45701ccSGreg Roach /** 1141d45701ccSGreg Roach * @param GedcomRecord $record 1142d45701ccSGreg Roach */ 1143d45701ccSGreg Roach protected function addMediaLinksToCart(GedcomRecord $record): void 1144d45701ccSGreg Roach { 1145d45701ccSGreg Roach preg_match_all('/\n\d OBJE @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1146d45701ccSGreg Roach 1147d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1148d45701ccSGreg Roach $media = Registry::mediaFactory()->make($xref, $record->tree()); 1149d45701ccSGreg Roach 1150d45701ccSGreg Roach if ($media instanceof Media && $media->canShow()) { 1151d45701ccSGreg Roach $this->addMediaToCart($media); 1152d45701ccSGreg Roach } 1153d45701ccSGreg Roach } 1154d45701ccSGreg Roach } 1155d45701ccSGreg Roach 1156d45701ccSGreg Roach /** 1157d45701ccSGreg Roach * @param Note $note 1158d45701ccSGreg Roach */ 1159d45701ccSGreg Roach protected function addNoteToCart(Note $note): void 1160d45701ccSGreg Roach { 1161d45701ccSGreg Roach $cart = Session::get('cart', []); 1162d45701ccSGreg Roach $tree = $note->tree()->name(); 1163d45701ccSGreg Roach $xref = $note->xref(); 1164d45701ccSGreg Roach 1165d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1166d45701ccSGreg Roach $cart[$tree][$xref] = true; 1167d45701ccSGreg Roach 11685a78cd34SGreg Roach Session::put('cart', $cart); 11695a78cd34SGreg Roach } 1170d45701ccSGreg Roach } 11715a78cd34SGreg Roach 11725a78cd34SGreg Roach /** 1173d45701ccSGreg Roach * @param GedcomRecord $record 11745a78cd34SGreg Roach */ 1175d45701ccSGreg Roach protected function addNoteLinksToCart(GedcomRecord $record): void 1176d45701ccSGreg Roach { 1177d45701ccSGreg Roach preg_match_all('/\n\d NOTE @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1178d45701ccSGreg Roach 1179d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1180d45701ccSGreg Roach $note = Registry::noteFactory()->make($xref, $record->tree()); 1181d45701ccSGreg Roach 1182d45701ccSGreg Roach if ($note instanceof Note && $note->canShow()) { 1183d45701ccSGreg Roach $this->addNoteToCart($note); 1184d45701ccSGreg Roach } 1185d45701ccSGreg Roach } 1186d45701ccSGreg Roach } 1187d45701ccSGreg Roach 1188d45701ccSGreg Roach /** 1189d45701ccSGreg Roach * @param Source $source 1190d45701ccSGreg Roach */ 1191d45701ccSGreg Roach protected function addSourceToCart(Source $source): void 1192c1010edaSGreg Roach { 11935a78cd34SGreg Roach $cart = Session::get('cart', []); 1194d45701ccSGreg Roach $tree = $source->tree()->name(); 1195d45701ccSGreg Roach $xref = $source->xref(); 11965a78cd34SGreg Roach 1197d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1198d45701ccSGreg Roach $cart[$tree][$xref] = true; 1199d45701ccSGreg Roach 1200d45701ccSGreg Roach Session::put('cart', $cart); 1201d45701ccSGreg Roach 1202d45701ccSGreg Roach $this->addNoteLinksToCart($source); 1203d45701ccSGreg Roach $this->addRepositoryLinksToCart($source); 1204d45701ccSGreg Roach } 1205d45701ccSGreg Roach } 1206d45701ccSGreg Roach 1207d45701ccSGreg Roach /** 1208d45701ccSGreg Roach * @param GedcomRecord $record 1209d45701ccSGreg Roach */ 1210d45701ccSGreg Roach protected function addSourceLinksToCart(GedcomRecord $record): void 1211d45701ccSGreg Roach { 1212d45701ccSGreg Roach preg_match_all('/\n\d SOUR @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1213d45701ccSGreg Roach 1214d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1215d45701ccSGreg Roach $source = Registry::sourceFactory()->make($xref, $record->tree()); 1216d45701ccSGreg Roach 1217d45701ccSGreg Roach if ($source instanceof Source && $source->canShow()) { 1218d45701ccSGreg Roach $this->addSourceToCart($source); 1219d45701ccSGreg Roach } 1220d45701ccSGreg Roach } 1221d45701ccSGreg Roach } 1222d45701ccSGreg Roach 1223d45701ccSGreg Roach /** 1224d45701ccSGreg Roach * @param Repository $repository 1225d45701ccSGreg Roach */ 1226d45701ccSGreg Roach protected function addRepositoryToCart(Repository $repository): void 1227d45701ccSGreg Roach { 1228d45701ccSGreg Roach $cart = Session::get('cart', []); 1229d45701ccSGreg Roach $tree = $repository->tree()->name(); 1230d45701ccSGreg Roach $xref = $repository->xref(); 1231d45701ccSGreg Roach 1232d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1233d45701ccSGreg Roach $cart[$tree][$xref] = true; 1234d45701ccSGreg Roach 1235d45701ccSGreg Roach Session::put('cart', $cart); 1236d45701ccSGreg Roach 1237d45701ccSGreg Roach $this->addNoteLinksToCart($repository); 1238d45701ccSGreg Roach } 1239d45701ccSGreg Roach } 1240d45701ccSGreg Roach 1241d45701ccSGreg Roach /** 1242d45701ccSGreg Roach * @param GedcomRecord $record 1243d45701ccSGreg Roach */ 1244d45701ccSGreg Roach protected function addRepositoryLinksToCart(GedcomRecord $record): void 1245d45701ccSGreg Roach { 1246d45701ccSGreg Roach preg_match_all('/\n\d REPO @(' . Gedcom::REGEX_XREF . '@)/', $record->gedcom(), $matches); 1247d45701ccSGreg Roach 1248d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1249d45701ccSGreg Roach $repository = Registry::repositoryFactory()->make($xref, $record->tree()); 1250d45701ccSGreg Roach 1251d45701ccSGreg Roach if ($repository instanceof Repository && $repository->canShow()) { 1252d45701ccSGreg Roach $this->addRepositoryToCart($repository); 1253d45701ccSGreg Roach } 1254d45701ccSGreg Roach } 1255d45701ccSGreg Roach } 1256d45701ccSGreg Roach 1257d45701ccSGreg Roach /** 1258d45701ccSGreg Roach * @param Submitter $submitter 1259d45701ccSGreg Roach */ 1260d45701ccSGreg Roach protected function addSubmitterToCart(Submitter $submitter): void 1261d45701ccSGreg Roach { 1262d45701ccSGreg Roach $cart = Session::get('cart', []); 1263d45701ccSGreg Roach $tree = $submitter->tree()->name(); 1264d45701ccSGreg Roach $xref = $submitter->xref(); 1265d45701ccSGreg Roach 1266d45701ccSGreg Roach if (($cart[$tree][$xref] ?? false) === false) { 1267d45701ccSGreg Roach $cart[$tree][$xref] = true; 1268d45701ccSGreg Roach 1269d45701ccSGreg Roach Session::put('cart', $cart); 1270d45701ccSGreg Roach 1271d45701ccSGreg Roach $this->addNoteLinksToCart($submitter); 1272d45701ccSGreg Roach } 1273d45701ccSGreg Roach } 1274d45701ccSGreg Roach 1275d45701ccSGreg Roach /** 1276d45701ccSGreg Roach * @param GedcomRecord $record 1277d45701ccSGreg Roach */ 1278d45701ccSGreg Roach protected function addSubmitterLinksToCart(GedcomRecord $record): void 1279d45701ccSGreg Roach { 1280d45701ccSGreg Roach preg_match_all('/\n\d SUBM @(' . Gedcom::REGEX_XREF . ')@/', $record->gedcom(), $matches); 1281d45701ccSGreg Roach 1282d45701ccSGreg Roach foreach ($matches[1] as $xref) { 1283d45701ccSGreg Roach $submitter = Registry::submitterFactory()->make($xref, $record->tree()); 1284d45701ccSGreg Roach 1285d45701ccSGreg Roach if ($submitter instanceof Submitter && $submitter->canShow()) { 1286d45701ccSGreg Roach $this->addSubmitterToCart($submitter); 1287d45701ccSGreg Roach } 1288d45701ccSGreg Roach } 12895a78cd34SGreg Roach } 12908c2e8227SGreg Roach} 1291