/**
  * @todo Fix this test to not rely on apd:override_function
  *
  */
 function test_adSelect2()
 {
     $this->sendMessage('test_adSelect2');
     require_once MAX_PATH . '/lib/max/Delivery/common.php';
     require MAX_PATH . '/lib/max/Delivery/tests/data/test_adSelectZone.php';
     // set up a small test data set
     $context = array();
     $test_ads = $aLinked_ads;
     $test_ads['ads'][4][1122] = $test_ads['ads'][5][1022];
     $test_ads['ads'][4][1124] = $test_ads['ads'][5][1024];
     $test_ads['ads'][5] = array();
     $test_ads['ads'][5][1022] = $test_ads['ads'][4][1122];
     $test_ads['ads'][5][1024] = $test_ads['ads'][4][1124];
     $test_ads['ads'][4][1122]['ad_id'] = '1122';
     $test_ads['ads'][4][1124]['ad_id'] = '1124';
     // case 1: cp5, 2 ads both 0.7
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0.7;
     $ads_copy['ads'][5][1024]['priority'] = 0.7;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][5];
     // this should pick the first one
     $GLOBALS['rand_val'] = 0.49;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][5]));
     $this->assertTrue($ads_copy['priority_used']['ads'][5] >= 1);
     // case 2: cp5, 2 ads both 0.7
     $prev_return = $return;
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0.7;
     $ads_copy['ads'][5][1024]['priority'] = 0.7;
     // this should pick the second one
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][5]));
     $this->assertNotEqual($return['ad_id'], $prev_return['ad_id']);
     // case 3: cp5, 2 ads both 0.4, cp4, 2 ads both 0.3
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0.4;
     $ads_copy['ads'][5][1024]['priority'] = 0.4;
     $ads_copy['ads'][4][1122]['priority'] = 0.3;
     $ads_copy['ads'][4][1124]['priority'] = 0.3;
     // this should not pick a cp5 ad
     $GLOBALS['rand_val'] = 0.8100000000000001;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     // this should choose the first ad
     $GLOBALS['rand_val'] = 0.49;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][4];
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 4);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][4]));
     $this->assertEqual($ads_copy['priority_used']['ads'][5], 0.8);
     $this->assertEqual($ads_copy['priority_used']['ads'][4], 0.6);
     // case 4: cp5, 2 ads both 0.4, cp4, 2 ads both 0.3
     $ads_copy = $test_ads;
     $prev_return = $return;
     $ads_copy['ads'][5][1022]['priority'] = 0.4;
     $ads_copy['ads'][5][1024]['priority'] = 0.4;
     $ads_copy['ads'][4][1122]['priority'] = 0.3;
     $ads_copy['ads'][4][1124]['priority'] = 0.3;
     // this should not pick a cp5 ad
     $GLOBALS['rand_val'] = 0.8100000000000001;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     // this should choose the second ad
     $GLOBALS['rand_val'] = 0.51;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][4];
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 4);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][4]));
     $this->assertEqual($ads_copy['priority_used']['ads'][5], 0.8);
     $this->assertEqual($ads_copy['priority_used']['ads'][4], 0.6);
     // make sure it's not the same ad
     $this->assertNotEqual($return['ad_id'], $prev_return['ad_id']);
     // case 5: cp5, 2 ads both 0.2, cp4, 2 ads both 0.2
     $ads_copy = $test_ads;
     $prev_return = $return;
     $ads_copy['ads'][5][1022]['priority'] = 0.2;
     $ads_copy['ads'][5][1024]['priority'] = 0.2;
     $ads_copy['ads'][4][1122]['priority'] = 0.2;
     $ads_copy['ads'][4][1124]['priority'] = 0.2;
     // this will not pick from cp5 or cp4
     $GLOBALS['rand_val'] = 0.41;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     $GLOBALS['rand_val'] = 0.67;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 4);
     $this->assertNull($return);
     $this->assertEqual($ads_copy['priority_used']['ads'][5], 0.4);
     $this->assertEqual($ads_copy['priority_used']['ads'][4], 0.4);
     // case 6: cp5, 2 ads both 0.5, cp4, 2 ads both 0.2
     // one of the cp5 ads will be filtered out
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0.5;
     $ads_copy['ads'][5][1024]['priority'] = 0.5;
     $ads_copy['ads'][4][1122]['priority'] = 0.2;
     $ads_copy['ads'][4][1124]['priority'] = 0.2;
     $context = array(array('!=' => 'bannerid:1024'));
     // this will not pick from cp5 due to the ad exclusion
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     $GLOBALS['rand_val'] = 0.79;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 4);
     $this->assertNotNull($return);
     $this->assertEqual($ads_copy['priority_used']['ads'][5], 0.5);
     $this->assertEqual($ads_copy['priority_used']['ads'][4], 0.4);
     // case 7: all ads get filtered out
     $ads_copy = $test_ads;
     unset($ads_copy['ads'][5][1022]);
     $ads_copy['ads'][5][1024]['priority'] = 0.5;
     $context = array(array('!=' => 'bannerid:1024'));
     // just expect null response
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     $this->assertTrue(!isset($ads_copy['priority_used']['ads'][5]));
     $context = "";
     // case 8: priority_used limit reached
     $ads_copy = $test_ads;
     $ads_copy['priority_used']['ads'][9] = 0.5;
     $ads_copy['priority_used']['ads'][8] = 0.3;
     $ads_copy['priority_used']['ads'][6] = 0.3;
     // this will return -1, since we've already used the entire priority space
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertEqual($return, $GLOBALS['OX_adSelect_SkipOtherPriorityLevels']);
     $this->assertTrue(!isset($ads_copy['priority_used']['ads'][5]));
     // case 9: cp5, 2 ads both 0.5, cp4, 2 ads both 0.2
     // one of the cp5 ads will be filtered out
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0;
     $ads_copy['ads'][5][1024]['priority'] = 0;
     // this will not pick from cp5 due to the ad exclusion
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 5);
     $this->assertNull($return);
     $this->assertEqual($ads_copy['priority_used']['ads'][5], 0);
     // case 10: cp5, 2 ads both 0.7, cp4, 2 ads both 0.2
     // cp5 ad will win, but confirm that the cp4 ads will be filtered
     $ads_copy = $test_ads;
     $ads_copy['ads'][5][1022]['priority'] = 0.7;
     $ads_copy['ads'][5][1024]['priority'] = 0.7;
     $ads_copy['ads'][4][1122]['priority'] = 0.2;
     $ads_copy['ads'][4][1124]['priority'] = 0.2;
     $context = array(array('!=' => 'bannerid:1124'));
     $GLOBALS['_MAX']['considered_ads'] = array();
     // this will not pick from cp5 due to the ad exclusion
     $GLOBALS['rand_val'] = 0.51;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][5];
     $return = _adSelectCommon($ads_copy, $context, $source, $richMedia);
     $this->assertNotNull($return);
     $ads_ret =& $GLOBALS['_MAX']['considered_ads'][0];
     $this->assertEqual($ads_ret['priority_used']['ads'][5], (double) 1.4);
     $this->assertFalse(isset($ads_ret['ads'][4][1124]));
     $this->assertTrue(isset($ads_ret['ads'][4][1122]));
     // case 11: cp5, 2 ads both 0.7, ecpm enabled
     $GLOBALS['_MAX']['CONF']['delivery']['ecpmSelectionRate'] = 1;
     $ads_copy = $test_ads;
     $ads_copy['ads'][6] = $ads_copy['ads'][5];
     $ads_copy['ads'][6][1022]['priority'] = 0.7;
     $ads_copy['ads'][6][1022]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1022]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1024]['priority'] = 0.7;
     $ads_copy['ads'][6][1024]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1024]['ecpm'] = 0.5;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][6];
     $context = '';
     // after ecpm optimization, the priorities should be
     //   [1022] = 0.7 => 0.7
     //   [1024] = 0.7 => 0.3
     //
     // this should pick the first one
     $GLOBALS['rand_val'] = 0.49;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 6);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][6]));
     $this->assertEqual($return['ad_id'], 1022);
     $this->assertTrue($ads_copy['priority_used']['ads'][6] >= 1);
     $ads_copy = $test_ads;
     $ads_copy['ads'][6] = $ads_copy['ads'][5];
     $ads_copy['ads'][6][1022]['priority'] = 0.7;
     $ads_copy['ads'][6][1022]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1022]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1024]['priority'] = 0.7;
     $ads_copy['ads'][6][1024]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1024]['ecpm'] = 0.5;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][6];
     // this should pick the second one
     $GLOBALS['rand_val'] = 0.71;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 6);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][6]));
     $this->assertEqual($return['ad_id'], 1024);
     $this->assertTrue($ads_copy['priority_used']['ads'][6] >= 1);
     // case 12: cp5, 2 ads both 0.7, ecpm enabled
     $GLOBALS['_MAX']['CONF']['delivery']['ecpmSelectionRate'] = 1;
     $ads_copy = $test_ads;
     $ads_copy['ads'][6] = $ads_copy['ads'][5];
     $ads_copy['ads'][6][1122] = $ads_copy['ads'][5][1022];
     $ads_copy['ads'][6][1124] = $ads_copy['ads'][5][1024];
     $ads_copy['ads'][6][1222] = $ads_copy['ads'][5][1222];
     $ads_copy['ads'][6][1022]['priority'] = 0.2;
     $ads_copy['ads'][6][1022]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1022]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1024]['priority'] = 0.5;
     $ads_copy['ads'][6][1024]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1024]['ecpm'] = 0.5;
     $ads_copy['ads'][6][1122]['ad_id'] = 1122;
     $ads_copy['ads'][6][1122]['priority'] = 0.7;
     $ads_copy['ads'][6][1122]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1122]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1124]['ad_id'] = 1124;
     $ads_copy['ads'][6][1124]['priority'] = 0.7;
     $ads_copy['ads'][6][1124]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1124]['ecpm'] = 0.5;
     $ads_copy['ads'][6][1222]['ad_id'] = 1222;
     $ads_copy['ads'][6][1222]['priority'] = 0.7;
     $ads_copy['ads'][6][1222]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1222]['ecpm'] = 0.4;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][6];
     // this should result in the following
     // [1022] = 0.2
     // [1024] = 0.5 * (1-(0.2+0.7)) / (0.5+0.7) = 0.0417
     // [1122] = 0.7
     // [1124] = 0.7 * (1-(0.2+0.7)) / (0.5+0.7) = 0.0583
     // [1222] = 0.0
     // this should pick 1024
     $GLOBALS['rand_val'] = 0.22;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 6);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][6]));
     $this->assertEqual($return['ad_id'], 1024);
     $this->assertTrue($ads_copy['priority_used']['ads'][6] >= 1);
     $this->assertEqual($ads_copy['ads'][6][1022]['priority'], 0.2);
     //unchanged
     $this->assertNotEqual($ads_copy['ads'][6][1024]['priority'], 0.5);
     //scaled
     $this->assertEqual($ads_copy['ads'][6][1222]['priority'], 0);
     //zeroed
     $this->assertEqual($ads_copy['ads'][6][1022]['priority'] + $ads_copy['ads'][6][1024]['priority'] + $ads_copy['ads'][6][1122]['priority'] + $ads_copy['ads'][6][1124]['priority'], 1);
     $ads_copy = $test_ads;
     $ads_copy['eAds'][-2] = $ads_copy['ads'][5];
     $ads_copy['eAds'][-2][1022]['priority'] = 0.2;
     $ads_copy['eAds'][-2][1022]['ecpm_enabled'] = 1;
     $ads_copy['eAds'][-2][1022]['ecpm'] = 2.0;
     $ads_copy['eAds'][-2][1024]['priority'] = 0.1;
     $ads_copy['eAds'][-2][1024]['ecpm_enabled'] = 1;
     $ads_copy['eAds'][-2][1024]['ecpm'] = 2.0;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['eAds'][-2];
     // this should pick the second one
     $GLOBALS['rand_val'] = 0.51;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'eAds', -2);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['eAds'][-2]));
     $this->assertEqual($return['ad_id'], 1024);
     $ads_copy = $test_ads;
     $ads_copy['eAds'][-2] = $ads_copy['ads'][5];
     $ads_copy['eAds'][-2][1022]['priority'] = 0.7;
     $ads_copy['eAds'][-2][1022]['ecpm_enabled'] = 1;
     $ads_copy['eAds'][-2][1022]['ecpm'] = 1.0;
     $ads_copy['eAds'][-2][1024]['priority'] = 0.1;
     $ads_copy['eAds'][-2][1024]['ecpm_enabled'] = 1;
     $ads_copy['eAds'][-2][1024]['ecpm'] = 2.0;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['eAds'][-2];
     // this should pick the second one
     $GLOBALS['rand_val'] = 0.01;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'eAds', -2);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['eAds'][-2]));
     $this->assertEqual($return['ad_id'], 1024);
     // case 13: cp6, 4 ads 2 0.7, 2 0.9, ecpm enabled
     $GLOBALS['_MAX']['CONF']['delivery']['ecpmSelectionRate'] = 0.001;
     $GLOBALS['_MAX']['CONF']['delivery']['enableControlOnPureCPM'] = 0;
     $ads_copy = $test_ads;
     $ads_copy['ads'][6] = $ads_copy['ads'][5];
     $ads_copy['ads'][6][1122] = $ads_copy['ads'][5][1022];
     $ads_copy['ads'][6][1124] = $ads_copy['ads'][5][1024];
     $ads_copy['ads'][6][1122]['ad_id'] = 1122;
     $ads_copy['ads'][6][1124]['ad_id'] = 1124;
     $ads_copy['ads'][6][1022]['priority'] = 0.7;
     $ads_copy['ads'][6][1022]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1022]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1022]['revenue_type'] = 1;
     $ads_copy['ads'][6][1024]['priority'] = 0.9;
     $ads_copy['ads'][6][1024]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1024]['ecpm'] = 0.5;
     $ads_copy['ads'][6][1024]['revenue_type'] = 1;
     $ads_copy['ads'][6][1122]['priority'] = 0.7;
     $ads_copy['ads'][6][1122]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1122]['ecpm'] = 2.0;
     $ads_copy['ads'][6][1122]['revenue_type'] = 1;
     $ads_copy['ads'][6][1124]['priority'] = 0.9;
     $ads_copy['ads'][6][1124]['ecpm_enabled'] = 1;
     $ads_copy['ads'][6][1124]['ecpm'] = 0.5;
     $ads_copy['ads'][6][1124]['revenue_type'] = 1;
     $GLOBALS['test_MAX_cacheGetAd_val'] = $ads_copy['ads'][6];
     $context = '';
     // if control were enabled, 1124 would be picked.
     // this should pick the 1122 after ecpm optimization
     $GLOBALS['rand_val'] = 0.99;
     $return = _adSelect($ads_copy, $context, $source, $richMedia, false, 'ads', 6);
     $this->assertTrue(array_key_exists($return['ad_id'], $ads_copy['ads'][6]));
     $this->assertEqual($return['ad_id'], 1122);
     $this->assertTrue($ads_copy['priority_used']['ads'][6] >= 1);
     $this->assertEqual(_controlTrafficEnabled($ads_copy['ads'][6]), false);
     $GLOBALS['_MAX']['CONF']['delivery']['enableControlOnPureCPM'] = 1;
     $this->assertEqual(_controlTrafficEnabled($ads_copy['ads'][6]), true);
     $ads_copy['ads'][6][1124]['revenue_type'] = 0;
     $this->assertEqual(_controlTrafficEnabled($ads_copy['ads'][6]), true);
 }
Esempio n. 2
0
function _adSelectZone($zoneId, $context = array(), $source = '', $richMedia = true)
{
    if ($zoneId === 0) {
        return false;
    }
    global $g_append, $g_prepend;
    while (!in_array($zoneId, $GLOBALS['_MAX']['followedChain'])) {
        $GLOBALS['_MAX']['followedChain'][] = $zoneId;
        $appendedThisZone = false;
        $aZoneInfo = MAX_cacheGetZoneInfo($zoneId);
        if (empty($aZoneInfo)) {
            return false;
        }
        if ($zoneId != 0 && MAX_limitationsIsZoneForbidden($zoneId, $aZoneInfo)) {
            $zoneId = _getNextZone($zoneId, $aZoneInfo);
            continue;
        }
        $aZoneLinkedAdInfos = MAX_cacheGetZoneLinkedAdInfos($zoneId);
        if (is_array($aZoneInfo)) {
            if (isset($aZoneInfo['forceappend']) && $aZoneInfo['forceappend'] == 't') {
                $g_prepend .= $aZoneInfo['prepend'];
                $g_append = $aZoneInfo['append'] . $g_append;
                $appendedThisZone = true;
            }
            $aZoneLinkedAdInfos += $aZoneInfo;
            $aLinkedAd = _adSelectCommon($aZoneLinkedAdInfos, $context, $source, $richMedia);
            if (is_array($aLinkedAd)) {
                $aLinkedAd['zoneid'] = $zoneId;
                $aLinkedAd['bannerid'] = $aLinkedAd['ad_id'];
                $aLinkedAd['storagetype'] = $aLinkedAd['type'];
                $aLinkedAd['campaignid'] = $aLinkedAd['placement_id'];
                $aLinkedAd['zone_companion'] = $aZoneLinkedAdInfos['zone_companion'];
                $aLinkedAd['block_zone'] = @$aZoneInfo['block_zone'];
                $aLinkedAd['cap_zone'] = @$aZoneInfo['cap_zone'];
                $aLinkedAd['session_cap_zone'] = @$aZoneInfo['session_cap_zone'];
                $aLinkedAd['affiliate_id'] = @$aZoneInfo['publisher_id'];
                if (!$appendedThisZone) {
                    $aLinkedAd['append'] .= @$aZoneInfo['append'] . $g_append;
                    $aLinkedAd['prepend'] = $g_prepend . @$aZoneInfo['prepend'] . $aLinkedAd['prepend'];
                } else {
                    $aLinkedAd['append'] .= $g_append;
                    $aLinkedAd['prepend'] = $g_prepend . $aLinkedAd['prepend'];
                }
                return $aLinkedAd;
            }
            $zoneId = _getNextZone($zoneId, $aZoneInfo);
        }
    }
    if (!empty($aZoneInfo['default_banner_image_url'])) {
        return array('default' => true, 'default_banner_image_url' => $aZoneInfo['default_banner_image_url'], 'default_banner_destination_url' => $aZoneInfo['default_banner_destination_url']);
    }
    return false;
}
Esempio n. 3
0
/**
 * This function selects an ad selected from a specific zone
 *
 * @param int     $zoneId       The ID of the zone to select an ad from
 * @param array   $context      The context of this ad selection
 *                              - used for companion positioning
 *                              - and excluding banner/campaigns from this ad-call
 * @param string  $source       The "source" parameter passed into the adcall
 * @param boolean $richMedia    Does this invocation method allow for serving 3rd party/html ads
 *
 * @return array|false          Returns an ad-array (see page DocBlock) or false if no ad found
 */
function _adSelectZone($zoneId, $context = array(), $source = '', $richMedia = true)
{
    // ZoneID zero is used for direct selected adRequests only
    if ($zoneId === 0) {
        return false;
    }
    global $g_append, $g_prepend;
    while (!in_array($zoneId, $GLOBALS['_MAX']['followedChain'])) {
        $GLOBALS['_MAX']['followedChain'][] = $zoneId;
        $appendedThisZone = false;
        // first get zone info
        $aZoneInfo = MAX_cacheGetZoneInfo($zoneId);
        if (empty($aZoneInfo)) {
            // the zone does not exist, sorry!
            return false;
        }
        //check zone level limitations
        if ($zoneId != 0 && MAX_limitationsIsZoneForbidden($zoneId, $aZoneInfo)) {
            $zoneId = _getNextZone($zoneId, $aZoneInfo);
            continue;
        }
        // Get all ads which are linked to the zone
        $aZoneLinkedAdInfos = MAX_cacheGetZoneLinkedAdInfos($zoneId);
        if (is_array($aZoneInfo)) {
            if (isset($aZoneInfo['forceappend']) && $aZoneInfo['forceappend'] == 't') {
                $g_prepend .= $aZoneInfo['prepend'];
                $g_append = $aZoneInfo['append'] . $g_append;
                $appendedThisZone = true;
            }
            // merge zone info and banner info
            $aZoneLinkedAdInfos += $aZoneInfo;
            $aLinkedAd = _adSelectCommon($aZoneLinkedAdInfos, $context, $source, $richMedia);
            if (is_array($aLinkedAd)) {
                $aLinkedAd['zoneid'] = $zoneId;
                $aLinkedAd['bannerid'] = $aLinkedAd['ad_id'];
                $aLinkedAd['storagetype'] = $aLinkedAd['type'];
                $aLinkedAd['campaignid'] = $aLinkedAd['placement_id'];
                $aLinkedAd['zone_companion'] = $aZoneLinkedAdInfos['zone_companion'];
                $aLinkedAd['block_zone'] = @$aZoneInfo['block_zone'];
                $aLinkedAd['cap_zone'] = @$aZoneInfo['cap_zone'];
                $aLinkedAd['session_cap_zone'] = @$aZoneInfo['session_cap_zone'];
                $aLinkedAd['affiliate_id'] = @$aZoneInfo['publisher_id'];
                if (!$appendedThisZone) {
                    $aLinkedAd['append'] .= @$aZoneInfo['append'] . $g_append;
                    $aLinkedAd['prepend'] = $g_prepend . @$aZoneInfo['prepend'] . $aLinkedAd['prepend'];
                } else {
                    $aLinkedAd['append'] .= $g_append;
                    $aLinkedAd['prepend'] = $g_prepend . $aLinkedAd['prepend'];
                }
                return $aLinkedAd;
            }
            $zoneId = _getNextZone($zoneId, $aZoneInfo);
        }
    }
    if (!empty($aZoneInfo['default_banner_image_url'])) {
        return array('default' => true, 'default_banner_image_url' => $aZoneInfo['default_banner_image_url'], 'default_banner_destination_url' => $aZoneInfo['default_banner_destination_url']);
    }
    return false;
}