File Manager
Viewing File: geo.php
<?php
namespace CookieAdminPro\Admin;
if(!defined('COOKIEADMIN_PRO_VERSION') || !defined('ABSPATH')){
die('Hacking Attempt');
}
class Geo{
static function geo_admin_page(){
\CookieAdmin\Admin::header_theme(__('Geo Targeting', 'cookieadmin'));
$geo_enabled = get_option('cookieadmin_geo_enabled', false);
$db_data = get_option('cookieadmin_pro_geo_target_db_download', []);
if(!empty($db_data['filename']) && !empty($db_data['time'])){
$wp_upload_dir_info = wp_upload_dir();
$upload_dir = $wp_upload_dir_info['basedir'] . '/cookieadmin/';
$db_data['db_exists'] = file_exists($upload_dir . $db_data['filename']);
}
$rules = get_option('cookieadmin_geo_rules', []);
$countries = include(COOKIEADMIN_PRO_DIR . 'lib/locations.php');
$laws = apply_filters('cookieadmin_geo_law_options', [
'cookieadmin_gdpr' => __('GDPR', 'cookieadmin'),
'cookieadmin_us' => __('US State Laws', 'cookieadmin'),
]);
echo '<div class="cookieadmin-geo-page">';
echo '<div id="cookieadmin_geo_notice" class="cookieadmin-geo-notice"></div>';
// Enable/Disable Toggle
echo '<div class="cookieadmin-geo-enable-section-con"><div class="cookieadmin-geo-enable-section">
<div>
<p class="cookieadmin-geo-enable-label">' . esc_html__('Enable Geo Targeting', 'cookieadmin') . '</p>
<p class="cookieadmin-geo-enable-desc">' . esc_html__('When enabled, visitors will see the consent banner based on their geographic location.', 'cookieadmin') . '</p>
<p class="cookieadmin-geo-enable-desc">' . esc_html__('When disabled, visitors will see the default consent banner.', 'cookieadmin') . '</p>
</div>
<label class="cookieadmin-toggle-wrap">
<input type="checkbox" id="cookieadmin_geo_enabled_toggle" ' . checked($geo_enabled, true, false) . '>
<span class="cookieadmin-toggle-track"><span class="cookieadmin-toggle-thumb"></span></span>
</label>
</div>';
// Enable/Disable Toggle
echo '<div class="cookieadmin-geo-enable-section">
<div>
<p class="cookieadmin-geo-enable-label">' . esc_html__('Download Country Database', 'cookieadmin') . '</p>
<p class="cookieadmin-geo-enable-desc">' . esc_html__('Country database file helps us to detect the end user\'s country accurately.', 'cookieadmin') . '</p>
<p>
<span class="cookieadmin-geo-db-avl" '.(empty($db_data['db_exists']) ? 'style="display:none;"' : '').'>'.esc_html__('Last Database Updated At : ', 'cookieadmin').'
<span class="cookieadmin-geo-db-download-time">'.(!empty($db_data['time']) ? wp_date('Y-m-d h:i:s', $db_data['time']) : '').'</span>
</span>
<span class="cookieadmin-geo-no-db" '.(!empty($db_data['db_exists']) ? 'style="display:none;"' : '').'>'.esc_html__('Database does not exists. download now!', 'cookieadmin').'</span>
</p>
</div>
<div class="cookieadmin-geo-db-download">
<input type="button" class="cookieadmin-btn cookieadmin-btn-primary" value="'.((!empty($db_data['filename']) && !empty($db_data['db_exists'])) ? esc_html__('Update Database', 'cookieadmin') : esc_html__('Download Database', 'cookieadmin')).'" id="cookieadmin-geo-download-db-btn">
</div>
</div></div>';
// Presets Section
echo '<div class="cookieadmin-geo-presets">
<p class="cookieadmin-geo-presets-title">' . esc_html__('Add GEO Targetting Rules', 'cookieadmin') . '</p>
<div class="cookieadmin-geo-presets-grid">
<button type="button" class="cookieadmin-geo-preset-btn cookieadmin-geo-preset-gdpr" data-preset="gdpr">
<span class="cookieadmin-geo-preset-icon"><span class="dashicons dashicons-privacy"></span></span>
<span class="cookieadmin-geo-preset-label">' . esc_html__('GDPR Rule', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-desc">' . esc_html__('Europe + EEA countries', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-add"><span class="dashicons dashicons-plus-alt2"></span> ' . esc_html__('Add Rule', 'cookieadmin') . '</span>
</button>
<button type="button" class="cookieadmin-geo-preset-btn cookieadmin-geo-preset-us" data-preset="us">
<span class="cookieadmin-geo-preset-icon"><span class="dashicons dashicons-flag"></span></span>
<span class="cookieadmin-geo-preset-label">' . esc_html__('US State Laws', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-desc">' . esc_html__('United States', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-add"><span class="dashicons dashicons-plus-alt2"></span> ' . esc_html__('Add Rule', 'cookieadmin') . '</span>
</button>
<button type="button" class="cookieadmin-geo-preset-btn cookieadmin-geo-preset-us" data-preset="custom">
<span class="cookieadmin-geo-preset-icon"><span class="dashicons dashicons-admin-settings"></span></span>
<span class="cookieadmin-geo-preset-label">' . esc_html__('Add Custom Rule', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-desc">' . esc_html__('Choose countries', 'cookieadmin') . '</span>
<span class="cookieadmin-geo-preset-add"><span class="dashicons dashicons-plus-alt2"></span> ' . esc_html__('Add Rule', 'cookieadmin') . '</span>
</button>
</div>
</div>';
// Modal Form (hidden by default)
echo '<div id="cookieadmin_geo_modal" class="cookieadmin_modal-overlay">';
echo '<div class="cookieadmin_modal-container cookieadmin-geo-modal">';
self::render_card_form($countries, $laws);
echo '</div>';
echo '</div>';
// Rules Table
echo '<div id="cookieadmin_geo_table_wrap" style="margin-bottom:16px;">';
self::render_rules_table($rules, $countries, $laws);
echo '</div>';
// Empty State
$empty_display = empty($rules) ? 'block' : 'none';
echo '<div id="cookieadmin_geo_empty_state" class="cookieadmin-geo-empty" style="display:' . esc_attr($empty_display) . ';">
<div class="cookieadmin-geo-empty-icon"><span class="dashicons dashicons-location-alt"></span></div>
<p>' . esc_html__('No geo targeting rules configured yet.', 'cookieadmin') . '</p>
<p>' . esc_html__('Use the presets above or add a custom rule.', 'cookieadmin') . '</p>
</div>';
echo '</div>'; // .cookieadmin-geo-page
\CookieAdmin\Admin::footer_theme();
}
static function render_card_form($countries, $laws){
$law_options = '';
foreach($laws as $key => $label){
$law_options .= '<option value="' . esc_attr($key) . '">' . esc_html($label) . '</option>';
}
$country_options = '';
foreach($countries['countries'] as $code => $name){
$country_options .= '<option value="' . esc_attr($code) . '">' . esc_html($code . ' - ' . $name) . '</option>';
}
echo '<div class="cookieadmin_modal-header">
<span class="cookieadmin_modal-title cookieadmin-geo-modal-title">' . esc_html__('Rule Configuration', 'cookieadmin') . '</span>
<button type="button" class="cookieadmin_dialog_modal_close_btn" id="cookieadmin_geo_modal_close">×</button>
<input type="hidden" id="cookieadmin_geo_card_id" value="">
</div>
<div class="cookieadmin_modal-body">
<!-- Rule Name -->
<div class="cookieadmin_form-group">
<label for="cookieadmin_geo_card_name">' . esc_html__('Rule Name', 'cookieadmin') . '</label>
<input type="text" id="cookieadmin_geo_card_name" value="" placeholder="' . esc_attr__('e.g. GDPR Countries', 'cookieadmin') . '" style="width:100%;">
</div>
<!-- Law Type -->
<div class="cookieadmin_form-group">
<label for="cookieadmin_geo_card_law">' . esc_html__('Law Type', 'cookieadmin') . '</label>
<select id="cookieadmin_geo_card_law" style="width:100%;">
<option disabled>' . esc_html__('Select Law Type', 'cookieadmin') . '</option>
<option value="">'.esc_html__('None', 'cookieadmin').'</option>
' . $law_options . '
</select>
</div>
<!-- Countries -->
<div class="cookieadmin_form-group">
<label>' . esc_html__('Countries', 'cookieadmin') . '</label>
<div id="cookieadmin_geo_card_tags" class="cookieadmin-geo-country-tags"></div>
<select id="cookieadmin_geo_card_country_select" style="width:100%; margin-top:8px;">
<option value="">' . esc_html__('+ Add Country', 'cookieadmin') . '</option>
' . $country_options . '
</select>
<div class="cookieadmin-geo-shortcuts">
<span class="cookieadmin-geo-shortcuts-label">' . esc_html__('Shortcuts:', 'cookieadmin') . '</span>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="eu">' . esc_html__('EU', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="eea">' . esc_html__('EEA', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="africa">' . esc_html__('Africa', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="asia">' . esc_html__('Asia', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="europe">' . esc_html__('Europe', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="north_america">' . esc_html__('North America', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="south_america">' . esc_html__('South America', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="oceania">' . esc_html__('Oceania', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="caribbean">' . esc_html__('Caribbean', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn" data-continent="asean">' . esc_html__('ASEAN', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-shortcut-btn cookieadmin-geo-shortcut-worldwide" data-continent="worldwide">' . esc_html__('Worldwide', 'cookieadmin') . '</button>
</div>
</div>
<!-- Feature Overrides -->
<div class="cookieadmin_form-group">
<label>' . esc_html__('Feature Overrides', 'cookieadmin') . '
<span class="dashicons dashicons-info cookieadmin-tooltip-box" data-tip="' . esc_attr__('Inherit uses the global setting. On/Off overrides for this rule.', 'cookieadmin') . '"></span>
</label>
<div class="cookieadmin-grid-2" style="gap:12px;">
<div class="cookieadmin-vertical">
<span class="cookieadmin-text-muted" style="font-size:12px; font-weight:500;">' . esc_html__('Block Scripts', 'cookieadmin') . '</span>
' . self::render_toggle_html('card', 'block_scripts', 'inherit') . '
</div>
<div class="cookieadmin-vertical">
<span class="cookieadmin-text-muted" style="font-size:12px; font-weight:500;">' . esc_html__('Content Blocking', 'cookieadmin') . '</span>
' . self::render_toggle_html('card', 'content_blocking', 'inherit') . '
</div>
<div class="cookieadmin-vertical">
<span class="cookieadmin-text-muted" style="font-size:12px; font-weight:500;">' . esc_html__('Google Consent Mode', 'cookieadmin') . '</span>
' . self::render_toggle_html('card', 'google_consent_mode_v2', 'inherit') . '
</div>
<div class="cookieadmin-vertical">
<span class="cookieadmin-text-muted" style="font-size:12px; font-weight:500;">' . esc_html__('Clarity Consent', 'cookieadmin') . '</span>
' . self::render_toggle_html('card', 'clarity_consent', 'inherit') . '
</div>
</div>
</div>
</div>
<div class="cookieadmin_modal-footer">
<button type="button" id="cookieadmin_geo_card_cancel" class="cookieadmin-btn cookieadmin-btn-secondary">' . esc_html__('Cancel', 'cookieadmin') . '</button>
<button type="button" id="cookieadmin_geo_card_save" class="cookieadmin-btn cookieadmin-btn-primary">' . esc_html__('Save Rule', 'cookieadmin') . '</button><span class="spinner" style="display:none;"></span>
</div>';
}
static function render_rules_table($rules, $countries, $laws){
if(empty($rules)){
return;
}
$shortcuts = $countries['continents'];
$shortcut_labels = [
'eu' => __('EU', 'cookieadmin'),
'eea' => __('EEA', 'cookieadmin'),
'africa' => __('Africa', 'cookieadmin'),
'asia' => __('Asia', 'cookieadmin'),
'europe' => __('Europe', 'cookieadmin'),
'north_america' => __('North America', 'cookieadmin'),
'south_america' => __('South America', 'cookieadmin'),
'oceania' => __('Oceania', 'cookieadmin'),
'antarctica' => __('Antarctica', 'cookieadmin'),
'caribbean' => __('Caribbean', 'cookieadmin'),
'asean' => __('ASEAN', 'cookieadmin'),
'worldwide' => __('Worldwide', 'cookieadmin'),
];
echo '<div class="cookieadmin-card">
<div class="cookieadmin-card-header">
<span class="cookieadmin-card-title">
<span class="dashicons dashicons-admin-site"></span>
' . esc_html__('Geo Targeting Rules', 'cookieadmin') . '
</span>
<div style="display:flex; justify-content:center; gap:5px; align-items:center;">
<span class="cookieadmin-badge cookieadmin-info">' . esc_html(count($rules)) . ' ' . esc_html(_n('rule', 'rules', count($rules), 'cookieadmin')) . '</span>
<span class="spinner" style="margin:0; display:none;"></span>
</div>
</div>
<div class="cookieadmin-card-body" style="padding:0;">
<table class="cookieadmin-table">
<thead>
<tr>
<th style="width:20%;">' . esc_html__('Rule Name', 'cookieadmin') . '</th>
<th style="width:10%;">' . esc_html__('Law', 'cookieadmin') . '</th>
<th style="width:25%;">' . esc_html__('Countries', 'cookieadmin') . '</th>
<th style="width:7%;">' . esc_html__('Scripts', 'cookieadmin') . '</th>
<th style="width:7%;">' . esc_html__('Content', 'cookieadmin') . '</th>
<th style="width:7%;">' . esc_html__('Google', 'cookieadmin') . '</th>
<th style="width:7%;">' . esc_html__('Clarity', 'cookieadmin') . '</th>
<th style="width:7%;">' . esc_html__('Actions', 'cookieadmin') . '</th>
</tr>
</thead>
<tbody>';
foreach($rules as $index => $rule){
$rule_id = $index;
$rule_name = !empty($rule['name']) ? $rule['name'] : '';
$rule_law = !empty($rule['law']) ? $rule['law'] : '';
$rule_law_label = isset($laws[$rule_law]) ? $laws[$rule_law] : $rule_law;
$rule_countries = !empty($rule['countries']) && is_array($rule['countries']) ? $rule['countries'] : [];
$country_badges = '';
$display_count = 0;
$total_items = count($rule_countries);
for($i = 0; $i < $total_items && $display_count < 4; $i++){
$code = $rule_countries[$i];
if($code === 'worldwide'){
$label = isset($shortcut_labels[$code]) ? $shortcut_labels[$code] : $code;
$country_badges .= '<span class="cookieadmin-badge cookieadmin-primary" style="padding:1px 8px; font-size:11px; margin-right:4px; margin-bottom:2px; display:inline-flex;">' . esc_html($label) . '</span>';
}elseif(isset($shortcuts[$code])){
$label = isset($shortcut_labels[$code]) ? $shortcut_labels[$code] : $code;
$count = count($shortcuts[$code]);
$country_badges .= '<span class="cookieadmin-badge cookieadmin-primary" style="padding:1px 8px; font-size:11px; margin-right:4px; margin-bottom:2px; display:inline-flex;">' . esc_html($label) . ' (' . esc_html($count) . ')</span>';
}else{
$name = isset($countries['countries'][$code]) ? $countries['countries'][$code] : $code;
$country_badges .= '<span class="cookieadmin-badge cookieadmin-info" style="padding:1px 8px; font-size:11px; margin-right:4px; margin-bottom:2px; display:inline-flex;">' . esc_html($code) . '</span>';
}
$display_count++;
}
if($total_items > $display_count){
$more = $total_items - $display_count;
$country_badges .= '<span class="cookieadmin-text-muted" style="font-size:11px;">+' . esc_html($more) . '</span>';
}
$block_scripts = !empty($rule['block_scripts']) ? $rule['block_scripts'] : 'inherit';
$content_blocking = !empty($rule['content_blocking']) ? $rule['content_blocking'] : 'inherit';
$google_consent_mode_v2 = !empty($rule['google_consent_mode_v2']) ? $rule['google_consent_mode_v2'] : 'inherit';
$clarity_consent = !empty($rule['clarity_consent']) ? $rule['clarity_consent'] : 'inherit';
// If law type is empty that means it is set to none, so we turn everything off on display
if(empty($rule_law_label)){
$block_scripts = 'off';
$content_blocking = 'off';
$google_consent_mode_v2 = 'off';
$clarity_consent = 'off';
}
echo '<tr data-rule-id="' . esc_attr($rule_id) . '">
<td><strong>' . esc_html($rule_name) . '</strong></td>
<td>' . (!empty($rule_law_label) ? esc_html($rule_law_label) : __('None', 'cookieadmin')). '</td>
<td>' . $country_badges . '</td>
<td>' . self::render_badge($block_scripts) . '</td>
<td>' . self::render_badge($content_blocking) . '</td>
<td>' . self::render_badge($google_consent_mode_v2) . '</td>
<td>' . self::render_badge($clarity_consent) . '</td>
<td style="text-align:right;">
<button type="button" class="cookieadmin-btn cookieadmin-btn-ghost cookieadmin-btn-sm cookieadmin-geo-table-edit" data-rule-id="' . esc_attr($rule_id) . '" title="' . esc_attr__('Edit', 'cookieadmin') . '" style="margin-right:2px;">
<span class="dashicons dashicons-edit"></span>
</button>
<button type="button" class="cookieadmin-btn cookieadmin-btn-ghost cookieadmin-btn-sm cookieadmin-geo-table-delete" data-rule-id="' . esc_attr($rule_id) . '" title="' . esc_attr__('Delete', 'cookieadmin') . '">
<span class="dashicons dashicons-trash"></span>
</button>
</td>
</tr>';
}
echo '</tbody>
</table>
</div>
</div>';
}
static function render_toggle_html($suffix, $field, $value){
$inherit_active = ($value === 'inherit') ? ' cookieadmin-geo-toggle-active' : '';
$on_active = ($value === 'on') ? ' cookieadmin-geo-toggle-active' : '';
$off_active = ($value === 'off') ? ' cookieadmin-geo-toggle-active' : '';
return '<div class="cookieadmin-geo-toggle" id="cookieadmin_geo_card_' . esc_attr($field) . '" data-field="' . esc_attr($field) . '">
<input type="hidden" class="cookieadmin-geo-toggle-value" value="' . esc_attr($value) . '">
<button type="button" class="cookieadmin-geo-toggle-btn cookieadmin-geo-toggle-inherit' . $inherit_active . '" data-value="inherit">' . esc_html__('Inherit', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-toggle-btn cookieadmin-geo-toggle-on' . $on_active . '" data-value="on">' . esc_html__('On', 'cookieadmin') . '</button>
<button type="button" class="cookieadmin-geo-toggle-btn cookieadmin-geo-toggle-off' . $off_active . '" data-value="off">' . esc_html__('Off', 'cookieadmin') . '</button>
</div>';
}
static function render_badge($value){
$class = '';
$label = '';
switch($value){
case 'inherit':
$class = 'cookieadmin-info';
$label = __('Inherit', 'cookieadmin');
break;
case 'on':
$class = 'cookieadmin-success';
$label = __('On', 'cookieadmin');
break;
case 'off':
$class = 'cookieadmin-danger';
$label = __('Off', 'cookieadmin');
break;
default:
$class = 'cookieadmin-info';
$label = __('Inherit', 'cookieadmin');
}
return '<span class="cookieadmin-badge ' . esc_attr($class) . '" data-value="' . esc_attr($value) . '" title="' . esc_attr($label) . '" style="padding:1px 8px; font-size:11px;">' . esc_html($label) . '</span>';
}
// Deleting the rule based on ID
static function delete_rule($id){
$rules = get_option('cookieadmin_geo_rules', []);
if(empty($rules)){
wp_send_json_error(['message' => __('There is no rule added to delete from', 'cookieadmin')]);
}
if(empty($rules[$id])){
wp_send_json_error(['message' => __('Request rule ID is not present, can not delete', 'cookieadmin')]);
}
unset($rules[$id]);
update_option('cookieadmin_geo_rules', $rules);
wp_send_json_success(['message' => __('Rule Deleted successfully', 'cookieadmin'), 'rules' => $rules]);
}
static function save_geo_settings(){
check_ajax_referer('cookieadmin_pro_admin_js_nonce', 'cookieadmin_pro_security');
if(!current_user_can('administrator')){
wp_send_json_error(['message' => __('Sorry, but you do not have permissions to perform this action', 'cookieadmin')]);
}
if(empty($_REQUEST['rule'])){
// If we need to delete the rule?
if(!empty($_REQUEST['delete_id'])){
$delete_id = sanitize_key(wp_unslash($_REQUEST['delete_id']));
self::delete_rule($delete_id);
}
wp_send_json_error(['message' => __('Request came empty', 'cookieadmin')]);
}
$rule_json = !empty($_REQUEST['rule']) ? wp_unslash($_REQUEST['rule']) : '';
$rule = json_decode($rule_json, true);
if(empty($rule) || !is_array($rule)){
wp_send_json_error(['message' => __('Invalid rules data', 'cookieadmin')]);
}
$rule = map_deep($rule, 'sanitize_text_field');
$sanitized_rules = [];
$locations = include(COOKIEADMIN_PRO_DIR . 'lib/locations.php');
$valid_countries = $locations['countries'];
$valid_shortcuts = $locations['continents'];
$valid_laws = apply_filters('cookieadmin_geo_law_options', [
'cookieadmin_gdpr' => 'GDPR',
'cookieadmin_us' => 'US State Laws',
]);
if(empty($rule['name'])){
wp_send_json_error(['message' => __('Enter a valid rule name', 'cookieadmin')]);
}
if(!empty($rule['law']) && !isset($valid_laws[$rule['law']])){
wp_send_json_error(['message' => __('Please select a valid law type', 'cookieadmin')]);
}
$countries = [];
if(!empty($rule['countries']) && is_array($rule['countries'])){
foreach($rule['countries'] as $country_code){
if(isset($valid_countries[$country_code])){
$countries[] = $country_code;
}elseif(isset($valid_shortcuts[$country_code])){
$countries[] = $country_code;
}elseif($country_code === 'worldwide'){
$countries[] = $country_code;
}
}
}
if(empty($countries)){
wp_send_json_error(['message' => __('Please select a valid country', 'cookieadmin')]);
}
$sanitized_rules = get_option('cookieadmin_geo_rules', []);
if(!empty($rule['id'])){
$rule_id = $rule['id'];
} else {
$rule_id = 'rule_' . uniqid();
}
$sanitized_rules[$rule_id] = [
'name' => $rule['name'],
'law' => !empty($rule['law']) ? $rule['law'] : '',
'countries' => $countries,
'block_scripts' => in_array($rule['block_scripts'], ['inherit', 'on', 'off']) ? $rule['block_scripts'] : 'inherit',
'content_blocking' => in_array($rule['content_blocking'], ['inherit', 'on', 'off']) ? $rule['content_blocking'] : 'inherit',
'google_consent_mode_v2' => in_array($rule['google_consent_mode_v2'], ['inherit', 'on', 'off']) ? $rule['google_consent_mode_v2'] : 'inherit',
'clarity_consent' => in_array($rule['clarity_consent'], ['inherit', 'on', 'off']) ? $rule['clarity_consent'] : 'inherit',
];
update_option('cookieadmin_geo_rules', $sanitized_rules, true);
wp_send_json_success([
'message' => __('Geo targeting rules saved successfully', 'cookieadmin'),
'rules' => $sanitized_rules
]);
}
static function add_default_rules_ajax(){
check_ajax_referer('cookieadmin_pro_admin_js_nonce', 'cookieadmin_pro_security');
if(!current_user_can('administrator')){
wp_send_json_error(['message' => __('Sorry, but you do not have permissions to perform this action', 'cookieadmin')]);
}
$preset = !empty($_REQUEST['preset']) ? sanitize_text_field(wp_unslash($_REQUEST['preset'])) : '';
$rules = get_option('cookieadmin_geo_rules', []);
if($preset === 'gdpr'){
$rules[] = [
'id' => 'rule_' . uniqid(),
'name' => __('GDPR Countries', 'cookieadmin'),
'law' => 'cookieadmin_gdpr',
'countries' => ['europe'],
'block_scripts' => 'on',
'content_blocking' => 'on',
'google_consent_mode_v2' => 'on',
'clarity_consent' => 'inherit',
];
}elseif($preset === 'us'){
$rules[] = [
'id' => 'rule_' . uniqid(),
'name' => __('US State Laws', 'cookieadmin'),
'law' => 'cookieadmin_us',
'countries' => ['US'],
'block_scripts' => 'inherit',
'content_blocking' => 'inherit',
'google_consent_mode_v2' => 'inherit',
'clarity_consent' => 'inherit',
];
}
update_option('cookieadmin_geo_rules', $rules, true);
wp_send_json_success(['rules' => $rules]);
}
static function toggle_geo_enabled(){
check_ajax_referer('cookieadmin_pro_admin_js_nonce', 'cookieadmin_pro_security');
if(!current_user_can('administrator')){
wp_send_json_error(['message' => __('Sorry, but you do not have permissions to perform this action', 'cookieadmin')]);
}
$enabled = !empty($_REQUEST['enabled']) ? true : false;
update_option('cookieadmin_geo_enabled', $enabled, true);
wp_send_json_success(['message' => $enabled ? __('Geo targeting enabled', 'cookieadmin') : __('Geo targeting disabled', 'cookieadmin')]);
}
static function show_db_update_notice(){
global $cookieadmin;
// Check if the page belongs to the cookieadmin
$current_page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : '';
if(strpos($current_page, 'cookieadmin') !== 0){
return false;
}
// Chekc if the database has been updated
$db_data = get_option('cookieadmin_pro_geo_db_update_available', []);
if(empty($db_data['filename'])){
return false;
}
echo '<div class="notice notice-warning is-dismissible" id="cookieadmin_pro_remove_geo_db_notice">
<p>
'.cookieadmin_logo_svg().'</br>
<strong>'.esc_html__('GeoIP database update.', 'cookieadmin').'</strong>
'.esc_html__('A newer GeoIP database is available for download. Visit ', 'cookieadmin').'
<a href="'.esc_url(admin_url('admin.php?page=cookieadmin-geo-targeting')).'">'.esc_html__('GEO Targeting', 'cookieadmin').'</a>'.esc_html__(' page to download the database.','cookieadmin').'
</p>
</div>';
wp_register_script('cookieadmin-pro-remove-geo-db-notice', '', ['jquery'], '', true);
wp_enqueue_script('cookieadmin-pro-remove-geo-db-notice');
wp_add_inline_script('cookieadmin-pro-remove-geo-db-notice', 'jQuery("#cookieadmin_pro_remove_geo_db_notice").on("click",
function(e){
let target = jQuery(e.target);
if(!target.hasClass("notice-dismiss")){
return;
}
var data;
// Hide it
jQuery("#cookieadmin_pro_remove_geo_db_notice").remove();
// Save this preference
jQuery.post("'.admin_url('admin-ajax.php?action=cookieadmin_pro_ajax_handler&cookieadmin_act=close_geo_db_update_notice').'&cookieadmin_pro_security='.wp_create_nonce('cookieadmin_pro_admin_js_nonce').'", data, function(response) {
console.log(response);
});
});');
}
static function close_geo_db_update_notice(){
check_ajax_referer('cookieadmin_pro_admin_js_nonce', 'cookieadmin_pro_security');
if(!current_user_can('administrator')){
wp_send_json_error( __('Sorry, but you do not have permissions to perform this action', 'cookieadmin'));
}
delete_option('cookieadmin_pro_geo_db_update_available');
wp_send_json_success();
}
static function download_geo_target_country_db(){
global $cookieadmin;
if(!current_user_can( 'manage_options' )){
wp_send_json_error(__('Invalid capability', 'cookieadmin'));
}
if(empty($cookieadmin['license']) || empty($cookieadmin['license']['license']) || empty($cookieadmin['license']['active'])){
wp_send_json_error(__('License key required', 'cookieadmin'));
}
if(function_exists('set_time_limit')){
@set_time_limit(0);
}
$fastest_api_endpoint = self::get_fastest_endpoint();
$api_endpoint = $fastest_api_endpoint . 'country-db.php?license='.$cookieadmin['license']['license'].'&url='.rawurlencode(site_url()).'&update=0';
// Get the filename from the API
$server_db_filename = self::check_for_db_update_available();
if(empty($server_db_filename)){
wp_send_json_error(__('Database file does not exists! please try after some time', 'cookieadmin'));
}
$server_db_filename = sanitize_file_name($server_db_filename);
$wp_upload_dir_info = wp_upload_dir();
$upload_dir = $wp_upload_dir_info['basedir'] . '/cookieadmin';
if(!is_dir($upload_dir)){
wp_mkdir_p($upload_dir);
}
// Adding htaccess file for security
if(!file_exists($upload_dir .'/.htaccess')){
file_put_contents($upload_dir .'/.htaccess', 'Deny from all');
touch($upload_dir .'/index.html');
touch($upload_dir .'/index.php');
}
$final_path = wp_normalize_path($upload_dir . '/' . $server_db_filename);
if(file_exists($final_path)){
$db_data = get_option('cookieadmin_pro_geo_target_db_download', []);
wp_send_json_success(['msg' => __('Database is already up to date', 'cookieadmin'), 'time' => wp_date('Y-m-s h:i:s', $db_data['time'])]);
}
$tmp_path = $final_path . '.tmp';
$backup_path = $final_path . '.bak';
// STEP 1: Download to TEMP file (NEVER live file)
$response = wp_remote_get($api_endpoint, [
'timeout' => 60,
'stream' => true,
'filename' => $tmp_path,
]);
if (is_wp_error($response)) {
@unlink($tmp_path);
wp_send_json_error($response->get_error_message());
}
$status_code = wp_remote_retrieve_response_code($response);
if($status_code !== 200){
@unlink($tmp_path);
wp_send_json_error(sprintf(__('Status Code: %s', 'cookieadmin'), $status_code));
}
// STEP 2: Basic file validation
if (!file_exists($tmp_path) || filesize($tmp_path) < 1024) {
@unlink($tmp_path);
wp_send_json_error(__('Downloaded file is invalid', 'cookieadmin'));
}
// STEP 4: Backup current live file ONLY AFTER validation
if (file_exists($final_path)) {
@rename($final_path, $backup_path);
}
// STEP 5: Promote temp → live
if (!@rename($tmp_path, $final_path)) {
// rollback
if (file_exists($backup_path)) {
@rename($backup_path, $final_path);
}
wp_send_json_error(__('Failed to replace database file', 'cookieadmin'));
}
// STEP 6: Cleanup backup AFTER success
if (file_exists($backup_path)) {
@unlink($backup_path);
}
// Checking if the downloaded file was a valid mmdb file
if(!class_exists('\CookieAdminProMaxMind\Db\Reader')){
include_once COOKIEADMIN_PRO_DIR . 'lib/MaxMind/autoloader.php';
}
try{
$reader = new \CookieadminProMaxMind\Db\Reader($final_path);
$metadata = $reader->metadata();
}catch(\Exception $e){
wp_send_json_error(sanitize_text_field(wp_unslash($e->getMessage())));
}
$db_data = ['filename' => $server_db_filename, 'time' => time()];
update_option('cookieadmin_pro_geo_target_db_download', $db_data);
wp_send_json_success(['msg' => __('Country database downloaded and updated successfully', 'cookieadmin'), 'time' => wp_date('Y-m-d h:i:s', $db_data['time'])]);
}
static function check_for_db_update_available(){
global $cookieadmin;
$fastest_api_endpoint = self::get_fastest_endpoint();
$api_endpoint = 'https://a.softaculous.com/cookieadmin/' . 'country-db.php?license='.$cookieadmin['license']['license'].'&url='.rawurlencode(site_url()).'&update=1';
$response = wp_remote_get($api_endpoint, ['timeout' => 60]);
// Network or WP error
if(is_wp_error($response)){
return false;
}
// Get HTTP status code, body and content type to detect if it's valid response or error
$status_code = wp_remote_retrieve_response_code($response);
$body = wp_remote_retrieve_body($response);
// If HTTP status is NOT 200, likely JSON error
if($status_code !== 200){
$json = json_decode($body, true);
if(!empty($json['error'])){
return false;
}
return false;
}
$body = json_decode($body, true);
if(json_last_error() !== JSON_ERROR_NONE){
return false;
}
if(empty($body)){
return false;
}
return $body;
}
static function get_fastest_endpoint(){
global $cookieadmin;
$endpoints = get_transient('cookieadmin_fastest_endpoint');
$mirror = 'https://s4.softaculous.com/a/cookieadmin/';
if(empty($endpoints)){
$res = wp_remote_get(COOKIEADMIN_API.'license.php?license='.$cookieadmin['license']['license'].'&url='.rawurlencode(site_url()));
// Did we get a response ?
if(!is_array($res)){
return $mirror;
}
if(empty($res['body'])){
return $mirror;
}
$body = json_decode($res['body'], true);
if(empty($body['fast_mirrors'])){
return $mirror;
}
$endpoints = $body['fast_mirrors'];
if(empty($endpoints) || !is_array($endpoints)){
return $mirror;
}
}
$index = floor(rand(0, count($endpoints) - 1));
if(empty($endpoints[$index])){
return $mirror;
}
set_transient('cookieadmin_fastest_endpoint', $endpoints, 1800);
$mirror = str_replace('a/softaculous', 'a/cookieadmin/', $endpoints[$index]);
return $mirror;
}
}