1821 lines
54 KiB
PHP
1821 lines
54 KiB
PHP
<?php
|
|
/**
|
|
* @package n3t Cookie Consent
|
|
* @author Pavel Poles - n3t.cz
|
|
* @copyright (C) 2021 - Pavel Poles - n3t.cz
|
|
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
|
|
*
|
|
* @noinspection PhpMultipleClassDeclarationsInspection
|
|
**/
|
|
|
|
defined( '_JEXEC' ) or die( 'Restricted access' );
|
|
|
|
use Joomla\CMS\Application\ApplicationHelper;
|
|
use Joomla\CMS\Factory;
|
|
use Joomla\CMS\Form\Form;
|
|
use Joomla\CMS\HTML\HTMLHelper;
|
|
use Joomla\CMS\Language\Multilanguage;
|
|
use Joomla\CMS\Language\Text;
|
|
use Joomla\CMS\Layout\FileLayout;
|
|
use Joomla\CMS\Plugin\CMSPlugin;
|
|
use Joomla\CMS\Log\Log;
|
|
use Joomla\CMS\Plugin\PluginHelper;
|
|
use Joomla\CMS\Router\Route;
|
|
use Joomla\CMS\Version;
|
|
use Joomla\Registry\Registry;
|
|
use Joomla\CMS\Uri\Uri;
|
|
|
|
class plgSystemN3tCookieConsent extends CMSPlugin
|
|
{
|
|
private const BLOCK_DESCRIPTION = 'description';
|
|
private const BLOCK_PRIVACY = 'privacy';
|
|
private const BLOCK_FUNCTIONAL = 'functional';
|
|
private const BLOCK_PREFERENCES = 'preferences';
|
|
private const BLOCK_ANALYTICS = 'analytics';
|
|
private const BLOCK_MARKETING = 'marketing';
|
|
private const BLOCK_UNKNOWN = 'unknown';
|
|
private const BLOCK_HIDDEN = 'hidden';
|
|
private const BLOCK_SYSTEM = 'system';
|
|
private const BLOCK_CUSTOM_DESCRIPTION = 'custom_description';
|
|
private const BLOCK_CUSTOM = 'custom';
|
|
private const BLOCK_CONSENT = 'consent';
|
|
|
|
private const SCAN_IGNORE = 'ignore';
|
|
|
|
private const LOG_FILE = 'n3t_cookie_consent.php';
|
|
|
|
/**
|
|
* Contains list of known Cookies
|
|
* @var ?array
|
|
* @since 4.0.0
|
|
*/
|
|
private $cookieList = null;
|
|
|
|
/**
|
|
* Is site set as multilingual?
|
|
* @var bool
|
|
* @since 4.0.0
|
|
*/
|
|
private $isMultiLanguage = false;
|
|
|
|
/**
|
|
* Is scan mode?
|
|
* @var bool
|
|
* @since 4.0.0
|
|
*/
|
|
private $isScanMode = false;
|
|
|
|
/**
|
|
* Scan mode just finished?
|
|
* @var bool
|
|
* @since 4.0.0
|
|
*/
|
|
private $isScanModeFinished = false;
|
|
|
|
/**
|
|
* Report cookie contents
|
|
* @var ?array
|
|
* @since 4.0.0
|
|
*/
|
|
private $reportCookie = null;
|
|
|
|
/**
|
|
* Array of newly registered Cookies
|
|
* @var array
|
|
* @since 4.0.0
|
|
*/
|
|
private $debuggerCollectedCookies = [];
|
|
|
|
/**
|
|
* Array of blocked PHP Cookies
|
|
* @var array
|
|
* @since 4.0.0
|
|
*/
|
|
private $debuggerBlockedCookies = [];
|
|
|
|
/**
|
|
* Array of discovered iframes
|
|
* @var array
|
|
* @since 4.0.2
|
|
*/
|
|
private $debuggerIFrames = [];
|
|
|
|
/**
|
|
* Constructor
|
|
* @param $subject
|
|
* @param $config
|
|
*/
|
|
public function __construct(&$subject, $config = array())
|
|
{
|
|
parent::__construct($subject, $config);
|
|
|
|
$app = Factory::getApplication();
|
|
|
|
$this->isMultiLanguage = Multilanguage::isEnabled();
|
|
if ($app->isClient('site'))
|
|
{
|
|
$this->isScanMode = !!Factory::getApplication()->getSession()->get('n3tcc_scan');
|
|
if (!$this->isScanMode && $this->getInput()->get('n3tcc_scan') === ApplicationHelper::getHash('plg_system_n3tcookiesconsent'))
|
|
{
|
|
$this->isScanMode = true;
|
|
$app->getSession()->set('n3tcc_scan', true);
|
|
}
|
|
elseif ($this->isScanMode && $this->getInput()->get('n3tcc_scan') === '0')
|
|
{
|
|
$this->isScanMode = false;
|
|
$this->isScanModeFinished = true;
|
|
$app->getSession()->set('n3tcc_scan', false);
|
|
}
|
|
|
|
if ($this->isScanMode) {
|
|
$this->loadLanguage();
|
|
$app->enqueueMessage(Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_MODE_RUNNING', Route::_('index.php?n3tcc_scan=0')), 'warning');
|
|
}
|
|
|
|
$reportCookie = $this->getInput()->cookie->get($this->params->get('cookie_name', 'n3t_cc') . '_report', '', 'string');
|
|
if ($reportCookie)
|
|
$this->reportCookie = explode(';', $reportCookie);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper function to get JInput based on Joomla version
|
|
*
|
|
* @return \Joomla\Input\Input
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function getInput(): \Joomla\Input\Input
|
|
{
|
|
if (Version::MAJOR_VERSION < 4)
|
|
return Factory::getApplication()->input;
|
|
else
|
|
return Factory::getApplication()->getInput();
|
|
}
|
|
|
|
/**
|
|
* Loads language files
|
|
*
|
|
* @param $extension
|
|
* @param $basePath
|
|
*
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function loadLanguage($extension = '', $basePath = JPATH_ADMINISTRATOR)
|
|
{
|
|
$langFile = 'plg_' . $this->_type . '_' . $this->_name . '.data';
|
|
$lang = Factory::getApplication()->getLanguage();
|
|
if (!$lang->getPaths($langFile))
|
|
$lang->load($langFile, JPATH_ADMINISTRATOR);
|
|
|
|
return parent::loadLanguage($extension, $basePath);
|
|
}
|
|
|
|
/**
|
|
* Returns true if plugin should be enabled
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function isEnabled(): bool
|
|
{
|
|
$app = Factory::getApplication();
|
|
|
|
return
|
|
$app->isClient('site')
|
|
&& $app->getDocument()->getType() === 'html'
|
|
&& (!$this->params->get('hide_from_bots', true) || !Factory::getApplication()->client->robot);
|
|
}
|
|
|
|
/**
|
|
* Returns true if current page is privacy page
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function isPrivacyPage(): bool
|
|
{
|
|
$input = $this->getInput();
|
|
|
|
if ($this->params->get('privacy_policy_type', 'menuitem') === 'menuitem' && $this->params->get('privacy_policy') === $input->get('Itemid'))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if plugin should use autorun
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function isVisible(): bool
|
|
{
|
|
static $disabledTmplList = null;
|
|
if ($disabledTmplList === null) {
|
|
$tmplList = (array) $this->params->get('disable_tmpl', [['tmpl' => 'component'], ['tmpl' => 'raw']]);
|
|
$disabledTmplList = [];
|
|
foreach ($tmplList as $tmpl)
|
|
$disabledTmplList[] = ((array)$tmpl)['tmpl'];
|
|
}
|
|
|
|
if (in_array($this->getInput()->get('tmpl'), $disabledTmplList))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns true if trigger should be visible
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function isTriggerVisible(): bool
|
|
{
|
|
return $this->params->get('show_trigger', 1)
|
|
&& $this->isVisible();
|
|
}
|
|
|
|
/**
|
|
* Returns current user consent
|
|
*
|
|
* @return Registry
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function getConsent(): Registry
|
|
{
|
|
$consent = $this->getInput()->cookie->get($this->params->get('cookie_name', 'n3t_cc'), null, 'raw');
|
|
return new Registry($consent);
|
|
}
|
|
|
|
/**
|
|
* Returns currently allowed categories by user consent
|
|
*
|
|
* @return Registry
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function allowedCategories(): array
|
|
{
|
|
$categories = [];
|
|
foreach ($this->params->get('blocks', []) as $block) {
|
|
if ($block->type == self::BLOCK_FUNCTIONAL || $block->type == self::BLOCK_SYSTEM || $block->type == self::BLOCK_CUSTOM && $block->readonly && $block->default_enabled)
|
|
$categories[] = $block->type;
|
|
}
|
|
|
|
$consent = $this->getConsent();
|
|
$categories = array_merge($categories, $consent->get('level', []));
|
|
|
|
return array_unique($categories);
|
|
}
|
|
|
|
/**
|
|
* Returns if cookie by given name is enabled by current user consent
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function isCookieEnabled(string $cookieName): bool
|
|
{
|
|
$cookieName = trim($cookieName);
|
|
|
|
$cookies = $this->loadCookies();
|
|
$category = null;
|
|
foreach ($cookies as $cookie) {
|
|
if ($cookie['is_regex'] && preg_match('~' . $cookie['name'] . '~', $cookieName)) {
|
|
$category = $cookie['category'];
|
|
break;
|
|
}
|
|
if (!$cookie['is_regex'] && $cookie['name'] == $cookieName) {
|
|
$category = $cookie['category'];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($category === self::BLOCK_HIDDEN)
|
|
$category = self::BLOCK_UNKNOWN;
|
|
|
|
if ($category === self::BLOCK_SYSTEM)
|
|
$category = self::BLOCK_FUNCTIONAL;
|
|
|
|
if ($category === null) {
|
|
switch ($this->params->get('allow_unknown_cookies', 'settings')) {
|
|
case 'allow': return true;
|
|
case 'block': return false;
|
|
default: $category = self::BLOCK_UNKNOWN; break;
|
|
}
|
|
}
|
|
|
|
return in_array($category, $this->allowedCategories());
|
|
}
|
|
|
|
/**
|
|
* Returns translation, if exists (avoids reporting unstranslated strings)
|
|
*
|
|
* @param $text
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function translateText(string $text, ?int $count = null): string
|
|
{
|
|
if ($text === 'SITENAME') {
|
|
$appConfig = Factory::getConfig();
|
|
return $appConfig->get('sitename');
|
|
}
|
|
|
|
static $lang = null;
|
|
if ($lang === null)
|
|
$lang = Factory::getApplication()->getLanguage();
|
|
if ($count === null)
|
|
return $lang->hasKey($text) ? Text::_($text) : $text;
|
|
else
|
|
return Text::plural($text, $count);
|
|
}
|
|
|
|
/**
|
|
* Returns translation of text constant, if site is multilanguage, returns the text constnt
|
|
*
|
|
* @param $text
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function multilang(string $text): string
|
|
{
|
|
return $this->isMultiLanguage ? $text : $this->translateText($text);
|
|
}
|
|
|
|
/**
|
|
* returns array of cookies used in script
|
|
* @return array
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
private function loadCookies(): array
|
|
{
|
|
if ($this->cookieList == null) {
|
|
$cookies = [];
|
|
foreach ($this->params->get('blocks', []) as $block) {
|
|
if (isset($block->cookies) && !empty($block->cookies)) {
|
|
foreach ((array)$block->cookies as $cookie) {
|
|
$cookie = (object)$cookie;
|
|
if ($block->alias ?? '')
|
|
$category = $block->alias;
|
|
else {
|
|
$category = $block->type ?? '';
|
|
if (!$category)
|
|
$category = self::BLOCK_UNKNOWN;
|
|
if ($category == self::BLOCK_HIDDEN)
|
|
$category = self::BLOCK_UNKNOWN;
|
|
if ($category == self::BLOCK_SYSTEM)
|
|
$category = self::BLOCK_FUNCTIONAL;
|
|
}
|
|
$cookies[] = [
|
|
'name' => $cookie->name,
|
|
'is_regex' => !!($cookie->regex ?? false),
|
|
'category' => $category,
|
|
'required' => $block->type == self::BLOCK_FUNCTIONAL || $block->type == self::BLOCK_SYSTEM || $block->type == self::BLOCK_CUSTOM && $block->readonly && $block->default_enabled,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->cookieList = $cookies;
|
|
}
|
|
|
|
return $this->cookieList;
|
|
}
|
|
|
|
/**
|
|
* returns true, if cookie is registered, otherwise false
|
|
*
|
|
* @param string $cookieName
|
|
*
|
|
* @return bool
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
private function isCookieRegistered(string $cookieName): bool
|
|
{
|
|
$cookies = $this->loadCookies();
|
|
foreach ($cookies as $cookie) {
|
|
if ($cookie['is_regex'] && preg_match('~' . $cookie['name'] . '~', $cookieName))
|
|
return true;
|
|
if (!$cookie['is_regex'] && $cookie['name'] == $cookieName)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* returns array containing CookieConsent script settings
|
|
* @return array
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function scriptOptions(): array
|
|
{
|
|
$appConfig = JFactory::getConfig();
|
|
$options = [];
|
|
if (!$this->params->get('autorun', true) || !$this->isVisible() || $this->isPrivacyPage())
|
|
$options['autorun'] = false;
|
|
if ((int)$this->params->get('delay', 0))
|
|
$options['delay'] = (int)$this->params->get('delay', 0);
|
|
$options['cookie_expiration'] = (int)$this->params->get('cookie_expiration', 395);
|
|
if ((int)$this->params->get('cookie_necessary_only_expiration'))
|
|
$options['cookie_necessary_only_expiration'] = (int)$this->params->get('cookie_necessary_only_expiration');
|
|
if ($path = $this->params->get('cookie_path', $appConfig->get('cookie_path')))
|
|
$options['cookie_path'] = $path;
|
|
if ($domain = $this->params->get('cookie_domain', $appConfig->get('cookie_domain')))
|
|
$options['cookie_domain'] = $domain;
|
|
if ($this->params->get('cookie_same_site', 'Lax') != 'Lax')
|
|
$options['cookie_same_site'] = $this->params->get('cookie_same_site');
|
|
$options['use_rfc_cookie'] = true;
|
|
if ($this->params->get('force_consent'))
|
|
$options['force_consent'] = true;
|
|
if ((int)$this->params->get('revision'))
|
|
$options['revision'] = (int)$this->params->get('revision');
|
|
$options['current_lang'] = 'default';
|
|
$options['autoclear_cookies'] = true;
|
|
if ($this->params->get('page_scripts'))
|
|
$options['page_scripts'] = true;
|
|
if ($this->params->get('mode', 'opt-in') != 'opt-in')
|
|
$options['mode'] = $this->params->get('mode');
|
|
if ($this->params->get('remove_cookie_tables'))
|
|
$options['remove_cookie_tables'] = true;
|
|
if ($this->params->get('hide_from_bots', true))
|
|
$options['hide_from_bots'] = true;
|
|
|
|
$guiOptions = [];
|
|
$guiOptions['consent_modal'] = [
|
|
'layout' => $this->params->get('consent_modal_layout', 'box'),
|
|
'position' => $this->params->get('consent_modal_position', 'bottom right'),
|
|
'transition' => $this->params->get('consent_modal_transition', 'slide'),
|
|
'swap_buttons' => !!$this->params->get('consent_modal_swap_buttons', true),
|
|
];
|
|
$guiOptions['settings_modal'] = [
|
|
'layout' => $this->params->get('settings_modal_layout', 'bar'),
|
|
'position' => $this->params->get('settings_modal_position', 'right'),
|
|
'transition' => $this->params->get('settings_modal_transition', 'slide'),
|
|
];
|
|
$options['gui_options'] = $guiOptions;
|
|
|
|
$language = [];
|
|
$privacyLink = '';
|
|
if ($this->params->get('privacy_policy_type', 'menuitem') === 'menuitem' && $this->params->get('privacy_policy'))
|
|
$privacyLink = Route::_('index.php?Itemid=' . $this->params->get('privacy_policy'));
|
|
elseif ($this->params->get('privacy_policy_type', 'menuitem') === 'url' && $this->params->get('privacy_policy_url'))
|
|
$privacyLink = $this->params->get('privacy_policy_url');
|
|
|
|
$consentText = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CONSENT_MODAL_DESCRIPTION');
|
|
if ($this->params->get('secondary_button_role', 'settings') !== 'settings' && $this->params->get('tertiary_button_role', 'none') !== 'settings')
|
|
$consentText .= ' ' . Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_SETTINGS_LINK');
|
|
|
|
if ($privacyLink)
|
|
$consentText .= ' ' . Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_PRIVACY_POLICY_LINK', $privacyLink);
|
|
|
|
if ((int)$this->params->get('revision'))
|
|
$consentText .= '{{revision_message}}';
|
|
|
|
$consentModallanguage = [
|
|
'title' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CONSENT_MODAL_TITLE'),
|
|
'description' => $consentText,
|
|
'revision_message' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CONSENT_MODAL_REVISION'),
|
|
'primary_btn' => [
|
|
'text' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_' . $this->params->get('primary_button_role', 'accept_all')),
|
|
'role' => $this->params->get('primary_button_role', 'accept_all'),
|
|
]
|
|
];
|
|
|
|
if ($this->params->get('secondary_button_role', 'settings') != 'none') {
|
|
$consentModallanguage['secondary_btn'] = [
|
|
'text' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_' . $this->params->get('secondary_button_role', 'settings')),
|
|
'role' => $this->params->get('secondary_button_role', 'settings'),
|
|
];
|
|
}
|
|
$language['consent_modal'] = $consentModallanguage;
|
|
|
|
$settingsModallanguage = [
|
|
'title' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_SETTINGS_MODAL_TITLE'),
|
|
'save_settings_btn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_SAVE_SETTINGS'),
|
|
'accept_all_btn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_ACCEPT_ALL_SETTINGS'),
|
|
'close_btn_label' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_CLOSE_SETTINGS'),
|
|
];
|
|
if ($this->params->get('show_reject_all', true))
|
|
$settingsModallanguage['reject_all_btn'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BTN_REJECT_ALL_SETTINGS');
|
|
|
|
$settingsModallanguage['cookie_table_headers'] = [
|
|
['name' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_TABLE_NAME')],
|
|
['description' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_TABLE_DESCRIPTION')],
|
|
];
|
|
|
|
if ($this->params->get('show_cookie_provider', 1))
|
|
$settingsModallanguage['cookie_table_headers'][] = ['provider' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_TABLE_PROVIDER')];
|
|
|
|
if ($this->params->get('show_cookie_expiration', 1))
|
|
$settingsModallanguage['cookie_table_headers'][] = ['expiration' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_TABLE_EXPIRATION')];
|
|
|
|
$settingsModallanguage['blocks'] = [];
|
|
|
|
if ($this->isScanMode) {
|
|
$blockOptions = [];
|
|
$blockOptions['title'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_SCAN_TITLE');
|
|
$blockOptions['description'] = Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_SCAN_DESCRIPTION', Route::_('index.php?n3tcc_scan=0'));
|
|
$settingsModallanguage['blocks'][] = $blockOptions;
|
|
}
|
|
|
|
foreach ($this->params->get('blocks', []) as $block) {
|
|
$blockOptions = [];
|
|
if ($block->type == self::BLOCK_HIDDEN)
|
|
continue;
|
|
if ($block->type == self::BLOCK_SYSTEM)
|
|
continue;
|
|
|
|
switch ($block->type) {
|
|
case self::BLOCK_CUSTOM:
|
|
case self::BLOCK_CUSTOM_DESCRIPTION:
|
|
$blockOptions['title'] = $this->translateText($block->title);
|
|
$blockOptions['description'] = $this->translateText($block->description);
|
|
if ($block->type == self::BLOCK_CUSTOM) {
|
|
$blockOptions['toggle'] = [
|
|
'value' => $block->alias,
|
|
'enabled' => !!$block->default_enabled,
|
|
'readonly' => !!$block->readonly,
|
|
];
|
|
}
|
|
break;
|
|
|
|
case self::BLOCK_PRIVACY:
|
|
if ($privacyLink) {
|
|
$blockOptions['title'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_TITLE');
|
|
$blockOptions['description'] = Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_DESCRIPTION', $privacyLink);
|
|
} else
|
|
continue 2;
|
|
break;
|
|
|
|
case self::BLOCK_CONSENT:
|
|
$blockOptions['title'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_TITLE');
|
|
$blockOptions['description'] = '<div class="n3tcc-consent-info">' . Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_DESCRIPTION') . '</div>';
|
|
break;
|
|
|
|
default:
|
|
$blockOptions['title'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_TITLE');
|
|
$blockOptions['description'] = Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_BLOCK_' . $block->type . '_DESCRIPTION');
|
|
break;
|
|
}
|
|
|
|
switch ($block->type) {
|
|
case self::BLOCK_CUSTOM:
|
|
$blockOptions['toggle'] = [
|
|
'value' => $block->alias,
|
|
'enabled' => !!$block->default_enabled,
|
|
'readonly' => !!$block->readonly,
|
|
];
|
|
break;
|
|
|
|
case self::BLOCK_FUNCTIONAL:
|
|
$blockOptions['toggle'] = [
|
|
'value' => $block->type,
|
|
'enabled' => true,
|
|
'readonly' => true,
|
|
];
|
|
break;
|
|
|
|
case self::BLOCK_PREFERENCES:
|
|
case self::BLOCK_ANALYTICS:
|
|
case self::BLOCK_MARKETING:
|
|
case self::BLOCK_UNKNOWN:
|
|
$blockOptions['toggle'] = [
|
|
'value' => $block->type,
|
|
'enabled' => false,
|
|
'readonly' => false,
|
|
];
|
|
break;
|
|
}
|
|
|
|
if (isset($block->cookies) && !empty($block->cookies)) {
|
|
$cookieTable = [];
|
|
foreach ((array)$block->cookies as $cookie) {
|
|
$cookie = (object)$cookie;
|
|
$cookieOptions = [
|
|
'name' => $cookie->name,
|
|
'description' => $this->translateText($cookie->description ?? '') ?: ' ',
|
|
'is_regex' => !!($cookie->regex ?? false),
|
|
];
|
|
|
|
if ($this->params->get('show_cookie_provider', 1))
|
|
$cookieOptions['provider'] = $this->translateText($cookie->provider ?? '') ?: ' ';
|
|
|
|
if ($this->params->get('show_cookie_expiration', 1)) {
|
|
if (isset($cookie->expiration_unit) && !empty($cookie->expiration_unit))
|
|
$cookieOptions['expiration'] = $this->translateText('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_' . strtoupper($cookie->expiration_unit), (int)($cookie->expiration ?? ''));
|
|
else
|
|
$cookieOptions['expiration'] = $this->translateText($cookie->expiration ?? '') ?: ' ';
|
|
}
|
|
|
|
$cookieTable[] = $cookieOptions;
|
|
}
|
|
|
|
if ($cookieTable)
|
|
$blockOptions['cookie_table'] = $cookieTable;
|
|
}
|
|
|
|
$settingsModallanguage['blocks'][] = $blockOptions;
|
|
}
|
|
|
|
$language['settings_modal'] = $settingsModallanguage;
|
|
$options['languages'] = [
|
|
'default' => $language,
|
|
];
|
|
|
|
return $options;
|
|
}
|
|
|
|
/**
|
|
* Returns array containing CSS variables with custom colors
|
|
* @return array
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
private function styleOptions(): array
|
|
{
|
|
$colors = [];
|
|
|
|
foreach ($this->params as $name => $value) {
|
|
if (preg_match('~^color_~', $name) && $value) {
|
|
$name = '--cc-' . preg_replace('~^color_~', '', $name);
|
|
$name = str_replace('_', '-', $name);
|
|
$colors[$name] = $value;
|
|
}
|
|
}
|
|
|
|
return $colors;
|
|
}
|
|
|
|
/**
|
|
* returns array containing IFrameManager script settings
|
|
* @return array
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function iframeManagerOptions(): array
|
|
{
|
|
$services = [];
|
|
$service = [
|
|
'embedUrl' => '{data-id}',
|
|
'cookie' => [
|
|
'name' => $this->params->get('cookie_name', 'n3t_cc') . '_ifm_unknown',
|
|
'expiration' => (int)$this->params->get('cookie_expiration', 395),
|
|
],
|
|
'languages' => [
|
|
'default' => [
|
|
'notice' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_UNKNOWN'),
|
|
'loadBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_LOAD'),
|
|
'loadAllBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_ALWAYS'),
|
|
]
|
|
],
|
|
];
|
|
if ($thumb = $this->params->get('ifm_thumbnail')) {
|
|
if (Version::MAJOR_VERSION >= 4)
|
|
$thumb = HTMLHelper::cleanImageURL($thumb)->url;
|
|
$service['thumbnailUrl'] = Uri::base() . $thumb;
|
|
}
|
|
$services['unknown'] = $service;
|
|
|
|
$service = [
|
|
'embedUrl' => 'https://www.youtube-nocookie.com/embed/{data-id}',
|
|
'thumbnailUrl' => 'https://i3.ytimg.com/vi/{data-id}/hqdefault.jpg',
|
|
'cookie' => [
|
|
'name' => $this->params->get('cookie_name', 'n3t_cc') . '_ifm_youtube',
|
|
],
|
|
'languages' => [
|
|
'default' => [
|
|
'notice' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_YOUTUBE'),
|
|
'loadBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_LOAD'),
|
|
'loadAllBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_ALWAYS'),
|
|
]
|
|
],
|
|
];
|
|
$services['youtube'] = $service;
|
|
|
|
$service = [
|
|
'embedUrl' => 'https://player.vimeo.com/video/{data-id}',
|
|
'cookie' => [
|
|
'name' => $this->params->get('cookie_name', 'n3t_cc') . '_ifm_vimeo',
|
|
],
|
|
'languages' => [
|
|
'default' => [
|
|
'notice' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_VIMEO'),
|
|
'loadBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_LOAD'),
|
|
'loadAllBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_ALWAYS'),
|
|
]
|
|
],
|
|
];
|
|
$services['vimeo'] = $service;
|
|
|
|
$service = [
|
|
'embedUrl' => 'https://www.dailymotion.com/embed/video/{data-id}',
|
|
'cookie' => [
|
|
'name' => $this->params->get('cookie_name', 'n3t_cc') . '_ifm_dailymotion',
|
|
],
|
|
'languages' => [
|
|
'default' => [
|
|
'notice' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_DAILYMOTION'),
|
|
'loadBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_LOAD'),
|
|
'loadAllBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_ALWAYS'),
|
|
]
|
|
],
|
|
];
|
|
$services['dailymotion'] = $service;
|
|
|
|
$providers = (array)$this->params->get('ifm_services');
|
|
foreach ($providers as $provider) {
|
|
$provider = (array)$provider;
|
|
|
|
$service = [
|
|
'embedUrl' => '{data-id}',
|
|
'cookie' => [
|
|
'name' => $this->params->get('cookie_name', 'n3t_cc') . '_ifm_' . md5($provider['url']),
|
|
],
|
|
'languages' => [
|
|
'default' => [
|
|
'notice' => $provider['terms'] ? Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_GENERAL_TOS', $provider['terms'], $provider['name']) : Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_GENERAL', $provider['name']),
|
|
'loadBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_LOAD'),
|
|
'loadAllBtn' => Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_IFM_BTN_ALWAYS'),
|
|
]
|
|
],
|
|
];
|
|
if ($thumb = $provider['thumbnail']) {
|
|
if (Version::MAJOR_VERSION >= 4)
|
|
$thumb = HTMLHelper::cleanImageURL($thumb)->url;
|
|
$service['thumbnailUrl'] = Uri::base() . $thumb;
|
|
} elseif ($thumb = $this->params->get('ifm_thumbnail')) {
|
|
if (Version::MAJOR_VERSION >= 4)
|
|
$thumb = HTMLHelper::cleanImageURL($thumb)->url;
|
|
$service['thumbnailUrl'] = Uri::base() . $thumb;
|
|
}
|
|
$services[md5($provider['url'])] = $service;
|
|
}
|
|
|
|
|
|
$options = [
|
|
'currLang' => 'default',
|
|
'services' => $services,
|
|
];
|
|
|
|
return $options;
|
|
}
|
|
|
|
/**
|
|
* Resturns string with HTML code to insert after <head>
|
|
* @return string|null
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function htmlOutput(): ?string
|
|
{
|
|
$html = "\n";
|
|
|
|
$path = HTMLHelper::script('plg_n3tcookieconsent/n3tconsentmanager.min.js', ['pathOnly' => true, 'relative' => true]);
|
|
$path .= '?' . Factory::getDocument()->getMediaVersion();
|
|
$html.= '<script src="' . $path. '"></script>' . "\n";
|
|
|
|
if ($this->isTriggerVisible()) {
|
|
$trigger = $this->renderLayout('trigger', [
|
|
'params' => $this->params,
|
|
]);
|
|
} else
|
|
$trigger = false;
|
|
|
|
$params = [
|
|
'options' => $this->scriptOptions(),
|
|
'cookies' => $this->loadCookies(),
|
|
'trigger' => $trigger,
|
|
'params' => $this->params,
|
|
'isScanMode' => $this->isScanMode,
|
|
];
|
|
if ($this->params->get('use_iframe_manager', false))
|
|
$params['iframeManagerOptions'] = $this->iframeManagerOptions();
|
|
$script = $this->renderLayout('script', $params);
|
|
$html.= '<script>' . $script . '</script>' . "\n";
|
|
|
|
return $html;
|
|
}
|
|
|
|
/**
|
|
* Updates plugin settings in database
|
|
* @return bool
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
private function updateParams(): bool
|
|
{
|
|
$plugin = PluginHelper::getPlugin($this->_type, $this->_name);
|
|
|
|
if (strlen((string)$this->params) > pow(2,16) - 1)
|
|
return false;
|
|
|
|
$db = Factory::getDbo();
|
|
$query = $db->getQuery(true);
|
|
$query->update('#__extensions')
|
|
->set('params=' . $db->quote((string)$this->params))
|
|
->where('extension_id = ' . (int)$plugin->id);
|
|
|
|
try
|
|
{
|
|
$db->lockTable('#__extensions');
|
|
} catch (Exception $e) {
|
|
return false;
|
|
}
|
|
|
|
try {
|
|
$result = $db->setQuery($query)->execute();
|
|
} catch (Exception $e) {
|
|
$db->unlockTables();
|
|
return false;
|
|
}
|
|
|
|
$db->unlockTables();
|
|
$this->cookieList = null;
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Parse expiration string into expiration and expiration unit
|
|
*
|
|
* @param string $expirationStr
|
|
* @param string $expiration
|
|
* @param string $expirationUnit
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function parseExpiration(string $expirationStr, ?string &$expiration, ?string &$expirationUnit)
|
|
{
|
|
$expiration = $expirationStr;
|
|
$expirationUnit = '';
|
|
if ($this->isMultiLanguage)
|
|
{
|
|
switch (true) {
|
|
case strpos(strtolower($expiration), 'session') !== false:
|
|
$expiration = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_SESSION');
|
|
break;
|
|
case strpos(strtolower($expiration), 'various') !== false:
|
|
$expiration = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_VARIOUS');
|
|
break;
|
|
case strpos(strtolower($expiration), 'year') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'years';
|
|
break;
|
|
case strpos(strtolower($expiration), 'month') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'months';
|
|
break;
|
|
case strpos(strtolower($expiration), 'day') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'days';
|
|
break;
|
|
case strpos(strtolower($expiration), 'hour') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'hours';
|
|
break;
|
|
case strpos(strtolower($expiration), 'minute') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'minutes';
|
|
break;
|
|
case strpos(strtolower($expiration), 'second') !== false:
|
|
$expiration = (int)$expiration;
|
|
$expirationUnit = 'seconds';
|
|
break;
|
|
}
|
|
} else {
|
|
switch (true) {
|
|
case strpos(strtolower($expiration), 'session') !== false:
|
|
$expiration = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_SESSION');
|
|
break;
|
|
case strpos(strtolower($expiration), 'various') !== false:
|
|
$expiration = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_VARIOUS');
|
|
break;
|
|
case strpos(strtolower($expiration), 'year') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_YEARS', (int) $expiration);
|
|
break;
|
|
case strpos(strtolower($expiration), 'month') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_MONTHS', (int) $expiration);
|
|
break;
|
|
case strpos(strtolower($expiration), 'day') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_DAYS', (int) $expiration);
|
|
break;
|
|
case strpos(strtolower($expiration), 'hour') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_HOURS', (int) $expiration);
|
|
break;
|
|
case strpos(strtolower($expiration), 'minute') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_MINUTES', (int) $expiration);
|
|
break;
|
|
case strpos(strtolower($expiration), 'second') !== false:
|
|
$expiration = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_SECONDS', (int) $expiration);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Search cookie databases for cookie and return its description
|
|
*
|
|
* @param string $cookieName
|
|
*
|
|
* @return ?array
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function searchCookieDatabase(string $cookieName): ?array
|
|
{
|
|
$cookieData = null;
|
|
|
|
// Joomla cookie database
|
|
$lang = Factory::getApplication()->getLanguage();
|
|
if (($handle = fopen(__DIR__ . '/data/joomla.csv', "r")) !== false) {
|
|
while (($data = fgetcsv($handle)) !== false) {
|
|
if (count($data) < 7)
|
|
continue;
|
|
$name = $data[1];
|
|
$name = str_replace('(n3t_cc)', $this->params->get('cookie_name', 'n3t_cc'), $name);
|
|
if ((int)$data[3])
|
|
$name = ApplicationHelper::getHash($name);
|
|
if ((int)$data[4])
|
|
$name = md5($name);
|
|
if (!(int)$data[2] && $cookieName !== $name)
|
|
continue;
|
|
if ((int)$data[2] && !preg_match('~' . $name . '~', $cookieName))
|
|
continue;
|
|
|
|
$cookieData = [
|
|
'name' => $name,
|
|
'description' => $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_DATABASE_' . $data[5]),
|
|
'regex' => (int)$data[2],
|
|
'provider' => $this->multilang('SITENAME'),
|
|
'expiration' => $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_UNKNOWN'),
|
|
'category' => $data[6],
|
|
];
|
|
|
|
switch ($data[7]) {
|
|
case 'plugin':
|
|
$info = explode('|', $data[8]);
|
|
if (count($info) < 5)
|
|
break;
|
|
$plugin = PluginHelper::getPlugin($info[0], $info[1]);
|
|
if (!$plugin)
|
|
break;
|
|
$params = new Registry($plugin->params);
|
|
if ($this->isMultiLanguage) {
|
|
$cookieData['expiration'] = (int)$params->get($info[2], (int)$info[3]);
|
|
$cookieData['expiration_unit'] = $info[4];
|
|
} else
|
|
$cookieData['expiration'] = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_' . strtoupper($info[4]), (int)$params->get($info[2], (int)$info[3]));
|
|
break;
|
|
case 'session':
|
|
case 'various':
|
|
case 'unknown':
|
|
$cookieData['expiration'] = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_' . strtoupper($data[7]));
|
|
break;
|
|
default:
|
|
if ($this->isMultiLanguage) {
|
|
$cookieData['expiration'] = $data[7];
|
|
$cookieData['expiration_unit'] = $data[8];
|
|
} else
|
|
$cookieData['expiration'] = Text::plural('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_' . strtoupper($data[7]), (int)$data[8]);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
fclose($handle);
|
|
}
|
|
|
|
// Open cookie database
|
|
if (!$cookieData && (($handle = fopen(__DIR__ . '/data/open-cookie-database.csv', "r")) !== false)) {
|
|
while (($data = fgetcsv($handle)) !== false) {
|
|
if (count($data) < 10)
|
|
continue;
|
|
if (!(int)$data[9] && $cookieName !== $data[3])
|
|
continue;
|
|
if ((int)$data[9] && strpos($cookieName, $data[3]) !== 0)
|
|
continue;
|
|
|
|
$description = $data[5];
|
|
if ($lang->hasKey('PLG_SYSTEM_N3TCOOKIECONSENT_DATABASE_' . $data[0]))
|
|
$description = $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_DATABASE_' . $data[0]);
|
|
$this->parseExpiration($data[6], $expiration, $expirationUnit);
|
|
$cookieData = [
|
|
'name' => (int)$data[9] ? '^' . $data[3] : $data[3],
|
|
'description' => $description,
|
|
'regex' => (int)$data[9],
|
|
'provider' => $data[1],
|
|
'expiration' => $expiration,
|
|
'expiration_unit' => $expirationUnit,
|
|
];
|
|
|
|
switch (strtolower($data[2])) {
|
|
case 'functional': $cookieData['category'] = self::BLOCK_FUNCTIONAL; break;
|
|
case 'analytics': $cookieData['category'] = self::BLOCK_ANALYTICS; break;
|
|
case 'marketing': $cookieData['category'] = self::BLOCK_MARKETING; break;
|
|
default: $cookieData['category'] = self::BLOCK_HIDDEN; break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
fclose($handle);
|
|
}
|
|
|
|
// Unknown Cookie
|
|
if (!$cookieData) {
|
|
$cookieData = [
|
|
'name' => $cookieName,
|
|
'description' => $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_DESCRIPTION_UNKNOWN'),
|
|
'regex' => 0,
|
|
'provider' => $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_PROVIDER_UNKNOWN'),
|
|
'expiration' => $this->multilang('PLG_SYSTEM_N3TCOOKIECONSENT_SCAN_COOKIE_EXPIRATION_UNKNOWN'),
|
|
'category' => self::BLOCK_HIDDEN,
|
|
];
|
|
}
|
|
|
|
return $cookieData;
|
|
}
|
|
|
|
/**
|
|
* Adds new unknown Cookie to "Unknown" category
|
|
*
|
|
* @param string $cookieName
|
|
*
|
|
* @return bool
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
private function registerUnknownCookie(string $cookieName): bool
|
|
{
|
|
$cookieName = trim($cookieName);
|
|
|
|
if (!$cookieName)
|
|
return false;
|
|
|
|
if ($this->isCookieRegistered($cookieName))
|
|
return false;
|
|
|
|
if ($this->isScanMode) {
|
|
$scannedList = Factory::getApplication()->getSession()->get('n3tcc_scan_list', []);
|
|
if (!in_array($cookieName, $scannedList)) {
|
|
$scannedList[] = $cookieName;
|
|
Factory::getApplication()->getSession()->set('n3tcc_scan_list', $scannedList);
|
|
}
|
|
}
|
|
|
|
$this->debuggerCollectedCookies[] = $cookieName;
|
|
$cookieData = $this->searchCookieDatabase($cookieName);
|
|
if ($cookieData['category'] === self::SCAN_IGNORE)
|
|
return false;
|
|
|
|
$blocks = (array)$this->params->get('blocks', []);
|
|
$blockIndex = null;
|
|
foreach ($blocks as $index => $block) {
|
|
if ($block->type == $cookieData['category'] || isset($block->alias) && $block->alias == $cookieData['category']) {
|
|
$blockIndex = $index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($blockIndex !== null)
|
|
$block = $blocks[$blockIndex];
|
|
else {
|
|
$block = new stdClass();
|
|
$block->type = $cookieData['category'];
|
|
$block->alias = '';
|
|
$block->title = '';
|
|
$block->description = '';
|
|
|
|
$block->default_enabled = 0;
|
|
$block->readonly = 0;
|
|
$block->cookies = [];
|
|
$blocks[] = $block;
|
|
}
|
|
|
|
unset($cookieData['category']);
|
|
if (isset($block->cookies) && !empty($block->cookies))
|
|
$block->cookies = (array)$block->cookies;
|
|
else
|
|
$block->cookies = [];
|
|
$block->cookies[] = (object)$cookieData;
|
|
|
|
$this->params->set('blocks', $blocks);
|
|
$this->cookieList = null;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns log file based on params
|
|
*
|
|
* @return string
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
private function logFile(): string
|
|
{
|
|
return $this->params->get('log_consents_rotate') ? self::LOG_FILE : 'keep/' . self::LOG_FILE;
|
|
}
|
|
|
|
/**
|
|
* Joomla onBeforeRender Event
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
public function onBeforeRender()
|
|
{
|
|
$app = Factory::getApplication();
|
|
|
|
if ($this->isScanModeFinished) {
|
|
$script = "window.parent.postMessage('n3t_cookie_consent_finish_scan', '*');";
|
|
|
|
if (Version::MAJOR_VERSION < 4)
|
|
Factory::getDocument()->addScriptDeclaration($script);
|
|
else
|
|
{
|
|
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
|
|
$wa->addInlineScript($script);
|
|
}
|
|
}
|
|
|
|
if (!$app->isClient('administrator'))
|
|
return;
|
|
|
|
$hasDefinition = false;
|
|
$blocks = (array)$this->params->get('blocks', []);
|
|
foreach ($blocks as $block) {
|
|
if (isset($block->cookies) && !empty($block->cookies)) {
|
|
$hasDefinition = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$hasDefinition) {
|
|
$this->loadLanguage();
|
|
$plugin = PluginHelper::getPlugin($this->_type, $this->_name);
|
|
|
|
$app->enqueueMessage(Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_WARNING_SETUP_COOKIES_FIRST',
|
|
Route::_('index.php?option=com_plugins&view=plugin&task=plugin.edit&extension_id=' . $plugin->id)), 'warning');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $attrStr
|
|
*
|
|
* @return array
|
|
*
|
|
* @since 4.0.2
|
|
*/
|
|
private function parseHtmlAttributes(string $htmlCode, array &$debuggerData = []): array
|
|
{
|
|
$dom = new \DomDocument();
|
|
$dom->loadHTML($htmlCode);
|
|
$elem = $dom->getElementsByTagName('iframe')->item(0);
|
|
$attrs = [];
|
|
foreach ($elem->attributes as $name => $value)
|
|
$attrs[$name] = $value->textContent;
|
|
|
|
return $attrs;
|
|
}
|
|
|
|
/**
|
|
* Joomla onAfterRender Event
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAfterRender()
|
|
{
|
|
$app = Factory::getApplication();
|
|
if (!$this->isEnabled())
|
|
return;
|
|
|
|
$buffer = $app->getBody();
|
|
if (strpos($buffer, '<html') === false)
|
|
return;
|
|
|
|
$this->loadLanguage();
|
|
|
|
$html = $this->htmlOutput();
|
|
if ($html)
|
|
$buffer = preg_replace('~(<head(\s[^>]*)?>)~', '$1' . $html, $buffer);
|
|
|
|
if (strpos($buffer, '{n3tcookieconsent ') !== false)
|
|
$buffer = preg_replace('~{n3tcookieconsent\ssettings}([^{]*){/n3tcookieconsent}~', '<a href="#" aria-label="$1" class="cc-link" data-cc="c-settings">$1</a>', $buffer);
|
|
|
|
if ($this->params->get('youtube_nocookie', true)) {
|
|
if (strpos($buffer, '<iframe') !== false) {
|
|
$buffer = preg_replace_callback('~<iframe\s[^>]*?>~', function($matches) {
|
|
return preg_replace('~http(s)?://(www\.)?youtube\.com/~', 'http$1://www.youtube-nocookie.com/', $matches[0]);
|
|
}, $buffer);
|
|
}
|
|
}
|
|
|
|
if ($this->params->get('use_iframe_manager', false)) {
|
|
if (strpos($buffer, '<iframe') !== false) {
|
|
$buffer = preg_replace_callback('~<iframe(\s[^>]*)?>~', function($matches) {
|
|
$debuggerIframe = [
|
|
'code' => $matches[0],
|
|
];
|
|
|
|
$attributes = $this->parseHtmlAttributes($matches[0], $debuggerIframe);
|
|
$debuggerIframe['attributes'] = $attributes;
|
|
|
|
$service = '';
|
|
$id = '';
|
|
if (isset($attributes['src'])) {
|
|
$id = $attributes['src'];
|
|
unset($attributes['src']);
|
|
}
|
|
|
|
$debuggerIframe['processed'] = !!$id;
|
|
if (!$id) {
|
|
$this->debuggerIFrames[] = $debuggerIframe;
|
|
return $matches[0];
|
|
}
|
|
|
|
$uri = new Uri($id);
|
|
$domain = $uri->getHost();
|
|
|
|
if (!$domain || $domain == (new Uri(Uri::base()))->getHost()) {
|
|
$debuggerIframe['processed'] = false;
|
|
$this->debuggerIFrames[] = $debuggerIframe;
|
|
return $matches[0];
|
|
}
|
|
|
|
$providers = (array)$this->params->get('ifm_whitelist', []);
|
|
foreach ($providers as $provider) {
|
|
$provider = (array)$provider;
|
|
if (stripos($id, $provider['url']) === 0) {
|
|
$debuggerIframe['processed'] = false;
|
|
$this->debuggerIFrames[] = $debuggerIframe;
|
|
return $matches[0];
|
|
}
|
|
}
|
|
|
|
$providers = (array)$this->params->get('ifm_services', []);
|
|
foreach ($providers as $provider) {
|
|
$provider = (array)$provider;
|
|
if (stripos($id, $provider['url']) === 0)
|
|
$service = md5($provider['url']);
|
|
}
|
|
|
|
if (!$service && preg_match('~^(www\.)(youtube(-nocookie)?\.com|youtu.be)$~i', $domain)) {
|
|
$service = 'youtube';
|
|
$id = $uri->getPath();
|
|
$id = explode('/', $id);
|
|
$id = array_pop($id);
|
|
}
|
|
|
|
if (!$service && preg_match('~^player\.vimeo\.com$~i', $domain)) {
|
|
$service = 'vimeo';
|
|
$id = $uri->getPath();
|
|
$id = explode('/', $id);
|
|
$id = array_pop($id);
|
|
}
|
|
|
|
if (!$service && preg_match('~^(api|www)\.dailymotion\.com$~i', $domain)) {
|
|
$service = 'dailymotion';
|
|
$id = $uri->getPath();
|
|
$id = explode('/', $id);
|
|
$id = array_pop($id);
|
|
}
|
|
|
|
$service = $service ?: 'unknown';
|
|
|
|
$this->debuggerIFrames[] = $debuggerIframe;
|
|
return '<div data-service="' . $service . '" data-id="' . $id . '" data-autoscale data-attributes="' . htmlspecialchars(json_encode($attributes), ENT_QUOTES) . '"></div>';
|
|
}, $buffer);
|
|
}
|
|
}
|
|
|
|
$app->setBody($buffer);
|
|
}
|
|
|
|
/**
|
|
* n3tDebug onN3tDebugAddPanel Event
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onN3tDebugAddPanel()
|
|
{
|
|
if (!Factory::getApplication()->isClient('site'))
|
|
return null;
|
|
|
|
if (Version::MAJOR_VERSION == 3)
|
|
JLoader::registerNamespace('n3tCookieConsent', __DIR__ . DIRECTORY_SEPARATOR);
|
|
else
|
|
JLoader::registerNamespace('n3tCookieConsent', __DIR__ . DIRECTORY_SEPARATOR . 'n3tCookieConsent');
|
|
|
|
return new \n3tCookieConsent\Debug\Panel($this);
|
|
}
|
|
|
|
/**
|
|
* Helper function for debugger panel
|
|
*
|
|
* @return array
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function collectDebugData(): array
|
|
{
|
|
$data = [
|
|
'consent' => $this->getConsent()->toArray(),
|
|
'allowedCategories' => $this->allowedCategories(),
|
|
];
|
|
|
|
if ($this->debuggerBlockedCookies)
|
|
$data['blockedCookies'] = $this->debuggerBlockedCookies;
|
|
|
|
if ($this->isScanMode) {
|
|
$data['scanMode'] = true;
|
|
$data['reportCookie'] = $this->reportCookie;
|
|
$data['scannedList'] = Factory::getApplication()->getSession()->get('n3tcc_scan_list', []);
|
|
$data['collectedCookies'] = $this->debuggerCollectedCookies;
|
|
}
|
|
|
|
if ($this->debuggerIFrames)
|
|
$data['iframes'] = $this->debuggerIFrames;
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Joomla onBeforeCompileHead Event
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onBeforeCompileHead()
|
|
{
|
|
if (!$this->isEnabled())
|
|
return;
|
|
|
|
$this->loadLanguage();
|
|
|
|
HTMLHelper::script('plg_n3tcookieconsent/cookieconsent.min.js', ['version' => 'auto', 'relative' => true], ['defer' => true]);
|
|
HTMLHelper::stylesheet( 'plg_n3tcookieconsent/n3tconsentmanager.min.css', ['version' => 'auto', 'relative' => true]);
|
|
if ($this->params->get('use_iframe_manager', false)) {
|
|
HTMLHelper::script('plg_n3tcookieconsent/iframemanager.min.js', ['version' => 'auto', 'relative' => true], ['defer' => true]);
|
|
}
|
|
|
|
$style = $this->renderLayout('style', [
|
|
'styles' => $this->styleOptions(),
|
|
'params' => $this->params,
|
|
]);
|
|
$doc = Factory::getDocument();
|
|
$doc->addStyleDeclaration($style);
|
|
|
|
if ($this->isScanMode) {
|
|
$input = $this->getInput();
|
|
$needUpdate = false;
|
|
|
|
if ($this->reportCookie) {
|
|
foreach($this->reportCookie as $cookieName)
|
|
$needUpdate = $this->registerUnknownCookie($cookieName) || $needUpdate;
|
|
|
|
$appConfig = JFactory::getConfig();
|
|
$path = $this->params->get('cookie_path', $appConfig->get('cookie_path', '/'));
|
|
$domain = $this->params->get('cookie_domain', $appConfig->get('cookie_domain'));
|
|
if (!$domain)
|
|
$domain = '.' . $this->getInput()->server->get('SERVER_NAME');
|
|
$input->cookie->set($this->params->get('cookie_name', 'n3t_cc') . '_report', '', 1, $path, $domain);
|
|
}
|
|
|
|
$headers = headers_list();
|
|
foreach ($headers as $header) {
|
|
if (stripos($header, 'Set-Cookie:') === 0) {
|
|
$cookie = explode(';', trim(substr($header, 11)));
|
|
$cookie = explode('=', $cookie[0]);
|
|
if (count($cookie) === 2)
|
|
$needUpdate = $this->registerUnknownCookie($cookie[0]) || $needUpdate;
|
|
}
|
|
}
|
|
|
|
if ($needUpdate)
|
|
$this->updateParams();
|
|
}
|
|
|
|
// Block PHP cookies
|
|
$headers = headers_list();
|
|
$needUpdate = false;
|
|
foreach ($headers as $index => $header) {
|
|
if (stripos($header, 'Set-Cookie:') === 0) {
|
|
$cookie = explode(';', trim(substr($header, 11)));
|
|
|
|
foreach ($cookie as $value) {
|
|
$value = trim($value);
|
|
if (preg_match('~^expires=~i', $value)) {
|
|
$value = explode('=', trim($value));
|
|
$date = new \DateTime($value[1]);
|
|
$now = new DateTime();
|
|
if ($date < $now)
|
|
continue 2;
|
|
}
|
|
}
|
|
|
|
$cookie = explode('=', $cookie[0]);
|
|
if (count($cookie) === 2) {
|
|
$cookieName = trim($cookie[0]);
|
|
if (!$this->isCookieEnabled($cookieName)) {
|
|
$this->debuggerBlockedCookies[] = $cookieName;
|
|
unset($headers[$index]);
|
|
$needUpdate = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($needUpdate) {
|
|
header_remove();
|
|
foreach ($headers as $header)
|
|
header($header);
|
|
}
|
|
|
|
// TODO add scripts based on categories
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentExport
|
|
* Export plugin settings in JSON format
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentExport()
|
|
{
|
|
$app = Factory::getApplication();
|
|
if (!$app->isClient('administrator'))
|
|
return;
|
|
|
|
$user = JFactory::getUser();
|
|
if (!$user->authorise('core.edit', 'com_plugins'))
|
|
return;
|
|
|
|
$app->setHeader('Content-disposition', 'attachment; filename="n3t-cookie-consent.json"', true);
|
|
$app->setHeader('Content-Type', 'application/json', true);
|
|
|
|
echo $this->params->toString();
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentImport
|
|
* Import plugin settings in JSON format. Supported formats
|
|
* - export from plugin settings
|
|
* - export from CookieBot.com scan
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentImport()
|
|
{
|
|
$app = Factory::getApplication();
|
|
if (!$app->isClient('administrator'))
|
|
return;
|
|
|
|
$user = JFactory::getUser();
|
|
if (!$user->authorise('core.edit', 'com_plugins'))
|
|
return;
|
|
|
|
$this->loadLanguage();
|
|
$plugin = PluginHelper::getPlugin($this->_type, $this->_name);
|
|
|
|
$files = $this->getInput()->files->get('n3tcc');
|
|
if (!is_array($files) || !isset($files['import']) || $files['import']['error']) {
|
|
$app->enqueueMessage(Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CFG_IMPORT_ERROR_FILE'));
|
|
$app->redirect(Route::_('index.php?option=com_plugins&view=plugin&layout=edit&extension_id=' . $plugin->id, false));
|
|
return;
|
|
}
|
|
|
|
// TODO detekce chyby
|
|
$params = new Joomla\Registry\Registry(file_get_contents($files['import']['tmp_name']));
|
|
|
|
if ($params->get('privacy_policy_type')) {
|
|
// Plugin export
|
|
$this->params = $params;
|
|
|
|
$this->updateParams();
|
|
$app->enqueueMessage(Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CFG_IMPORT_SUCCESS'));
|
|
} elseif ($params->get('domain') && $params->get('cookies')) {
|
|
// CookieBot.com export
|
|
$blocks = [];
|
|
$blocks[0] = [
|
|
'type' => self::BLOCK_DESCRIPTION,
|
|
];
|
|
foreach ($params->get('cookies') as $cookie) {
|
|
if (!isset($blocks[(int)$cookie->Category])) {
|
|
$blocks[(int)$cookie->Category] = [
|
|
'type' => ['', self::BLOCK_FUNCTIONAL, self::BLOCK_PREFERENCES, self::BLOCK_ANALYTICS, self::BLOCK_MARKETING, self::BLOCK_UNKNOWN][(int)$cookie->Category],
|
|
'cookies' => [],
|
|
];
|
|
}
|
|
|
|
$this->parseExpiration($cookie->ExpireDescription, $expiration, $expirationUnit);
|
|
$blockCookie = [
|
|
'name' => $cookie->NamePattern ?: $cookie->Name,
|
|
'description' => $cookie->PurposeDescription,
|
|
'regex' => (int)!!$cookie->NamePattern,
|
|
'provider' => $cookie->Provider,
|
|
'expiration' => $expiration,
|
|
'expiration_unit' => $expirationUnit,
|
|
];
|
|
|
|
$blocks[(int)$cookie->Category]['cookies'][] = $blockCookie;
|
|
}
|
|
|
|
$blocks[1000] = [
|
|
'type' => self::BLOCK_PRIVACY,
|
|
];
|
|
|
|
$blocks[1001] = [
|
|
'type' => self::BLOCK_CONSENT,
|
|
];
|
|
|
|
$this->params->set('blocks', $blocks);
|
|
|
|
$this->updateParams();
|
|
$app->enqueueMessage(Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_CFG_IMPORT_SUCCESS_COOKIEBOT', $params->get('domain')));
|
|
} else {
|
|
|
|
$app->enqueueMessage(Text::_('PLG_SYSTEM_N3TCOOKIECONSENT_CFG_IMPORT_ERROR_FORMAT'));
|
|
}
|
|
|
|
$app->redirect(Route::_('index.php?option=com_plugins&view=plugin&layout=edit&extension_id=' . $plugin->id, false));
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentLogConsent
|
|
* Log user consent
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentLogConsent()
|
|
{
|
|
if ($this->params->get('log_consents', 1)) {
|
|
$this->loadLanguage();
|
|
|
|
Log::addLogger(
|
|
[
|
|
'text_file' => $this->logFile(),
|
|
'text_entry_format' => "{DATETIME}\t{CLIENTIP}\t{MESSAGE}"
|
|
],
|
|
JLog::ALL,
|
|
['n3t_cookie_consent']
|
|
);
|
|
|
|
$consent = $this->getConsent();
|
|
$categories = implode(',', $consent->get('level', []));
|
|
$guid = $consent->get('data.guid');
|
|
Log::add(Text::sprintf('PLG_SYSTEM_N3TCOOKIECONSENT_LOG_CONSENT', $categories, (int) $this->params->get('revision'), $guid), Log::INFO, 'n3t_cookie_consent');
|
|
}
|
|
|
|
// Clear unallowed cookies
|
|
$input = $this->getInput();
|
|
|
|
$appConfig = JFactory::getConfig();
|
|
$path = $appConfig->get('cookie_path', '/');
|
|
$domain = $appConfig->get('cookie_domain');
|
|
|
|
foreach($input->cookie->getArray() as $cookieName => $value) {
|
|
if (!$this->isCookieEnabled($cookieName)) {
|
|
$this->debuggerBlockedCookies[] = $cookieName;
|
|
$input->cookie->set($cookieName, '', 1, $path, $domain);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentDefaults
|
|
* Scan frontpage on Cookies
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentDefaults()
|
|
{
|
|
$this->loadLanguage();
|
|
|
|
$app = Factory::getApplication();
|
|
if (!$app->isClient('administrator'))
|
|
return;
|
|
|
|
$user = JFactory::getUser();
|
|
if (!$user->authorise('core.edit', 'com_plugins'))
|
|
return;
|
|
|
|
$blocks = [];
|
|
$blocks[] = (object)['type' => self::BLOCK_DESCRIPTION];
|
|
$blocks[] = (object)['type' => self::BLOCK_FUNCTIONAL];
|
|
$blocks[] = (object)['type' => self::BLOCK_PREFERENCES];
|
|
$blocks[] = (object)['type' => self::BLOCK_ANALYTICS];
|
|
$blocks[] = (object)['type' => self::BLOCK_MARKETING];
|
|
$blocks[] = (object)['type' => self::BLOCK_UNKNOWN];
|
|
$blocks[] = (object)['type' => self::BLOCK_HIDDEN];
|
|
$blocks[] = (object)['type' => self::BLOCK_SYSTEM];
|
|
$blocks[] = (object)['type' => self::BLOCK_PRIVACY];
|
|
$blocks[] = (object)['type' => self::BLOCK_CONSENT];
|
|
$this->params->set('blocks', $blocks);
|
|
$this->updateParams();
|
|
|
|
// Register basic cookies
|
|
$this->registerUnknownCookie($this->params->get('cookie_name', 'n3t_cc'));
|
|
if ($this->params->get('use_iframe_manager', false))
|
|
$this->registerUnknownCookie($this->params->get('cookie_name', 'n3t_cc') . '_ifm_');
|
|
$this->registerUnknownCookie(md5(ApplicationHelper::getHash('site')));
|
|
$this->registerUnknownCookie(md5(ApplicationHelper::getHash('administrator')));
|
|
|
|
$this->registerUnknownCookie('joomla_user_state');
|
|
$this->registerUnknownCookie(ApplicationHelper::getHash('PlgSystemLogout'));
|
|
if (PluginHelper::isEnabled('system', 'remember'))
|
|
$this->registerUnknownCookie('joomla_remember_me_');
|
|
|
|
if (Multilanguage::isEnabled())
|
|
$this->registerUnknownCookie('language');
|
|
|
|
// Register some core extensions
|
|
if (PluginHelper::isEnabled('captcha', 'recaptcha'))
|
|
$this->registerUnknownCookie('_GRECAPTCHA');
|
|
if (PluginHelper::isEnabled('captcha', 'recaptcha_invisible'))
|
|
$this->registerUnknownCookie('_GRECAPTCHA');
|
|
|
|
// Register some other known extensions
|
|
if (PluginHelper::isEnabled('captcha', 'n3tmulticaptcha'))
|
|
$this->registerUnknownCookie(ApplicationHelper::getHash('n3t_multicaptcha'));
|
|
if (PluginHelper::isEnabled('captcha', 'n3tmulticaptcha'))
|
|
$this->registerUnknownCookie(ApplicationHelper::getHash('n3t_multicaptcha'));
|
|
|
|
$this->updateParams();
|
|
|
|
$plugin = PluginHelper::getPlugin($this->_type, $this->_name);
|
|
$app->redirect(Route::_('index.php?option=com_plugins&view=plugin&layout=edit&extension_id=' . $plugin->id, false));
|
|
}
|
|
|
|
/**
|
|
* Joomla onContentPrepareForm Event
|
|
* @param $form
|
|
* @param $data
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onContentPrepareForm($form, $data)
|
|
{
|
|
if (!($form instanceof Form))
|
|
return;
|
|
if ($form->getName() != 'com_plugins.plugin')
|
|
return;
|
|
if (!is_object($data))
|
|
return;
|
|
if (!isset($data->extension_id))
|
|
return;
|
|
$plugin = PluginHelper::getPlugin($this->_type, $this->_name);
|
|
if ($data->extension_id != $plugin->id)
|
|
return;
|
|
|
|
$blocksField = $form->getField('blocks', 'params');
|
|
$subform = new SimpleXMLElement($blocksField->formsource);
|
|
|
|
if (!$this->params->get('show_cookie_provider', 1)) {
|
|
$node = $subform->xpath(".//field[@name='provider']");
|
|
unset($node[0][0]);
|
|
}
|
|
|
|
if (!$this->params->get('show_cookie_expiration', 1)) {
|
|
$node = $subform->xpath(".//field[@name='expiration']");
|
|
unset($node[0][0]);
|
|
}
|
|
|
|
if (!$this->params->get('show_cookie_expiration', 1) || !$this->isMultiLanguage) {
|
|
$node = $subform->xpath(".//field[@name='expiration_unit']");
|
|
unset($node[0][0]);
|
|
}
|
|
|
|
$form->setFieldAttribute('blocks', 'formsource', $subform->asXML(), 'params');
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentSetCookie
|
|
* Sets cookie value
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentSetCookie()
|
|
{
|
|
if (version_compare(phpversion(), '7.3.0', '<'))
|
|
return;
|
|
|
|
if (!$this->params->get('cookie_domains'))
|
|
return;
|
|
|
|
$app = Factory::getApplication();
|
|
$appConfig = JFactory::getConfig();
|
|
$value = $this->getInput()->get('val', '', 'string');
|
|
if (!$value)
|
|
return;
|
|
if (null === json_decode($value))
|
|
return;
|
|
|
|
$time = time() + (int)$this->params->get('cookie_expiration', '395') * 24 * 60 * 60;
|
|
$name = $this->params->get('cookie_name', 'n3t_cc');
|
|
$path = $this->params->get('cookie_path', $appConfig->get('cookie_path', '/'));
|
|
$domain = $this->params->get('cookie_domain', $appConfig->get('cookie_domain'));
|
|
if (!$domain)
|
|
$domain = '.' . $this->getInput()->server->get('SERVER_NAME');
|
|
|
|
setrawcookie($name, rawurlencode($value), [
|
|
'expires' => $time,
|
|
'path' => $path,
|
|
'domain' => $domain,
|
|
'secure' => $app->isSSLConnection(),
|
|
'httponly' => false,
|
|
'samesite' => 'None',
|
|
]);
|
|
|
|
$app->setHeader('Content-Type', 'image/svg+xml', true);
|
|
return '<svg xmlns="http://www.w3.org/2000/svg"/>';
|
|
}
|
|
|
|
/**
|
|
* Joomla Ajax Event
|
|
* index.php?option=com_ajax&group=system&format=raw&plugin=N3tCookieConsentExportLog
|
|
* Export consents log
|
|
*
|
|
* @throws Exception
|
|
* @since 4.0.0
|
|
*/
|
|
public function onAjaxN3tCookieConsentExportLog()
|
|
{
|
|
$app = Factory::getApplication();
|
|
if (!$app->isClient('administrator'))
|
|
return;
|
|
|
|
$user = JFactory::getUser();
|
|
if (!$user->authorise('core.edit', 'com_plugins'))
|
|
return;
|
|
|
|
$logFile = Factory::getApplication()->get('log_path', JPATH_ADMINISTRATOR . '/logs') . '/' . $this->logFile();
|
|
|
|
header('Content-disposition: attachment; filename="n3t-cookie-consent.log"', true);
|
|
header('Content-Type: text/plain; charset=UTF-8', true);
|
|
if (!file_exists($logFile)) {
|
|
header('Content-Length: 0', true);
|
|
return;
|
|
}
|
|
|
|
$size = filesize($logFile);
|
|
header('Content-Length: ' . $size, true);
|
|
readfile($logFile);
|
|
}
|
|
|
|
/**
|
|
* Renders Joomla Layout file with correct paths
|
|
*
|
|
* @param string $layoutFile
|
|
* @param array $displayData
|
|
*
|
|
* @since 4.1.5
|
|
*/
|
|
private function renderLayout(string $layoutFile, array $displayData = []): string {
|
|
ob_start();
|
|
require PluginHelper::getLayoutPath($this->_type, $this->_name, $layoutFile);
|
|
return ob_get_clean();
|
|
}
|
|
}
|