xref: /webtrees/app/Statistics/Repository/GedcomRepository.php (revision 4d314e6b28a3e57668463e010244449523e91e5c)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2019 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16declare(strict_types=1);
17
18namespace Fisharebest\Webtrees\Statistics\Repository;
19
20use Fisharebest\Webtrees\Date;
21use Fisharebest\Webtrees\Fact;
22use Fisharebest\Webtrees\GedcomRecord;
23use Fisharebest\Webtrees\Statistics\Repository\Interfaces\GedcomRepositoryInterface;
24use Fisharebest\Webtrees\Tree;
25use Illuminate\Database\Capsule\Manager as DB;
26use Illuminate\Database\Query\Builder;
27
28/**
29 * A repository providing methods for GEDCOM related statistics.
30 */
31class GedcomRepository implements GedcomRepositoryInterface
32{
33    /**
34     * @var Tree
35     */
36    private $tree;
37
38    /**
39     * Constructor.
40     *
41     * @param Tree $tree
42     */
43    public function __construct(Tree $tree)
44    {
45        $this->tree = $tree;
46    }
47
48    /**
49     * Get information from the GEDCOM's HEAD record.
50     *
51     * @return string[]
52     */
53    private function gedcomHead(): array
54    {
55        $title   = '';
56        $version = '';
57        $source  = '';
58
59        $head = GedcomRecord::getInstance('HEAD', $this->tree);
60
61        if ($head instanceof GedcomRecord) {
62            $sour = $head->facts(['SOUR'])->first();
63
64            if ($sour instanceof Fact) {
65                $source  = $sour->value();
66                $title   = $sour->attribute('NAME');
67                $version = $sour->attribute('VERS');
68            }
69        }
70
71        return [
72            $title,
73            $version,
74            $source,
75        ];
76    }
77
78    /**
79     * @inheritDoc
80     */
81    public function gedcomFilename(): string
82    {
83        return $this->tree->name();
84    }
85
86    /**
87     * @inheritDoc
88     */
89    public function gedcomId(): int
90    {
91        return $this->tree->id();
92    }
93
94    /**
95     * @inheritDoc
96     */
97    public function gedcomTitle(): string
98    {
99        return e($this->tree->title());
100    }
101
102    /**
103     * @inheritDoc
104     */
105    public function gedcomCreatedSoftware(): string
106    {
107        return $this->gedcomHead()[0];
108    }
109
110    /**
111     * @inheritDoc
112     */
113    public function gedcomCreatedVersion(): string
114    {
115        $head = $this->gedcomHead();
116
117        if ($head === null) {
118            return '';
119        }
120
121        // Fix broken version string in Family Tree Maker
122        if (strpos($head[1], 'Family Tree Maker ') !== false) {
123            $p       = strpos($head[1], '(') + 1;
124            $p2      = strpos($head[1], ')');
125            $head[1] = substr($head[1], $p, $p2 - $p);
126        }
127
128        // Fix EasyTree version
129        if ($head[2] === 'EasyTree') {
130            $head[1] = substr($head[1], 1);
131        }
132
133        return $head[1];
134    }
135
136    /**
137     * @inheritDoc
138     */
139    public function gedcomDate(): string
140    {
141        $head = GedcomRecord::getInstance('HEAD', $this->tree);
142
143        if ($head instanceof GedcomRecord) {
144            $fact = $head->facts(['DATE'])->first();
145
146            if ($fact instanceof Fact) {
147                return (new Date($fact->value()))->display();
148            }
149        }
150
151        return '';
152    }
153
154    /**
155     * @inheritDoc
156     */
157    public function gedcomUpdated(): string
158    {
159        $row = DB::table('dates')
160            ->select(['d_year', 'd_month', 'd_day'])
161            ->where('d_julianday1', '=', function (Builder $query): void {
162                $query->selectRaw('MAX(d_julianday1)')
163                    ->from('dates')
164                    ->where('d_file', '=', $this->tree->id())
165                    ->where('d_fact', '=', 'CHAN');
166            })
167            ->first();
168
169        if ($row) {
170            $date = new Date("{$row->d_day} {$row->d_month} {$row->d_year}");
171            return $date->display();
172        }
173
174        return $this->gedcomDate();
175    }
176
177    /**
178     * @inheritDoc
179     */
180    public function gedcomRootId(): string
181    {
182        return $this->tree->getPreference('PEDIGREE_ROOT_ID');
183    }
184}
185