diff --git a/dfp.module b/dfp.module index e1ad37e..a5b57d4 100755 --- a/dfp.module +++ b/dfp.module @@ -660,14 +660,6 @@ function _dfp_get_ad_category($term, $clean_string = FALSE) { * slot definitions. */ function _dfp_js_global_settings() { - // Initialize the google varibales and inject user-defined javascript. - $js = 'var googletag = googletag || {};' . "\n"; - $js .= 'googletag.cmd = googletag.cmd || [];'; - $js .= variable_get('dfp_injected_js', '') . "\n"; - - // Add a place to store the slot name variable - $js .= 'googletag.slots = googletag.slots || {};'; - $options = array( 'type' => 'inline', 'group' => JS_LIBRARY, @@ -675,27 +667,54 @@ function _dfp_js_global_settings() { 'weight' => -10, 'force header' => TRUE, ); - drupal_add_js($js, $options); // Include a script tag for the Google Tag Services. // @todo: One day this should include an async=true attribute. See #1140356. // However, there is a good chance this might break <= IE8. - $options['type'] = 'external'; - $options['weight']++; - drupal_add_js(($GLOBALS['is_https'] ? "https://" : "http://") . DFP_GOOGLE_TAG_SERVICES_URL, $options); + + // Initialize the google variables and inject user-defined javascript. + $js = variable_get('dfp_injected_js', '') . "\n"; + + // Add a place to store the slot name variable. + $js .= " var dfp_slots = new Array();\n"; + + // Add vendor code to include third party gpt.js file. + $js .= " var googletag = googletag || {}; + googletag.cmd = googletag.cmd || []; + (function() { + var gads = document.createElement('script'); + gads.type = 'text/javascript'; + var useSSL = 'https:' == document.location.protocol; + gads.src = (useSSL ? 'https:' : 'http:') + + '//www.googletagservices.com/tag/js/gpt.js'; + var node = document.getElementsByTagName('script')[0]; + node.parentNode.insertBefore(gads, node); + })();"; + drupal_add_js($js, $options); // Add global settings with a heavy weight so that they appear after all the // defineSlot() calls otherwise IE8 and Opera fail to display ads properly. $js = 'googletag.cmd.push(function() {' . "\n"; + + // Cycles through available ad slots in the array, executes them. + $js .= ' for (slot in dfp_slots) {' . "\n"; + $js .= ' dfp_slots[slot]();' . "\n"; + $js .= ' };' . "\n"; + + // Async / Sync loading of ads if (variable_get('dfp_async_rendering', 1)) { $js .= ' googletag.pubads().enableAsyncRendering();' . "\n"; } else { $js .= ' googletag.pubads().enableSyncRendering();' . "\n"; } + + // Trigger single request. if (variable_get('dfp_single_request', 1)) { $js .= ' googletag.pubads().enableSingleRequest();' . "\n"; } + + // Toggles visibility of empty ads. switch (variable_get('dfp_collapse_empty_divs', 1)) { case 1: $js .= ' googletag.pubads().collapseEmptyDivs();' . "\n"; @@ -704,6 +723,8 @@ function _dfp_js_global_settings() { $js .= ' googletag.pubads().collapseEmptyDivs(true);' . "\n"; break; } + + // Initial Loads if (variable_get('dfp_disable_init_load', 0)) { $js .= ' googletag.pubads().disableInitialLoad();' . "\n"; } @@ -721,13 +742,18 @@ function _dfp_js_global_settings() { } } + // Activate service. + $js .= ' googletag.enableServices();' . "\n"; $js .= '});' . "\n"; + + // Inject second set of custom code. $js .= variable_get('dfp_injected_js2', '') . "\n"; - $js .= 'googletag.enableServices();'; + // Embed code into header. $options = array( 'type' => 'inline', 'group' => JS_DEFAULT, + 'defer' => TRUE, 'every_page' => TRUE, 'weight' => 10, 'force header' => TRUE, @@ -748,50 +774,78 @@ function _dfp_js_slot_definition($tag) { // Add the js needed to define this adSlot to . $js = ''; + + // Encapsulate code into an entry in the slots array. + $js .= 'dfp_slots["' . $tag->machinename . '"] = function() { '; + // Start by defining breakpoints for this ad. if (!empty($tag->breakpoints)) { $breakpoints = $tag->breakpoints; - $js .= 'var mapping = googletag.sizeMapping()' . "\n"; + $js .= 'var mapping = googletag.sizeMapping()'; foreach ($breakpoints as $breakpoint) { - $js .= ' .addSize(' . dfp_format_size($breakpoint['browser_size']) . ', ' . dfp_format_size($breakpoint['ad_sizes']) . ')' . "\n"; + $js .= '.addSize(' . dfp_format_size($breakpoint['browser_size']) . ', ' . dfp_format_size($breakpoint['ad_sizes']) . ')'; } - $js .= ' .build();' . "\n"; + $js .= '.build();' . "\n"; } + + // Is this ad an out of page institial? if (!empty($tag->settings['out_of_page'])) { - $js .= 'googletag.slots["' . $tag->machinename . '"] = googletag.defineOutOfPageSlot("' . $tag->adunit . '", "' . $tag->placeholder_id . '")' . "\n"; + $js .= 'googletag.defineOutOfPageSlot("' . $tag->adunit . '", "' . $tag->placeholder_id . '")'; } else { - $js .= 'googletag.slots["' . $tag->machinename . '"] = googletag.defineSlot("' . $tag->adunit . '", ' . $tag->size . ', "' . $tag->placeholder_id . '")' . "\n"; + $js .= 'googletag.defineSlot("' . $tag->adunit . '", ' . $tag->size . ', "' . $tag->placeholder_id . '")'; } + + // Set DFP Click URL (sync mode only). $click_url = variable_get('dfp_click_url', ''); if (!empty($click_url)) { - $js .= ' .setClickUrl("' . url($click_url, array('absolute' => TRUE)) . '")' . "\n"; + if (!preg_match("/^https?:\/\//", $click_url)) { + // relative URL; prepend site domain + $click_url = (($GLOBALS['is_https']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . "/" . $click_url; + } + $js .= '.setClickUrl("' . url($click_url, array('absolute' => TRUE)) . '")' . "\n"; } - $js .= ' .addService(googletag.pubads())' . "\n"; + // Set ad type if explicitly defined. if (!empty($tag->adsense_ad_types)) { - $js .= ' .set("adsense_ad_types", "' . $tag->adsense_ad_types . '")' . "\n"; + $js .= '.set("adsense_ad_types", "' . $tag->adsense_ad_types . '")'; } + + // Set channel type if explicitly defined. if (!empty($tag->adsense_channel_ids)) { - $js .= ' .set("adsense_channel_ids", "' . $tag->adsense_channel_ids . '")' . "\n"; + $js .= '.set("adsense_channel_ids", "' . $tag->adsense_channel_ids . '")'; } + + // Set styling for the ad. foreach ($tag->adsense_colors as $key => $val) { if (!empty($val)) { $key = 'adsense_' . $key . '_color'; $val = '#' . drupal_strtoupper($val); - $js .= ' .set("' . $key . '", "' . $val . '")' . "\n"; + $js .= '.set("' . $key . '", "' . $val . '")'; } } + + // Apply ad-specific targeting parameters. $targeting = dfp_format_targeting($tag->targeting, $tag); foreach ($targeting as $target) { - $js .= ' .setTargeting(' . $target['target'] . ', ' . $target['value'] . ')' . "\n"; + $js .= '.setTargeting(' . $target['target'] . ', ' . $target['value'] . ')'; } + // Apply size mapping when there are breakpoints. if (!empty($tag->breakpoints)) { - $js .= ' .defineSizeMapping(mapping)' . "\n"; + $js .= '.defineSizeMapping(mapping)'; } + + // Execute method to publish ads. + $js .= '.addService(googletag.pubads())'; + + // Clean up. $js = rtrim($js, "\n") . ';'; + // Close the function declaration. + $js .= ' }'; + + // Add this bit after the declaration of all the ad slots. $options = array( 'type' => 'inline', 'group' => JS_LIBRARY,