xref: /webtrees/app/Module/HitCountFooterModule.php (revision e5a6b4d4f6f6e7ff2fba7ae2cf27546ae68a79cc)
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