1<?php 2 3/** 4 * webtrees: online genealogy 5 * Copyright (C) 2023 webtrees development team 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <https://www.gnu.org/licenses/>. 16 */ 17 18declare(strict_types=1); 19 20namespace Fisharebest\Webtrees\Cli\Commands; 21 22use Fisharebest\Webtrees\Auth; 23use Fisharebest\Webtrees\DB; 24use Fisharebest\Webtrees\Encodings\UTF8; 25use Fisharebest\Webtrees\Services\GedcomExportService; 26use Fisharebest\Webtrees\Services\TreeService; 27use Symfony\Component\Console\Command\Command; 28use Symfony\Component\Console\Completion\CompletionInput; 29use Symfony\Component\Console\Input\InputArgument; 30use Symfony\Component\Console\Input\InputInterface; 31use Symfony\Component\Console\Input\InputOption; 32use Symfony\Component\Console\Output\OutputInterface; 33use Symfony\Component\Console\Style\SymfonyStyle; 34 35use function addcslashes; 36use function stream_get_contents; 37 38class TreeExport extends Command 39{ 40 public function __construct( 41 private readonly GedcomExportService $gedcom_export_service, 42 private readonly TreeService $tree_service, 43 ) { 44 parent::__construct(); 45 } 46 47 protected function configure(): void 48 { 49 $this 50 ->setName(name: 'tree-export') 51 ->addArgument(name: 'tree_name', mode: InputArgument::REQUIRED, description: 'The name of the tree', suggestedValues: self::autoCompleteTreeName(...)) 52 ->addOption(name: 'format', shortcut: null, mode: InputOption::VALUE_REQUIRED, description: 'Export format') 53 ->addOption(name: 'filename', shortcut: null, mode: InputOption::VALUE_REQUIRED, description: 'Export filename') 54 ->setDescription(description: 'Export a tree to a GEDCOM file'); 55 } 56 57 private function autoCompleteTreeName(CompletionInput $input): array 58 { 59 return DB::table('tree') 60 ->where('tree_name', 'LIKE', addcslashes($input->getCompletionValue(), '%_\\') . '%') 61 ->pluck('name') 62 ->all(); 63 } 64 65 protected function execute(InputInterface $input, OutputInterface $output): int 66 { 67 $io = new SymfonyStyle(input: $input, output: $output); 68 69 $tree_name = $input->getArgument(name: 'tree_name'); 70 $format = $input->getOption(name: 'format'); 71 $filename = $input->getOption(name: 'filename'); 72 73 $tree = $this->tree_service->all()[$tree_name] ?? null; 74 75 if ($tree === null) { 76 $io->error(message: 'Tree "' . $tree_name . '" not found.'); 77 78 return Command::FAILURE; 79 } 80 81 $stream = $this->gedcom_export_service->export( 82 tree: $tree, 83 sort_by_xref: false, 84 encoding: UTF8::NAME, 85 access_level: Auth::PRIV_HIDE, 86 line_endings: 'CRLF', 87 records: null, 88 zip_filesystem: null, 89 media_path: null, 90 ); 91 92 echo stream_get_contents($stream); 93 94 $io->success('File exported successfully.'); 95 96 return Command::SUCCESS; 97 } 98} 99