* @license GPL-2.0+
* @link https://advertiseworld.com
* @copyright 2016 Devisd Pty Ltd
*
* @wordpress-plugin
* Plugin Name: Advertise World
* Plugin URI: https://wordpress.org/plugins/advertise-world/
* Description: This plugin simplifies adding Advertise World advertisements to your Wordpress site
* Version: 1.2.2
* Author: Devisd Pty Ltd
* Author URI: http://www.devisd.com/
* License: GPL2
*/
/*
* Initializes plugin widget
*/
require( 'widget.php' );
/*
* Initializes plugin admin section
*/
require( 'admin/main.php' );
/**
* Relative Image location URL.
*
* @since 1.0.0
* @access public
* @var string Relative image location url
*/
define( 'ADWORLD_IMAGE_PATH', 'wp-content/uploads/' );
/**
* Advert URL prefix.
*
* @since 1.0.0
* @access public
* @var String Advert URL prefix
*/
define( 'ADVERTISE_WORLD_ADVERT_URL_PREFIX', 'adspace://' );
/**
* Returns connection protocol and domain
*
* @since 1.0.0
*
* @return String Current connection protocol and domain
*/
function siteURL() {
$protocol = ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== "off" || $_SERVER['SERVER_PORT'] == 443 ) ? "https://" : "http://";
$domainName = $_SERVER['HTTP_HOST'] . '/';
return $protocol . $domainName;
}
define( 'SITE_URL', siteURL() );
// Initialize ad list option ( If this is not done the first time saving data to the table will be called twice )
add_option( 'advertise-world-wp-options-new-ad' );
/**
* Determines if url request is an advert request
*
* @since 1.0.0
*/
function scan_generated_url() {
$querys = explode( '&', $_SERVER['QUERY_STRING'] );
$advert_url = base64_decode( $querys[0] );
$advert_width = base64_decode( $querys[1] );
$advert_height = base64_decode( $querys[2] );
$reqId = base64_decode( $querys[3] );
if ( substr( $advert_url, 0, strlen( ADVERTISE_WORLD_ADVERT_URL_PREFIX ) ) == ADVERTISE_WORLD_ADVERT_URL_PREFIX ) {
$advert_id = substr( $advert_url, strlen( ADVERTISE_WORLD_ADVERT_URL_PREFIX ) );
generate_ad( $advert_id, $advert_width, $advert_height, $reqId );
}
}
add_action( 'plugins_loaded', 'scan_generated_url' );
/**
* Gets the client ip address and returns
*
* @since 1.0.1
*
* @return string
*/
function Advertise_World_Get_Client_IP() {
// Get user IP address
$ip = false;
if ( isset( $_SERVER['HTTP_CLIENT_IP'] ) && ! empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) && ! empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = ( isset( $_SERVER['REMOTE_ADDR'] ) ) ? $_SERVER['REMOTE_ADDR'] : "66.249.64.1";
}
$ip = filter_var( $ip, FILTER_VALIDATE_IP );
$ip = ( $ip === false ) ? "66.249.64.1" : $ip;
return $ip;
}
/**
* Returns the latitude and longitude of an IP address
*
* @since 1.0.4
*
* @param $ip
*
* @return array(string,string)
*/
function Advertise_World_Get_LATLON( $ip ) {
$v = strpos( $ip, ":" ) === false ? "4" : "6"; // Fast check IP version
$ipFormatted = $v === "4" ? ip2long( $ip ) : bin2hex( inet_pton( $ip ) );
if ( $ipFormatted === false ) {
// Fallback to US location (US Googleplex)
return array( "37.452", "-122.08" );
}
$result = Advertise_World_Get_URL( "https://www.advertiseworld.com/portal/GeoIPModelLookup?ip=" . $ip . "&v=" . $v );
if ( $result && strpos( $result, "," ) !== false ) {
return explode( ",", $result );
} else {
// Fallback to US location (US Googleplex)
return array( "37.452", "-122.08" );
}
}
/**
* Makes a HTTP request to a given URL and returns the response.
* Note: If PHP-CURL is available, if will be used. If not, then fopen() will be used to download the URL.
*
* @since 1.0.1
* @since 1.0.5 added the ability to make a POST request with parameters
* @since 1.2.2 turned off curl's CURLOPT_FOLLOWLOCATION option as this causes problems if php is in safe_mode.
*
* @param string $url - The URL you would like to request.
* @param bool $binaryResult - If true, the function will return the binary response. Used for downloading images.
* @param bool $headers - An associative array of key value pairs to send in the HTTP request header.
* @param array $post_params - false if your are using a GET request, or the key/value pairs of parameters to post.
*
* @return bool|mixed|string - Returns FALSE if there is an error or a timeout. Otherwise the response data is returned.
*/
function Advertise_World_Get_URL( $url, $binaryResult = false, $headers = false, $post_params = false ) {
$result = false;
// Check if we're posting the parameters, if so we need to add a Content-Type header
if ( $post_params ) {
$content_type_exists = false;
$content_type_key = false;
if ( $headers ) {
foreach ( $headers as $key => $value ) {
if ( strtolower( trim( $key ) ) == "content-type" ) {
$content_type_exists = true;
$content_type_key = $key;
}
}
if ( $content_type_exists ) {
$headers[ $content_type_key ] = "application/x-www-form-urlencoded";
} else {
$headers["Content-Type"] = "application/x-www-form-urlencoded";
}
} else {
$headers = array( "Content-Type" => "application/x-www-form-urlencoded" );
}
}
if ( function_exists( 'curl_init' ) ) {
// Make URL Request using CURL
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
if ( $binaryResult ) {
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
}
if ( $headers ) {
$curl_header = array();
foreach ( $headers as $key => $value ) {
$curl_header[] = $key . ": " . $value;
}
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $curl_header );
}
if ( $post_params ) {
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query( $post_params ) );
}
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec( $ch );
curl_close( $ch );
} elseif ( function_exists( 'fopen' ) && function_exists( 'stream_get_contents' ) ) {
// Make URL Request using fopen
if ( $headers ) {
// Construct the header for the URL Request
$header = '';
foreach ( $headers as $key => $value ) {
$header .= $key . ": " . $value . "\r\n";
}
// Create the stream options
$opts = array(
'http' => array(
'method' => $post_params ? "POST" : "GET",
'header' => $header
)
);
// Add the post parameters if to the stream options
if ( $post_params ) {
$opts['http']['content'] = http_build_query( $post_params );
}
$context = stream_context_create( $opts );
$handle = fopen( $url, "r", false, $context );
} else {
$handle = fopen( $url, "r" );
}
$result = stream_get_contents( $handle );
fclose( $handle );
}
return $result;
}
/**
* This method will send an email to Advertise World support
*
* @since 1.0.5
*
* @param $subject
* @param $message
*/
function Advertise_World_Send_Email_To_Support( $subject, $message, $reply_to = false ) {
$result = Advertise_World_Get_URL(
"https://www.advertiseworld.com/portal/ContactSupport",
false,
false,
array(
"name" => "Wordpress Plugin",
"email" => $reply_to ? $reply_to : "support@advertiseworld.com",
"your-subject" => $subject,
"comment" => "",
"message" => $message . "\r\n\r\n\r\n" . "Wordpress Version: " . get_bloginfo( 'version' ) . "\r\n\r\n\r\nPlugin Info:\r\n" . print_r( get_plugin_data( __FILE__ ), 1 )
)
);
if ( $result === false ) {
return false;
} else {
return true;
}
}
/**
* Generates ad HTML with advert id and desired width
*
* @since 1.0.0
* @since 1.0.3 Added $advert_height_choice arguement
* @since 1.0.6 Changed to use fixed width and height for ad space (client decides now)
* Added $reqId parameter
* @since 1.1.0 Fixed the json_decode line, the code was incompatible with older versions of PHP.
*
* @param string $advert_id - Adspace id
* @param Int $advert_width - Width of client adspace
* @param Int $advert_height - Height of client adspace
* @param Int $reqId - The id of the request for a new ad
*
*/
function generate_ad( $advert_id, $advert_width, $advert_height, $reqId = false ) {
if ( $advert_width == 0 ) {
exit;
}
// Get the client IP address
$clientIP = Advertise_World_Get_Client_IP();
// Get the latitude and longitude of the client
list( $lat, $lon ) = Advertise_World_Get_LATLON( $clientIP );
$api_url = 'http://ads.advertiseworld.com/ads/'
. "?site-id=" . $advert_id
. "&ua=" . urlencode( $_SERVER['HTTP_USER_AGENT'] )
. "&ip=" . $clientIP
. "&w=" . $advert_width
. "&h=" . $advert_height
. "&fmt=json"
. "&ver=s2s_1"
. "&lat=" . $lat
. "&lon=" . $lon;
$result = false;
$json = Advertise_World_Get_URL( $api_url );
if ( $json ) {
$decoded = json_decode( $json, true );
$result = $decoded[0];
}
/**
* if we dont have a small enough ad show nothing!
* this should only happen if the space is not big enough for us to deem worthy
*/
if ( ! $result ) {
exit;
}
$name = basename( $result['img'] );
$local_url = WP_CONTENT_DIR . '/aw-images/' . $name;
$fp = @fopen( $local_url, 'r' );
if ( $fp === false ) {
$fetch_url = transform_internal_url( SITE_URL . ADWORLD_IMAGE_PATH . $name );
$raw = Advertise_World_Get_URL( $fetch_url );
if ( file_exists( $local_url ) ) {
error_log( 'Failed to create file for image: File already exists!' );
} else {
if (!is_dir(dirname($local_url))) {
mkdir(dirname($local_url), 0755, true);
}
$new_fp = @fopen( $local_url, 'x+' );
if ( $new_fp !== false ) {
fwrite( $new_fp, $raw );
rewind( $new_fp );
Advertise_World_Server_And_Impress( $name, $result['curl'], $result['csc'], $reqId );
} else {
error_log( 'Failed to create file for image: ' . $fetch_url );
}
}
} else {
Advertise_World_Server_And_Impress( $name, $result['curl'], $result['csc'], $reqId );
}
exit;
}
/**
* Converts an external image url to internal
*
* @since 1.0.0
*
* @param string $url External image url
*
* @return string Local image url
*/
function transform_external_url( $url ) {
$filename = basename( $url );
$base_url = SITE_URL . ADWORLD_IMAGE_PATH . $filename;
return $base_url;
}
/**
* Converts an local image url to external
*
* @since 1.0.0
*
* @param string $url Local image url
*
* @return string External image url
*/
function transform_internal_url( $url ) {
$filename = basename( $url );
$base_url = ( ( ! empty( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443 ) ? "https://" : "http://" ) . 'wac.33233.alphacdn.net/8033233/adworld/' . $filename;
return $base_url;
}
/**
* Fires before each widget is displayed
*
* Creates a random amount of fake widgets before and after a real advert
* widget
*
* @since 1.0.0
*
* @param $instance Widget instance
* @param $widget Widget object
* @param $args Widget placement
*
* @return array Widget instance
*/
function Advertise_World_Widget_Injection( $instance, $widget, $args ) {
// reset widget count for a new sidebar
if ( $_SESSION['ADVERTISE_WORLD_LAST_SIDEBAR'] != $args['id'] ) {
$_SESSION['ADVERTISE_WORLD_LAST_SIDEBAR'] = $args['id'];
$_SESSION['ADVERTISE_WORLD_INJECTION_COUNT'] = 0;
}
$sidebars_widgets = get_option( 'sidebars_widgets' );
$widget_prefix = "advertise_world_widget";
$sidebar_has_widget = false;
foreach ( $sidebars_widgets[ $_SESSION['ADVERTISE_WORLD_LAST_SIDEBAR'] ] as $active_widget ) {
if ( substr( $active_widget, 0, strlen( $widget_prefix ) ) == $widget_prefix ) {
$sidebar_has_widget = true;
}
}
if ( ! $sidebar_has_widget ) {
return $instance;
}
$_SESSION['ADVERTISE_WORLD_INJECTION_COUNT'] ++;
$spoof_args = $args;
$spoof_instance = Array( 'title' => '' );
$last_element = 0;
$element_end = 1;
$style = 'style="border: 0 !important; height: 0 !important; padding: 0 !important; margin: 0 !important;"';
$count = mt_rand( 0, 4 );
for ( $i = 0; $i < $count; $i ++ ) {
while ( $element_end ) {
$element_end = strpos( $spoof_args['before_widget'], '>', $last_element );
if ( $element_end !== false ) {
$spoof_args['before_widget'] = substr_replace( $spoof_args['before_widget'], $style, $element_end, 0 );
$last_element = $element_end + strlen( $style ) + 1;
}
}
$advertise_world_spoof_widget = new Advertise_World_Widget();
$advertise_world_spoof_widget->widget( $spoof_args, $spoof_instance );
}
return $instance;
}
add_filter( 'widget_display_callback', 'Advertise_World_Widget_Injection', 10, 3 );
/**
* Fires after wordpress plugins are loaded
*
* @since 1.0.0
*/
function Advertise_World_Widget_Init() {
if ( ! session_id() ) {
session_start();
}
$_SESSION['ADVERTISE_WORLD_INJECTION_COUNT'] = 0;
$_SESSION['ADVERTISE_WORLD_LAST_SIDEBAR'] = '';
}
add_action( 'plugins_loaded', 'Advertise_World_Widget_Init' );
/**
* Registers an impression then serve advert image and click url
*
* @since 1.0.0
*
* @param string $image_file Relative image file location
* @param string $click_url Advert click url
* @param string $impression_url Advert impression url
*/
function Advertise_World_Server_And_Impress( $image_file, $click_url, $impression_url, $reqId = false ) {
$clientIP = Advertise_World_Get_Client_IP();
$userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36";
// Request headers to doing an impression
$headers = array(
"User-Agent" => $userAgent,
"X-Forwarded-For" => $clientIP
);
// Log any issues
if ($clientIP == "66.249.64.1" || !isset($_SERVER['HTTP_USER_AGENT'])) {
$last_reminder = get_option("advertise-world-wp-options-send-header-reminder",FALSE);
if ($last_reminder === FALSE || $last_reminder != date("d/m/y")) {
update_option( "advertise-world-wp-options-send-header-reminder", date( "d/m/y" ) );
$message = "Customer: " . get_site_url() . "
";
$message .= "
"; $message .= print_r($_SERVER,1); $message .= ""; Advertise_World_Send_Email_To_Support( 'ISSUE WITH HEADERS: (wp plugin) for customer ' . get_site_url(), $message ); } } Advertise_World_Get_URL( $impression_url, true, $headers ); // Echo the image data to the response header( 'Content-Type: text/plain' ); echo base64_encode( file_get_contents( WP_CONTENT_DIR . '/aw-images/' . $image_file ) ) . '&&&&' . $click_url; if ($reqId) { echo '&&&&' . $reqId; } exit; } /** * Fires before the page header is loaded * * Captures header output and attatch any assigned adverts * * @since 1.0.0 * * @param string $name Theme header name */ function Advertise_World_Header_Injection( $name ) { ob_start(); $templates = array(); $name = (string) $name; if ( '' !== $name ) { $templates[] = "header-{$name}.php"; } $templates[] = 'header.php'; locate_template( $templates, true ); $theme_header = ob_get_contents(); ob_end_clean(); $advertise_world_ad_list = get_option( 'advertise-world-wp-options-new-ad' ); $header_ads_above = Array(); $header_ads_below = Array(); $content_ads_above = Array(); foreach ( $advertise_world_ad_list as $ad_id => $advert ) { if ( ! isset($advert['height-choice']) ) { // Add backward compatibility for ad height selection $advert['height-choice'] = "shortest"; } if ( 'header' == $advert['type'] ) { if ( 'top' == $advert['placement'] ) { $header_ads_above[ $ad_id ] = $advert; } elseif ( 'bottom' == $advert['placement'] ) { $header_ads_below[ $ad_id ] = $advert; } } elseif ( 'content' == $advert['type'] ) { if ( 'top' == $advert['placement'] ) { $content_ads_above[ $ad_id ] = $advert; } } } $advertise_world_spoof_widget = new Advertise_World_Widget(); // Insert Inside Header Above Adverts $header_start_pos = strpos( $theme_header, '