praiadeseselle/site/modules/PrivacyWire/PrivacyWire.module
2024-04-16 11:51:21 +02:00

204 lines
8.3 KiB
PHP

<?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.6",
'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);
}
}