Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
279 / 279
100.00% covered (success)
100.00%
4 / 4
CRAP
n/a
0 / 0
visitors_install
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
visitors_schema
100.00% covered (success)
100.00%
213 / 213
100.00% covered (success)
100.00%
1 / 1
1
visitors_requirements
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
3
visitors_update_30000
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
9
1<?php
2
3/**
4 * @file
5 * Install/uninstall visitors module.
6 */
7
8use Drupal\Core\Entity\EntityTypeInterface;
9use Drupal\Core\Url;
10use Drupal\Component\Serialization\Yaml;
11
12/**
13 * Implements hook_install().
14 */
15function 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 */
36function 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 */
564function 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 */
587function 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}