Passed
Branch feature/2.0 (ef99fd)
by Jonathan
11:25
created

HealthCheckService   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 39
c 2
b 0
f 0
dl 0
loc 98
rs 10
wmc 4

4 Methods

Rating   Name   Duplication   Size   Complexity  
A changesByRecordType() 0 13 1
A errorLogs() 0 18 1
A countByRecordType() 0 7 1
A allGedcomRecords() 0 12 1
1
<?php
2
3
/**
4
 * webtrees-lib: MyArtJaub library for webtrees
5
 *
6
 * @package MyArtJaub\Webtrees
7
 * @subpackage AdminTasks
8
 * @author Jonathan Jaubart <[email protected]>
9
 * @copyright Copyright (c) 2020, Jonathan Jaubart
10
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3
11
 */
12
13
declare(strict_types=1);
14
15
namespace MyArtJaub\Webtrees\Module\AdminTasks\Services;
16
17
use Fisharebest\Webtrees\Carbon;
18
use Fisharebest\Webtrees\Tree;
19
use Illuminate\Database\Capsule\Manager as DB;
20
use Illuminate\Database\Query\Builder;
21
use Illuminate\Database\Query\Expression;
22
use Illuminate\Database\Query\JoinClause;
23
use Illuminate\Support\Collection;
24
25
/**
26
 * Service for retrieving data for the Healthcheck task
27
 */
28
class HealthCheckService
29
{
30
    /**
31
     * Returns a query collating all gedcom records, for use in other queries
32
     *
33
     * @param Tree $tree
34
     * @return Builder
35
     */
36
    private function allGedcomRecords(Tree $tree): Builder
37
    {
38
        return DB::table('individuals')
39
            ->select(DB::raw("'indi' AS ged_type"), 'i_id AS ged_id')->where('i_file', '=', $tree->id())
40
            ->unionAll(DB::table('families')
41
                ->select(DB::raw("'fam' AS ged_type"), 'f_id AS ged_id')->where('f_file', '=', $tree->id()))
42
            ->unionAll(DB::table('sources')
43
                ->select(DB::raw("'sour' AS ged_type"), 's_id AS ged_id')->where('s_file', '=', $tree->id()))
44
            ->unionAll(DB::table('media')
45
                ->select(DB::raw("'media' AS ged_type"), 'm_id AS ged_id')->where('m_file', '=', $tree->id()))
46
            ->unionAll(DB::table('other')
47
                ->select(DB::raw('LOWER(o_type) AS ged_type'), 'o_id AS ged_id')->where('o_file', '=', $tree->id()));
48
    }
49
    
50
    /**
51
     * Returns the count of gedcom records by type in a Tree, as a keyed Collection.
52
     *
53
     * Collection output:
54
     *      - Key : gedcom record type
55
     *      - Value: count of records
56
     *
57
     * @param Tree $tree
58
     * @return Collection
59
     */
60
    public function countByRecordType(Tree $tree): Collection
61
    {
62
        return DB::query()
63
            ->fromSub($this->allGedcomRecords($tree), 'gedrecords')
64
            ->select('ged_type', new Expression('COUNT(ged_id) AS total'))
65
            ->groupBy('ged_type')
66
            ->pluck('total', 'ged_type');
67
    }
68
    
69
    /**
70
     * Returns the count of gedcom records changes by type in a Tree across a number of days, as a keyed Collection.
71
     *
72
     * Collection output:
73
     *      - Key : gedcom record type
74
     *      - Value: count of changes
75
     *
76
     * @param Tree $tree
77
     * @return Collection
78
     */
79
    public function changesByRecordType(Tree $tree, int $nb_days): Collection
80
    {
81
        return DB::table('change')
82
            ->joinSub($this->allGedcomRecords($tree), 'gedrecords', function (JoinClause $join) use ($tree) {
83
84
                $join->on('change.xref', '=', 'gedrecords.ged_id')
85
                    ->where('change.gedcom_id', '=', $tree->id());
86
            })
87
            ->select('ged_type AS type', new Expression('COUNT(change_id) AS count'))
88
            ->where('change.status', '', 'accepted')
89
            ->where('change.change_time', '>=', Carbon::now()->subDays($nb_days))
90
            ->groupBy('ged_type')
91
            ->pluck('total', 'ged_type');
92
    }
93
    
94
    /**
95
     * Return the error logs associated with a tree across a number of days, grouped by error message, as a Collection.
96
     *
97
     * Collection output:
98
     *      - Value: stdClass object
99
     *          - log message:  Error log message
100
     *          - type:         'site' if no associated Tree, the Tree ID otherwise
101
     *          - nblogs:       The number of occurence of the same error message
102
     *          - lastoccurred: Date/time of the last occurence of the error message
103
     *
104
     * @param Tree $tree
105
     * @param int $nb_days
106
     * @return Collection
107
     */
108
    public function errorLogs(Tree $tree, int $nb_days): Collection
109
    {
110
        return DB::table('log')
111
            ->select(
112
                'log_message',
113
                new Expression("IFNULL(gedcom_id, 'site') as type"),
114
                new Expression('COUNT(log_id) AS nblogs'),
115
                new Expression('MAX(log_time) AS lastoccurred')
116
            )
117
            ->where('log_type', '=', 'error')
118
            ->where(function (Builder $query) use ($tree) {
119
                $query->where('gedcom_id', '=', $tree->id())
120
                    ->orWhereNull('gedcom_id');
121
            })
122
            ->where('log_time', '>=', Carbon::now()->subDays($nb_days))
123
            ->groupBy('log_message', 'gedcom_id')
124
            ->orderByDesc('lastoccurred')
125
            ->get();
126
    }
127
}
128