name = $name;
$this->width = $width;
$this->height = $height;
$this->area = ($width*$height);
$this->code = $code;
if($this->code == ""){
$this->buildAdSense();
}
$this->types = $types;
}
public function getName(){return $this->name;}
public function getWidth(){return $this->width;}
public function getHeight(){return $this->height;}
public function getTypes(){return $this->types;}
public function setBgColor($bgColor){$this->bgColor = $bgColor;}
public function display(){
return $this->code;
}
////
// Given the properties of an ad, builds the AdSense javascript code to display and track the ad.
////
private function buildAdSense(){
$types = $this->types;
if($types == 0){
$types = AD_TYPE_TEXT | AD_TYPE_IMAGE; // the default if types was not set
}
$channels = array(
'links' => '9861204257',
'text' => '2735973429',
'image' => '4976358981',
'text_image' => '4600189986',
'video' => '8300127981',
);
$code = "\n";
$code.= "\n";
$this->code = $code;
}
} // end class Ad
class AdModule extends Module{
private $adFormats; // all available ads.
private $myAd;
private $bgColor;
private $allowedTypes;
public function AdModule($moduleId=0){
parent::Module( 'ad', STR_ADVERTISEMENTS, '', $moduleId );
$this->adFormats = array();
$this->myAd = "";
$this->bgColor = "#ff0080"; // atrocious-pink so that we remember to figure this out by the actual bg of the page.
$this->allowedTypes = (AD_TYPE_TEXT | AD_TYPE_IMAGE);
}
public function setTypes($types){$this->allowedTypes = $types;}
public function getTypes(){return $this->allowedTypes;}
public function setBgColor($bgColor){
$this->bgColor= $bgColor;
if($this->wasSet()){
$this->myAd->setBgColor($bgColor);
}
}
public function wasSet(){return (get_class($this->myAd) == "Ad");}
public function getContent(){
$retVal = "";
//if( WHICH_SERVER != SERVER_DEV ){
if(!$this->wasSet()){
$this->myAd = new Ad('Text/Image Wide Skyscraper', 160, 600, AD_TYPE_TEXT & AD_TYPE_IMAGE);
}
$retVal .= "
\n";
$retVal .= $this->myAd->display();
$retVal .= "
\n";
$this->setId($this->getId() + 1);
// Logs the viewing of this ad (mainly to tell people how many ads they've seen to convince them to upgrade).
$user = getUser();
if($user->isLoggedIn()){
sendQuery("UPDATE userStats SET adViews=adViews+1 WHERE user_id=".$user->getId());
}
//}
return $retVal;
}
public function setLeaderboard(){$this->myAd = new Ad('Text/Image Leaderboard', 728, 90, AD_TYPE_TEXT & AD_TYPE_IMAGE);}
public function setByName($name){
$this->loadFormats();
foreach($this->adFormats as $currAd){
if($currAd->getName() == $name){
$this->myAd = $currAd;
break;
}
}
}
////
// If the ad wasn't explicitly set before this point, sets the optimal ad
/// based on it's best choice given the width, height, and
// bgColor. If height isn't known, pass in 0 for the height.
////
public function informSize($width, $height, $bgColor){
// Only choose an ad if this ad was not set explicitly yet.
if(!$this->wasSet()){
$this->bgColor = $bgColor;
$this->loadFormats();
$method = "pixels"; // this is way better than the width algorithm.
if($method == "pixels"){
// Finds the ad with the greatest difference between the total pixels of ad-space minus
// the total pixels of empty space.
$bestScore = 0;
foreach($this->adFormats as $currAd){
// Ignore ads that aren't allowed (for exapmle, most often video ads won't be allowed).
if($this->getTypes() & $currAd->getTypes()){
// Ignore ads that won't fit in the given constraints.
if(($currAd->getWidth() <= $width) && (($height <=0 ) || ($currAd->getHeight() <= $height))){
$adPixels = ($currAd->getWidth() * $currAd->getHeight());
if($height > 0){
// If there is a height limit, count all of the unused potentail space as empty.
$emptyPixels = (($width * $height) - $adPixels);
} else {
$emptyPixels = (($width * $currAd->getHeight()) - $adPixels);
}
$pixelScore = ($adPixels - $emptyPixels);
if($pixelScore >= $bestScore){
$this->myAd = $currAd;
$bestScore = $pixelScore;
}
}
}
}
} else if($method == "width"){// Finds the widest, then tallest module that will fit
// Find all of the widest ads that fit.
$maxW = 0;
$biggest = array(); //array of all ads which have the widest fitting width (since several ads have the same width).
foreach($this->adFormats as $currAd){
// Make sure it fits in the width provided and is of the right type.
if(($currAd->getWidth() <= $width) && ($this->getTypes() & $currAd->getTypes())){ // bitwise '&' checks that this type is allowed
if($currAd->getWidth() > $maxW){
$maxW = $currAd->getWidth();
$biggest = array($currAd);
} else if($currAd->getWidth() == $maxW){
$biggest[] = $currAd;
}
}
}
// Find the tallest ad that will fit given the height constraints.
$maxH = 0;
$widest = $biggest; //copy so that biggest can be modified
foreach($widest as $currAd){
// If there is a height constraint, make sure the ad fits it before even considering.
if(($height <= 0) || ($currAd->getHeight() <= $height)){
if($currAd->getHeight() > $maxH){
$maxH = $currAd->getHeight();
$biggest = array($currAd);
} else if($currAd->getHeight() == $maxH){
$biggest[] = $currAd;
}
}
}
if(count($biggest) > 0){
$this->myAd = $biggest[rand(0, count($biggest)-1)];
}
}
}
$this->setBgColor($bgColor); // do this after creating the ad, otherwise the color will be overwritten
} // end informSize
////
// Given a layout string and background color, picks the ideal ad format, then returns
// a modified layout string that indicates where the ad is located.
////
public function modifyLayout($layout, $bgColor){
$this->bgColor = $bgColor;
// If there is already an ad in the page, don't modify the layout
$index = strpos($layout, "%ad");
if($index === false){
$index = strpos($layout, ",ad"); // second possibility for formatting
}
if($index === false){
// Determine where in the layout-string the ad belongs.
$cols = explode("||", $layout);
$widest = 0;
foreach($cols as $currCol){
$matches = array();
if(0 < preg_match("/^([0-9a-f]*)%(([0-9a-f#]*[,]?)*)$/i", $currCol, $matches)){
$colWidth = $matches[1];
$mods = explode(",", $matches[2]);
$widest = MAX($colWidth, $widest);
} else {
throw new Exception("Poorly formed layout string: \"$layout\" in column \"$currCol\"");
}
}
// Places the ad at the bottom of the widest column for now.
$origLayout = $layout;
$layout = preg_replace("/($widest%(([0-9a-f]*[,]?)*))(\|\||$)/", "$1,ad$4", $layout, 1);
if($origLayout == $layout){
$layout .= ",ad"; // emergency fallback is just to throw it on the bottom-right.
}
// Determine the best ad to go in that space.
// TODO: SINCE THERE ARE A FINITE NUMBER OF LAYOUTS TO CHOOSE FROM, JUST HARDCODE THE BEST RESULTS TO START.
}
return $layout;
} // end modifyLayout()
private function loadFormats(){
GLOBAL $AD_FORMAT_CACHE;
if(!isset($AD_FORMAT_CACHE)){
// Links
$AD_FORMAT_CACHE[] = new Ad('Horizontal Links Long', 728, 15, AD_TYPE_LINK);
$AD_FORMAT_CACHE[] = new Ad('Horizontal Links Medium', 468, 15, AD_TYPE_LINK);
$AD_FORMAT_CACHE[] = new Ad('Square Links XL', 200, 90, AD_TYPE_LINK);
$AD_FORMAT_CACHE[] = new Ad('Square Links Large', 180, 90, AD_TYPE_LINK);
$AD_FORMAT_CACHE[] = new Ad('Square Links Medium', 160, 90, AD_TYPE_LINK);
$AD_FORMAT_CACHE[] = new Ad('Square Links Small', 120, 90, AD_TYPE_LINK);
// Text
$AD_FORMAT_CACHE[] = new Ad('Text Leaderboard', 728, 90, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Banner', 468, 60, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Half-Banner', 234, 60, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Skyscraper', 120, 600, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Wide Skyscraper', 160, 600, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Vertical Banner', 120, 240, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Large Rectangle', 336, 280, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Medium Rectangle', 300, 250, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Square', 250, 250, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Small Square', 200, 200, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Small Rectangle', 180, 150, AD_TYPE_TEXT);
$AD_FORMAT_CACHE[] = new Ad('Text Button', 125, 125, AD_TYPE_TEXT);
// Text/image
$AD_FORMAT_CACHE[] = new Ad('Text/Image Leaderboard', 728, 90, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Banner', 468, 60, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Half-Banner', 234, 60, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Skyscraper', 120, 600, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Wide Skyscraper', 160, 600, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Vertical Banner', 120, 240, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Large Rectangle', 336, 280, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Medium Rectangle', 300, 250, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Square', 250, 250, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Small Square', 200, 200, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Small Rectangle', 180, 150, AD_TYPE_TEXT | AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Text/Image Button', 125, 125, AD_TYPE_TEXT | AD_TYPE_IMAGE);
// Image
$AD_FORMAT_CACHE[] = new Ad('Image Leaderboard', 728, 90, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Banner', 468, 60, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Skyscraper', 120, 600, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Wide Skyscraper', 160, 600, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Large Rectangle', 336, 280, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Medium Rectangle', 300, 250, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Square', 250, 250, AD_TYPE_IMAGE);
$AD_FORMAT_CACHE[] = new Ad('Image Small Square', 200, 200, AD_TYPE_IMAGE);
/*
$AD_FORMAT_CACHE[] = new Ad(, , , );
$AD_FORMAT_CACHE[] = new Ad(, , , );
$AD_FORMAT_CACHE[] = new Ad(, , , );
$AD_FORMAT_CACHE[] = new Ad(, , , );
$AD_FORMAT_CACHE[] = new Ad(, , , );
*/
}
$this->adFormats = $AD_FORMAT_CACHE;
}
} // end class AdModule
?>