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