xref: /webtrees/app/Module/TopPageViewsModule.php (revision d32a32162970e6bfef5abe5397602a75311438d3)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 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 */
16namespace Fisharebest\Webtrees\Module;
17
18use Fisharebest\Webtrees\Auth;
19use Fisharebest\Webtrees\Database;
20use Fisharebest\Webtrees\Filter;
21use Fisharebest\Webtrees\GedcomRecord;
22use Fisharebest\Webtrees\I18N;
23
24/**
25 * Class TopPageViewsModule
26 */
27class TopPageViewsModule extends AbstractModule implements ModuleBlockInterface {
28	/**
29	 * How should this module be labelled on tabs, menus, etc.?
30	 *
31	 * @return string
32	 */
33	public function getTitle() {
34		return /* I18N: Name of a module */ I18N::translate('Most viewed pages');
35	}
36
37	/**
38	 * A sentence describing what this module does.
39	 *
40	 * @return string
41	 */
42	public function getDescription() {
43		return /* I18N: Description of the “Most visited pages” module */ I18N::translate('A list of the pages that have been viewed the most number of times.');
44	}
45
46	/**
47	 * Generate the HTML content of this block.
48	 *
49	 * @param int      $block_id
50	 * @param bool     $template
51	 * @param string[] $cfg
52	 *
53	 * @return string
54	 */
55	public function getBlock($block_id, $template = true, $cfg = []): string {
56		global $ctype, $WT_TREE;
57
58		$num             = $this->getBlockSetting($block_id, 'num', '10');
59		$count_placement = $this->getBlockSetting($block_id, 'count_placement', 'before');
60
61		extract($cfg, EXTR_OVERWRITE);
62
63		// load the lines from the file
64		$top10 = Database::prepare(
65			"SELECT page_parameter, page_count" .
66			" FROM `##hit_counter`" .
67			" WHERE gedcom_id = :tree_id AND page_name IN ('individual.php','family.php','source.php','repo.php','note.php','mediaviewer.php')" .
68			" ORDER BY page_count DESC LIMIT :limit"
69		)->execute([
70			'tree_id' => $WT_TREE->getTreeId(),
71			'limit'   => (int) $num,
72		])->fetchAssoc();
73
74		$content = '<table>';
75		foreach ($top10 as $id => $count) {
76			$record = GedcomRecord::getInstance($id, $WT_TREE);
77			if ($record && $record->canShow()) {
78				$content .= '<tr>';
79				if ($count_placement == 'before') {
80					$content .= '<td dir="ltr" style="text-align:right">[' . $count . ']</td>';
81				}
82				$content .= '<td class="name2" ><a href="' . e($record->url()) . '">' . $record->getFullName() . '</a></td>';
83				if ($count_placement == 'after') {
84					$content .= '<td dir="ltr" style="text-align:right">[' . $count . ']</td>';
85				}
86				$content .= '</tr>';
87			}
88		}
89		$content .= '</table>';
90
91		if ($template) {
92			if ($ctype === 'gedcom' && Auth::isManager($WT_TREE)) {
93				$config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
94			} elseif ($ctype === 'user' && Auth::check()) {
95				$config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $WT_TREE->getName()]);
96			} else {
97				$config_url = '';
98			}
99
100			return view('blocks/template', [
101				'block'      => str_replace('_', '-', $this->getName()),
102				'id'         => $block_id,
103				'config_url' => $config_url,
104				'title'      => $this->getTitle(),
105				'content'    => $content,
106			]);
107		} else {
108			return $content;
109		}
110	}
111
112	/**
113	 * Should this block load asynchronously using AJAX?
114	 *
115	 * Simple blocks are faster in-line, more comples ones
116	 * can be loaded later.
117	 *
118	 * @return bool
119	 */
120	public function loadAjax(): bool {
121		return true;
122	}
123
124	/**
125	 * Can this block be shown on the user’s home page?
126	 *
127	 * @return bool
128	 */
129	public function isUserBlock(): bool {
130		return false;
131	}
132
133	/**
134	 * Can this block be shown on the tree’s home page?
135	 *
136	 * @return bool
137	 */
138	public function isGedcomBlock(): bool {
139		return true;
140	}
141
142	/**
143	 * An HTML form to edit block settings
144	 *
145	 * @param int $block_id
146	 *
147	 * @return void
148	 */
149	public function configureBlock($block_id) {
150		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
151			$this->setBlockSetting($block_id, 'num', Filter::postInteger('num', 1, 10000, 10));
152			$this->setBlockSetting($block_id, 'count_placement', Filter::post('count_placement', 'before|after', 'before'));
153
154			return;
155		}
156
157		$num             = $this->getBlockSetting($block_id, 'num', '10');
158		$count_placement = $this->getBlockSetting($block_id, 'count_placement', 'before');
159
160		$options = [
161			'before' => /* I18N: An option in a list-box */ I18N::translate('before'),
162			'after'  => /* I18N: An option in a list-box */ I18N::translate('after'),
163		];
164
165		echo view('blocks/top-page-views-config', [
166			'count_placement' => $count_placement,
167			'num'             => $num,
168			'options'         => $options,
169		]);
170	}
171}
172