xref: /webtrees/app/Module/ModuleAnalyticsTrait.php (revision bfed30e4637307a4679a3e3e333171c671154b8b)
1<?php
2
3/**
4 * webtrees: online genealogy
5 * Copyright (C) 2021 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
18declare(strict_types=1);
19
20namespace Fisharebest\Webtrees\Module;
21
22use Fisharebest\Webtrees\Http\RequestHandlers\ModulesAnalyticsPage;
23use Fisharebest\Webtrees\Http\ViewResponseTrait;
24use Fisharebest\Webtrees\I18N;
25use Fisharebest\Webtrees\Validator;
26use Psr\Http\Message\ResponseInterface;
27use Psr\Http\Message\ServerRequestInterface;
28
29use function app;
30use function assert;
31
32/**
33 * Trait ModuleAnalyticsTrait - default implementation of ModuleAnalyticsInterface
34 */
35trait ModuleAnalyticsTrait
36{
37    use ViewResponseTrait;
38
39    /**
40     * A unique internal name for this module (based on the installation folder).
41     *
42     * @return string
43     */
44    abstract public function name(): string;
45
46    /**
47     * How should this module be identified in the control panel, etc.?
48     *
49     * @return string
50     */
51    abstract public function title(): string;
52
53    /**
54     * Set a module setting.
55     *
56     * Since module settings are NOT NULL, setting a value to NULL will cause
57     * it to be deleted.
58     *
59     * @param string $setting_name
60     * @param string $setting_value
61     *
62     * @return void
63     */
64    abstract public function setPreference(string $setting_name, string $setting_value): void;
65
66    /**
67     * Should we add this tracker?
68     *
69     * @return bool
70     */
71    public function analyticsCanShow(): bool
72    {
73        $request = app(ServerRequestInterface::class);
74        assert($request instanceof ServerRequestInterface);
75
76        // If the browser sets the DNT header, then we won't use analytics.
77        if (Validator::serverParams($request)->boolean('HTTP_DNT', false)) {
78            return false;
79        }
80
81        foreach ($this->analyticsParameters() as $parameter) {
82            if ($parameter === '') {
83                return false;
84            }
85        }
86
87        return true;
88    }
89
90    /**
91     * The parameters that need to be embedded in the snippet.
92     *
93     * @return array<string>
94     */
95    public function analyticsParameters(): array
96    {
97        return [];
98    }
99
100    /**
101     * A sentence describing what this module does.
102     *
103     * @return string
104     */
105    public function description(): string
106    {
107        return I18N::translate('Tracking and analytics');
108    }
109
110    /**
111     * @param ServerRequestInterface $request
112     *
113     * @return ResponseInterface
114     */
115    public function getAdminAction(/** @scrutinizer ignore-unused */ ServerRequestInterface $request): ResponseInterface
116    {
117        $this->layout = 'layouts/administration';
118
119        return $this->viewResponse('admin/analytics-edit', [
120            'action'      => route('module', ['module' => $this->name(), 'action' => 'Admin']),
121            'form_fields' => $this->analyticsFormFields(),
122            'preview'     => $this->analyticsSnippet($this->analyticsParameters()),
123            'title'       => $this->title(),
124        ]);
125    }
126
127    /**
128     * Form fields to edit the parameters.
129     *
130     * @return string
131     */
132    public function analyticsFormFields(): string
133    {
134        return '';
135    }
136
137    /**
138     * Embed placeholders in the snippet.
139     *
140     * @param array<string> $parameters
141     *
142     * @return string
143     */
144    public function analyticsSnippet(/** @scrutinizer ignore-unused */ array $parameters): string
145    {
146        return '';
147    }
148
149    /**
150     * Is this a tracker, as opposed to just a site-verification.
151     *
152     * @return bool
153     */
154    public function isTracker(): bool
155    {
156        return true;
157    }
158
159    /**
160     * @param ServerRequestInterface $request
161     *
162     * @return ResponseInterface
163     */
164    public function postAdminAction(ServerRequestInterface $request): ResponseInterface
165    {
166        $params = (array) $request->getParsedBody();
167
168        foreach (array_keys($this->analyticsParameters()) as $parameter) {
169            $new_value = $params[$parameter];
170
171            $this->setPreference($parameter, $new_value);
172        }
173
174        return redirect(route(ModulesAnalyticsPage::class));
175    }
176}
177