forked from Daniel-KM/Omeka-S-module-AnalyticsSnippet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathModule.php
122 lines (110 loc) · 4.3 KB
/
Module.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?php declare(strict_types=1);
namespace AnalyticsSnippet;
if (!class_exists(\Generic\AbstractModule::class)) {
require file_exists(dirname(__DIR__) . '/Generic/AbstractModule.php')
? dirname(__DIR__) . '/Generic/AbstractModule.php'
: __DIR__ . '/src/Generic/AbstractModule.php';
}
use Generic\AbstractModule;
use Laminas\EventManager\Event;
use Laminas\EventManager\SharedEventManagerInterface;
use Laminas\View\Model\JsonModel;
use Laminas\View\View;
use Laminas\View\ViewEvent;
/**
* AnalyticsSnippet
*
* Add a snippet, generally a javascript tracker, in public or admin pages, and
* allows to track json and xml requests.
*
* @copyright Daniel Berthereau, 2017-2022
* @license http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
*/
class Module extends AbstractModule
{
const NAMESPACE = __NAMESPACE__;
public function postInstall(): void
{
$messenger = new \Omeka\Mvc\Controller\Plugin\Messenger;
$message = new \Omeka\Stdlib\Message(
'Fill the snippet in the main settings.' // @translate
);
$messenger->addNotice($message);
$message = new \Omeka\Stdlib\Message(
'To get statistics about keywords used by visitors in search engines, see %1$sMatomo/Piwik help%2$s.', // @translate
'<a href="https://matomo.org/faq/reports/analyse-search-keywords-reports/" target="_blank">',
'</a>'
);
$message->setEscapeHtml(false);
$messenger->addNotice($message);
}
public function attachListeners(SharedEventManagerInterface $sharedEventManager): void
{
$sharedEventManager->attach(
View::class,
ViewEvent::EVENT_RESPONSE,
[$this, 'appendAnalyticsSnippet']
);
$sharedEventManager->attach(
\Omeka\Form\SettingForm::class,
'form.add_elements',
[$this, 'handleMainSettings']
);
$sharedEventManager->attach(
\Omeka\Form\SiteSettingsForm::class,
'form.add_elements',
[$this, 'handleSiteSettings']
);
}
public function appendAnalyticsSnippet(ViewEvent $viewEvent): void
{
// In case of error or a internal redirection, there may be two calls.
static $processed;
if ($processed) {
return;
}
$processed = true;
$model = $viewEvent->getParam('model');
if (is_object($model) && $model instanceof JsonModel) {
$this->trackCall('json', $viewEvent);
return;
}
$content = $viewEvent->getResponse()->getContent();
// Quick hack to avoid a lot of checks for an event that always occurs.
// Headers are not yet available, so the content type cannot be checked.
// Note: The layout of the theme should start with this doctype, without
// space or line break. This is not the case in the admin layout of
// Omeka S 1.0.0, so a check is done.
// The ltrim is required in case of a bad theme layout, and the substr
// allows a quicker check because it avoids a trim on all the content.
// if (substr($content, 0, 15) != '<!DOCTYPE html>') {
$startContent = ltrim(substr((string) $content, 0, 30));
if (strpos($startContent, '<!DOCTYPE html>') === 0) {
$this->trackCall('html', $viewEvent);
} elseif (strpos($startContent, '<?xml ') !== 0) {
$this->trackCall('xml', $viewEvent);
} elseif (json_decode($content) !== null) {
$this->trackCall('json', $viewEvent);
} else {
$this->trackCall('undefined', $viewEvent);
}
}
/**
* Track an html, an api, a json, an xml or an undefined response.
*
* @param string $type "html", "json", "xml", "undefined", or "error".
* @param Event $event
*/
protected function trackCall($type, Event $event): void
{
$services = $this->getServiceLocator();
$serverUrl = $services->get('ViewHelperManager')->get('ServerUrl');
$url = $serverUrl(true);
$trackers = $services->get('Config')['analyticssnippet']['trackers'];
foreach ($trackers as $tracker) {
$tracker = new $tracker();
$tracker->setServiceLocator($services);
$tracker->track($url, $type, $event);
}
}
}