-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathPrivacyWire.module
204 lines (173 loc) · 8.27 KB
/
PrivacyWire.module
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php namespace ProcessWire;
/**
* PrivacyWire
* This module adds management options for GDPR-relevant elements (loading maps, videos etc. only after accepting
* external media) and cookies.
*
* @author blaueQuelle
*
* ProcessWire 3.x
* Copyright (C) 2011 by Ryan Cramer
* Licensed under GNU/GPL v2, see LICENSE.TXT
*
* http://www.processwire.com
* http://www.ryancramer.com
*
*/
class PrivacyWire extends WireData implements Module, ConfigurableModule
{
var $modulePath;
var $moduleUrl;
var $headContent = "";
var $bodyContent = "";
var $lang;
public static function getModuleInfo()
{
return [
'title' => "PrivacyWire",
'summary' => "This module adds management options for GDPR-relevant elements (loading maps, videos etc. only after accepting external media) and cookies.",
'author' => "blaueQuelle",
'href' => "https://github.com/blaueQuelle/privacywire",
'version' => "1.1.7",
'autoload' => true,
'singular' => true,
'requires' => ["PHP>=7.2", "ProcessWire>=3.0.110"],
'installs' => ["TextformatterPrivacyWire"],
'icon' => 'eye-slash'
];
}
public function ready()
{
if (
$this->wire('page')->template == 'admin' || // exclude admin pages
$this->wire('page')->template == 'form-builder' || // exclude from form-builder iframe
! $this->is_active // exclude, if PrivacyWire is NOT active
) {
return;
}
// 1. - 5. within initiatePrivacyWire method
$this->wire('page')->addHookBefore('render', $this, 'initiatePrivacyWire');
// 6. Render everything!
/*
* Hint: If you want to render everything manually, make sure to insert the PrivacyWireConfig (step 2), PrivacyWireCore (step 3), Banner Markup (step 4) and if you want to display the ask-for-consent windows also the consent blueprint (step 5) somewhere in your template.
* The banner markup and consent window blueprint can be loaded anywhere, for example at the end of the body tag.
*/
if (!$this->render_manually) {
$this->wire('page')->addHookAfter('render', $this, 'render', ['priority' => 101]);
}
}
public function initiatePrivacyWire(HookEvent $event)
{
$this->modulePath = $this->wire('config')->paths->$this;
$this->moduleUrl = $this->wire('config')->urls->$this;
$this->lang = ($this->wire('languages') && !$this->wire('user')->language->isDefault()) ? '__' . $this->wire('user')->language->id : '';
// 1. Add some styling via inline CSS (if wanted, configured via backend)
if ($this->add_basic_css_styling) {
$this->headContent .= $this->renderPrivacyWireStyles();
}
// 2. Insert PrivacyWire Configuration Object as inline JS (hookable method if you want to override something)
$this->headContent .= $this->renderPrivacyWireConfigAsInlineJs();
// 3. Insert JS File (hookable method) - either modern ES6 version or legacy version with IE support.
// Output modes: a) regular script tag b) ProCache script tag c) inline script
$this->headContent .= $this->renderPrivacyWireCoreJs();
// 4. Insert PrivacyWire Banner Markup
$this->bodyContent .= $this->renderPrivacyWireBannerTemplate();
// 5. Insert PrivacyWire Blueprint for Consent Window Markup
$this->bodyContent .= $this->renderPrivacyWireConsentBlueprint();
// 6. (within ready method)
}
public function render(HookEvent $event)
{
$event->return = str_replace("</head>", "{$this->headContent}</head>", $event->return);
$event->return = str_replace("</body>", "{$this->bodyContent}</body>", $event->return);
}
public function ___renderPrivacyWireStyles()
{
$file = $this->getPrivacyWireStyles();
return "<style>" . file_get_contents($file->path) . "</style>";
}
public function ___renderPrivacyWireConfigAsInlineJs()
{
return "<script>var PrivacyWireSettings={$this->getPrivacyWireConfigObject()};</script>";
}
public function ___renderPrivacyWireCoreJs()
{
if ($this->output_mode === "inline") {
$output = "<script type='module'>" . file_get_contents($this->modulePath . "js/PrivacyWire.js") . "</script>";
$output .= "<script nomodule type='text/javascript'>" . file_get_contents($this->modulePath . "js/ie_polyfill.js") . "</script>";
$output .= "<script nomodule type='text/javascript'>" . file_get_contents($this->modulePath . "js/PrivacyWire_legacy.js") . "</script>";
return $output;
}
$output = "<script type='module' src='" . $this->moduleUrl . "js/PrivacyWire.js" . "'></script>";
$output .= "<script nomodule type='text/javascript' src='" . $this->moduleUrl . "js/ie_polyfill.js" . "'></script>";
$output .= "<script nomodule type='text/javascript' src='" . $this->moduleUrl . "js/PrivacyWire_legacy.js" . "'></script>";
return $output;
}
public function ___renderPrivacyWireBannerTemplate()
{
return $this->renderTemplate('PrivacyWireBanner.php', $this->alternate_banner_template);
}
public function ___renderPrivacyWireConsentBlueprint()
{
return $this->renderTemplate('PrivacyWireConsentBlueprint.php', $this->alternate_inline_consent_template);
}
protected function renderTemplate($filename, $alternatePath = '')
{
$filePath = $this->wire('config')->paths->$this . $filename;
$alternatePath = ltrim($alternatePath, '/');
if (
!empty($alternatePath) &&
file_exists($this->wire('config')->paths->root . $alternatePath)) {
$filePath = $this->wire('config')->paths->root . $alternatePath;
}
return wireRenderFile($filePath, ['module' => $this]);
}
/**
* Get the PrivacyWire stylesheet as Object with path and url
* @return \StdClass $file with $file->path and $file->url
*/
public function ___getPrivacyWireStyles(): \StdClass
{
$file = new \StdClass;
$file->name = "css/PrivacyWire.css";
$file->path = $this->modulePath . $file->name;
$file->url = $this->moduleUrl . $file->name;
return $file;
}
/**
* @param bool $legacy
* @return \StdClass $file with $file->path and $file->url
* @deprecated since version 1.0.2
* Get the PrivacyWire Core file as Object with path and url
*/
public function ___getPrivacyWireCore(bool $legacy = false): \StdClass
{
$file = new \StdClass;
$file->name = "js/PrivacyWire" . ($legacy ? '_legacy' : '') . ".js";
$file->path = $this->modulePath . $file->name;
$file->url = $this->moduleUrl . $file->name;
return $file;
}
/**
* Get the current PrivacyWire config options and output them as JSON Object
* @return string JSON Object of PrivacyWire config options
*/
public function ___getPrivacyWireConfigObject(): string
{
$privacyWireSettings = new \StdClass;
$privacyWireSettings->version = $this->version;
$privacyWireSettings->dnt = ($this->respectDNT) ? "1" : "0";
$privacyWireSettings->bots = ($this->checkForBots) ? "1" : "0";
$privacyWireSettings->customFunction = ($this->wire('sanitizer')->text($this->trigger_custom_js_function)) ?? "";
$privacyWireSettings->messageTimeout = ($this->messageTimeout && intval($this->messageTimeout) > 1) ? intval($this->messageTimeout) : 1500;
$privacyWireSettings->consentByClass = ($this->detect_consents_by_class) ? "1" : "0";
$privacyWireSettings->cookieGroups = [
'necessary' => $this->get("cookies_necessary_label{$this->lang}|cookies_necessary_label"),
'functional' => $this->get("cookies_functional_label{$this->lang}|cookies_functional_label"),
'statistics' => $this->get("cookies_statistics_label{$this->lang}|cookies_statistics_label"),
'marketing' => $this->get("cookies_marketing_label{$this->lang}|cookies_marketing_label"),
'external_media' => $this->get("cookies_external_media_label{$this->lang}|cookies_external_media_label"),
];
return json_encode($privacyWireSettings);
}
}