get_options(); if ( isset( $options['advanced-visitor-conditions'] ) ) { $this->options = $options['advanced-visitor-conditions']; } // only execute when enabled if ( ! isset( $this->options['enabled'] ) || ! $this->options['enabled'] ) { return ; } $is_admin = is_admin(); $this->is_ajax = wp_doing_ajax(); add_filter( 'advanced-ads-visitor-conditions', [ $this, 'visitor_conditions' ] ); // action after ad output is created; used for js injection add_filter( 'advanced-ads-ad-output', [ $this, 'after_ad_output' ], 10, 2 ); if ( $is_admin ) { // add referrer check to visitor conditions // add_action( 'advanced-ads-visitor-conditions-after', array( $this, 'referrer_check_metabox' ), 10, 2 ); /*if ( $this->is_ajax ) { add_action( 'advanced-ads-ajax-ad-select-init', array( $this, 'ajax_init_ad_select' ) ); }*/ // wp ajax is admin but this will allow other ajax callbacks to avoid setting the referrer } elseif ( ! $this->is_ajax ) { // save referrer url in session for visitor referrer url feature $this->save_first_referrer_url(); // count page impression $this->count_page_impression(); // register js script to set cookie for cached pages add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']); // enable common frontend logic // $this->init_common_frontend(); } } /** * Specially prepare for ajax ad select calls. * */ public function ajax_init_ad_select() { $this->init_common_frontend(); } /** * Init for any frontend action (including ajax ad select calls) * */ public function init_common_frontend() { // check the url referrer condition // add_filter( 'advanced-ads-can-display', array( $this, 'can_display_by_url_referrer' ), 10, 2 ); } /** * Add scripts to non-ajax frontend calls. */ public function enqueue_scripts() { if ( function_exists( 'advads_is_amp' ) && advads_is_amp() ) { return; } // add dependency to manipulate cookies easily /*wp_enqueue_script( 'jquery' ); wp_enqueue_script( 'js.cookie', '//cdnjs.cloudflare.com/ajax/libs/js-cookie/1.5.1/js.cookie.min.js', array( 'jquery' ), '1.5.1', true );*/ // add own code wp_register_script( 'advanced_ads_pro/visitor_conditions', sprintf( '%sinc/conditions%s.js', plugin_dir_url( __FILE__ ), defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ), [ ADVADS_SLUG . '-advanced-js' ], AAP_VERSION ); // 1 year by default $referrer_exdays = ( defined( 'ADVANCED_ADS_PRO_REFERRER_EXDAYS' ) && absint( ADVANCED_ADS_PRO_REFERRER_EXDAYS ) > 0 ) ? absint( ADVANCED_ADS_PRO_REFERRER_EXDAYS ) : 365; // 10 years by default $page_impressions_exdays = ( defined( 'ADVANCED_ADS_PRO_PAGE_IMPR_EXDAYS' ) && absint( ADVANCED_ADS_PRO_PAGE_IMPR_EXDAYS ) > 0 ) ? absint( ADVANCED_ADS_PRO_PAGE_IMPR_EXDAYS ) : 3650; wp_localize_script( 'advanced_ads_pro/visitor_conditions', 'advanced_ads_pro_visitor_conditions', [ 'referrer_cookie_name' => self::REFERRER_COOKIE_NAME, 'referrer_exdays' => $referrer_exdays, 'page_impr_cookie_name' => self::PAGE_IMPRESSIONS_COOKIE_NAME, 'page_impr_exdays' => $page_impressions_exdays ]); wp_enqueue_script( 'advanced_ads_pro/visitor_conditions' ); } /** * Add visitor conditions * * @since 1.0.1 * * @param array $conditions visitor conditions of the main plugin. * * @return array $conditions new global visitor conditions. */ public function visitor_conditions( $conditions ) { $conditions['referrer_url'] = [ 'label' => __( 'referrer url', 'advanced-ads-pro' ), 'description' => __( 'Display ads based on the referrer URL.', 'advanced-ads-pro' ), 'metabox' => [ 'Advanced_Ads_Visitor_Conditions', 'metabox_string' ], 'check' => [ $this, 'check_referrer_url' ], 'helplink' => 'https://wpadvancedads.com/manual/referrer-url/?utm_source=advanced-ads&utm_medium=link&utm_campaign=condition-referrer-url', ]; $conditions['user_agent'] = [ 'label' => __( 'user agent', 'advanced-ads-pro' ), 'description' => __( 'Display ads based on the user agent.', 'advanced-ads-pro' ), 'metabox' => [ 'Advanced_Ads_Visitor_Conditions', 'metabox_string' ], 'check' => [ $this, 'check_user_agent' ], 'helplink' => 'https://wpadvancedads.com/manual/display-ads-based-on-browser-or-device/?utm_source=advanced-ads&utm_medium=link&utm_campaign=condition-user-agent', ]; $conditions['capability'] = [ 'label' => __( 'user can (capabilities)', 'advanced-ads-pro' ), 'description' => __( ' Display ads based on the user’s capabilities.', 'advanced-ads-pro' ), 'metabox' => [ $this, 'metabox_capabilities' ], 'check' => [ $this, 'check_capabilities' ], 'passive_info' => [ 'hash_fields' => 'value', 'remove' => 'login', 'function' => [ $this, 'get_passive_capability' ], ], ]; $conditions['role'] = [ 'label' => __( 'user role', 'advanced-ads-pro' ), 'description' => sprintf( /* translators: %s is a placeholder for the URL. */ __( 'Display ads based on the user\'s roles. See List of roles in WordPress.', 'advanced-ads-pro' ), 'https://codex.wordpress.org/Roles_and_Capabilities' ), 'metabox' => [ $this, 'metabox_roles' ], 'check' => [ $this, 'check_roles' ], 'passive_info' => [ 'hash_fields' => 'value', 'remove' => 'login', 'function' => [ 'Advanced_Ads_Pro_Module_Advanced_Visitor_Conditions', 'get_passive_role' ] ], 'helplink' => 'https://wpadvancedads.com/manual/user-role/?utm_source=advanced-ads&utm_medium=link&utm_campaign=condition-user-role', ]; $conditions['browser_lang'] = [ 'label' => __( 'browser language', 'advanced-ads-pro' ), 'description' => __( "Display ads based on the visitor's browser language.", 'advanced-ads-pro' ), 'metabox' => [ $this, 'metabox_browser_lang' ], 'check' => [ $this, 'check_browser_lang' ], ]; $conditions['cookie'] = [ 'label' => __( 'cookie', 'advanced-ads-pro' ), 'description' => __( 'Display ads based on the value of a cookie. Set the operator to “matches/does not match” and leave the value empty to check only the existence of the cookie.', 'advanced-ads-pro' ), 'metabox' => [ $this, 'metabox_cookie' ], 'check' => [ $this, 'check_cookie' ], ]; $conditions['page_impressions'] = [ 'label' => __( 'page impressions', 'advanced-ads-pro' ), 'description' => __( 'Display ads based on the number of page impressions the user already made before the current one.', 'advanced-ads-pro' ), 'metabox' => [ 'Advanced_Ads_Visitor_Conditions', 'metabox_number' ], 'check' => [ $this, 'check_page_impressions' ], 'helplink' => 'https://wpadvancedads.com/manual/ads-by-page-impressions/?utm_source=advanced-ads&utm_medium=link&utm_campaign=condition-page-impressions', ]; $conditions['ad_impressions'] = [ 'label' => __( 'max. ad impressions', 'advanced-ads-pro' ), 'description' => __( 'Display the ad only for a few impressions in a given period per user.', 'advanced-ads-pro' ), 'metabox' => [ $this, 'metabox_ad_impressions' ], 'check' => [ $this, 'check_ad_impressions' ], ]; $conditions['new_visitor'] = [ 'label' => __( 'new visitor', 'advanced-ads-pro' ), 'description' => __( 'Display or hide ads for new visitors.', 'advanced-ads-pro' ), 'metabox' => [ 'Advanced_Ads_Visitor_Conditions', 'metabox_is_or_not' ], 'check' => [ $this, 'check_new_visitor' ], 'helplink' => 'https://wpadvancedads.com/manual/ads-for-new-visitors/?utm_source=advanced-ads&utm_medium=link&utm_campaign=condition-new-visitors', ]; $conditions['adblocker'] = [ 'label' => __( 'Adblocker', 'advanced-ads-pro' ), 'description' => __( 'Display or hide ad when user use adblocker.', 'advanced-ads-pro' ), 'metabox' => [ 'Advanced_Ads_Visitor_Conditions', 'metabox_is_or_not' ], 'check' => [ 'Advanced_Ads_Pro_Module_Advanced_Visitor_Conditions', 'check_adblocker' ], 'helplink' => 'https://wpadvancedads.com/manual/ad-blockers/', ]; $conditions['ip_address'] = [ 'label' => __( 'User IP Address', 'advanced-ads-pro' ), 'description' => __( 'Display ads based on the user IP address. Enter one IP address per line.', 'advanced-ads-pro' ), 'metabox' => [ $this, 'metabox_ip_address' ], 'check' => [ $this, 'check_ip_address' ], ]; return $conditions; } /** * Save the first referrer url submitted. Cookies is set using JavaScript * * @since 1.1.0 */ protected function save_first_referrer_url() { $cookie = Params::cookie( self::REFERRER_COOKIE_NAME ); if ( ! $cookie && ! empty( Params::server( 'HTTP_REFERER' ) ) ) { // make cookies directly available to current request. $_COOKIE[ self::REFERRER_COOKIE_NAME ] = Params::server( 'HTTP_REFERER' ); } } /** * save page impressions in cookie. Cookies is set using JavaScript * * @since 1.1.0 */ protected function count_page_impression(){ if ( $this->is_ajax ) { return; } // Make cookies directly available to current request. $impressions = Params::cookie( self::PAGE_IMPRESSIONS_COOKIE_NAME ); $impressions = $impressions ? absint( self::extract_cookie_data( $impressions ) ) : 0; $_COOKIE[ self::PAGE_IMPRESSIONS_COOKIE_NAME ] = $impressions + 1; } /** * callback to display the "capabilities" condition * * @param arr $options options of the condition * @param int $index index of the condition */ static function metabox_capabilities( $options, $index = 0, $form_name = '' ) { if ( ! isset ( $options['type'] ) || '' === $options['type'] ) { return; } $type_options = Advanced_Ads_Visitor_Conditions::get_instance()->conditions; if ( ! isset( $type_options[ $options['type'] ] ) ) { return; } // form name basis $name = self::get_form_name_with_index( $form_name, $index ); // options $value = isset( $options['value'] ) ? $options['value'] : ''; $operator = isset( $options['operator'] ) ? $options['operator'] : 'can'; // load capabilities global $wp_roles; $roles = $wp_roles->roles; // loop through all roles in order to get registered capabilities $capabilities = []; foreach ( $roles as $_role ){ if( isset( $_role['capabilities'] )){ $capabilities += $_role['capabilities']; } } // sort keys by alphabet ksort( $capabilities ); ?>
conditions; if ( ! isset( $type_options[ $options['type'] ] ) ) { return; } // form name basis $name = self::get_form_name_with_index( $form_name, $index ); // options $value = $options['value'] ?? ''; $operator = $options['operator'] ?? 'is'; global $wp_roles; $roles = $wp_roles->get_names(); ?> conditions; if ( ! isset( $type_options[ $options['type'] ] ) ) { return; } // form name basis $name = self::get_form_name_with_index( $form_name, $index ); // options $operator = isset( $options['operator'] ) ? $options['operator'] : 'is'; $value = isset( $options['value'] ) ? $options['value'] : ''; // load browser languages include plugin_dir_path( __FILE__ ) . 'inc/browser_langs.php'; if( isset( $advads_browser_langs )){ asort( $advads_browser_langs ); } ?> conditions; if ( ! isset( $type_options[ $options['type'] ] ) ) { return; } // form name basis $name = self::get_form_name_with_index( $form_name, $index ); $operator = isset( $options['operator'] ) ? self::maybe_replace_cookie_operator( $options['operator'] ) : 'contain'; // options $cookie = isset( $options['cookie'] ) ? $options['cookie'] : ''; // Cookie name. // the value may be slashed if displayed in placement, we also need to convert to htmlentities to display `"` $value = isset( $options['value'] ) ? htmlentities( wp_unslash( $options['value'] ) ) : ''; ob_start(); if ( 0 <= version_compare( ADVADS_VERSION, '1.9.1' ) ) { include( ADVADS_ABSPATH . 'admin/views/ad-conditions-string-operators.php' ); } $operatoroption = ob_get_clean(); $cookieoption = ''; $valueoption = ''; ?>%s
', esc_html( $type_options[ $options['type'] ]['description'] ) ); } /** * check referrer url in frontend * * @since 1.0.1 * @param array $options Options of the condition. * @return bool true if ad can be displayed */ static function check_referrer_url( $options = [] ){ // Check if session variable is set. $cookie = Params::cookie( self::REFERRER_COOKIE_NAME ); if ( ! $cookie ) { return false; } $referrer = self::extract_cookie_data( $cookie ); return Advanced_Ads_Visitor_Conditions::helper_check_string( $referrer, $options ); } /** * check user agent in frontend * * @since 1.0.1 * @param arr $options options of the condition * @return bool true if ad can be displayed */ static function check_user_agent( $options = [] ){ $user_agent = Params::server( 'HTTP_USER_AGENT', '' ); return Advanced_Ads_Visitor_Conditions::helper_check_string( $user_agent, $options ); } /** * check user capabilities in frontend * * @since 1.0.1 * @param arr $options options of the condition * @return bool true if ad can be displayed */ static function check_capabilities( $options = [] ){ if ( ! isset( $options['value'] ) || '' === $options['value'] || ! isset( $options['operator'] ) ){ return true; } switch ( $options['operator'] ){ case 'can' : return ( current_user_can( $options['value'] ) ); break; case 'can_not' : return ( ! current_user_can( $options['value'] ) ); } return true; } /** * Check user roles in frontend. * * @param arr $options options of the condition * @return bool true if ad can be displayed */ static function check_roles( $options = [] ){ if ( ! isset( $options['value'] ) || '' === $options['value'] || ! isset( $options['operator'] ) ){ return true; } $user = wp_get_current_user(); if ( ! is_array( $user->roles ) ) { return false; } switch ( $options['operator'] ) { case 'is' : return ( in_array( $options['value'], $user->roles, true ) ); break; case 'is_not' : return ! ( in_array( $options['value'], $user->roles, true ) ); } return true; } /** * check browser language * * @since 1.0.1 * @param arr $options options of the condition * @return bool true if ad can be displayed */ static function check_browser_lang( $options = [] ){ if ( ! isset( $options['value'] ) || '' === $options['value'] ){ return true; } $language = Params::server( 'HTTP_ACCEPT_LANGUAGE', '' ); if ( '' === $language ) { return false; } // check if the browser lang is within the accepted language string $regex = "@\b" . $options['value'] . "\b@i"; // \b checks for "whole words" $result = preg_match( $regex, $language ) === 1; if ( isset( $options['operator'] ) && $options['operator'] === 'is_not' ) { return ! $result; } else { return $result; } } /** * check cookie value in frontend * * @param array $options Options of the condition. * * @return bool true if ad can be displayed * @since 1.1.1 */ public static function check_cookie( $options = [] ) { if ( isset( $options['operator'] ) ) { $options['operator'] = self::maybe_replace_cookie_operator( $options['operator'] ); } // do not manipulate the cookie values and the comparison for RegEx. $encode = ! in_array($options['operator'], ['regex', 'regex_not'], true); $must_be_set = ! isset( $options['operator'] ) || 'match_not' !== $options['operator']; // Check if cookie option exists. if ( empty( $options['cookie'] ) || empty( $options['value'] ) ) { return $must_be_set; } // check if there are cookies. $cookie = Params::server( 'HTTP_COOKIE', '' ); if ( empty( $cookie ) ) { return ! $must_be_set; } // Get the raw cookie keys and values; the superglobal $_COOKIE holds manipulated keys and values. $raw_cookies = array_reduce( explode( ';', $cookie ), static function( $carry, $item ) use($encode) { $cookie_pair = explode( '=', $item, 2 ); if ( count( $cookie_pair ) !== 2 ) { return $carry; } $carry[ trim( $cookie_pair[0] ) ] = $encode ? urlencode( urldecode( wp_unslash( trim( $cookie_pair[1] ) ) ) ) : $cookie_pair[1]; return $carry; }, [] ); // check if the cookie exists. if ( ! isset( $raw_cookies[ $options['cookie'] ] ) ) { return ! $must_be_set; } if ($encode) { // de- and then encode the value, this catches values the user entered decoded and encoded. $options['value'] = urlencode( urldecode( wp_unslash( $options['value'] ) ) ); } return Advanced_Ads_Visitor_Conditions::helper_check_string( $raw_cookies[ $options['cookie'] ], $options ); } /** * check page_impressions in frontend * * @since 1.1.1 * @param array $options Options of the condition. * @return bool true if ad can be displayed */ static function check_page_impressions( $options = [] ){ if ( ! isset( $options['operator'] ) || ! isset( $options['value'] ) ) { return true; } $impressions = Params::cookie( self::PAGE_IMPRESSIONS_COOKIE_NAME, 0 ); if ( ! $impressions ) { return false; } $value = absint( $options['value'] ); $impressions = absint( self::extract_cookie_data( $impressions ) ); switch ( $options['operator'] ){ case 'is_equal' : if ( $value !== $impressions ) { return false; } break; case 'is_higher' : if ( $value > $impressions ) { return false; } break; case 'is_lower' : if ( $value < $impressions ) { return false; } break; } return true; } /** * Check IP address in frontend. * * @param array $options options of the condition. * * @return bool true if ad can be displayed. */ public static function check_ip_address( $options = [] ) { if ( empty( $options['value'] ) || empty( $options['operator'] ) ) { return true; } $user_ip = get_user_ip_address(); $ip_addresses = explode( "\n", $options['value'] ); switch ( $options['operator'] ) { case 'is': return in_array( $user_ip, $ip_addresses, true ); case 'is_not': return ! in_array( $user_ip, $ip_addresses, true ); } return true; } /** * check ad impressions limit for the ad in frontend * * @since 1.2.4 * @param arr $options options of the condition * @param obj $ad Ad * @return bool true if ad can be displayed */ static function check_ad_impressions( $options = [], $ad = false ){ if ( ! is_an_ad( $ad ) || ! isset( $options['value'] ) || ! isset( $options['timeout'] ) ) { return true; } $value = absint( $options['value'] ); $impressions = 0; $cookie_name = self::AD_IMPRESSIONS_COOKIE_NAME . '_' . $ad->get_id(); $cookie_timeout_name = $cookie_name . '_timeout'; $cookie_value = Params::cookie( $cookie_name ); if ( $cookie_value && Params::cookie( $cookie_timeout_name ) ) { $impressions = absint( $cookie_value ); if ( $value <= $impressions ) { return false; } } return true; } /** * check new_visitor in frontend * * @since 1.1.1 * @param array $options Options of the condition. * @return bool true if ad can be displayed */ static function check_new_visitor( $options = [] ){ if ( ! isset( $options['operator'] ) ) { return true; } $impressions = Params::cookie( self::PAGE_IMPRESSIONS_COOKIE_NAME, 0 ); if ( $impressions ) { $impressions = absint( self::extract_cookie_data( $impressions ) ); } switch ( $options['operator'] ){ case 'is' : return 1 === $impressions; break; case 'is_not' : return 1 < $impressions; break; } return true; } /** * Get capability information to use in passive cache-busting. */ static function get_passive_capability( $options = [] ) { if ( ! isset( $options['value'] ) ) { return; } $userdata = get_userdata( get_current_user_id() ); if ( ! empty( $userdata->allcaps ) && is_array( $userdata->allcaps ) && ! empty( $userdata->allcaps[ $options['value'] ] ) ) { return $options['value']; } } /** * Get role information to use in passive cache-busting. */ static function get_passive_role( $options = [] ) { if ( ! isset( $options['value'] ) ) { return; } $user = wp_get_current_user(); if ( ! empty( $user->roles ) && is_array( $user->roles ) && in_array( $options['value'], $user->roles ) ) { return $options['value']; } } /** * Inject ad output and js code. * * @since 1.2.4 * @param string $content Ad content. * @param Ad $ad Ad object. * * @return string */ public function after_ad_output( $content, Ad $ad ) { // Do not enqueue on AMP pages. if ( function_exists( 'advads_is_amp' ) && advads_is_amp() ) { return $content; } $options = $ad->get_visitor_conditions(); if( is_array( $options )) foreach( $options as $_visitor_condition ){ if( isset( $_visitor_condition['type'] )){ switch( $_visitor_condition['type'] ){ // set limit and timeout for max_ad_impressions visitor condition case 'ad_impressions' : $limit = isset( $_visitor_condition['value'] ) ? $_visitor_condition['value'] : ''; $timeout = isset( $_visitor_condition['timeout'] ) ? $_visitor_condition['timeout'] : ''; $timeout = ( $timeout ) ? $timeout : '""'; // cookie names $cookie_name = self::AD_IMPRESSIONS_COOKIE_NAME . '_' . $ad->get_id(); $cookie_timeout_name = $cookie_name . '_timeout'; // get current count, if timeout not reached yet $count = ( isset( $_COOKIE[ $cookie_name ] ) && isset( $_COOKIE[ $cookie_timeout_name ] ) ) ? $_COOKIE[ $cookie_name ] : 1; $content .= ''; break; } } } return $content; } /** * Helper function to the name of a form field. * falls back to default * * @param string $form_name form name if submitted. * @param int $index index of the condition. * * @return string */ public static function get_form_name_with_index( $form_name = '', $index = 0 ) { // form name basis if ( method_exists( 'Advanced_Ads_Visitor_Conditions', 'get_form_name_with_index' ) ) { return Advanced_Ads_Visitor_Conditions::get_form_name_with_index( $form_name, $index ); } else { return Advanced_Ads_Visitor_Conditions::FORM_NAME . '[' . $index . ']'; } } /** * Replace operator name to ensure backward compatibility. * * @param string $operator Operator name. * @return string $operator Operator name. */ private static function maybe_replace_cookie_operator( $operator ) { $replace = [ 'show' => 'match', 'hide' => 'match_not' ]; return isset( $replace[ $operator ] ) ? $replace[ $operator ] : $operator; } /** * Extract cookie data from a stringified cookie. * * @param string $cookie { * A stringified cookie. * * @type string $data Cookie data. * @type string $expire Expiration time. * } * @return mixed The data field on success, original stringified cookie on error. */ private static function extract_cookie_data( $cookie ) { $cookie_array = json_decode( wp_unslash( $cookie ), true ); if ( ! is_array( $cookie_array ) || ! array_key_exists( 'data', $cookie_array ) ) { return $cookie; } return $cookie_array['data']; } }