Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
253 / 253 |
|
100.00% |
8 / 8 |
CRAP | |
100.00% |
1 / 1 |
SettingsForm | |
100.00% |
253 / 253 |
|
100.00% |
8 / 8 |
14 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
create | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getFormId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getEditableConfigNames | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
buildForm | |
100.00% |
214 / 214 |
|
100.00% |
1 / 1 |
4 | |||
submitForm | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
1 | |||
entityTypes | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
roleOptions | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace Drupal\visitors\Form; |
4 | |
5 | use Drupal\Core\Config\Entity\ConfigEntityType; |
6 | use Drupal\Core\Entity\EntityTypeManagerInterface; |
7 | use Drupal\Core\Form\ConfigFormBase; |
8 | use Drupal\Core\Form\FormStateInterface; |
9 | use Drupal\Core\Url; |
10 | use Drupal\visitors\VisitorsVisibilityInterface; |
11 | use Symfony\Component\DependencyInjection\ContainerInterface; |
12 | |
13 | /** |
14 | * Visitors Settings Form. |
15 | */ |
16 | class SettingsForm extends ConfigFormBase { |
17 | |
18 | /** |
19 | * Visitors settings. |
20 | * |
21 | * @var string |
22 | */ |
23 | const SETTINGS = 'visitors.settings'; |
24 | |
25 | /** |
26 | * An extension discovery instance. |
27 | * |
28 | * @var \Drupal\Core\Entity\EntityTypeManagerInterface |
29 | */ |
30 | protected $entityTypeManager; |
31 | |
32 | /** |
33 | * Constructs a Settings form. |
34 | * |
35 | * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager |
36 | * The entity type manager. |
37 | */ |
38 | public function __construct(EntityTypeManagerInterface $entity_type_manager) { |
39 | $this->entityTypeManager = $entity_type_manager; |
40 | } |
41 | |
42 | /** |
43 | * {@inheritdoc} |
44 | */ |
45 | public static function create(ContainerInterface $container) { |
46 | return new self( |
47 | $container->get('entity_type.manager') |
48 | ); |
49 | } |
50 | |
51 | /** |
52 | * {@inheritdoc} |
53 | */ |
54 | public function getFormId() { |
55 | return 'visitors_admin_settings'; |
56 | } |
57 | |
58 | /** |
59 | * {@inheritdoc} |
60 | */ |
61 | protected function getEditableConfigNames() { |
62 | return [ |
63 | static::SETTINGS, |
64 | ]; |
65 | } |
66 | |
67 | /** |
68 | * {@inheritdoc} |
69 | */ |
70 | public function buildForm(array $form, FormStateInterface $form_state) { |
71 | $config = $this->config(self::SETTINGS); |
72 | $form = parent::buildForm($form, $form_state); |
73 | |
74 | $form['visitors_disable_tracking'] = [ |
75 | '#type' => 'radios', |
76 | '#title' => $this->t('Track visitors'), |
77 | '#options' => [ |
78 | $this->t('Enabled'), |
79 | $this->t('Disabled'), |
80 | ], |
81 | '#description' => $this->t('Enable or disable tracking of visitors.'), |
82 | '#default_value' => (int) $config->get('disable_tracking'), |
83 | ]; |
84 | |
85 | $form['tracking_scope'] = [ |
86 | '#type' => 'vertical_tabs', |
87 | '#title' => $this->t('Tracking scope'), |
88 | '#title_display' => 'invisible', |
89 | '#default_tab' => 'edit-tracking', |
90 | '#attached' => [ |
91 | 'library' => [ |
92 | 'visitors/visitors.admin', |
93 | ], |
94 | ], |
95 | ]; |
96 | |
97 | $form['page_visibility_settings'] = [ |
98 | '#type' => 'details', |
99 | '#title' => $this->t('Pages'), |
100 | '#group' => 'tracking_scope', |
101 | ]; |
102 | |
103 | $description = $this->t( |
104 | "Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", |
105 | [ |
106 | '%blog' => '/blog', |
107 | '%blog-wildcard' => '/blog/*', |
108 | '%front' => '<front>', |
109 | ] |
110 | ); |
111 | |
112 | $form['page_visibility_settings']['visitors_visibility_request_path_pages'] = [ |
113 | '#type' => 'textarea', |
114 | '#title' => $this->t('Pages'), |
115 | '#title_display' => 'invisible', |
116 | '#default_value' => $config->get('visibility.request_path_pages') ?? '', |
117 | '#description' => $description, |
118 | '#rows' => (int) 10, |
119 | ]; |
120 | $form['page_visibility_settings']['visitors_visibility_request_path_mode'] = [ |
121 | '#type' => 'radios', |
122 | '#title' => $this->t('Add tracking to specific pages'), |
123 | '#title_display' => 'invisible', |
124 | '#options' => [ |
125 | VisitorsVisibilityInterface::PATH_EXCLUDE => $this->t('All pages except those listed'), |
126 | VisitorsVisibilityInterface::PATH_INCLUDE => $this->t('Only the listed pages'), |
127 | ], |
128 | '#default_value' => $config->get('visibility.request_path_mode'), |
129 | ]; |
130 | |
131 | $visibility_user_role_roles = $config->get('visibility.user_role_roles'); |
132 | |
133 | $form['role_visibility_settings'] = [ |
134 | '#type' => 'details', |
135 | '#title' => $this->t('Roles'), |
136 | '#group' => 'tracking_scope', |
137 | ]; |
138 | |
139 | $form['role_visibility_settings']['visitors_visibility_user_role_mode'] = [ |
140 | '#type' => 'radios', |
141 | '#title' => $this->t('Add tracking for specific roles'), |
142 | '#options' => [ |
143 | $this->t('Add to the selected roles only'), |
144 | $this->t('Add to every role except the selected ones'), |
145 | ], |
146 | '#default_value' => $config->get('visibility.user_role_mode'), |
147 | ]; |
148 | $form['role_visibility_settings']['visitors_visibility_user_role_roles'] = [ |
149 | '#type' => 'checkboxes', |
150 | '#title' => $this->t('Roles'), |
151 | '#default_value' => !empty($visibility_user_role_roles) ? $visibility_user_role_roles : [], |
152 | '#options' => $this->roleOptions(), |
153 | '#description' => $this->t('If none of the roles are selected, all users will be tracked. If a user has any of the roles checked, that user will be tracked (or excluded, depending on the setting above).'), |
154 | ]; |
155 | |
156 | $visibility_user_account_mode = $config->get('visibility.user_account_mode'); |
157 | |
158 | $form['user_visibility_settings'] = [ |
159 | '#type' => 'details', |
160 | '#title' => $this->t('Users'), |
161 | '#group' => 'tracking_scope', |
162 | ]; |
163 | $t_permission = ['%permission' => $this->t('opt-out of visitors tracking')]; |
164 | $form['user_visibility_settings']['visitors_visibility_user_account_mode'] = [ |
165 | '#type' => 'radios', |
166 | '#title' => $this->t('Allow users to customize tracking on their account page'), |
167 | '#options' => [ |
168 | VisitorsVisibilityInterface::USER_NO_PERSONALIZATION => $this->t('No customization allowed'), |
169 | VisitorsVisibilityInterface::USER_OPT_OUT => $this->t('Tracking on by default, users with %permission permission can opt out', $t_permission), |
170 | VisitorsVisibilityInterface::USER_OPT_IN => $this->t('Tracking off by default, users with %permission permission can opt in', $t_permission), |
171 | ], |
172 | '#default_value' => !empty($visibility_user_account_mode) ? $visibility_user_account_mode : 0, |
173 | ]; |
174 | $form['user_visibility_settings']['visitors_trackuserid'] = [ |
175 | '#type' => 'checkbox', |
176 | '#title' => $this->t('Track User ID'), |
177 | '#default_value' => $config->get('track.userid'), |
178 | '#description' => $this->t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and representing a user. <a href=":url">Learn more about the benefits of using User ID</a>.', [':url' => 'https://matomo.org/docs/user-id/']), |
179 | ]; |
180 | |
181 | $form['user_visibility_settings']['visibility_exclude_user1'] = [ |
182 | '#type' => 'checkbox', |
183 | '#title' => $this->t('Exclude user1 from statistics'), |
184 | '#default_value' => $config->get('visibility.exclude_user1'), |
185 | '#description' => $this->t('Exclude hits of user1 from statistics.'), |
186 | ]; |
187 | |
188 | $form['entity'] = [ |
189 | '#type' => 'details', |
190 | '#title' => $this->t('Entity counter'), |
191 | '#group' => 'tracking_scope', |
192 | ]; |
193 | $form['entity']['counter_enabled'] = [ |
194 | '#type' => 'checkbox', |
195 | '#title' => $this->t('Count entity views'), |
196 | '#default_value' => $config->get('counter.enabled'), |
197 | '#description' => $this->t('Count the number of times entities are viewed.'), |
198 | ]; |
199 | $form['entity']['entity_types'] = [ |
200 | '#type' => 'checkboxes', |
201 | '#title' => $this->t('Entity Types'), |
202 | '#options' => $this->entityTypes(), |
203 | '#default_value' => $config->get('counter.entity_types') ?? [], |
204 | '#description' => $this->t('Which entity types should be tracked.'), |
205 | ]; |
206 | |
207 | $form['retention'] = [ |
208 | '#type' => 'details', |
209 | '#title' => $this->t('Retention'), |
210 | '#group' => 'tracking_scope', |
211 | ]; |
212 | |
213 | $form['retention']['flush_log_timer'] = [ |
214 | '#type' => 'select', |
215 | '#title' => $this->t('Discard visitors logs older than'), |
216 | '#default_value' => $config->get('flush_log_timer'), |
217 | '#options' => [ |
218 | 0 => $this->t('Never'), |
219 | 3600 => $this->t('1 hour'), |
220 | 10800 => $this->t('3 hours'), |
221 | 21600 => $this->t('6 hours'), |
222 | 32400 => $this->t('9 hours'), |
223 | 43200 => $this->t('12 hours'), |
224 | 86400 => $this->t('1 day'), |
225 | 172800 => $this->t('2 days'), |
226 | 259200 => $this->t('3 days'), |
227 | 604800 => $this->t('1 week'), |
228 | 1209600 => $this->t('2 weeks'), |
229 | 4838400 => $this->t('1 month 3 weeks'), |
230 | 9676800 => $this->t('3 months 3 weeks'), |
231 | 31536000 => $this->t('1 year'), |
232 | 34214400 => $this->t('13 months'), |
233 | ], |
234 | '#description' => |
235 | $this->t('Older visitors log entries (including referrer statistics) will be automatically discarded. (Requires a correctly configured <a href="@cron">cron maintenance task</a>.)', |
236 | ['@cron' => Url::fromRoute('system.status')->toString()] |
237 | ), |
238 | ]; |
239 | |
240 | $form['retention']['bot_retention_log'] = [ |
241 | '#type' => 'select', |
242 | '#title' => $this->t('Discard bot logs older than'), |
243 | '#default_value' => $config->get('bot_retention_log'), |
244 | '#options' => [ |
245 | -1 => $this->t('Do not log'), |
246 | 0 => $this->t('Never'), |
247 | 3600 => $this->t('1 hour'), |
248 | 10800 => $this->t('3 hours'), |
249 | 21600 => $this->t('6 hours'), |
250 | 32400 => $this->t('9 hours'), |
251 | 43200 => $this->t('12 hours'), |
252 | 86400 => $this->t('1 day'), |
253 | 172800 => $this->t('2 days'), |
254 | 259200 => $this->t('3 days'), |
255 | 604800 => $this->t('1 week'), |
256 | 1209600 => $this->t('2 weeks'), |
257 | 4838400 => $this->t('1 month 3 weeks'), |
258 | 9676800 => $this->t('3 months 3 weeks'), |
259 | 31536000 => $this->t('1 year'), |
260 | 34214400 => $this->t('13 months'), |
261 | ], |
262 | '#description' => |
263 | $this->t('Control how long or if visits by bots are logged.'), |
264 | ]; |
265 | |
266 | $form['miscellaneous'] = [ |
267 | '#type' => 'details', |
268 | '#title' => $this->t('Miscellaneous'), |
269 | '#group' => 'tracking_scope', |
270 | ]; |
271 | $script_type = $config->get('script_type'); |
272 | $form['miscellaneous']['script_type'] = [ |
273 | '#type' => 'radios', |
274 | '#title' => $this->t('Script type'), |
275 | '#options' => [ |
276 | 'minified' => $this->t('Minified'), |
277 | 'full' => $this->t('Full'), |
278 | ], |
279 | '#default_value' => $script_type == 'full' ? 'full' : 'minified', |
280 | '#description' => $this->t('Full script is for debugging purposes. Minified script is for production.'), |
281 | ]; |
282 | |
283 | $form['miscellaneous']['items_per_page'] = [ |
284 | '#type' => 'select', |
285 | '#title' => 'Items per page', |
286 | '#default_value' => $config->get('items_per_page'), |
287 | '#options' => [ |
288 | 5 => 5, |
289 | 10 => 10, |
290 | 25 => 25, |
291 | 50 => 50, |
292 | 100 => 100, |
293 | 200 => 200, |
294 | 250 => 250, |
295 | 500 => 500, |
296 | 1000 => 1000, |
297 | ], |
298 | '#description' => |
299 | $this->t('The default maximum number of items to display per page.'), |
300 | ]; |
301 | |
302 | return $form; |
303 | } |
304 | |
305 | /** |
306 | * {@inheritdoc} |
307 | */ |
308 | public function submitForm(array &$form, FormStateInterface $form_state) { |
309 | $config = $this->config(self::SETTINGS); |
310 | $values = $form_state->getValues(); |
311 | |
312 | $config |
313 | ->set('items_per_page', $values['items_per_page']) |
314 | ->set('flush_log_timer', $values['flush_log_timer']) |
315 | ->set('bot_retention_log', $values['bot_retention_log']) |
316 | ->set('track.userid', $values['visitors_trackuserid']) |
317 | ->set('counter.enabled', $values['counter_enabled']) |
318 | ->set('counter.entity_types', array_filter($values['entity_types'] ?? [])) |
319 | ->set('disable_tracking', $values['visitors_disable_tracking']) |
320 | ->set('visibility.request_path_mode', $values['visitors_visibility_request_path_mode']) |
321 | ->set('visibility.request_path_pages', $values['visitors_visibility_request_path_pages']) |
322 | ->set('visibility.user_account_mode', $values['visitors_visibility_user_account_mode']) |
323 | ->set('visibility.user_role_mode', $values['visitors_visibility_user_role_mode']) |
324 | ->set('visibility.user_role_roles', array_filter($values['visitors_visibility_user_role_roles'])) |
325 | ->set('visibility.exclude_user1', $values['visibility_exclude_user1']) |
326 | ->set('script_type', $values['script_type'] ?? 'minified') |
327 | ->save(); |
328 | |
329 | parent::submitForm($form, $form_state); |
330 | } |
331 | |
332 | /** |
333 | * Returns a list of entity types. |
334 | */ |
335 | protected function entityTypes() { |
336 | $entity_types_list = []; |
337 | $entity_definitions = $this->entityTypeManager->getDefinitions(); |
338 | foreach ($entity_definitions as $entity_name => $entity_definition) { |
339 | if ($entity_definition instanceof ConfigEntityType) { |
340 | continue; |
341 | } |
342 | $entity_types_list[$entity_name] = (string) $entity_definition->getLabel(); |
343 | } |
344 | asort($entity_types_list); |
345 | |
346 | return $entity_types_list; |
347 | } |
348 | |
349 | /** |
350 | * Returns a list of roles. |
351 | */ |
352 | protected function roleOptions() { |
353 | $user_roles = $this->entityTypeManager->getStorage('user_role')->loadMultiple(); |
354 | $options = []; |
355 | foreach ($user_roles as $role) { |
356 | $options[$role->id()] = $role->label(); |
357 | } |
358 | |
359 | return \array_map('\Drupal\Component\Utility\Html::escape', $options); |
360 | } |
361 | |
362 | } |