Press enter to see results or esc to cancel.

Customizations

Ad Inserter uses WordPress action and filter hooks to insert codes into WordPress pages. Each block has many settings so you can insert it practically anywhere on any page. This will work fine for most websites. However, in some cases you may need additional filters or actions not available in the plugin. For this purpose Ad Inserter offers additional actions, filters and hooks to extend the plugin functionality.

Filter Hooks

Custom block insertion checks

ai_block_insertion_check ($enabled, $block, $server_side_check)

This filter hook is called just before the block is to be inserted – all the settings were already checked. This is a place where you can prevent insertion. When the function returns false the block will not be inserted. See below for details.

$enabled is the default return value (normally true).

$block is the block number – it is set to 0 when the call is a client-side check for all blocks – in such a case an array of enabled blocks should be returned. Alternatively, the array can contain * which means all blocks are enabled and optionally negative block numbers of disabled blocks, for example array ('*', - 5, -10).

$server_side_check is true when the check is done server-side (when the page is created). The function should return null to be called client-side once again – this is a typical case where the website uses caching and checks need to be done client-side (in the browser). For single block checks (block number from 1 to 96) the function should return true if the block is enabled.

The hook function can set a global variable $ai_block_insertion_check_comments with some debugging data which is shown when the Label blocks debugging function is used.

Example 1 – check IP address against the blacklisted IP addresses in a file:

// Example for blacklisted IP addresses in a file located at /wp-content/uploads/blocked-ip-addresses.txt
// This approach requires Ad Inserter Pro
function ai_block_insertion_check_ip_addresses ($enabled, $block, $server_side_check) {
  global $ai_wp_data, $ai_block_insertion_check_comments, $ip_address_found;

  // Return null to signal client-side checks (in the case pages are cached)
  if ($server_side_check) {
    return null;
  }

  // Check the address and store it to $ip_address_found
  if (!isset ($ip_address_found)) {
    require_once AD_INSERTER_PLUGIN_DIR.'includes/geo/Ip2Country.php';

    // Load the file with IP addresses and prepare a string with comma separated addresses
    $upload_dir = wp_upload_dir ();
    $blocked_ip_addresses = str_replace (array ("\n", "\r"), array (',', ''), file_get_contents ($upload_dir ['basedir'] . '/blocked-ip-addresses.txt'));

    // Use function check_ip_address_list () of Ad Inserter Pro to check the IP addresses (wildcards are possible as in IP address list)
    $ip_address_found = check_ip_address_list ($blocked_ip_addresses, true);
  }

  // Debugging info
  if ($ai_wp_data [AI_WP_DEBUGGING] != 0) {
    if ($ip_address_found) $ai_block_insertion_check_comments = 'BLOCKED IP ADDRESS: ' . get_client_ip_address ();
  }

  // For block 0 return an array of enabled blocks
  if ($block == 0) {
    // If IP address is blocked then return empty array
    if ($ip_address_found) return array ();

    // Otherwise all blocks are enabled
    return array ('*');
  }

  return !$ip_address_found;
}

add_filter ('ai_block_insertion_check', 'ai_block_insertion_check_ip_addresses', 10, 3);

Example 2 – check the client with ipqualityscore.commake sure you use your key:

// Example for https://www.ipqualityscore.com/
function ai_block_insertion_check_ipqualityscore ($enabled, $block, $server_side_check) {
  global $ai_wp_data, $ai_block_insertion_check_comments, $ipqualityscore_data;

  // Return null to signal client-side checks (in case pages are cached)
  if ($server_side_check) {
    return null;
  }

  // Get the data and store it to $ipqualityscore_data
  if (!isset ($ipqualityscore_data)) {
    // Your API Key
    $key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

    // Retrieve the user's IP address. You could also pull this from another source such as a database.
    if (file_exists (AD_INSERTER_PLUGIN_DIR.'includes/geo/Ip2Country.php')) {
      // This approach requires Ad Inserter Pro
      require_once AD_INSERTER_PLUGIN_DIR.'includes/geo/Ip2Country.php';

      $ip = get_client_ip_address ();
    } else {
        // This approach works with Ad Inserter
        $ip = isset($_SERVER['HTTP_CF_CONNECTING_IP']) ? $_SERVER['HTTP_CF_CONNECTING_IP'] : $_SERVER['REMOTE_ADDR'];
      }

    // Retrieve additional (optional) data points which help us enhance fraud scores.
    if (!$server_side_check && isset ($_GET ['http_user_agent']) && isset ($_GET ['http_accept_language'])) {
      // Ajax request for client-side checks
      $user_agent     = urldecode ($_GET ['http_user_agent']);
      $user_language  = urldecode ($_GET ['http_accept_language']);
    } else {
        // Server-side or server-sice W3TC check
        $user_agent     = $_SERVER ['HTTP_USER_AGENT'];
        $user_language  = $_SERVER ['HTTP_ACCEPT_LANGUAGE'];
      }

    // Set the strictness for this query. (0 (least strict) - 3 (most strict))
    $strictness = 1;

    // You may want to allow public access points like coffee shops, schools, corporations, etc...
    $allow_public_access_points = 'true';

    // Reduce scoring penalties for mixed quality IP addresses shared by good and bad users.
    $lighter_penalties = 'false';

    // Create parameters array.
    $parameters = array(
      'user_agent' => $user_agent,
      'user_language' => $user_language,
      'strictness' => $strictness,
      'allow_public_access_points' => $allow_public_access_points,
      'lighter_penalties' => $lighter_penalties
    );

    // User & Transaction Scoring
    // Score additional information from a user, order, or transaction for risk analysis
    // Please see the documentation and example code to include this feature in your scoring:
    // https://www.ipqualityscore.com/documentation/proxy-detection/transaction-scoring
    // This feature requires a Premium plan or greater

    // Format Parameters
    $formatted_parameters = http_build_query ($parameters);

    // Create API URL
    $url = sprintf ('https://www.ipqualityscore.com/api/json/ip/%s/%s?%s', $key, $ip, $formatted_parameters);

    // Fetch The Result
    $timeout = 5;

    $curl = curl_init();
    curl_setopt ($curl, CURLOPT_URL, $url);
    curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);

    $json = curl_exec ($curl);
    curl_close ($curl);

    // Decode the result into an array.
    $ipqualityscore_data = json_decode ($json, true);
  }

  // For block 0 return array of enabled blocks
  if ($block == 0) {

    // Check to see if our query was successful.
    if (isset ($ipqualityscore_data ['success']) && $ipqualityscore_data ['success']) {
      // Debugging info
      if ($ai_wp_data [AI_WP_DEBUGGING] != 0) {
        $ai_block_insertion_check_comments = $ipqualityscore_data;
      }


      // Example 1: We'd like to block all proxies
      if ($ipqualityscore_data ['proxy'] === true){
        $enabled = false;
      }


      // Example 2: We'd like to block all proxies, but allow legitimate crawlers like Google on our site
      if ($ipqualityscore_data ['proxy'] === true && $ipqualityscore_data ['is_crawler'] === false){
        $enabled = false;
      }


      // Example 3: We'd like to block only visitors with a fraud score, over 80, but allow crawlers such as Google
      if ($ipqualityscore_data ['fraud_score'] >= 80 && $ipqualityscore_data ['is_crawler'] === false) {
        $enabled = false;
      }


      // Example 4: We'd like to block only visitors which are a proxy with a fraud score over 80, but allow crawlers such as Google
      if ($ipqualityscore_data ['proxy'] === true && $ipqualityscore_data ['fraud_score'] >= 80 && $ipqualityscore_data ['is_crawler'] === false) {
        $enabled = false;
      }


      // Example 5: We'd like to block only visitors which are using tor
      if ($ipqualityscore_data ['tor'] === true){
        $enabled = false;
      }
    }

    // If not enabled then return empty array
    if (!$enabled) return array ();

    // All blocks are enabled
    return array ('*');
  }

  // Return individual block status
  return $enabled;
}

add_filter ('ai_block_insertion_check', 'ai_block_insertion_check_ipqualityscore', 10, 3);

PRO Custom gelolocation services

ai_ip_to_country ($default, $ip, $details)

This filter hook is called before IP address to country lookup. You can use it for custom geolocation services. $default is the default return value, $ip is the IP address of the client, $details is true when country subdivision data is required (ignore it if your database contains only country data). The function should return uppercase two-character country ISO code. When the function returns false the configured Ad Inserter Pro lookup will be used. Code example:

add_filter ('ai_ip_to_country', 'custom_ip_to_country', 10, 3);

function custom_ip_to_country ($default, $ip, $details) {
// $default: default return value (false, means not found and configured Ad Inserter Pro lookup will be used)
// $ip: IP address of the client
// $details: true when country subdivision data is required (ignore it if your database contains only country data)

// DB lookup

  return 'XX'; // Uppercase country ISO code

// for country subdivisions
//   return array ($isoCode, $subdivision, $city); // Complete data 

// when not found
//   return false; // false means not found and configured Ad Inserter Pro lookup will be used 
}

Code example to check Kosovo IP ranges:

add_filter ('ai_ip_to_country', 'kosovo_ip_to_country', 10, 3);

function kosovo_ip_to_country ($default, $ip, $details) {
$kosovo_ipv4_ranges = array (
"46.99.0.0-46.99.255.255",
"80.80.160.0-80.80.175.255",
"91.187.96.0-91.187.127.255",
"37.26.64.0-37.26.71.255",
"185.248.172.0-185.248.175.255",
"185.254.116.0-185.254.119.255",
"147.78.160.0-147.78.163.255",
"91.217.14.0-91.217.15.255",
"46.19.224.0-46.19.231.255",
"82.114.64.0-82.114.95.255",
"178.132.216.0-178.132.223.255",
"185.67.176.0-185.67.179.255",
"185.190.132.0-185.190.135.255",
"193.0.254.0-193.0.254.255",
"178.175.0.0-178.175.127.255",
"185.47.188.0-185.47.191.255",
"213.163.96.0-213.163.127.255",
"94.100.48.0-94.100.63.255",
"77.247.248.0-77.247.255.255",
"185.177.28.0-185.177.31.255",
"185.188.216.0-185.188.219.255",
"185.24.32.0-185.24.35.255",
"185.114.112.0-185.114.115.255",
"185.205.168.0-185.205.171.255",
"185.222.138.0-185.222.138.255",
"185.244.24.0-185.244.27.255",
"194.169.164.0-194.169.167.255",
"147.78.160.0-147.78.163.255",
"45.84.116.0-45.84.119.255",
"194.5.235.0-194.5.235.255",
"185.190.38.0-185.190.38.255",
"37.35.64.0-37.35.71.255",
"84.22.32.0-84.22.63.255",
"185.173.204.0-185.173.207.255",
"84.22.32.0-84.22.63.255",
"185.82.108.0-185.82.111.255",
"185.196.180.0-185.196.183.255",
"194.5.235.0-194.5.235.255",
"194.5.252.0-194.5.252.255",
"194.6.234.0-194.6.234.255",
"194.6.247.0-194.6.247.255",
"185.188.248.0-185.188.251.255",
"91.239.145.0-91.239.145.255",
"5.206.232.0-5.206.239.255",
"87.238.208.0-87.238.215.255",
"185.171.60.0-185.171.63.255",
"185.174.208.0-185.174.211.255",
"185.179.28.0-185.179.31.255",
"185.186.80.0-185.186.83.255",
"185.191.164.0-185.191.167.255"
);

foreach ($kosovo_ipv4_ranges as $kosovo_ipv4_range) {
  $range_addresses = explode ('-', $kosovo_ipv4_range);
  $ip_address = ip2long ($ip);
  $low_address = ip2long ($range_addresses [0]);
  $high_address = ip2long ($range_addresses [1]);
  if (is_int ($ip_address) && is_int ($low_address) && is_int ($high_address)) {
    if ($ip_address >= $low_address && $ip_address <= $high_address) {
      return 'XK';
    }
  }
}

// Not found
   return false; // false means not found and configured Ad Inserter Pro lookup will be used 
}


PRO Custom ad blocking detection scripts path

ai_adb_scripts_path ($default)

When ad blocking detection is set to Advanced, Ad Inserter Pro moves scripts for ad blocking detection to a folder with random name. By default the scripts are moved into /wp-content/uploads

This filter hook is called on init action hook just before the scripts used for ad blocking detection are moved. With this filter you can define a custom folder according to your needs. In any case Ad Inserter Pro will either in the default or in the specified folder create subfolders ad-inserter/random-name/ where the scripts will be placed.

The custom folder returned by this filter hook must already exist.

You need to add filter hook before it is used in the init action, for example on action after_setup_theme. Check WP Plugin API Action Reference for the order of WP action hooks.

function adb_scripts_path ($path) {
  return '/wp-content/static';
}

add_filter ('ai_adb_scripts_path', 'adb_scripts_path', 10, 1);

Custom ad labels

ai_block_ad_label ($label_code, $block_number)

This filter hook is called before the ad label for the block is returned. With this filter you can define a custom label or translate it with your translation solutuion. $label_code is the original (configured) ad label value (text or HTML code), $block_number is the number of the block for which the label is returned.

function block_ad_label ($label_code, $block_number) {
  if ($block_number == 1) return 'Block 1';
  return $label_code;
}

add_filter ('ai_block_ad_label', 'block_ad_label', 10, 2);

Javascript actions

PRO Manual loading of blocks

ai_load_blocks ([block])

This function loads blocks when they are set to be loaded manually. The block number parameter is optional, if it is not provided all blocks enabled for manual loading (and not loaded yet) will be loaded. Of course, the code for the ads needs to support asynchronous loading (loading after the page is created).


PRO Action when a block is clicked

ai_click_action (block, block_name, code_version, code_version_name)

When the plugin detects a click on a block with enabled tracking, it calls Javascript function ai_click_action with block data as parameters.


PRO Action when a block is closed

ai_close_button_action (block)

When a block is closed, the plugin calls Javascript function ai_close_button_action with block number as parameter.

To close all blocks when one block is closed you can use the following approach:

function ai_close_button_action (block) {
  document.querySelectorAll ('.ai-close .ai-close-button').forEach ((block_to_close, index) => {
    ai_close_block (block_to_close);
  });
}

PRO Action for external tracking

ai_external_tracking_event (event_data, category, action, label, non_interaction)

Before the plugin generates event for external tracking it calls Javascript function ai_external_tracking_event with various event data as parameters. category, action and label are defined on the Tracking settings tab, non_interaction is a parameter for the Google analytics events and event_data is defined as object:

var event_data = {'event': event, 'block': block, 'block_name': block_name, 'block_counter': block_counter, 'version': version, 'version_name': version_name};

You can use this function to define custom actions for external tracking, for example, when you are using some unsupported web analytics. When the function ai_external_tracking_event returns 0 no further actions are performed. Otherwise the tracking event is sent also to Google Analytics, GTM, Piwik web analytics and other supported external tracking services.