"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("", "{$this->headContent}", $event->return); $event->return = str_replace("", "{$this->bodyContent}", $event->return); } public function ___renderPrivacyWireStyles() { $file = $this->getPrivacyWireStyles(); return ""; } public function ___renderPrivacyWireConfigAsInlineJs() { return ""; } public function ___renderPrivacyWireCoreJs() { if ($this->output_mode === "inline") { $output = ""; $output .= ""; $output .= ""; return $output; } $output = ""; $output .= ""; $output .= ""; 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); } }