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