Issues (2502)

app/Module/TopPageViewsModule.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * webtrees: online genealogy
5
 * Copyright (C) 2025 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
18
declare(strict_types=1);
19
20
namespace Fisharebest\Webtrees\Module;
21
22
use Fisharebest\Webtrees\DB;
23
use Fisharebest\Webtrees\GedcomRecord;
24
use Fisharebest\Webtrees\I18N;
25
use Fisharebest\Webtrees\Registry;
26
use Fisharebest\Webtrees\Tree;
27
use Fisharebest\Webtrees\Validator;
28
use Illuminate\Support\Str;
29
use Psr\Http\Message\ServerRequestInterface;
30
31
use function count;
32
33
class TopPageViewsModule extends AbstractModule implements ModuleBlockInterface
34
{
35
    use ModuleBlockTrait;
36
37
    private const string DEFAULT_NUMBER_TO_SHOW = '10';
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_STRING, expecting '=' on line 37 at column 25
Loading history...
38
39
    private const array PAGES = ['individual.php', 'family.php', 'source.php', 'repo.php', 'note.php', 'mediaviewer.php'];
40
41
    public function title(): string
42
    {
43
        /* I18N: Name of a module */
44
        return I18N::translate('Most viewed pages');
45
    }
46
47
    public function description(): string
48
    {
49
        /* I18N: Description of the “Most viewed pages” module */
50
        return I18N::translate('A list of the pages that have been viewed the most number of times.');
51
    }
52
53
    /**
54
     * Generate the HTML content of this block.
55
     *
56
     * @param Tree                 $tree
57
     * @param int                  $block_id
58
     * @param string               $context
59
     * @param array<string,string> $config
60
     *
61
     * @return string
62
     */
63
    public function getBlock(Tree $tree, int $block_id, string $context, array $config = []): string
64
    {
65
        $num = (int) $this->getBlockSetting($block_id, 'num', self::DEFAULT_NUMBER_TO_SHOW);
66
67
        extract($config, EXTR_OVERWRITE);
68
69
        $query = DB::table('hit_counter')
70
            ->where('gedcom_id', '=', $tree->id())
71
            ->whereIn('page_name', self::PAGES)
72
            ->select(['page_parameter', 'page_count'])
73
            ->orderByDesc('page_count');
74
75
        $results = [];
76
        foreach ($query->cursor() as $row) {
77
            $record = Registry::gedcomRecordFactory()->make($row->page_parameter, $tree);
78
79
            if ($record instanceof GedcomRecord && $record->canShow()) {
80
                $results[] = [
81
                    'record' => $record,
82
                    'count'  => (int) $row->page_count,
83
                ];
84
            }
85
86
            if (count($results) === $num) {
87
                break;
88
            }
89
        }
90
91
        $content = view('modules/top10_pageviews/list', ['results' => $results]);
92
93
        if ($context !== self::CONTEXT_EMBED) {
94
            return view('modules/block-template', [
95
                'block'      => Str::kebab($this->name()),
96
                'id'         => $block_id,
97
                'config_url' => $this->configUrl($tree, $context, $block_id),
98
                'title'      => $this->title(),
99
                'content'    => $content,
100
            ]);
101
        }
102
103
        return $content;
104
    }
105
106
    /**
107
     * Should this block load asynchronously using AJAX?
108
     *
109
     * Simple blocks are faster in-line, more complex ones can be loaded later.
110
     *
111
     * @return bool
112
     */
113
    public function loadAjax(): bool
114
    {
115
        return true;
116
    }
117
118
    /**
119
     * Can this block be shown on the user’s home page?
120
     *
121
     * @return bool
122
     */
123
    public function isUserBlock(): bool
124
    {
125
        return false;
126
    }
127
128
    /**
129
     * Can this block be shown on the tree’s home page?
130
     *
131
     * @return bool
132
     */
133
    public function isTreeBlock(): bool
134
    {
135
        return true;
136
    }
137
138
    /**
139
     * Update the configuration for a block.
140
     *
141
     * @param ServerRequestInterface $request
142
     * @param int     $block_id
143
     *
144
     * @return void
145
     */
146
    public function saveBlockConfiguration(ServerRequestInterface $request, int $block_id): void
147
    {
148
        $num = Validator::parsedBody($request)->integer('num');
149
150
        $this->setBlockSetting($block_id, 'num', (string) $num);
151
    }
152
153
    /**
154
     * An HTML form to edit block settings
155
     *
156
     * @param Tree $tree
157
     * @param int  $block_id
158
     *
159
     * @return string
160
     */
161
    public function editBlockConfiguration(Tree $tree, int $block_id): string
162
    {
163
        $num = $this->getBlockSetting($block_id, 'num', self::DEFAULT_NUMBER_TO_SHOW);
164
165
        return view('modules/top10_pageviews/config', [
166
            'num' => $num,
167
        ]);
168
    }
169
}
170