$terms) { if (!empty($terms) && has_term($terms, $taxonomy, $post_id)) { return sprintf('Post is in an excluded %s', $taxonomy); } } foreach ($rules['include_terms'] as $taxonomy => $terms) { if (!empty($terms) && !has_term($terms, $taxonomy, $post_id)) { return sprintf('Post is not in an included %s', $taxonomy); } } } return null; } const LOGGED_IN = ['', 'writers', 'all']; private static function logged_in_reason($rule) { if ($rule === '' || !function_exists('is_user_logged_in') || !is_user_logged_in()) { return null; } if (get_option('adghost_debug_mode', false) && current_user_can('manage_options')) { return null; } if ($rule === 'all') { return 'Ads are hidden from logged-in visitors'; } if ($rule === 'writers' && current_user_can('edit_posts')) { return 'Ads are hidden from people who write for the site'; } return null; } public static function unit_exclusion_reason(array $unit) { if (isset($unit['enabled']) && !filter_var($unit['enabled'], FILTER_VALIDATE_BOOLEAN)) { return 'Unit is paused'; } $devices = $unit['devices'] ?? (['desktop' => 'desktop', 'mobile' => 'tablet,mobile'][$unit['device'] ?? ''] ?? ''); if ($devices !== '' && $devices !== 'all' && self::device_mode() === 'server') { $allowed = array_map('trim', explode(',', (string) $devices)); $device = self::device(); if (!in_array($device, $allowed, true)) { return sprintf('Unit is not shown on %s', $device); } } $today = function_exists('current_time') ? current_time('Y-m-d') : gmdate('Y-m-d'); $start = (string) ($unit['scheduleStart'] ?? ''); $end = (string) ($unit['scheduleEnd'] ?? ''); if ($start !== '' && $today < $start) { return sprintf('Unit is scheduled to start on %s', $start); } if ($end !== '' && $today > $end) { return sprintf('Unit\'s schedule ended on %s', $end); } $pages = (string) ($unit['pages'] ?? ''); if ($pages !== '' && function_exists('is_singular')) { $type = self::page_type(); if (!in_array($type, array_map('trim', explode(',', $pages)), true)) { return sprintf('Unit is not shown on %s pages', $type); } } return null; } public static function device_mode() { return get_option('adghost_device_detection', 'browser') === 'server' ? 'server' : 'browser'; } const BREAKPOINTS = [ 'mobile' => '(max-width: 767px)', 'tablet' => '(min-width: 768px) and (max-width: 1024px)', 'desktop' => '(min-width: 1025px)', ]; public static function device_script(array $formats, array $rules) { $parts = self::device_parts($formats, $rules); return ($parts['css'] !== '' ? '' : '') . ($parts['js'] !== '' ? '' : ''); } public static function device_parts(array $formats, array $rules) { $all = [ self::device_only_parts($formats, $rules), self::referrer_parts($formats), class_exists('AdGhost_IVT_Manager') ? AdGhost_IVT_Manager::cached_page_parts($formats) : ['css' => '', 'js' => ''], ]; return [ 'css' => implode('', array_column($all, 'css')), 'js' => implode('', array_column($all, 'js')), ]; } private static function device_only_parts(array $formats, array $rules) { $css = ''; foreach (self::BREAKPOINTS as $device => $query) { $css .= '@media ' . $query . '{.adghost-ad-container[data-adghost-devices]:not([data-adghost-devices~="' . $device . '"]),.adghost-shaft[data-adghost-devices]:not([data-adghost-devices~="' . $device . '"]){display:none!important}}'; } if (self::device_mode() === 'server') { $device = self::device(); $off = false; foreach ($rules as $family => $allowed) { if (isset($formats[$family]) && !in_array($device, $allowed, true)) { $formats[$family]['enabled'] = false; $off = true; } } return [ 'css' => '', 'js' => $off ? 'window.AdGhostConfig=window.AdGhostConfig||{};window.AdGhostConfig.formats=' . wp_json_encode($formats, JSON_HEX_TAG) . ';' : '', ]; } $json = function ($value) { return wp_json_encode($value, JSON_HEX_TAG | JSON_HEX_AMP); }; return [ 'css' => $css, 'js' => '(function(w,d,q,f,r){var c="desktop",k,n=0;' . 'for(k in q){if(w.matchMedia&&w.matchMedia(q[k]).matches){c=k;break;}}' . 'w.AdGhostDevice=c;w.AdGhostConfig=w.AdGhostConfig||{};' . 'var a="[data-adghost-devices~=\\""+c+"\\"]";' . 'w.AdGhostConfig.discovery={selector:"[data-adghost]:not([data-adghost-devices]),[data-adghost-slot]:not([data-adghost-devices]),[data-adghost]"+a+",[data-adghost-slot]"+a};' . 'for(k in r){if(f[k]&&r[k].indexOf(c)<0){f[k].enabled=false;n++;}}' . 'if(n){w.AdGhostConfig.formats=f;}' . 'd.addEventListener("DOMContentLoaded",function(){var e=d.querySelectorAll("[data-adghost-devices]"),i;' . 'for(i=0;i '', 'js' => '']; } return [ 'css' => self::suppress_css('adghost-referrer-off'), 'js' => '(function(w,d,x){var f=(d.referrer||"").toLowerCase(),i,m=0;' . 'if(!f){return;}' . 'for(i=0;i-1){m=1;break;}}' . 'if(!m){return;}' . 'w.AdGhostReferrerExcluded=true;' . self::suppress_js($formats, 'adghost-referrer-off') . '})(window,document,' . wp_json_encode($needles, JSON_HEX_TAG | JSON_HEX_AMP) . ');', ]; } const SUPPRESS_SELECTOR = '[data-adghost],[data-adghost-slot],[data-adghost-format],.adghost-ad-container,.adghost-shaft'; public static function suppress_css($class) { $scope = '.' . sanitize_html_class($class) . ' '; return $scope . implode(',' . $scope, explode(',', self::SUPPRESS_SELECTOR)) . '{display:none!important}'; } public static function suppress_js(array $formats, $class) { $off = ['anchor' => ['enabled' => false], 'interstitial' => ['enabled' => false], 'rewarded' => ['enabled' => false]]; foreach (array_keys($formats) as $family) { $off[$family] = ['enabled' => false]; } return 'd.documentElement.className+=' . wp_json_encode(' ' . sanitize_html_class($class)) . ';' . 'var c=w.AdGhostConfig=w.AdGhostConfig||{},o=' . wp_json_encode((object) $off, JSON_HEX_TAG | JSON_HEX_AMP) . ',k;' . 'c.networkCode="";c.units=[];c.adblock={detect:false};' . 'c.discovery={selector:"[data-adghost-suppressed]",watchDom:false};' . 'c.formats=c.formats||{};for(k in o){c.formats[k]=c.formats[k]||{};c.formats[k].enabled=false;}' . 'd.addEventListener("DOMContentLoaded",function(){var e=d.querySelectorAll(' . wp_json_encode(self::SUPPRESS_SELECTOR) . '),j;' . 'for(j=0;j [], 'exclude_referrers' => [], 'exclude_post_ids' => [], 'include_post_ids' => [], 'exclude_terms' => ['category' => [], 'post_tag' => []], 'include_terms' => ['category' => [], 'post_tag' => []], 'hide_logged_in' => '', ]; $saved = get_option('adghost_targeting', []); if (!is_array($saved)) { $saved = []; } $rules = array_merge($defaults, $saved); foreach (['exclude_urls', 'exclude_referrers'] as $key) { $rules[$key] = array_values(array_filter(array_map('trim', (array) $rules[$key]))); } foreach (['exclude_post_ids', 'include_post_ids'] as $key) { $rules[$key] = array_values(array_filter(array_map('intval', (array) $rules[$key]))); } foreach (['exclude_terms', 'include_terms'] as $key) { $rules[$key] = is_array($rules[$key]) ? $rules[$key] : []; } if (!in_array($rules['hide_logged_in'], self::LOGGED_IN, true)) { $rules['hide_logged_in'] = ''; } return apply_filters('adghost_targeting_rules', $rules); } }