hooks();
}
/**
* Hooks.
*
* @return void
*/
public function hooks() {
add_action( 'wp_footer', array( $this, 'maybe_output_banner' ) );
}
/**
* Check if the banner should be hidden.
*
* @return bool
*/
protected function should_hide_banner() {
return false;
}
/**
* Output the banner if enabled.
*
* @return void
*/
public function maybe_output_banner() {
if ( ! $this->is_enabled() ) {
return;
}
// Don't load in legacy widget preview in the block editor.
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
return;
}
// Don't load in the customizer preview.
if ( is_customize_preview() ) {
return;
}
// Filter to control whether the banner should be output. Child classes can override should_hide_banner().
$should_output = ! $this->should_hide_banner();
if ( ! apply_filters( 'wpconsent_banner_output', $should_output ) ) {
return;
}
$this->output_banner();
}
/**
* Check if the banner is enabled.
*
* @return bool
*/
public function is_enabled() {
return wpconsent()->settings->get_option( 'enable_consent_banner' );
}
/**
* Output the banner with proper escaping.
*
* @return void
*/
public function output_banner() {
// Allowed tags we start with the ones from wp_kses_post.
$allowed_tags = wp_kses_allowed_html( 'post' );
// Add the SVG tags from our icons.
$allowed_tags = array_merge( $allowed_tags, wpconsent_get_icon_allowed_tags() );
// Let's allow tabindex attribute.
$allowed_tags['div']['tabindex'] = true;
$allowed_tags['div']['part'] = true;
$allowed_tags['button']['part'] = true;
$allowed_tags['h2']['part'] = true;
$allowed_tags['label']['part'] = true;
$allowed_tags['span']['part'] = true;
$allowed_tags['input']['part'] = true;
$allowed_tags['p']['part'] = true;
$allowed_tags['img']['part'] = true;
// Get colors and create CSS variables.
$colors = $this->get_color_settings();
$css_vars = $this->get_css_variables( $colors );
// Create the Shadow DOM container with CSS variables.
echo '
';
echo '
';
// Create a template that contains both styles and HTML.
echo '
';
// Add the banner HTML to the template.
echo wp_kses( $this->get_banner(), $allowed_tags );
// Add the preferences modal to the template.
echo $this->get_preferences_modal(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
// Add the floating button to the template.
$this->floating_consent_button();
// Add GPC toast notification to the template.
$this->add_gpc_toast_notification();
echo ' ';
echo '
';
}
/**
* Get CSS variables string from colors array.
*
* @param array $colors Color settings.
*
* @return string
*/
public function get_css_variables( $colors ) {
$vars = array(
'--wpconsent-z-index: 900000;',
'--wpconsent-background: ' . $colors['background'] . ';',
'--wpconsent-text: ' . $colors['text'] . ';',
'--wpconsent-outline-color: ' . $this->hex_to_rgba( $colors['text'], 0.2 ) . ';',
'--wpconsent-accept-bg: ' . $colors['accept_bg'] . ';',
'--wpconsent-cancel-bg: ' . $colors['cancel_bg'] . ';',
'--wpconsent-preferences-bg: ' . $colors['preferences_bg'] . ';',
'--wpconsent-accept-color: ' . $colors['accept_color'] . ';',
'--wpconsent-cancel-color: ' . $colors['cancel_color'] . ';',
'--wpconsent-preferences-color: ' . $colors['preferences_color'] . ';',
'--wpconsent-font-size: ' . $colors['font_size'] . ';',
);
return implode( ' ', $vars );
}
/**
* Convert hex color to rgba.
*
* @param string $hex Hex color code.
* @param float $opacity Opacity value.
*
* @return string
*/
private function hex_to_rgba( $hex, $opacity ) {
$hex = str_replace( '#', '', $hex );
// Convert shorthand hex to full hex.
if ( strlen( $hex ) === 3 ) {
$hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
}
// Convert hex to rgb.
$r = hexdec( substr( $hex, 0, 2 ) );
$g = hexdec( substr( $hex, 2, 2 ) );
$b = hexdec( substr( $hex, 4, 2 ) );
return "rgba({$r}, {$g}, {$b}, {$opacity})";
}
/**
* Get the banner markup.
*
* @return string
*/
public function get_banner() {
$font_size = wpconsent()->settings->get_option( 'banner_font_size', '16px' );
$button_size = wpconsent()->settings->get_option( 'banner_button_size', 'regular' );
$button_corner = wpconsent()->settings->get_option( 'banner_button_corner', 'slightly-rounded' );
$button_type = wpconsent()->settings->get_option( 'banner_button_type', 'filled' );
$button_order = wpconsent()->settings->get_option(
'button_order',
array(
'accept',
'cancel',
'preferences',
)
);
$banner_layout = wpconsent()->settings->get_option( 'banner_layout', 'long' );
$banner_position = wpconsent()->settings->get_option( 'banner_position', 'top' );
$position_class = ! empty( $banner_position ) ? 'wpconsent-banner-' . esc_attr( $banner_layout ) . '-' . esc_attr( $banner_position ) : '';
$logo = wpconsent()->settings->get_option( 'banner_logo', '' );
$banner_classes = apply_filters(
'wpconsent_banner_classes',
array(
'wpconsent-banner-holder',
'wpconsent-banner-' . $banner_layout,
$position_class,
)
);
$html = '';
$html .= '
';
$html .= $this->get_banner_top_buttons();
if ( ! empty( $logo ) ) {
$html .= '';
}
$text = wpconsent()->settings->get_option( 'banner_message', wpconsent()->strings->get_string( 'banner_message' ) );
$html .= '
';
$html .= '
' . esc_html__( 'Cookie Consent', 'wpconsent-cookies-banner-privacy-suite' ) . ' ';
$html .= '
' . wp_kses_post( wpautop( $text ) ) . '
';
$html .= apply_filters( 'wpconsent_after_banner_message', '' );
$html .= '
';
$html .= ''; // .wpconsent-banner-footer
$html .= $this->powered_by();
$html .= '
'; // .wpconsent-banner
$html .= '
';// .wpconsent-banner-holder
return $html;
}
/**
* Get the top buttons for the banner.
*
* @return string
*/
public function get_banner_top_buttons() {
// Check if close button is disabled in settings.
if ( wpconsent()->settings->get_option( 'disable_close_button' ) ) {
return '';
}
$close_text = esc_attr__( 'Close', 'wpconsent-cookies-banner-privacy-suite' );
return '' . wpconsent_get_icon( 'close', 12, 12 ) . ' ';
}
/**
* Get the color settings.
*
* @return array
*/
public function get_color_settings() {
return array(
'background' => wpconsent()->settings->get_option( 'banner_background_color', '#FFFFFF' ),
'text' => wpconsent()->settings->get_option( 'banner_text_color', '#000000' ),
'button_text' => wpconsent()->settings->get_option( 'banner_button_text_color', '#FFFFFF' ),
'accept_bg' => wpconsent()->settings->get_option( 'banner_accept_bg', '#0073AA' ),
'cancel_bg' => wpconsent()->settings->get_option( 'banner_cancel_bg', '#0073AA' ),
'preferences_bg' => wpconsent()->settings->get_option( 'banner_preferences_bg', '#0073AA' ),
'accept_color' => wpconsent()->settings->get_option( 'banner_accept_color', '#FFFFFF' ),
'cancel_color' => wpconsent()->settings->get_option( 'banner_cancel_color', '#FFFFFF' ),
'preferences_color' => wpconsent()->settings->get_option( 'banner_preferences_color', '#FFFFFF' ),
'font_size' => wpconsent()->settings->get_option( 'banner_font_size', '16px' ),
);
}
/**
* Get the preferences modal.
*
* @return string
*/
public function get_preferences_modal() {
$categories = wpconsent()->cookies->get_categories();
$accept_button_text = wpconsent()->settings->get_option( 'accept_button_text', wpconsent()->strings->get_string( 'accept_button_text' ) );
$logo = wpconsent()->settings->get_option( 'banner_logo', '' );
$cookie_policy_title = wpconsent()->settings->get_option( 'cookie_policy_title', wpconsent()->strings->get_string( 'cookie_policy_title' ) );
$preferences_panel_title = wpconsent()->settings->get_option( 'preferences_panel_title', wpconsent()->strings->get_string( 'preferences_panel_title' ) );
$default_allow = wpconsent()->settings->get_option( 'default_allow', 0 );
$preferences_classes = apply_filters(
'wpconsent_preferences_modal_classes',
array(
'wpconsent-preferences-modal',
)
);
$html = '';
$html .= '
';
// Preferences header div.
$html .= ''; // .wpconsent-preferences-header
$html .= '
';
$html .= apply_filters( 'wpconsent_preferences_before_description', '' );
$html .= '
' . wpautop( wp_kses_post( wpconsent()->settings->get_option( 'preferences_panel_description', wpconsent()->strings->get_string('preferences_panel_description') ) ) ) . '
';
$html .= apply_filters( 'wpconsent_preferences_after_description', '' );
$html .= '
';
$all_cookies = $this->get_cookies_from_cache();
/**
* Filter to group categories in the preferences modal.
*
* Allows plugins to group categories with optional section titles and descriptions.
* By default, returns a single group with all categories.
*
* @param array $groups Array of groups. Each group should have:
* - 'title' (string, optional): Section title.
* - 'description' (string, optional): Section description.
* - 'css_class' (string, optional): CSS class for the section wrapper.
* - 'categories' (array): Array of categories to render in this group.
* @param array $categories All available categories.
*
* @since 1.0.11
*/
$category_groups = apply_filters(
'wpconsent_preferences_category_groups',
array(
array(
'categories' => $categories,
),
),
$categories
);
// Loop through each group and render categories.
foreach ( $category_groups as $group ) {
if ( empty( $group['categories'] ) ) {
continue;
}
// Open section wrapper if CSS class is provided.
if ( ! empty( $group['css_class'] ) ) {
$html .= '
';
}
// Add section title if provided.
if ( ! empty( $group['title'] ) ) {
$html .= '
' . esc_html( $group['title'] ) . ' ';
}
// Add section description if provided.
if ( ! empty( $group['description'] ) ) {
$html .= '
' . esc_html( $group['description'] ) . '
';
}
// Render categories in this group.
foreach ( $group['categories'] as $category_slug => $category ) {
// Skip empty categories (no cookies and no services) unless it's the essential category.
$category_cookies = isset( $all_cookies[ $category['id'] ] ) ? $all_cookies[ $category['id'] ] : array();
$has_cookies = ! empty( $category_cookies['cookies'] );
$has_services = ! empty( $category_cookies['services'] );
if ( 'essential' !== $category_slug && ! $has_cookies && ! $has_services ) {
continue;
}
$html .= $this->render_category_item( $category_slug, $category, $all_cookies, $default_allow );
}
// Close section wrapper if it was opened.
if ( ! empty( $group['css_class'] ) ) {
$html .= '
';
}
}
// Cookie policy section, if set.
$cookie_policy_page_id = wpconsent()->settings->get_option( 'cookie_policy_page', 0 );
if ( $cookie_policy_page_id ) {
$cookie_policy_page_url = get_permalink( $cookie_policy_page_id );
$privacy_policy = get_privacy_policy_url();
$html .= '
';
$html .= ''; // .wpconsent-preferences-accordion-header
$html .= '
';
$html .= '
';
if ( $privacy_policy ) {
$default_cookie_policy_text = sprintf(
/* translators: 1: Cookie policy URL, 2: Privacy policy URL */
esc_html__( 'You can find more information about our %1$s and %2$s.', 'wpconsent-cookies-banner-privacy-suite' ),
'' . esc_html__( 'Cookie Policy', 'wpconsent-cookies-banner-privacy-suite' ) . ' ',
'' . esc_html__( 'Privacy Policy', 'wpconsent-cookies-banner-privacy-suite' ) . ' '
);
} else {
$default_cookie_policy_text = sprintf(
/* translators: %s: Cookie policy URL */
esc_html__( 'You can find more information in our %s.', 'wpconsent-cookies-banner-privacy-suite' ),
'' . esc_html__( 'Cookie Policy', 'wpconsent-cookies-banner-privacy-suite' ) . ' '
);
}
$html .= wp_kses_post( $this->maybe_replace_smart_tags( wpconsent()->settings->get_option( 'cookie_policy_text', $default_cookie_policy_text ) ) );
$html .= '
';
$html .= '
'; // .wpconsent-preferences-accordion-content
$html .= '
'; // .wpconsent-cookie-category
}
$html .= '
'; // .wpconsent-preference-cookies
$html .= apply_filters( 'wpconsent_preferences_after_cookies', '' );
// Add GPC override toggle to preference panel.
$html .= $this->add_gpc_override_toggle();
$html .= '
'; // .wpconsent-preferences-body
$save_preferences_text = wpconsent()->settings->get_option( 'save_preferences_button_text', wpconsent()->strings->get_string( 'save_preferences_button_text' ) );
$close_text = wpconsent()->settings->get_option( 'close_button_text', wpconsent()->strings->get_string( 'close_button_text' ) );
$button_size = wpconsent()->settings->get_option( 'banner_button_size', 'regular' );
$button_corner = wpconsent()->settings->get_option( 'banner_button_corner', 'slightly-rounded' );
$button_type = wpconsent()->settings->get_option( 'banner_button_type', 'filled' );
$html .= '
';
$html .= '
'; // .wpconsent-preferences-buttons
$html .= '
'; // .wpconsent-preferences-actions
// div for Powered by WPConsent.
if ( ! wpconsent()->settings->get_option( 'hide_powered_by' ) ) {
$html .= '
';
$html .= $this->powered_by();
$html .= '
'; // .wpconsent-preferences-powered-by
}
$html .= '
'; // .wpconsent-preferences-content
$html .= '
'; // #wpconsent-preferences-modal
return $html;
}
/**
* Add GPC override acknowledgment to preference panel
*
* @return string HTML for the GPC override toggle.
*/
public function add_gpc_override_toggle() {
// Only add if respect_gpc is enabled.
if ( ! wpconsent()->settings->get_option( 'respect_gpc', 0 ) ) {
return;
}
$gpc_message = wpconsent()->settings->get_option( 'gpc_override_message', wpconsent()->strings->get_string( 'gpc_override_message' ) );
$content = '';
$content .= '';
$content .= ''; // .wpconsent-gpc-override-header.
$content .= '
'; // .wpconsent-gpc-override-container.
return $content;
}
/**
* Add GPC toast notification to preference panel
*
* @return void.
*/
public function add_gpc_toast_notification() {
// Only add if respect_gpc is enabled.
if ( ! wpconsent()->settings->get_option( 'respect_gpc', 0 ) ) {
return;
}
$gpc_toast_message = wpconsent()->settings->get_option( 'gpc_toast_message', wpconsent()->strings->get_string( 'gpc_toast_message' ) );
echo '';
echo '
';
echo '' . esc_html( $gpc_toast_message ) . ' ';
echo '× ';
echo '
'; // .wpconsent-toast-content.
echo '
'; // .wpconsent-gpc-toast.
}
/**
* Get cookies from cache or database
*
* @return array
*/
private function get_cookies_from_cache() {
$cache_key = 'wpconsent_preference_cookies';
// Allow cache key to be filtered (e.g., for multilanguage support).
$cache_key = apply_filters( 'wpconsent_preference_cookies_cache_key', $cache_key );
$cookies = get_transient( $cache_key );
if ( false === $cookies ) {
$categories = wpconsent()->cookies->get_categories();
$cookies = array();
foreach ( $categories as $category_slug => $category ) {
$category_id = $category['id'];
$cookies[ $category_id ] = array(
'cookies' => array(),
'services' => array(),
);
$category_cookies = wpconsent()->cookies->get_cookies_by_category( $category_id );
$services = wpconsent()->cookies->get_services_by_category( $category_id );
if ( ! empty( $category_cookies ) ) {
foreach ( $category_cookies as $cookie ) {
// Let's skip here the cookies that are not associated with this category directly and are associated with a service.
if ( ! in_array( $category_id, $cookie['categories'], true ) ) {
continue;
}
// Add cookie to the category's cookie array.
$cookies[ $category_id ]['cookies'][] = $cookie;
}
}
// Process services and their cookies.
if ( ! empty( $services ) ) {
foreach ( $services as $service ) {
$service_slug = sanitize_title( $service['name'] );
$cookies[ $category_id ]['services'][ $service_slug ] = array(
'name' => $service['name'],
'description' => $service['description'],
'service_url' => $service['service_url'],
'cookies' => array(),
);
// We already loaded all the cookies for this category so we need to simply add the ones for this service.
if ( ! empty( $category_cookies ) ) {
foreach ( $category_cookies as $cookie_for_service ) {
if ( ! in_array( $service['id'], $cookie_for_service['categories'], true ) ) {
continue;
}
$cookies[ $category_id ]['services'][ $service_slug ]['cookies'][] = $cookie_for_service;
}
}
}
}
}
// Cache for 24 hours.
set_transient( $cache_key, $cookies, DAY_IN_SECONDS );
}
return apply_filters( 'wpconsent_get_cookies_from_cache', $cookies );
}
/**
* Render a single category item in the preferences modal.
*
* @param string $category_slug The category slug.
* @param array $category The category data.
* @param array $all_cookies All cookies data.
* @param bool $default_allow Default allow setting.
*
* @return string HTML for the category item.
*/
private function render_category_item( $category_slug, $category, $all_cookies, $default_allow ) {
$cookies = isset( $all_cookies[ $category['id'] ] ) ? $all_cookies[ $category['id'] ] : array();
$html = '';
$html .= ''; // .wpconsent-preferences-accordion-header
$html .= '
';
$html .= '
' . wp_kses_post( $category['description'] ) . '
';
/**
* Filter to add content after category description.
*
* @param string $content HTML content to add.
* @param string $category_slug The category slug.
* @param array $category The category data.
*
* @since 1.0.11
*/
$html .= apply_filters( 'wpconsent_after_category_description', '', $category_slug, $category );
$html .= $this->get_cookies_content_by_category( $cookies, $category['name'], $category_slug );
$html .= '
'; // .wpconsent-preferences-accordion-content
$html .= '
'; // .wpconsent-cookie-category
return $html;
}
/**
* Generate the cookies accordioncontent for a category
*
* @param array $cookies The cookies array for each category to display.
* @param string $category_name The name of the category.
* @param string $category_slug The slug of the category.
*
* @return string
*/
private function get_cookies_content_by_category( $cookies, $category_name = '', $category_slug = '' ) {
if ( empty( $cookies ) ) {
return '';
}
$html = '';
$default_allow = wpconsent()->settings->get_option( 'default_allow', false );
if ( ! empty( $cookies['cookies'] ) ) {
$html .= $this->get_cookies_table_by_category( $cookies['cookies'] );
}
// First display services and their cookies.
if ( ! empty( $cookies['services'] ) ) {
foreach ( $cookies['services'] as $service_slug => $service ) {
$html .= '';
$html .= ''; // .wpconsent-preferences-accordion-header
$html .= '
'; // .wpconsent-cookie-service
} else {
// Regular service rendering with accordion and checkbox.
$html .= '';
$html .= '';
$html .= ' ';
$html .= '' . esc_html(
sprintf(
/* translators: %s: Service name */
__( 'Toggle %s', 'wpconsent-cookies-banner-privacy-suite' ),
$service['name']
)
) . ' ';
$html .= ' '; // .wpconsent-preferences-accordion-toggle
$html .= '' . esc_html( $service['name'] ) . ' ';
$html .= '
'; // .wpconsent-cookie-category-text
$html .= '';
if ( wpconsent()->settings->get_option( 'manual_toggle_services', false ) ) {
if ( 'essential' === $category_slug ) {
$html .= '';
$html .= ' ';
$html .= ' ';
$html .= ' '; // .wpconsent-preferences-checkbox-toggle
} else {
// Apply filter to allow customization of default state for this service.
$default_checked = apply_filters( 'wpconsent_service_default_checked', $default_allow, $service_slug, $service, $category_slug );
$checked_attr = $default_checked ? 'checked' : '';
$html .= '';
$html .= ' ';
$html .= ' ';
$html .= ' '; // .wpconsent-preferences-checkbox-toggle
}
}
$html .= '
'; // .wpconsent-cookie-category-checkbox
$html .= ''; // .wpconsent-preferences-accordion-header
$html .= '';
if ( ! empty( $service['description'] ) ) {
$html .= '
' . wp_kses_post( $service['description'] ) . '
';
}
// Add service URL to description if it exists.
if ( ! empty( $service['service_url'] ) ) {
$service_url_label = wpconsent()->settings->get_option( 'cookie_table_header_service_url', wpconsent()->strings->get_string( 'cookie_table_header_service_url' ) );
$html .= '
' . sprintf(
/* translators: %1$s: Service URL label, %2$s: Service URL */
esc_html__( '%1$s: %2$s', 'wpconsent-cookies-banner-privacy-suite' ),
esc_html( $service_url_label ),
'' . esc_html( wp_parse_url( $service['service_url'], PHP_URL_HOST ) ) . ' ' . esc_html__( '(opens in a new window)', 'wpconsent-cookies-banner-privacy-suite' ) . ' '
) . '
';
}
$html .= $this->get_cookies_table_by_category( $service['cookies'] );
$html .= '
'; // .wpconsent-preferences-accordion-content
$html .= ''; // .wpconsent-cookie-service
}
}
}
return $html;
}
/**
* Generate the cookies table for a category
*
* @param array $cookies The cookies to display.
*
* @return string
*/
private function get_cookies_table_by_category( $cookies ) {
if ( empty( $cookies ) ) {
return '';
}
$html = '';
$html .= ''; // .wpconsent-preferences-list-header
foreach ( $cookies as $cookie ) {
$html .= '
';
$html .= '
' . esc_html( $cookie['name'] ) . '
';
$html .= '
' . wp_kses_post( $cookie['description'] ) . '
';
$html .= '
' . esc_html( ! empty( $cookie['duration'] ) ? $cookie['duration'] : '-' ) . '
';
$html .= '
'; // .wpconsent-preferences-list-item
}
$html .= '
'; // .wpconsent-preferences-cookies-list
return $html;
}
/**
* Output the powered by WPConsent logo.
*
* @return string
*/
public function powered_by() {
if ( wpconsent()->settings->get_option( 'hide_powered_by' ) ) {
return '';
}
$url = wpconsent_utm_url( 'https://wpconsent.com/powered-by/', 'poweredby' );
$html = ''; // .wpconsent-powered-by
return $html;
}
/**
* Output the floating consent button.
*
* @return void
*/
public function floating_consent_button() {
if ( is_admin() ) {
return;
}
$colors = $this->get_color_settings();
$style = 'background-color: ' . esc_attr( $colors['background'] ) . '; color: ' . esc_attr( $colors['text'] ) . ';';
echo '';
$icon_value = wpconsent()->settings->get_option( 'consent_floating_icon', 'preferences' );
if ( filter_var( $icon_value, FILTER_VALIDATE_URL ) ) {
echo ' ';
} else {
echo wp_kses(
apply_filters(
'wpconsent_preferences_icon',
wpconsent_get_icon( $icon_value, 24, 24, '0 -960 960 960', $colors['text'] )
),
wpconsent_get_icon_allowed_tags()
);
}
echo ' ';
}
/**
* Replace smart tags for the cookie policy text.
*
* @param string $text The text to replace smart tags in.
* @param string $locale The locale to use for the replacement.
*
* @return string
*/
public function maybe_replace_smart_tags( $text, $locale = '' ) {
$cookie_policy_page_id = apply_filters( 'wpconsent_get_cookie_policy_id', wpconsent()->settings->get_option( 'cookie_policy_page', 0 ), $locale );
$privacy_policy_page_id = apply_filters( 'wpconsent_get_privacy_policy_id', get_option( 'wp_page_for_privacy_policy' ), $locale );
// Get the URLs and titles.
$cookie_policy_page_url = $cookie_policy_page_id ? get_permalink( $cookie_policy_page_id ) : '';
$cookie_policy_page_title = $cookie_policy_page_id ? get_the_title( $cookie_policy_page_id ) : '';
$privacy_policy_url = $privacy_policy_page_id ? get_permalink( $privacy_policy_page_id ) : '';
$privacy_policy_page_title = $privacy_policy_page_id ? get_the_title( $privacy_policy_page_id ) : '';
// Replace {cookie_policy} with a link to the cookie policy where the text of the link is the page title.
if ( $cookie_policy_page_url && $cookie_policy_page_title ) {
$text = str_replace( '{cookie_policy}', '' . esc_html( $cookie_policy_page_title ) . ' ', $text );
} else {
$text = str_replace( '{cookie_policy}', '', $text );
}
// Replace {privacy_policy} with a link to the privacy policy where the text of the link is the page title.
if ( $privacy_policy_url && $privacy_policy_page_title ) {
$text = str_replace( '{privacy_policy}', '' . esc_html( $privacy_policy_page_title ) . ' ', $text );
} else {
// If there is no privacy policy page, remove the {privacy_policy} tag.
$text = str_replace( '{privacy_policy}', '', $text );
}
return $text;
}
}