|
Server : Apache System : Linux s1230 5.15.0-139-generic #149~20.04.1 SMP Tue Jul 14 11:21:49 UTC 2026 x86_64 User : p141464 ( 418825) PHP Version : 7.4.33.12 Disable Function : NONE Directory : /html/relaunch-kmu/wp-content/plugins/real-cookie-banner/inc/ |
Upload File : |
<?php
namespace DevOwl\RealCookieBanner;
use DevOwl\RealCookieBanner\Vendor\DevOwl\CookieConsentManagement\consent\Transaction;
use DevOwl\RealCookieBanner\Vendor\DevOwl\CookieConsentManagement\settings\BannerLink as SettingsBannerLink;
use DevOwl\RealCookieBanner\Vendor\DevOwl\CookieConsentManagement\Utils as CookieConsentManagementUtils;
use DevOwl\RealCookieBanner\base\UtilsProvider;
use DevOwl\RealCookieBanner\settings\BannerLink;
use DevOwl\RealCookieBanner\settings\Revision;
use DevOwl\RealCookieBanner\view\Banner;
use DevOwl\RealCookieBanner\view\Blocker;
use DevOwl\RealCookieBanner\view\blocker\Plugin;
use WP_Error;
// @codeCoverageIgnoreStart
\defined('ABSPATH') or die('No script kiddies please!');
// Avoid direct file request
// @codeCoverageIgnoreEnd
/**
* Handle consents of "me".
* @internal
*/
class MyConsent
{
use UtilsProvider;
/**
* Singleton instance.
*
* @var MyConsent
*/
private static $me = null;
/**
* C'tor.
*/
private function __construct()
{
// Silence is golden.
}
/**
* Persist an user consent to the database.
*
* @param Transaction $transaction
* @param boolean $dummy If `true`, no data will saved in database
*/
public function persist($transaction, $dummy = \false)
{
global $wpdb;
$table_name_blocker_thumbnails = $this->getTableName(Plugin::TABLE_NAME_BLOCKER_THUMBNAILS);
$blockerThumbnail = $transaction->getBlockerThumbnail();
if (\is_string($blockerThumbnail)) {
$blockerThumbnailSplit = \explode('-', $blockerThumbnail, 2);
if (\count($blockerThumbnailSplit) > 1) {
$blockerThumbnail = $wpdb->get_var(
// phpcs:disable WordPress.DB.PreparedSQL
$wpdb->prepare("SELECT id FROM {$table_name_blocker_thumbnails} WHERE embed_id = %s AND file_md5 = %s", $blockerThumbnailSplit[0], $blockerThumbnailSplit[1])
);
// Blocker thumbnail does not exist - this cannot be the case (expect user deletes database table entries)
$blockerThumbnail = \is_numeric($blockerThumbnail) ? \intval($blockerThumbnail) : null;
} else {
$blockerThumbnail = null;
}
$transaction->setBlockerThumbnail($blockerThumbnail);
}
$consent = $this->getCurrentUser();
$previousDecision = $consent->getDecision() ?? \false;
$previousTcfString = $this->isPro() ? $consent->getTcfString() ?? \false : \false;
$previousGcmConsent = $this->isPro() ? $consent->getGcmConsent() ?? \false : \false;
$previousCreated = $consent->getCreated() ?? \false;
$revision = $consent->getCookieConsentManagement()->getRevision();
$revisionHash = $revision->create('force', \false)['hash'];
$revisionIndependentHash = $revision->createIndependent(\true)['hash'];
$ips = \DevOwl\RealCookieBanner\IpHandler::getInstance()->persistIp();
$contextString = $revision->getPersistence()->getContextVariablesString();
$transaction->setIpAddress(\DevOwl\RealCookieBanner\Utils::getIpAddress());
$result = $consent->commit($transaction, function () use($transaction, $ips, $consent, $revisionHash, $revisionIndependentHash, $contextString, $previousDecision, $previousTcfString, $previousGcmConsent, $dummy) {
global $wpdb;
if ($dummy) {
return 1;
}
$ipId = $this->persistIps($ips);
if (\is_wp_error($ipId)) {
return $ipId;
}
$urlIds = $this->persistUrls([$transaction->getReferer(), \DevOwl\RealCookieBanner\Utils::removeNonPermalinkQueryFromUrl($transaction->getReferer()), BannerLink::getInstance()->getLegalLink(SettingsBannerLink::PAGE_TYPE_LEGAL_NOTICE, 'url'), BannerLink::getInstance()->getLegalLink(SettingsBannerLink::PAGE_TYPE_PRIVACY_POLICY, 'url')]);
if (\is_wp_error($urlIds)) {
return $urlIds;
}
$decisionIds = $this->persistDecisions([$previousDecision === \false ? [] : $previousDecision, $consent->getDecision(), $previousGcmConsent === \false ? null : $previousGcmConsent, $consent->getGcmConsent() === null ? null : $consent->getGcmConsent()]);
if (\is_wp_error($decisionIds)) {
return $decisionIds;
}
$tcfStringIds = $this->persistTcfStrings([$previousTcfString === \false ? null : $previousTcfString, $consent->getTcfString()]);
if (\is_wp_error($tcfStringIds)) {
return $tcfStringIds;
}
$table_name = $this->getTableName(\DevOwl\RealCookieBanner\UserConsent::TABLE_NAME);
$table_name_revisions = $this->getTableName(Revision::TABLE_NAME);
$table_name_revisions_independent = $this->getTableName(Revision::TABLE_NAME_INDEPENDENT);
// phpcs:disable WordPress.DB.PreparedSQL
list($revisionId, $revisionIndependentId) = \array_map('intval', $wpdb->get_col($wpdb->prepare("SELECT id FROM {$table_name_revisions} WHERE `hash` = %s UNION ALL SELECT id FROM {$table_name_revisions_independent} WHERE `hash` = %s", $revisionHash, $revisionIndependentHash)));
// phpcs:enable WordPress.DB.PreparedSQL
if (!($revisionId > 0 && $revisionIndependentId > 0)) {
return new WP_Error('rcb_consent_commit_read_revision_failed');
}
$recorderJsonString = $transaction->getRecorderJsonString();
if (\is_string($recorderJsonString)) {
$recorderJsonString = CookieConsentManagementUtils::gzCompressForDatabase($recorderJsonString, $recorderJsonString);
} else {
$recorderJsonString = 'NULL';
}
$wpdb->query(
// phpcs:disable WordPress.DB.PreparedSQL
\str_ireplace("'NULL'", 'NULL', $wpdb->prepare("INSERT IGNORE INTO {$table_name}\n (plugin_version, design_version,\n ip, uuid, revision, revision_independent,\n previous_decision, decision,\n blocker, blocker_thumbnail,\n dnt, custom_bypass,\n button_clicked, context, viewport_width, viewport_height,\n referer, pure_referer, url_imprint, url_privacy_policy,\n forwarded, forwarded_blocker,\n user_country,\n previous_tcf_string, tcf_string,\n previous_gcm_consent, gcm_consent,\n recorder, ui_view, created, created_client_time)\n VALUES\n (%s, %d,\n %s, %s, %s, %s,\n %s, %s,\n %s, %s,\n %s, %s,\n %s, %s, %s, %s,\n %s, %s, %s, %s,\n %s, %s,\n %s,\n %s, %s,\n %s, %s,\n %s, %s, %s, %s)", RCB_VERSION, Banner::DESIGN_VERSION, $ipId, $consent->getUuid(), $revisionId, $revisionIndependentId, $decisionIds[0], $decisionIds[1], $transaction->getBlocker() > 0 ? $transaction->getBlocker() : 'NULL', $transaction->getBlockerThumbnail() > 0 ? $transaction->getBlockerThumbnail() : 'NULL', $transaction->isMarkAsDoNotTrack(), $transaction->getCustomBypass() === null ? 'NULL' : $transaction->getCustomBypass(), $transaction->getButtonClicked(), $contextString, $transaction->getViewPortWidth(), $transaction->getViewPortHeight(), $urlIds[0] === null ? 'NULL' : $urlIds[0], $urlIds[1] === null ? 'NULL' : $urlIds[1], $urlIds[2] === null ? 'NULL' : $urlIds[2], $urlIds[3] === null ? 'NULL' : $urlIds[3], $transaction->getForwarded() > 0 ? $transaction->getForwarded() : 'NULL', $transaction->isForwardedBlocker(), $transaction->getUserCountry() ?? 'NULL', $tcfStringIds[0] === null ? 'NULL' : $tcfStringIds[0], $tcfStringIds[1] === null ? 'NULL' : $tcfStringIds[1], $decisionIds[2] === null ? 'NULL' : $decisionIds[2], $decisionIds[3] === null ? 'NULL' : $decisionIds[3], $recorderJsonString, $transaction->getUiView() === null ? 'NULL' : $transaction->getUiView(), \mysql2date('c', \current_time('mysql'), \false), \is_string($transaction->getCreatedClientTime()) ? \mysql2date('c', $transaction->getCreatedClientTime(), \false) : 'NULL'))
);
return $wpdb->insert_id;
});
if ($result === \false) {
return new WP_Error('rcb_consent_commit_failed');
}
// Set cookies on browser
foreach ($result['setCookie'] as $i => $setCookie) {
$setCookieResult = \DevOwl\RealCookieBanner\Utils::setCookie($setCookie->key, $setCookie->value, $setCookie->expire, \constant('COOKIEPATH'), \constant('COOKIE_DOMAIN'), \is_ssl(), \false, 'None');
if (!$dummy && $setCookieResult && $i === 0) {
/**
* Real Cookie Banner saved the cookie which holds information about the user with
* UUID, revision and consent choices.
*
* @hook RCB/Consent/SetCookie
* @param {string} $cookieName
* @param {string} $cookieValue
* @param {boolean} $result Got the cookie successfully created?
* @param {boolean} $revoke `true` if the cookie should be deleted
* @param {string|null} $uuid
* @param {string[]} $uuids Since v3 multiple consent UUIDs are saved to the database
* @param {array}
* @since 2.0.0
* @deprecated This will removed in a future release!
*/
\do_action('RCB/Consent/SetCookie', $setCookie->key, $setCookie->value, \true, \false, $consent->getUuid(), \array_merge([$consent->getUuid()], $consent->getPreviousUuids() ?? []));
}
}
// Persist stats (only when not forwarded)
if (!$dummy && $transaction->getForwarded() === 0) {
$stats = \DevOwl\RealCookieBanner\Stats::getInstance();
$stats->persistTerm($contextString, $transaction->getDecision(), $previousDecision, $previousCreated);
$stats->persistButtonClicked($contextString, $transaction->getButtonClicked());
if ($transaction->getButtonClicked() !== Blocker::BUTTON_CLICKED_IDENTIFIER) {
$stats->persistCustomBypass(
$contextString,
// Save DNT also as custom_bypass
$transaction->getCustomBypass() === null ? $transaction->isMarkAsDoNotTrack() ? 'dnt' : null : $transaction->getCustomBypass()
);
}
}
// Backwards-compatibility for RCB/Consent/Created filter
$filterResult = ['uuid' => $consent->getUuid(), 'previous_uuids' => $consent->getPreviousUuids(), 'created' => \is_numeric($consent->getCreated()) ? \mysql2date('c', \gmdate('Y-m-d H:i:s', \intval($consent->getCreated())), \false) : null, 'cookie_revision' => $revisionHash, 'decision_in_cookie' => $consent->getDecision(), 'updated' => \true, 'consent_id' => $result['response']['consentId']];
if (!$dummy) {
\DevOwl\RealCookieBanner\UserConsent::getInstance()->scheduleDeletionOfConsents();
/**
* An user has given a new consent.
*
* @hook RCB/Consent/Created
* @param {array} $result
* @param {array} $args Passed arguments to `MyConsent::persist` as map (since 2.0.0)
* @param {Transaction} $transaction The full transaction representing the new consent (since 4.4.2), use this instead of `$args`
*/
\do_action('RCB/Consent/Created', $filterResult, [$transaction->getDecision(), $transaction->isMarkAsDoNotTrack(), $transaction->getButtonClicked(), $transaction->getViewPortWidth(), $transaction->getViewPortHeight(), $transaction->getReferer(), $transaction->getBlocker(), $transaction->getBlockerThumbnail(), $transaction->getForwarded(), $transaction->getForwardedUuid(), $transaction->isForwardedBlocker(), $transaction->getTcfString(), $transaction->getGcmConsent(), $transaction->getCustomBypass(), $transaction->getRecorderJsonString(), $transaction->getUiView()], $transaction);
}
return $result['response'];
}
/**
* Persist the IPs of the current user.
*
* @param array $ips
*/
protected function persistIps($ips)
{
global $wpdb;
$table_name = $this->getTableName(\DevOwl\RealCookieBanner\UserConsent::TABLE_NAME_IP);
// phpcs:disable WordPress.DB.PreparedSQL
$wpdb->query(\str_ireplace("'NULL'", 'NULL', $wpdb->prepare(
// Do not use INSERT IGNORE here because it increments AUTO_INCREMENT (https://www.perplexity.ai/search/in-mysql-when-using-insert-ign-fsJfL5IpRoKYLVEBjDksyw)
"INSERT INTO {$table_name} (ipv4, ipv6, save_ip, ipv4_hash, ipv6_hash) VALUES (%s, %s, %d, %s, %s) ON DUPLICATE KEY UPDATE ipv4 = VALUES(ipv4), ipv6 = VALUES(ipv6), save_ip = VALUES(save_ip), ipv4_hash = VALUES(ipv4_hash), ipv6_hash = VALUES(ipv6_hash)",
$ips['ipv4'] === null ? 'NULL' : $ips['ipv4'],
$ips['ipv6'] === null ? 'NULL' : $ips['ipv6'],
$ips['save_ip'] ? 1 : 0,
$ips['ipv4_hash'] === null ? '' : $ips['ipv4_hash'],
$ips['ipv6_hash'] === null ? '' : $ips['ipv6_hash']
)));
// phpcs:enable WordPress.DB.PreparedSQL
$rowId = $wpdb->insert_id;
if ($rowId < 1) {
// The row already exists and we got no last_insert_id, so we need to read the row
// phpcs:disable WordPress.DB.PreparedSQL
$rowId = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$table_name} WHERE save_ip = %d AND ipv4_hash = %s AND ipv6_hash = %s", $ips['save_ip'] ? 1 : 0, $ips['ipv4_hash'] === null ? '' : $ips['ipv4_hash'], $ips['ipv6_hash'] === null ? '' : $ips['ipv6_hash']));
// phpcs:enable WordPress.DB.PreparedSQL
}
return \is_numeric($rowId) ? \intval($rowId) : new WP_Error('rcb_consent_ip_commit_failed');
}
/**
* Persist a list of URLs.
*
* @param string[] $urls
*/
protected function persistUrls($urls)
{
global $wpdb;
if (empty($urls)) {
return [];
}
$table_name = $this->getTableName(\DevOwl\RealCookieBanner\UserConsent::TABLE_NAME_URL);
$sqlValues = [];
$validUrls = [];
foreach ($urls as $url) {
if (!empty($url)) {
$hash = \md5($url);
$sqlValues[] = $wpdb->prepare('(%s, %s)', $hash, $url);
$validUrls[] = $url;
}
}
// phpcs:disable WordPress.DB
$queryResult = \count($sqlValues) > 0 ? $wpdb->query(\str_ireplace(
"'NULL'",
'NULL',
// Do not use INSERT IGNORE here because it increments AUTO_INCREMENT (https://www.perplexity.ai/search/in-mysql-when-using-insert-ign-fsJfL5IpRoKYLVEBjDksyw)
"INSERT INTO {$table_name} (`hash`, `url`) VALUES " . \implode(',', $sqlValues) . ' ON DUPLICATE KEY UPDATE `url` = VALUES(`url`)'
)) : [];
// phpcs:enable WordPress.DB
if ($queryResult === \false) {
return new WP_Error('rcb_consent_url_commit_failed');
}
// phpcs:disable WordPress.DB
$rows = \count($validUrls) > 0 ? $wpdb->get_results("SELECT `hash`, id FROM {$table_name} WHERE `hash` IN (" . \implode(',', \array_map(function ($url) {
return \sprintf("'%s'", \md5($url));
}, $validUrls)) . ')', ARRAY_A) : [];
// phpcs:enable WordPress.DB
$hashes = \array_column($rows, 'hash');
$result = [];
foreach ($urls as $url) {
if (!empty($url)) {
$idx = \array_search(\md5($url), $hashes, \true);
$result[] = $idx !== \false ? \intval($rows[$idx]['id']) : null;
} else {
$result[] = null;
}
}
return $result;
}
/**
* Persist a list of decisions. This could be used for example to persist the decisions of a Real
* Cookie Banner decision or Google Consent Mode decision.
*
* @param array $decisions
*/
protected function persistDecisions($decisions)
{
global $wpdb;
if (empty($decisions)) {
return [];
}
$table_name = $this->getTableName(\DevOwl\RealCookieBanner\UserConsent::TABLE_NAME_DECISION);
$sqlValues = [];
$validDecisions = [];
foreach ($decisions as $decision) {
if (\is_array($decision)) {
$json = \json_encode($decision);
$hash = \md5($json);
$sqlValues[] = $wpdb->prepare('(%s, %s)', $hash, $json);
$validDecisions[] = $decision;
}
}
// phpcs:disable WordPress.DB
$queryResult = \count($sqlValues) > 0 ? $wpdb->query(\str_ireplace(
"'NULL'",
'NULL',
// Do not use INSERT IGNORE here because it increments AUTO_INCREMENT (https://www.perplexity.ai/search/in-mysql-when-using-insert-ign-fsJfL5IpRoKYLVEBjDksyw)
"INSERT INTO {$table_name} (`hash`, `decision`) VALUES " . \implode(',', $sqlValues) . ' ON DUPLICATE KEY UPDATE `decision` = VALUES(`decision`)'
)) : [];
// phpcs:enable WordPress.DB
if ($queryResult === \false) {
return new WP_Error('rcb_consent_decision_commit_failed');
}
// phpcs:disable WordPress.DB
$rows = \count($validDecisions) > 0 ? $wpdb->get_results("SELECT `hash`, id FROM {$table_name} WHERE `hash` IN (" . \implode(',', \array_map(function ($decision) {
return \sprintf("'%s'", \md5(\json_encode($decision)));
}, $validDecisions)) . ')', ARRAY_A) : [];
// phpcs:enable WordPress.DB
$hashes = \array_column($rows, 'hash');
$result = [];
foreach ($decisions as $decision) {
if (\is_array($decision)) {
$idx = \array_search(\md5(\json_encode($decision)), $hashes, \true);
$result[] = $idx !== \false ? \intval($rows[$idx]['id']) : null;
} else {
$result[] = null;
}
}
return $result;
}
/**
* Persist a list of TCF strings.
*
* @param string[] $tcfStrings
*/
protected function persistTcfStrings($tcfStrings)
{
global $wpdb;
if (empty($tcfStrings)) {
return [];
}
$table_name = $this->getTableName(\DevOwl\RealCookieBanner\UserConsent::TABLE_NAME_TCF_STRING);
$sqlValues = [];
$validTcfStrings = [];
foreach ($tcfStrings as $tcfString) {
if (!empty($tcfString)) {
$hash = \md5($tcfString);
$sqlValues[] = $wpdb->prepare('(%s, %s)', $hash, $tcfString);
$validTcfStrings[] = $tcfString;
}
}
// phpcs:disable WordPress.DB
$queryResult = \count($sqlValues) > 0 ? $wpdb->query(\str_ireplace(
"'NULL'",
'NULL',
// Do not use INSERT IGNORE here because it increments AUTO_INCREMENT (https://www.perplexity.ai/search/in-mysql-when-using-insert-ign-fsJfL5IpRoKYLVEBjDksyw)
"INSERT INTO {$table_name} (`hash`, `tcf_string`) VALUES " . \implode(',', $sqlValues) . ' ON DUPLICATE KEY UPDATE `tcf_string` = VALUES(`tcf_string`)'
)) : [];
// phpcs:enable WordPress.DB
if ($queryResult === \false) {
return new WP_Error('rcb_consent_tcf_string_commit_failed');
}
// phpcs:disable WordPress.DB
$rows = \count($validTcfStrings) > 0 ? $wpdb->get_results("SELECT `hash`, id FROM {$table_name} WHERE `hash` IN (" . \implode(',', \array_map(function ($tcfString) {
return \sprintf("'%s'", \md5($tcfString));
}, $validTcfStrings)) . ')', ARRAY_A) : [];
// phpcs:enable WordPress.DB
$hashes = \array_column($rows, 'hash');
$result = [];
foreach ($tcfStrings as $tcfString) {
if (!empty($tcfString)) {
$idx = \array_search(\md5($tcfString), $hashes, \true);
$result[] = $idx !== \false ? \intval($rows[$idx]['id']) : null;
} else {
$result[] = null;
}
}
return $result;
}
/**
* Get's the current user from the cookie.
*/
public function getCurrentUser()
{
$consent = \DevOwl\RealCookieBanner\Core::getInstance()->getCookieConsentManagement()->startConsent();
$consent->setCurrentCookies($_COOKIE);
return $consent;
}
/**
* Get the history of the current user.
*/
public function getCurrentHistory()
{
$user = $this->getCurrentUser();
$result = [];
if (!empty($user->getUuid())) {
$rows = \DevOwl\RealCookieBanner\UserConsent::getInstance()->byCriteria(['revisionJson' => \true, 'context' => Revision::getInstance()->getContextVariablesString(), 'perPage' => 100, 'uuids' => \array_merge([$user->getUuid()], $user->getPreviousUuids())]);
foreach ($rows as $row) {
$result[] = \DevOwl\RealCookieBanner\Core::getInstance()->getCookieConsentManagement()->getFrontend()->persistedTransactionToJsonForHistoryViewer(\DevOwl\RealCookieBanner\UserConsent::getInstance()->toPersistedTransactionInstance($row));
}
}
return $result;
}
/**
* Get singleton instance.
*
* @codeCoverageIgnore
*/
public static function getInstance()
{
return self::$me === null ? self::$me = new \DevOwl\RealCookieBanner\MyConsent() : self::$me;
}
}