133c34396SGreg Roach<?php 233c34396SGreg Roach/** 333c34396SGreg Roach * webtrees: online genealogy 433c34396SGreg Roach * Copyright (C) 2019 webtrees development team 533c34396SGreg Roach * This program is free software: you can redistribute it and/or modify 633c34396SGreg Roach * it under the terms of the GNU General Public License as published by 733c34396SGreg Roach * the Free Software Foundation, either version 3 of the License, or 833c34396SGreg Roach * (at your option) any later version. 933c34396SGreg Roach * This program is distributed in the hope that it will be useful, 1033c34396SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 1133c34396SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1233c34396SGreg Roach * GNU General Public License for more details. 1333c34396SGreg Roach * You should have received a copy of the GNU General Public License 1433c34396SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>. 1533c34396SGreg Roach */ 1633c34396SGreg Roachdeclare(strict_types=1); 1733c34396SGreg Roach 1833c34396SGreg Roachnamespace Fisharebest\Webtrees\Module; 1933c34396SGreg Roach 20*e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface; 2133c34396SGreg Roachuse Fisharebest\Webtrees\I18N; 2233c34396SGreg Roachuse Fisharebest\Webtrees\Session; 2333c34396SGreg Roachuse Fisharebest\Webtrees\Tree; 2433c34396SGreg Roachuse Fisharebest\Webtrees\User; 2533c34396SGreg Roachuse Illuminate\Database\Capsule\Manager as DB; 2633c34396SGreg Roachuse Symfony\Component\HttpFoundation\Request; 2733c34396SGreg Roach 2833c34396SGreg Roach/** 2933c34396SGreg Roach * Class HitCountFooterModule - show the popular sites in the footer. 3033c34396SGreg Roach */ 3133c34396SGreg Roachclass HitCountFooterModule extends AbstractModule implements ModuleFooterInterface 3233c34396SGreg Roach{ 3333c34396SGreg Roach use ModuleFooterTrait; 3433c34396SGreg Roach 3533c34396SGreg Roach // Which pages/routes do we count? 3633c34396SGreg Roach // For historical reasons, we record the names of the original webtrees script and parameter. 3733c34396SGreg Roach protected const PAGE_NAMES = [ 3833c34396SGreg Roach 'family' => 'family.php', 3933c34396SGreg Roach 'individual' => 'individual.php', 4033c34396SGreg Roach 'media' => 'mediaviewer.php', 4133c34396SGreg Roach 'note' => 'note.php', 4233c34396SGreg Roach 'repository' => 'repo.php', 4333c34396SGreg Roach 'source' => 'source.php', 4433c34396SGreg Roach 'tree-page' => 'index.php', 4533c34396SGreg Roach 'user-page' => 'index.php', 4633c34396SGreg Roach ]; 4733c34396SGreg Roach 4833c34396SGreg Roach /** @var Request */ 4933c34396SGreg Roach protected $request; 5033c34396SGreg Roach 5133c34396SGreg Roach /** @var Tree|null */ 5233c34396SGreg Roach protected $tree; 5333c34396SGreg Roach 5433c34396SGreg Roach /** @var User */ 5533c34396SGreg Roach protected $user; 5633c34396SGreg Roach 5733c34396SGreg Roach /** @var int */ 5833c34396SGreg Roach protected $page_hits = 0; 5933c34396SGreg Roach 6033c34396SGreg Roach /** 6133c34396SGreg Roach * Dependency injection. 6233c34396SGreg Roach * 6333c34396SGreg Roach * @param Tree|null $tree 64*e5a6b4d4SGreg Roach * @param UserInterface $user 6533c34396SGreg Roach * @param Request $request 6633c34396SGreg Roach */ 67*e5a6b4d4SGreg Roach public function __construct(?Tree $tree, UserInterface $user, Request $request) 6833c34396SGreg Roach { 6933c34396SGreg Roach $this->tree = $tree; 7033c34396SGreg Roach $this->user = $user; 7133c34396SGreg Roach $this->request = $request; 7233c34396SGreg Roach 7333c34396SGreg Roach if ($this->tree !== null && $this->tree->getPreference('SHOW_COUNTER')) { 7433c34396SGreg Roach $route = $request->get('route'); 7533c34396SGreg Roach 7633c34396SGreg Roach $page_name = self::PAGE_NAMES[$route] ?? ''; 7733c34396SGreg Roach 7833c34396SGreg Roach switch ($route) { 7933c34396SGreg Roach case 'family': 8033c34396SGreg Roach case 'individual': 8133c34396SGreg Roach case 'media': 8233c34396SGreg Roach case 'note': 8333c34396SGreg Roach case 'repository': 8433c34396SGreg Roach case 'source': 8533c34396SGreg Roach $this->page_hits = $this->countHit($page_name, $request->get('xref', '')); 8633c34396SGreg Roach break; 8733c34396SGreg Roach 8833c34396SGreg Roach case 'tree-page': 8933c34396SGreg Roach $this->page_hits = $this->countHit($page_name, 'gedcom:' . $this->tree->id()); 9033c34396SGreg Roach break; 9133c34396SGreg Roach 9233c34396SGreg Roach case 'user-page': 9333c34396SGreg Roach $this->page_hits = $this->countHit($page_name, 'user:' . $this->user->id()); 9433c34396SGreg Roach break; 9533c34396SGreg Roach } 9633c34396SGreg Roach } 9733c34396SGreg Roach } 9833c34396SGreg Roach 9933c34396SGreg Roach /** 100d4c04956SGreg Roach * How should this module be labelled on tabs, footers, etc.? 101d4c04956SGreg Roach * 102d4c04956SGreg Roach * @return string 103d4c04956SGreg Roach */ 104d4c04956SGreg Roach public function title(): string 105d4c04956SGreg Roach { 106d4c04956SGreg Roach /* I18N: Name of a module */ 107d4c04956SGreg Roach return I18N::translate('Hit counters'); 108d4c04956SGreg Roach } 109d4c04956SGreg Roach 110d4c04956SGreg Roach /** 111d4c04956SGreg Roach * A sentence describing what this module does. 112d4c04956SGreg Roach * 113d4c04956SGreg Roach * @return string 114d4c04956SGreg Roach */ 115d4c04956SGreg Roach public function description(): string 116d4c04956SGreg Roach { 117d4c04956SGreg Roach /* I18N: Description of the “Hit counters” module */ 118d4c04956SGreg Roach return I18N::translate('Count the visits to each page'); 119d4c04956SGreg Roach } 120d4c04956SGreg Roach 121d4c04956SGreg Roach /** 12233c34396SGreg Roach * The default position for this footer. It can be changed in the control panel. 12333c34396SGreg Roach * 12433c34396SGreg Roach * @return int 12533c34396SGreg Roach */ 12633c34396SGreg Roach public function defaultFooterOrder(): int 12733c34396SGreg Roach { 12833c34396SGreg Roach return 3; 12933c34396SGreg Roach } 13033c34396SGreg Roach 13133c34396SGreg Roach /** 13233c34396SGreg Roach * A footer, to be added at the bottom of every page. 13333c34396SGreg Roach * 13433c34396SGreg Roach * @return string 13533c34396SGreg Roach */ 13633c34396SGreg Roach public function getFooter(): string 13733c34396SGreg Roach { 13833c34396SGreg Roach if ($this->tree === null || $this->page_hits === 0) { 13933c34396SGreg Roach return ''; 14033c34396SGreg Roach } 14133c34396SGreg Roach 14233c34396SGreg Roach $digits = '<span class="odometer">' . I18N::digits($this->page_hits) . '</span>'; 14333c34396SGreg Roach 14433c34396SGreg Roach return view('modules/hit-counter/footer', [ 14533c34396SGreg Roach 'hit_counter' => I18N::plural('This page has been viewed %s time.', 'This page has been viewed %s times.', $this->page_hits, $digits), 14633c34396SGreg Roach ]); 14733c34396SGreg Roach } 14833c34396SGreg Roach 14933c34396SGreg Roach /** 15033c34396SGreg Roach * Increment the page count. 15133c34396SGreg Roach * 15233c34396SGreg Roach * @param string $page 15333c34396SGreg Roach * @param string $parameter 15433c34396SGreg Roach * 15533c34396SGreg Roach * @return int 15633c34396SGreg Roach */ 15733c34396SGreg Roach protected function countHit($page, $parameter): int 15833c34396SGreg Roach { 15997350b3fSGreg Roach if ($this->tree === null) { 16097350b3fSGreg Roach return 0; 16197350b3fSGreg Roach } 16297350b3fSGreg Roach 16333c34396SGreg Roach $gedcom_id = $this->tree->id(); 16433c34396SGreg Roach 16533c34396SGreg Roach // Don't increment the counter while we stay on the same page. 16633c34396SGreg Roach if ( 16733c34396SGreg Roach Session::get('last_gedcom_id') === $gedcom_id && 16833c34396SGreg Roach Session::get('last_page_name') === $page && 16933c34396SGreg Roach Session::get('last_page_parameter') === $parameter 17033c34396SGreg Roach ) { 17133c34396SGreg Roach return Session::get('last_count'); 17233c34396SGreg Roach } 17333c34396SGreg Roach 17433c34396SGreg Roach $count = (int) DB::table('hit_counter') 17533c34396SGreg Roach ->where('gedcom_id', '=', $this->tree->id()) 17633c34396SGreg Roach ->where('page_name', '=', $page) 17733c34396SGreg Roach ->where('page_parameter', '=', $parameter) 1788491737aSGreg Roach ->value('page_count'); 17933c34396SGreg Roach 18033c34396SGreg Roach $count++; 18133c34396SGreg Roach 18233c34396SGreg Roach DB::table('hit_counter')->updateOrInsert([ 18333c34396SGreg Roach 'gedcom_id' => $this->tree->id(), 18433c34396SGreg Roach 'page_name' => $page, 18533c34396SGreg Roach 'page_parameter' => $parameter, 18633c34396SGreg Roach ], [ 18733c34396SGreg Roach 'page_count' => $count, 18833c34396SGreg Roach ]); 18933c34396SGreg Roach 19033c34396SGreg Roach Session::put('last_gedcom_id', $gedcom_id); 19133c34396SGreg Roach Session::put('last_page_name', $page); 19233c34396SGreg Roach Session::put('last_page_parameter', $parameter); 19333c34396SGreg Roach Session::put('last_count', $count); 19433c34396SGreg Roach 19533c34396SGreg Roach return $count; 19633c34396SGreg Roach } 19733c34396SGreg Roach} 198