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