Maybe this has been answered elsewhere, but had not seen in my searches. I'm sure many of you are aware, AdSense limits a page to having no more than three ads posted. I'm combining AdSense with a couple of other ads from another provider. I'd like to be able to post random ads in various blocks on the page, but how do I ensure no more than three AdSense ads are shown?

For example say I have one leaderboard ad, three ads on the sidebar and one ad in the footer. Each of the five blocks can randomly select from a group of 10 ads, of which five are AdSense and 5 are not. Other than doing something programmatically, is there a way in the ad module to have it be "smart enough" to not pick from AdSense after the allotment of 3 has been met?

Comments

jeremy’s picture

Status: Active » Postponed (maintainer needs more info)

My first question is, how are you displaying adsense ads with the ad module? Are you using the ad_html module, or ad_external module, or something else?

sgdev’s picture

Right now just ad_html. We have created ads of html type, then display those ads in blocks. To ensure we limit how many AdSense ads are displayed we have not been using the blocks generated by creating new ad categories. Instead, we have written PHP IF and switch statements in custom-created blocks, forcing particular ads to be displayed in blocks of our choice with code such as follows:

if(arg(0) == 'frontpage') {
print ad(NULL, 1, array('nids' => '81'));
} elseif(arg(0) == 'about-us') {
  print ad(NULL, 1, array('nids' => '50'));
} else {
  print ad(NULL, 1, array('nids' => '42'));
}

I'd like us to be able to move toward an approach that offers random placement of ads. However I'm not quite understanding how I can do this and ensure there won't be times when more than 3 AdSense ads are randomly selected for the 5 blocks.

Obviously we can keep doing what we're already doing, but the ads are only as random as the code we create. Our current code basically synchronizes the randomness per node type, by having an AdSense leaderboard on page nodes, non-AdSense leaderboard on blog nodes, etc.

jeremy’s picture

Category: support » feature
Status: Postponed (maintainer needs more info) » Active

Each image that is served is an independent GET from the webserver, and a this time there is nothing connecting each request. Thus, I see two potential ways to handle this:

  1. Update a cookie as ads are displayed. The information in this cookie could be used to limit the number of ads being displayed from any group such as what you want. It would also be useful for preventing the same ad from being displayed twice on the same page.
  2. Store session info in the database when ads are displayed. The information could be used in the same way.

The problem I see with #1 is that images may be served from different subdomains (for page-load time performance reasons), in which case they won't share cookies. Thus, I suspect the proper solution will be #2.

It's not a minor issue, but it is something I'd like to implement at some point. My interest in this is to prevent the same ad from being displayed multiple times on the same page, but you could use the information for your purpose as well.

jeremy’s picture

Status: Active » Postponed

Postponing until I either find the time to work on it, or someone contributed a patch.

jeremy’s picture

Title: Suggestion on AdSense Limitation » Don't display the same ad twice on the same page
Version: 5.x-1.4-1 » 6.x-2.x-dev

Moving to the current development branch, and updating the title so I can find this issue in the future.

sgdev’s picture

Just to make sure you're aware, "don't display the same ad twice on the same page" doesn't really describe the issue. It is about setting a limit to the number of ads of a particular type on a given page.

I think your comment in #3 is correct. I would envision it residing as a solution in the database. I assume there are two ways you could do this:

1) Use the "Ad groups" taxonomy to allow an admin to set the number of ads of any group to be loaded on a given page. This could be on a new admin page that lists all ad groups, and the admin can set the maximum number of ads to be loaded from a given ad group. Therefore admins would be able to set options to say "no more than 1 Google AdSense ad, 1 Amazon book ad, and 2 custom banner ads on a given page."

2) Identify with code when a Google AdSense ad has been loaded on the page, and add it to a counter. When the counter reaches three and the next ad is randomly selected, check to see if it is an AdSense ad. If it is, randomly select the ad again.

Option #1 is more generic and can be applied to any ad type, as long as it is within an ad group. #2 is more behind the scenes and specific to meeting the limitations of AdSense.

jeremy’s picture

As noted above, my interests are in no way connected to AdSense -- I would simply be adding logic that would prevent displaying the same advertisement twice on the same page. It's simply that by tracking this information, you could also solve your dilemma with AdSense as you could limit the number of ads per ad type, etc. I will not be adding any AdSense specific (or other ad source specific) code to the core ad module, nor will I accept patches that do so. (That doesn't stop anyone creating a third part module that integrates with the ad module and does whatever fancy thing they way -- there are many hooks that can be tapped into at this point, controlling most anything about what ads are displayed.)

sgdev’s picture

I think we are having a bit of a communication disconnect. In no way am I implying a solution should be specific to AdSense. I was only stating the options. In fact, my response says I believe a more generic solution (as noted in comment #6 - point 1) is the appropriate approach, leveraging taxonomy and the ad groups functionality. I was merely stating there are multiple approaches to solving this issue, but I also said "Option #1 is more generic and can be applied to any ad type."

The primary reason I wrote comment #6 is "Don't display the same ad twice on the same page" does not accurately describe the issue. If you want a more appropriate title based on what I wrote back in April 2008, then it should be called "Track ad types loaded on a page", "Allow admin to set maximum number of ads per page for a given ad group", or something like that.

jeremy’s picture

Agreed that the title could be more accurately about the information that would be tracked, not about what we would do with it. But my interest in collecting this information would be in the ability to limit the number of times the same ad was displayed on the page. And as this specific request comes up over and over again in the issue queue, I wanted to make it easy to find to try and minimize duplicates.

askibinski’s picture

The title if this issue is exactly my problem.

I'm currently displaying 3 ads between views results using this type of code three times in the views-view-unformatted-####.tpl.php file.

<?php
print ad($ad_group_id,1);
?>

I assumed the javascript code which fetches the ads would be smart enough not to display ads twice on the same page, which it now does.
I looked in the code but can't find an option for this...

Am I overlooking something?

jeremy’s picture

No, this is not yet implemented. Patches are welcome.

philpro’s picture

What's the status of the "preventing duplicates" patch? This is a feature that a client of mine is really interested in. We may be interested in sponsoring this feature addition or committing some time to create a patch. Please let me know what we can do to move this forward. Thanks.

jeremy’s picture

I've added some cookie logic to a development branch, but it's not yet generic enough to merge into the Ad module. And it depends on something like memcache to store session info for a few seconds -- it would be difficult to scale it in MySQL on a semi-active website. I've not had time to focus on this module for a while, but hope to go through the issue queue again soon and to tackle this.

panthar’s picture

Hi,

I have been trying to fix the problem listed in this thread with regard to the ad-module serving duplicate ad's.

I took the advise from the thread, about using either a db or a session solution. The problem with utilizing the db to much, is clearly scaling. For this, I am trying to use a session/mysql combination.

There is problems with both of these solutions though, that I can't seem to crack. Its either a race condition, or.. something is wrong with how the $_SESSION varibles are stored from within the ad module?

...
This is a bit hard to explain, but here I go.

So, assuming I have 10 blocks on a page, and a $_SESSION variable to store the ads that have already been displayed as their displayed.. The next ad to be loaded, does not have an updated version of the $_SESSION variable to work with. I am dumbfounded as to why the next ad to be loaded in order, can not get the AID from the previous ad's loaded. Drupal does not have concurrency does it? Any help?

Below is the function I am using to store the AID into the session.

//$id is the AID to be added to the list of already processed AID's.
function adserve_add_id($id){
if( !$_SESSION['expiresAt'] || (time() > $_SESSION['expiresAt'])){
$_SESSION['reloadIds'] = array();
$_SESSION['expiresAt'] = time() + 5;
}
array_push($_SESSION['reloadIds'],$id);
print_r($_SESSION['reloadIds']);
}

In other words, the SECOND ad serve instance can't access the CORRECT $_SESSION['reloadIds'] variable which contains the AID of the FIRST loaded ad. This is either a race condition, or something about the $_SESSION is not working correctly from within the ad module?

So in other words, I am looking for any function(s)/ideas/strategies/code snips you can suggest to finish this up. I have not tried memcache yet, do you think this could provide anything over just a simple session variable?

Thanks for the response in advance.

panthar’s picture

Status: Postponed » Needs review

Hey guys.

I *finally* figured out a hack around.

And I think it will scale!! (ie: no additional mysql queries anyhow)

Instructions:

Download/Install the "ad views" module, and "Views PHP Filter" modules. Nothing fancy about the installations, just follow their directions.

Once installed, goto the /ad_views/ad_views.module file and modify the following function (approx line 21):

function template_preprocess_ad_views_view_row_ad(&$vars) {
// Offload to ad module for rendering, using preferred display method
$vars['content'] = ad(FALSE, 1, array('nids' => $vars['row']->aid, 'ad_display' => $vars['options']['ad_display']));
}

Change it to:

function template_preprocess_ad_views_view_row_ad(&$vars) {
if (!isset($_SESSION['loaded_aids']) || $_SESSION['aids_validuntil'] < time() ){
$_SESSION['loaded_aids'] = $vars['row']->aid;
$_SESSION['aids_validuntil'] = time()+5;
}
else{
$_SESSION['loaded_aids'] .= "," . $vars['row']->aid;
}
// Offload to ad module for rendering, using preferred display method
$vars['content'] = ad(FALSE, 1, array('nids' => $vars['row']->aid, 'ad_display' => $vars['options']['ad_display']));
}

This code will not allow the same ID twice to be shown within a 5 second period. This can be changed to however many seconds you would like. I know this is arbitrary, but its a hack!

OK, NOW, create your advertisement view according to the ad_view instructions.

Then, add a "Node: PHP filter" to the filters for the ADERTISEMENT view you have just created.

Once you have added the "Node: PHP filter", edit the feild.

Set the "Operator" to "NOR".

Set the "Handler" to "php code"

Then, add the following php code to the "node:php filter" field:


return explode(",", $_SESSION['loaded_aids']);

Hope this works for everyone!!

lrwebks’s picture

Issue summary: View changes
Status: Needs review » Closed (outdated)

Drupal 6 is EOL and no longer supported. Closing this as outdated for that reason. Thanks for your contribution!