Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
279 / 279 |
|
100.00% |
4 / 4 |
CRAP | n/a |
0 / 0 |
|
visitors_install | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
3 | |||
visitors_schema | |
100.00% |
213 / 213 |
|
100.00% |
1 / 1 |
1 | |||
visitors_requirements | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
3 | |||
visitors_update_30000 | |
100.00% |
41 / 41 |
|
100.00% |
1 / 1 |
9 |
1 | <?php |
2 | |
3 | /** |
4 | * @file |
5 | * Install/uninstall visitors module. |
6 | */ |
7 | |
8 | use Drupal\Core\Entity\EntityTypeInterface; |
9 | use Drupal\Core\Url; |
10 | use Drupal\Component\Serialization\Yaml; |
11 | |
12 | /** |
13 | * Implements hook_install(). |
14 | */ |
15 | function visitors_install($is_syncing) { |
16 | if ($is_syncing) { |
17 | return; |
18 | } |
19 | if (!\Drupal::moduleHandler()->moduleExists('statistics')) { |
20 | return; |
21 | } |
22 | $settings = \Drupal::service('config.factory')->getEditable('visitors.settings'); |
23 | $settings->set('counter.enabled', FALSE) |
24 | ->save(); |
25 | |
26 | \Drupal::messenger()->addWarning(t( |
27 | 'The Statistics module is installed. <a href="@url">Convert the Statistics node views</a> to Visitors page views.', |
28 | ['@url' => Url::fromRoute('visitors.statistics_migrate')->toString()] |
29 | )); |
30 | |
31 | } |
32 | |
33 | /** |
34 | * Implements hook_schema(). |
35 | */ |
36 | function visitors_schema() { |
37 | |
38 | $schema['visitors_visit'] = [ |
39 | 'fields' => [ |
40 | 'id' => [ |
41 | 'description' => 'Primary key', |
42 | 'type' => 'serial', |
43 | 'not null' => TRUE, |
44 | ], |
45 | 'visitor_id' => [ |
46 | 'description' => 'Unique id, provided by the visitor', |
47 | 'type' => 'varchar', |
48 | 'length' => 32, |
49 | 'not null' => FALSE, |
50 | 'default' => NULL, |
51 | ], |
52 | 'uid' => [ |
53 | 'description' => 'The user of the session', |
54 | 'type' => 'int', |
55 | 'not null' => FALSE, |
56 | ], |
57 | 'localtime' => [ |
58 | 'description' => 'Seconds since midnight, in the local of the visitor', |
59 | 'type' => 'int', |
60 | 'size' => 'medium', |
61 | 'not null' => FALSE, |
62 | 'default' => NULL, |
63 | ], |
64 | 'returning' => [ |
65 | 'description' => 'Is the visitor returning, or new', |
66 | 'type' => 'int', |
67 | 'size' => 'tiny', |
68 | ], |
69 | 'visit_count' => [ |
70 | 'description' => 'Previous visits', |
71 | 'type' => 'int', |
72 | 'not null' => FALSE, |
73 | 'default' => NULL, |
74 | ], |
75 | 'page_count' => [ |
76 | 'description' => 'Page views this visit', |
77 | 'type' => 'int', |
78 | 'not null' => FALSE, |
79 | 'default' => NULL, |
80 | ], |
81 | 'entry' => [ |
82 | 'description' => 'First page view', |
83 | 'type' => 'int', |
84 | 'not null' => FALSE, |
85 | 'default' => NULL, |
86 | ], |
87 | 'entry_time' => [ |
88 | 'description' => 'The time the visit was started', |
89 | 'type' => 'int', |
90 | 'not null' => FALSE, |
91 | 'default' => NULL, |
92 | ], |
93 | 'exit' => [ |
94 | 'description' => 'Last page view', |
95 | 'type' => 'int', |
96 | 'not null' => FALSE, |
97 | 'default' => NULL, |
98 | ], |
99 | 'exit_time' => [ |
100 | 'description' => 'The time the visit was ended', |
101 | 'type' => 'int', |
102 | 'not null' => FALSE, |
103 | 'default' => NULL, |
104 | ], |
105 | 'total_time' => [ |
106 | 'description' => 'The total time of the visit', |
107 | 'type' => 'int', |
108 | 'not null' => FALSE, |
109 | 'default' => NULL, |
110 | ], |
111 | 'bot' => [ |
112 | 'description' => 'Is the visitor a bot', |
113 | 'type' => 'int', |
114 | 'size' => 'tiny', |
115 | 'not null' => FALSE, |
116 | 'default' => NULL, |
117 | ], |
118 | 'config_id' => [ |
119 | 'description' => 'The fingerprint id', |
120 | 'type' => 'varchar', |
121 | 'length' => 16, |
122 | 'not null' => TRUE, |
123 | ], |
124 | 'config_resolution' => [ |
125 | 'description' => 'The screen resolution', |
126 | 'type' => 'varchar', |
127 | 'length' => 18, |
128 | 'not null' => FALSE, |
129 | 'default' => NULL, |
130 | ], |
131 | 'config_pdf' => [ |
132 | 'description' => 'Has PDF support', |
133 | 'type' => 'int', |
134 | 'size' => 'tiny', |
135 | 'not null' => FALSE, |
136 | 'default' => NULL, |
137 | ], |
138 | 'config_flash' => [ |
139 | 'description' => 'Has Flash support', |
140 | 'type' => 'int', |
141 | 'size' => 'tiny', |
142 | 'not null' => FALSE, |
143 | 'default' => NULL, |
144 | ], |
145 | 'config_java' => [ |
146 | 'description' => 'Has Java support', |
147 | 'type' => 'int', |
148 | 'size' => 'tiny', |
149 | 'not null' => FALSE, |
150 | 'default' => NULL, |
151 | ], |
152 | 'config_quicktime' => [ |
153 | 'description' => 'Has Quicktime support', |
154 | 'type' => 'int', |
155 | 'size' => 'tiny', |
156 | 'not null' => FALSE, |
157 | 'default' => NULL, |
158 | ], |
159 | 'config_realplayer' => [ |
160 | 'description' => 'Has Realplayer support', |
161 | 'type' => 'int', |
162 | 'size' => 'tiny', |
163 | 'not null' => FALSE, |
164 | 'default' => NULL, |
165 | ], |
166 | 'config_windowsmedia' => [ |
167 | 'description' => 'Has Windows Media support', |
168 | 'type' => 'int', |
169 | 'size' => 'tiny', |
170 | 'not null' => FALSE, |
171 | 'default' => NULL, |
172 | ], |
173 | 'config_silverlight' => [ |
174 | 'description' => 'Has Silverlight support', |
175 | 'type' => 'int', |
176 | 'size' => 'tiny', |
177 | 'not null' => FALSE, |
178 | 'default' => NULL, |
179 | ], |
180 | 'config_cookie' => [ |
181 | 'description' => 'Has cookie support', |
182 | 'type' => 'int', |
183 | 'size' => 'tiny', |
184 | 'not null' => FALSE, |
185 | 'default' => NULL, |
186 | ], |
187 | 'config_browser_engine' => [ |
188 | 'description' => 'The browser engine', |
189 | 'type' => 'varchar', |
190 | 'length' => '10', |
191 | 'not null' => FALSE, |
192 | 'default' => NULL, |
193 | ], |
194 | 'config_browser_name' => [ |
195 | 'description' => 'The browser name', |
196 | 'type' => 'varchar', |
197 | 'length' => '2', |
198 | 'not null' => FALSE, |
199 | 'default' => NULL, |
200 | ], |
201 | 'config_browser_version' => [ |
202 | 'description' => 'The browser version', |
203 | 'type' => 'varchar', |
204 | 'length' => '20', |
205 | 'not null' => FALSE, |
206 | 'default' => NULL, |
207 | ], |
208 | 'config_client_type' => [ |
209 | 'description' => 'The client type', |
210 | 'type' => 'varchar', |
211 | 'length' => '100', |
212 | 'not null' => FALSE, |
213 | 'default' => NULL, |
214 | ], |
215 | 'config_device_brand' => [ |
216 | 'description' => 'The device brand', |
217 | 'type' => 'varchar', |
218 | 'length' => '100', |
219 | 'not null' => FALSE, |
220 | 'default' => NULL, |
221 | ], |
222 | 'config_device_model' => [ |
223 | 'description' => 'The device model', |
224 | 'type' => 'varchar', |
225 | 'length' => '100', |
226 | 'not null' => FALSE, |
227 | 'default' => NULL, |
228 | ], |
229 | 'config_device_type' => [ |
230 | 'description' => 'The device type', |
231 | 'type' => 'varchar', |
232 | 'length' => '100', |
233 | 'not null' => FALSE, |
234 | 'default' => NULL, |
235 | ], |
236 | 'config_os' => [ |
237 | 'description' => 'The operating system', |
238 | 'type' => 'varchar', |
239 | 'length' => '3', |
240 | 'not null' => FALSE, |
241 | 'default' => NULL, |
242 | ], |
243 | 'config_os_version' => [ |
244 | 'description' => 'The operating system version', |
245 | 'type' => 'varchar', |
246 | 'length' => '100', |
247 | 'not null' => FALSE, |
248 | 'default' => NULL, |
249 | ], |
250 | 'location_browser_lang' => [ |
251 | 'description' => 'The browser language', |
252 | 'type' => 'varchar', |
253 | 'length' => 20, |
254 | 'not null' => FALSE, |
255 | 'default' => NULL, |
256 | ], |
257 | 'location_ip' => [ |
258 | 'description' => 'The IP address', |
259 | 'type' => 'varchar', |
260 | 'length' => 45, |
261 | 'not null' => TRUE, |
262 | 'default' => '', |
263 | ], |
264 | 'location_continent' => [ |
265 | 'description' => 'The continent of the visitor', |
266 | 'type' => 'varchar', |
267 | 'length' => 2, |
268 | 'not null' => FALSE, |
269 | 'default' => '', |
270 | ], |
271 | 'location_country' => [ |
272 | 'description' => 'The country of the visitor', |
273 | 'type' => 'varchar', |
274 | 'length' => 2, |
275 | 'not null' => FALSE, |
276 | 'default' => '', |
277 | ], |
278 | 'location_region' => [ |
279 | 'description' => 'The region of the visitor', |
280 | 'type' => 'varchar', |
281 | 'length' => 128, |
282 | 'not null' => FALSE, |
283 | 'default' => '', |
284 | ], |
285 | 'location_city' => [ |
286 | 'description' => 'The city of the visitor', |
287 | 'type' => 'varchar', |
288 | 'length' => 128, |
289 | 'not null' => FALSE, |
290 | 'default' => '', |
291 | ], |
292 | 'location_latitude' => [ |
293 | 'description' => 'The latitude from the IP address', |
294 | 'type' => 'numeric', |
295 | 'precision' => 13, |
296 | 'scale' => 10, |
297 | 'default' => NULL, |
298 | ], |
299 | 'location_longitude' => [ |
300 | 'description' => 'The longitude from the IP address', |
301 | 'type' => 'numeric', |
302 | 'precision' => 13, |
303 | 'scale' => 10, |
304 | 'default' => NULL, |
305 | ], |
306 | 'referer_keyword' => [ |
307 | 'description' => 'The referer keyword', |
308 | 'type' => 'varchar', |
309 | 'length' => 255, |
310 | 'not null' => FALSE, |
311 | 'default' => NULL, |
312 | ], |
313 | 'referer_name' => [ |
314 | 'description' => 'The referer name', |
315 | 'type' => 'varchar', |
316 | 'length' => 255, |
317 | 'not null' => FALSE, |
318 | 'default' => NULL, |
319 | ], |
320 | 'referer_type' => [ |
321 | 'description' => 'The referer type', |
322 | 'type' => 'varchar', |
323 | 'length' => 32, |
324 | 'not null' => FALSE, |
325 | 'default' => NULL, |
326 | ], |
327 | 'referer_url' => [ |
328 | 'description' => 'The referer URL', |
329 | 'type' => 'varchar', |
330 | 'length' => 1500, |
331 | 'not null' => FALSE, |
332 | 'default' => NULL, |
333 | ], |
334 | ], |
335 | 'primary key' => ['id'], |
336 | 'indexes' => [ |
337 | 'visitor_id' => ['visitor_id'], |
338 | 'bot' => ['bot'], |
339 | 'exit_time' => ['exit_time'], |
340 | 'uid' => ['uid'], |
341 | ], |
342 | ]; |
343 | |
344 | $schema['visitors_event'] = [ |
345 | 'fields' => [ |
346 | 'id' => [ |
347 | 'description' => 'Primary key', |
348 | 'type' => 'serial', |
349 | 'not null' => TRUE, |
350 | ], |
351 | 'visit_id' => [ |
352 | 'description' => 'The visitors_visit id', |
353 | 'type' => 'int', |
354 | ], |
355 | 'page_view' => [ |
356 | 'description' => 'The unique page view id', |
357 | 'type' => 'varchar', |
358 | 'length' => 32, |
359 | 'not null' => FALSE, |
360 | 'default' => NULL, |
361 | ], |
362 | 'plugin' => [ |
363 | 'description' => 'The plugin that generated the event', |
364 | 'type' => 'varchar', |
365 | 'length' => 255, |
366 | 'not null' => FALSE, |
367 | 'default' => NULL, |
368 | ], |
369 | 'event' => [ |
370 | 'description' => 'The event', |
371 | 'type' => 'varchar', |
372 | 'length' => 255, |
373 | 'not null' => FALSE, |
374 | 'default' => NULL, |
375 | ], |
376 | 'plugin_int_1' => [ |
377 | 'description' => 'The first event int variable', |
378 | 'type' => 'int', |
379 | 'not null' => FALSE, |
380 | 'default' => NULL, |
381 | ], |
382 | 'plugin_int_2' => [ |
383 | 'description' => 'The second event int variable', |
384 | 'type' => 'int', |
385 | 'not null' => FALSE, |
386 | 'default' => NULL, |
387 | ], |
388 | 'plugin_var_1' => [ |
389 | 'description' => 'The first event varchar variable', |
390 | 'type' => 'varchar', |
391 | 'length' => 255, |
392 | 'not null' => FALSE, |
393 | 'default' => NULL, |
394 | ], |
395 | 'plugin_var_2' => [ |
396 | 'description' => 'The second event varchar variable', |
397 | 'type' => 'varchar', |
398 | 'length' => 255, |
399 | 'not null' => FALSE, |
400 | 'default' => NULL, |
401 | ], |
402 | 'plugin_var_3' => [ |
403 | 'description' => 'The third event varchar variable', |
404 | 'type' => 'varchar', |
405 | 'length' => 255, |
406 | 'not null' => FALSE, |
407 | 'default' => NULL, |
408 | ], |
409 | 'plugin_var_4' => [ |
410 | 'description' => 'The fourth event varchar variable', |
411 | 'type' => 'varchar', |
412 | 'length' => 255, |
413 | 'not null' => FALSE, |
414 | 'default' => NULL, |
415 | ], |
416 | 'title' => [ |
417 | 'description' => 'The page title', |
418 | 'type' => 'text', |
419 | 'not null' => TRUE, |
420 | ], |
421 | 'uid' => [ |
422 | 'description' => 'The user who viewed the page', |
423 | 'type' => 'int', |
424 | ], |
425 | 'url_prefix' => [ |
426 | 'description' => 'The protocol and if started with www', |
427 | 'type' => 'int', |
428 | 'size' => 'small', |
429 | ], |
430 | 'url' => [ |
431 | 'description' => 'The page URL', |
432 | 'type' => 'text', |
433 | 'not null' => TRUE, |
434 | ], |
435 | 'path' => [ |
436 | 'description' => 'The Drupal path', |
437 | 'type' => 'varchar', |
438 | 'length' => 255, |
439 | 'not null' => TRUE, |
440 | 'default' => '', |
441 | ], |
442 | 'route' => [ |
443 | 'description' => 'The Drupal route name', |
444 | 'type' => 'varchar', |
445 | 'length' => 255, |
446 | 'not null' => TRUE, |
447 | 'default' => '', |
448 | ], |
449 | 'referrer_url' => [ |
450 | 'description' => 'The referrer URL', |
451 | 'type' => 'text', |
452 | 'not null' => TRUE, |
453 | ], |
454 | 'server' => [ |
455 | 'description' => 'The server that generated the response', |
456 | 'type' => 'varchar', |
457 | 'length' => 255, |
458 | 'not null' => FALSE, |
459 | 'default' => NULL, |
460 | ], |
461 | 'pf_network' => [ |
462 | 'description' => 'Network performance', |
463 | 'type' => 'int', |
464 | 'not null' => FALSE, |
465 | 'default' => NULL, |
466 | ], |
467 | 'pf_server' => [ |
468 | 'description' => 'Server performance', |
469 | 'type' => 'int', |
470 | 'not null' => FALSE, |
471 | 'default' => NULL, |
472 | ], |
473 | 'pf_transfer' => [ |
474 | 'description' => 'Transfer performance', |
475 | 'type' => 'int', |
476 | 'not null' => FALSE, |
477 | 'default' => NULL, |
478 | ], |
479 | 'pf_dom_processing' => [ |
480 | 'description' => 'DOM processing performance', |
481 | 'type' => 'int', |
482 | 'not null' => FALSE, |
483 | 'default' => NULL, |
484 | ], |
485 | 'pf_dom_complete' => [ |
486 | 'description' => 'DOM complete performance', |
487 | 'type' => 'int', |
488 | 'not null' => FALSE, |
489 | 'default' => NULL, |
490 | ], |
491 | 'pf_on_load' => [ |
492 | 'description' => 'On load performance', |
493 | 'type' => 'int', |
494 | 'not null' => FALSE, |
495 | 'default' => NULL, |
496 | ], |
497 | 'pf_total' => [ |
498 | 'description' => 'Total performance', |
499 | 'type' => 'int', |
500 | 'not null' => FALSE, |
501 | 'default' => NULL, |
502 | ], |
503 | 'created' => [ |
504 | 'description' => 'The time the request was made', |
505 | 'type' => 'int', |
506 | ], |
507 | ], |
508 | 'primary key' => ['id'], |
509 | 'indexes' => [ |
510 | 'visit_id' => ['visit_id'], |
511 | 'created' => ['created'], |
512 | ], |
513 | ]; |
514 | |
515 | $schema['visitors_counter'] = [ |
516 | 'fields' => [ |
517 | 'entity_id' => [ |
518 | 'description' => 'The entity id for these visits.', |
519 | 'type' => 'int', |
520 | 'unsigned' => TRUE, |
521 | 'not null' => TRUE, |
522 | 'default' => 0, |
523 | ], |
524 | 'entity_type' => [ |
525 | 'type' => 'varchar_ascii', |
526 | 'not null' => TRUE, |
527 | 'default' => 'node', |
528 | 'length' => EntityTypeInterface::ID_MAX_LENGTH, |
529 | 'description' => 'The entity_type of the entity for these visits.', |
530 | ], |
531 | 'total' => [ |
532 | 'description' => 'The total number of times the entity has been viewed.', |
533 | 'type' => 'int', |
534 | 'unsigned' => TRUE, |
535 | 'not null' => TRUE, |
536 | 'default' => 0, |
537 | 'size' => 'big', |
538 | ], |
539 | 'today' => [ |
540 | 'description' => 'The total number of times the entity has been viewed today.', |
541 | 'type' => 'int', |
542 | 'unsigned' => TRUE, |
543 | 'not null' => TRUE, |
544 | 'default' => 0, |
545 | 'size' => 'medium', |
546 | ], |
547 | 'timestamp' => [ |
548 | 'description' => 'The most recent time the entity has been viewed.', |
549 | 'type' => 'int', |
550 | 'unsigned' => TRUE, |
551 | 'not null' => TRUE, |
552 | 'default' => 0, |
553 | ], |
554 | ], |
555 | 'primary key' => ['entity_type', 'entity_id'], |
556 | ]; |
557 | |
558 | return $schema; |
559 | } |
560 | |
561 | /** |
562 | * Implements hook_requirements(). |
563 | */ |
564 | function visitors_requirements($phase) { |
565 | $requirements = []; |
566 | if ($phase != 'runtime') { |
567 | return $requirements; |
568 | } |
569 | $device = \Drupal::service('visitors.device'); |
570 | if (!$device->hasLibrary()) { |
571 | $requirements['visitors_device'] = [ |
572 | 'title' => t('Device Detector'), |
573 | 'value' => t('Not found'), |
574 | 'severity' => REQUIREMENT_WARNING, |
575 | 'description' => t('The <a href=":url">Device Detector</a> library is strongly encouraged by the Visitors module. Composer will download the library automatically.', [ |
576 | ':url' => 'https://github.com/matomo-org/device-detector', |
577 | ]), |
578 | ]; |
579 | } |
580 | |
581 | return $requirements; |
582 | } |
583 | |
584 | /** |
585 | * Upgrade to Visitors 3. |
586 | */ |
587 | function visitors_update_30000(&$sandbox) { |
588 | |
589 | if (!isset($sandbox['current'])) { |
590 | $sandbox['current'] = 0; |
591 | $sandbox['max'] = 4; |
592 | } |
593 | |
594 | // Change visitors.settings to visitors.settings. |
595 | if ($sandbox['current'] == 0) { |
596 | $config_factory = \Drupal::configFactory(); |
597 | |
598 | $config = $config_factory->getEditable('visitors.config'); |
599 | $config_data = $config->getRawData(); |
600 | |
601 | $settings = $config_factory->getEditable('visitors.settings'); |
602 | $settings->setData($config_data)->save(); |
603 | |
604 | $config->delete(); |
605 | } |
606 | |
607 | if ($sandbox['current'] == 1) { |
608 | $schema = \Drupal::database()->schema(); |
609 | // @todo replace visitors_schema() with static before an initial release. |
610 | $visitors_schema = visitors_schema(); |
611 | $schema->createTable('visitors_visit', $visitors_schema['visitors_visit']); |
612 | $schema->createTable('visitors_event', $visitors_schema['visitors_event']); |
613 | } |
614 | |
615 | if ($sandbox['current'] == 2) { |
616 | $config_factory = \Drupal::configFactory(); |
617 | |
618 | // @todo This needs to be replace with static before an initial release. |
619 | $view = file_get_contents(__DIR__ . '/config/optional/views.view.visitors.yml'); |
620 | $config_data = Yaml::decode($view); |
621 | $config_factory->getEditable('views.view.visitors')->setData($config_data)->save(); |
622 | |
623 | // @todo This needs to be replace with static before an initial release. |
624 | $spam = file_get_contents(__DIR__ . '/config/install/visitors.spam.yml'); |
625 | $config_data = Yaml::decode($spam); |
626 | $config_factory->getEditable('visitors.spam')->setData($config_data)->save(); |
627 | |
628 | // @todo This needs to be replace with static before an initial release. |
629 | $ai_assistants = file_get_contents(__DIR__ . '/config/install/visitors.ai_assistants.yml'); |
630 | $config_data = Yaml::decode($ai_assistants); |
631 | $config_factory->getEditable('visitors.ai_assistants')->setData($config_data)->save(); |
632 | |
633 | // @todo This needs to be replace with static before an initial release. |
634 | $search_engine = file_get_contents(__DIR__ . '/config/install/visitors.search_engines.yml'); |
635 | $config_data = Yaml::decode($search_engine); |
636 | $config_factory->getEditable('visitors.search_engine')->setData($config_data)->save(); |
637 | |
638 | // @todo This needs to be replace with static before an initial release. |
639 | $social_networks = file_get_contents(__DIR__ . '/config/install/visitors.social_networks.yml'); |
640 | $config_data = Yaml::decode($social_networks); |
641 | $config_factory->getEditable('visitors.social_networks')->setData($config_data)->save(); |
642 | |
643 | // Check if views 'views.view.visitors_geoip' exists, and delete it. |
644 | $geoip_view = $config_factory->getEditable('views.view.visitors_geoip'); |
645 | if ($geoip_view) { |
646 | $geoip_view->delete(); |
647 | } |
648 | |
649 | } |
650 | |
651 | if ($sandbox['current'] == 3) { |
652 | $visitors_geoip_is_installed = \Drupal::moduleHandler()->moduleExists('visitors_geoip'); |
653 | if ($visitors_geoip_is_installed) { |
654 | \Drupal::service('module_installer')->uninstall(['visitors_geoip']); |
655 | } |
656 | } |
657 | |
658 | $sandbox['current'] += 1; |
659 | |
660 | $sandbox['#finished'] = ($sandbox['max'] == $sandbox['current']) ? 1 : $sandbox['current'] / $sandbox['max']; |
661 | } |