Passed
Push — master ( 506a57...22e73d )
by Greg
06:57
created

PendingChangesLogData::handle()   B

Complexity

Conditions 6
Paths 1

Size

Total Lines 52
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 35
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 52
rs 8.7377

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Http\RequestHandlers;
21
22
use Fisharebest\Algorithm\MyersDiff;
23
use Fisharebest\Webtrees\Carbon;
24
use Fisharebest\Webtrees\Gedcom;
25
use Fisharebest\Webtrees\GedcomRecord;
26
use Fisharebest\Webtrees\I18N;
27
use Fisharebest\Webtrees\Services\DatatablesService;
28
use Fisharebest\Webtrees\Services\PendingChangesService;
29
use Fisharebest\Webtrees\Services\TreeService;
30
use Fisharebest\Webtrees\Tree;
31
use InvalidArgumentException;
32
use Psr\Http\Message\ResponseInterface;
33
use Psr\Http\Message\ServerRequestInterface;
34
use Psr\Http\Server\RequestHandlerInterface;
35
use stdClass;
36
37
use function e;
38
use function explode;
39
use function implode;
40
use function preg_replace_callback;
41
42
/**
43
 * Find pending changes.
44
 */
45
class PendingChangesLogData implements RequestHandlerInterface
46
{
47
    /** @var DatatablesService */
48
    private $datatables_service;
49
50
    /** @var MyersDiff */
51
    private $myers_diff;
52
53
    /** @var PendingChangesService */
54
    private $pending_changes_service;
55
56
    /** @var TreeService */
57
    private $tree_service;
58
59
    /**
60
     * @param DatatablesService     $datatables_service
61
     * @param MyersDiff             $myers_diff
62
     * @param PendingChangesService $pending_changes_service
63
     * @param TreeService           $tree_service
64
     */
65
    public function __construct(
66
        DatatablesService $datatables_service,
67
        MyersDiff $myers_diff,
68
        PendingChangesService $pending_changes_service,
69
        TreeService $tree_service
70
    ) {
71
        $this->datatables_service      = $datatables_service;
72
        $this->myers_diff              = $myers_diff;
73
        $this->pending_changes_service = $pending_changes_service;
74
        $this->tree_service            = $tree_service;
75
    }
76
77
    /**
78
     * @param ServerRequestInterface $request
79
     *
80
     * @return ResponseInterface
81
     */
82
    public function handle(ServerRequestInterface $request): ResponseInterface
83
    {
84
        $tree = $request->getAttribute('tree');
85
        assert($tree instanceof Tree, new InvalidArgumentException());
86
87
        $query = $this->pending_changes_service->changesQuery($request);
88
89
        $callback = function (stdClass $row) use ($tree): array {
90
            $old_lines = explode("\n", $row->old_gedcom);
91
            $new_lines = explode("\n", $row->new_gedcom);
92
93
            $differences = $this->myers_diff->calculate($old_lines, $new_lines);
94
            $diff_lines  = [];
95
96
            foreach ($differences as $difference) {
97
                switch ($difference[1]) {
98
                    case MyersDiff::DELETE:
99
                        $diff_lines[] = '<del>' . $difference[0] . '</del>';
100
                        break;
101
                    case MyersDiff::INSERT:
102
                        $diff_lines[] = '<ins>' . $difference[0] . '</ins>';
103
                        break;
104
                    default:
105
                        $diff_lines[] = $difference[0];
106
                }
107
            }
108
109
            // Only convert valid xrefs to links
110
            $record = GedcomRecord::getInstance($row->xref, $tree);
111
112
            return [
113
                $row->change_id,
114
                Carbon::make($row->change_time)->local()->format('Y-m-d H:i:s'),
115
                I18N::translate($row->status),
116
                $record ? '<a href="' . e($record->url()) . '">' . $record->xref() . '</a>' : $row->xref,
117
                '<div class="gedcom-data" dir="ltr">' .
118
                preg_replace_callback(
119
                    '/@(' . Gedcom::REGEX_XREF . ')@/',
120
                    static function (array $match) use ($tree): string {
121
                        $record = GedcomRecord::getInstance($match[1], $tree);
122
123
                        return $record ? '<a href="' . e($record->url()) . '">' . $match[0] . '</a>' : $match[0];
124
                    },
125
                    implode("\n", $diff_lines)
126
                ) .
127
                '</div>',
128
                $row->user_name,
129
                $row->gedcom_name,
130
            ];
131
        };
132
133
        return $this->datatables_service->handle($request, $query, [], [], $callback);
134
    }
135
}
136