/**
  * A method to run distributed maintenance.
  */
 function run()
 {
     if (empty($GLOBALS['_MAX']['CONF']['lb']['enabled'])) {
         OA::debug('Distributed stats disabled, not running Maintenance Distributed Engine', PEAR_LOG_INFO);
         return;
     }
     if (!empty($GLOBALS['_MAX']['CONF']['rawDatabase'])) {
         $GLOBALS['_MAX']['CONF']['database'] = $GLOBALS['_MAX']['CONF']['rawDatabase'] + $GLOBALS['_MAX']['CONF']['database'];
         OA::debug('rawDatabase functionality is being used, switching settings', PEAR_LOG_INFO);
     }
     $oLock =& OA_DB_AdvisoryLock::factory();
     if (!$oLock->get(OA_DB_ADVISORYLOCK_DISTRIBUTED)) {
         OA::debug('Maintenance Distributed Engine Already Running', PEAR_LOG_INFO);
         return;
     }
     OA::debug('Running Maintenance Distributed Engine', PEAR_LOG_INFO);
     // Attempt to increase PHP memory
     OX_increaseMemoryLimit(OX_getMinimumRequiredMemory('maintenance'));
     // Ensure the current time is registered with the OA_ServiceLocator
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oNow =& $oServiceLocator->get('now');
     if (!$oNow) {
         // Record the current time, and register with the OA_ServiceLocator
         $oNow = new Date();
         $oServiceLocator->register('now', $oNow);
     }
     OA::debug(' - Current time is ' . $oNow->format('%Y-%m-%d %H:%M:%S') . ' ' . $oNow->tz->getShortName(), PEAR_LOG_DEBUG);
     // Get the components of the deliveryLog extension
     $aBuckets = OX_Component::getComponents('deliveryLog');
     // Copy buckets' records with "interval_start" up to and including previous OI start,
     // and then prune the data processed
     $aPreviousOperationIntervalDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oNow);
     OA::debug(' - Will process data for all operation intervals before and up to start', PEAR_LOG_DEBUG);
     OA::debug('   time of ' . $aPreviousOperationIntervalDates['start']->format('%Y-%m-%d %H:%M:%S') . ' ' . $aPreviousOperationIntervalDates['start']->tz->getShortName(), PEAR_LOG_DEBUG);
     foreach ($aBuckets as $sBucketName => $oBucketClass) {
         if ($oBucketClass->testStatisticsMigration($oBucketClass->getStatisticsMigration())) {
             $oBucketClass->processBucket($aPreviousOperationIntervalDates['start']);
             $oBucketClass->pruneBucket($aPreviousOperationIntervalDates['start']);
         } else {
             OA::debug('  - Skipping ' . $sBucketName, PEAR_LOG_DEBUG);
         }
     }
     $oLock->release();
     OA::debug('Maintenance Distributed Engine Completed', PEAR_LOG_INFO);
 }
 /**
  * A method to test the convertDateToPreviousOperationIntervalStartAndEndDates() method.
  */
 function testConvertDateToPreviousOperationIntervalStartAndEndDates()
 {
     // Test a date in the first operation interval ID in the week before the test was
     // written, using a default operation interval of 60 minutes
     $date = new Date('2004-08-08 00:40:00');
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($date, 60);
     $this->assertEqual($aDates['start'], new Date('2004-08-07 23:00:00'));
     $this->assertEqual($aDates['end'], new Date('2004-08-07 23:59:59'));
     // Test the same date, but with an operation interval of 30 minutes
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($date, 30);
     $this->assertEqual($aDates['start'], new Date('2004-08-08 00:00:00'));
     $this->assertEqual($aDates['end'], new Date('2004-08-08 00:29:59'));
 }
 /**
  * Method to test the getZonesForecastsForAllZones method.
  *
  * Requirements:
  * Test 1: Test with no Date registered in the service locator, ensure false returned.
  * Test 2: Test with a Date registered in the service locator, no data in the database,
  *         and ensure no data is returned.
  * Test 3: Test with forecast data but no actual impressions
  * Test 3.5: Test with actual data but no forecast impressions
  * Test 4: Test with data both in, and not in, the current OI, and ensure the correct
  *         data is returned.
  * Test 5: Repeat Test 4, but with additional zones (that don't have data) in the zones
  *         table.
  */
 function testGetAllZonesImpInv()
 {
     $conf = $GLOBALS['_MAX']['CONF'];
     $oDbh =& OA_DB::singleton();
     $oMaxDalMaintenance = new OA_Dal_Maintenance_Priority();
     $zoneForecastDefaultZoneImpressions = 0;
     // $oMaxDalMaintenance->getZoneForecastDefaultZoneImpressions();
     // Test 1
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oServiceLocator->remove('now');
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $this->assertFalse($result);
     // Test 2
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $this->assertEqual($result, array(0 => $zoneForecastDefaultZoneImpressions));
     // Zone 0
     // Test 3
     // generate the first zone
     $aZones = $this->_generateTestZones(1);
     //         only generate previous OI delivered impressions, should return zone 0 only
     $oDate =& $oServiceLocator->get('now');
     $oNewDate = new Date();
     $oNewDate->copy($oDate);
     $oNewDate->subtractSeconds($conf['maintenance']['operationInterval'] * 60 + 1);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oNewDate);
     $this->_generateTestHistory(1, $aDates, 42, 0);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $expected = array(0 => $zoneForecastDefaultZoneImpressions, 1 => $zoneForecastDefaultZoneImpressions);
     $this->assertEqual($result, $expected);
     // Test 3.5
     // generate the second zone
     $aZones = $this->_generateTestZones(1);
     //     only generate previous OI forecasted impressions, should return zone 0 only
     $oNewDate = new Date();
     $oNewDate->copy($aDates['start']);
     $oNewDate->subtractSeconds(1);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oNewDate);
     $this->_generateTestHistory(2, $aDates, 0, 37);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $expected = array(0 => $zoneForecastDefaultZoneImpressions, 1 => $zoneForecastDefaultZoneImpressions, 2 => $zoneForecastDefaultZoneImpressions);
     $this->assertEqual($result, $expected);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 4
     $oDate =& $oServiceLocator->get('now');
     // generate three zone
     $this->_generateTestZones(3);
     // set forecast and impressions for OI - 1
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $this->_generateTestHistory(1, $aDates, 42, 100);
     $this->_generateTestHistory(2, $aDates, 5, 2);
     $this->_generateTestHistory(3, $aDates, 9999, 9999);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $expected = array(0 => $zoneForecastDefaultZoneImpressions, 1 => 42, 2 => 5, 3 => 9999);
     $this->assertEqual($result, $expected);
     // Test 5
     // New zone must appear in the array with default forecast
     $aZones = $this->_generateTestZones(1);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $expected = array(0 => $zoneForecastDefaultZoneImpressions, 1 => 42, 2 => 5, 3 => 9999, 4 => $zoneForecastDefaultZoneImpressions);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $this->assertEqual($result, $expected);
     // register forecast for the OI before, this should not affect current OI forecast
     $oDate =& $oServiceLocator->get('now');
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $currentOpIntID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
     $this->_generateTestHistory(1, $aDates, 3700, 0);
     $this->_generateTestHistory(2, $aDates, 300, 0);
     $this->_generateTestHistory(3, $aDates, 500, 0);
     $result =& $oMaxDalMaintenance->getZonesForecastsForAllZones();
     $this->assertEqual($result, $expected);
     DataGenerator::cleanUp();
 }
 /**
  * The method to test the getZonesForecasts() method.
  */
 function testgetZonesForecasts()
 {
     $this->_createTestData();
     $operationInterval = $GLOBALS['_MAX']['CONF']['maintenance']['operationInterval'];
     $oDal = new OA_Dal_Maintenance_Priority();
     $oLowerDate = new Date('2007-09-16 12:00:00');
     $oUpperDate = new Date('2007-09-16 17:00:00');
     $lowerDateStr = $oLowerDate->format(self::DATE_TIME_FORMAT);
     $upperDateStr = $oUpperDate->format(self::DATE_TIME_FORMAT);
     $weeks = 2;
     // Test with bad input
     $badAgencyId = -1;
     $result = $oDal->getZonesForecasts($lowerDateStr, $upperDateStr);
     $expected = array();
     $this->assertEqual($result, $expected);
     // Test with data outside the range
     $oDate = new Date('2007-09-16 11:00:00');
     $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $previousOIDate = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $startDateStr = $aDates['start']->format(self::DATE_TIME_FORMAT);
     $endDateStr = $aDates['end']->format(self::DATE_TIME_FORMAT);
     $doDIA = OA_Dal::factoryDO('data_intermediate_ad');
     $aDIAs = DataGenerator::generate($doDIA, 1);
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[0]);
     $doDIA->date_time = $startDateStr;
     $doDIA->operation_interval = $operationInterval;
     $doDIA->zone_id = $this->zoneId1;
     $doDIA->ad_id = 1;
     $doDIA->impressions = 1000;
     $doDIA->update();
     $result = $oDal->getZonesForecasts($startDateStr, $endDateStr);
     $expected = array();
     $this->assertEqual($result, $expected);
     // Test with data inside the range
     $oDate = new Date('2007-09-16 13:00:00');
     $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $previousOIDate = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $startDateStr = $aDates['start']->format(self::DATE_TIME_FORMAT);
     $endDateStr = $aDates['end']->format(self::DATE_TIME_FORMAT);
     $aDIAs = DataGenerator::generate($doDIA, 1);
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[0]);
     $doDIA->date_time = $previousOIDate['start']->format(self::DATE_TIME_FORMAT);
     $doDIA->operation_interval = $operationInterval;
     $doDIA->zone_id = $this->zoneId1;
     $doDIA->ad_id = 1;
     $doDIA->impressions = 70;
     $doDIA->update();
     $result = $oDal->getZonesForecasts($startDateStr, $endDateStr);
     $expected = array($this->zoneId1 => 70);
     $this->assertEqual($result, $expected);
     // Test with more data from the same zone
     $oDate = new Date('2007-09-16 14:00:00');
     $operationIntervalId = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $previousOIDate = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $startDateStr = $aDates['start']->format(self::DATE_TIME_FORMAT);
     $endDateStr = $aDates['end']->format(self::DATE_TIME_FORMAT);
     $aDIAs = DataGenerator::generate($doDIA, 3);
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[0]);
     $doDIA->date_time = $previousOIDate['start']->format(self::DATE_TIME_FORMAT);
     $doDIA->operation_interval = $operationInterval;
     $doDIA->zone_id = $this->zoneId1;
     $doDIA->ad_id = 2;
     $doDIA->impressions = 90;
     $doDIA->update();
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[1]);
     $doDIA->date_time = $previousOIDate['start']->format(self::DATE_TIME_FORMAT);
     $doDIA->operation_interval = $operationInterval;
     $doDIA->zone_id = $this->zoneId1;
     $doDIA->ad_id = 4;
     $doDIA->impressions = 110;
     $doDIA->update();
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[2]);
     $doDIA->date_time = $previousOIDate['start']->format(self::DATE_TIME_FORMAT);
     $doDIA->operation_interval = $operationInterval;
     $doDIA->zone_id = $this->zoneId2;
     $doDIA->ad_id = 4;
     $doDIA->impressions = 15000;
     $doDIA->update();
     $result = $oDal->getZonesForecasts($startDateStr, $endDateStr);
     $expected = array($this->zoneId1 => 200, $this->zoneId2 => 15000);
     $this->assertEqual($result, $expected);
     DataGenerator::cleanUp();
 }
Beispiel #5
0
 /**
  * A method to get the most recent details of contract campaign creative delivery
  * for a given list of creative/zone pairs set to deliver in the current
  * operation interval. Normally, the data will be retrieved from the previous
  * operation interval, but if no data exists for that creative/zone pair, then the
  * next previous operation interval will be tried, and so on, up to a limit
  * of MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT minutes (default is one week).
  *
  * - Requires that a current day/time (as a Date object) be registered
  *   with the OA_ServiceLocator (as "now").
  *
  * - Ignores creative ID 0 and zone ID 0 items, as these are reserved for
  *   direct selection, which is considered to be outside the process of
  *   priority compensation calculations (even though priority values for
  *   all contract campaign creatives are calculated and stored for the
  *   zone ID 0).
  *
  * Note: The logic of this method seems a little convoluted, and it is.
  * However, it needs to be. The reason being:
  *
  *  - If a contract campaign creative delivered in the previous operation interval,
  *    then it should have had a priority set in ad_zone_assoc (that's how OpenX
  *    knows to deliver contract campiang creatives, natch!). This should be the most
  *    recent entry in data_summary_ad_zone_assoc. So, the first step is to get the
  *    data for all contract campiang creatives that have delivered in the previous
  *    OI, and the associated prioritisation data.
  *  - If a contract campaign creative did not deliver, the prioritisation data set
  *    in the previous OI is still needed anyway (as it might have been *supposed*
  *    to deliver), so the second step is to get those creatives that had
  *    prioiritisation data set in the previous OI, but did not deliver.
  *  - Finally, as some creatives are limited by hour (for example), we want to
  *    to be able to get past prioritisation data for creatives that were
  *    disabled in the last OI, so, we need to look for creative/zone pairs
  *    that have not yet been found, and get BOTH the prioritisation AND the
  *    delivery data from the last OI when the creatives were active in the
  *    zones.
  *
  * This is why the method uses a complex, 3 step process!
  *
  * @access public
  * @param array $aCurrentZones An array of Zones, indexed by Zone ID, with each
  *                             Zone containing the Advert objects that are linked
  *                             to deliver in the zone, in the current operation
  *                             interval.
  * @return mixed An array of arrays of arrays, each one representing a set of
  *               ad/zone delivery information, indexed by ad ID and zone ID.
  *               Each sub-sub array, if present, has the format:
  *               array (
  *                  'ad_id'                         => integer
  *                  'zone_id'                       => integer
  *                  'required_impressions'          => integer
  *                  'requested_impressions'         => integer
  *                  'priority_factor'               => double
  *                  'past_zone_traffic_fraction'    => double
  *                  'impressions'                   => integer
  *               )
  *               Returns false when the current date/time is not set in the
  *               OA_ServiceLocator.
  */
 function &getPreviousAdDeliveryInfo($aCurrentZones)
 {
     OA::debug("  - Getting details of previous creative/zone delivery", PEAR_LOG_DEBUG);
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oDate =& $oServiceLocator->get('now');
     if (!$oDate) {
         return false;
     }
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aPastDeliveryResult = array();
     $aPastPriorityResult = array();
     $aNonDeliveringPastPriorityResult = array();
     $aFinalResult = array();
     // Obtain the earliest existing interval_start date found in the
     // data_summary_ad_zone_assoc table
     $table = $this->_getTablename('data_summary_ad_zone_assoc');
     $query = "\n            SELECT\n                interval_start AS interval_start\n            FROM\n            {$table}\n            ORDER BY\n                interval_start\n            LIMIT\n                1";
     $rc = $this->oDbh->query($query);
     if (!PEAR::isError($rc) && $rc->numRows() == 1) {
         $aRow = $rc->fetchRow();
         $oEarliestPastPriorityRecordDate = new Date($aRow['interval_start']);
         // Create a new date that is the limit number of minutes ago
         $oLimitDate = new Date();
         $oLimitDate->copy($oDate);
         $oLimitDate->subtractSeconds(MAX_PREVIOUS_AD_DELIVERY_INFO_LIMIT * 60);
         // Is the earliest date before this date?
         if ($oEarliestPastPriorityRecordDate->before($oLimitDate)) {
             // Use the limit date instead
             $oEarliestPastPriorityRecordDate = new Date();
             $oEarliestPastPriorityRecordDate->copy($oLimitDate);
         }
     }
     // Obtain the operation interval ID, and the start and end dates of the previous
     // operation interval
     $currentOperationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($currentOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     // Obtain the ad ID, zone ID and number of impressions delivered for every ad/zone
     // combination that delivered impressions in the previous operation interval, where
     // the ad is from a contract campaign (as we don't care about other campaign types)
     OA::debug("  - Getting details of contract campaign creative/zone pairs that delivered last OI", PEAR_LOG_DEBUG);
     $sDataIntermediateAd = $this->_getTablename('data_intermediate_ad');
     $sBanners = $this->_getTablename('banners');
     $sCampaigns = $this->_getTablename('campaigns');
     $query = "\n            SELECT\n                ad_id AS ad_id,\n                zone_id AS zone_id,\n                SUM(impressions) AS impressions\n            FROM\n            {$sDataIntermediateAd} AS dia,\n            {$sBanners} AS b,\n            {$sCampaigns} AS c\n            WHERE\n                dia.operation_interval = {$aConf['maintenance']['operationInterval']}\n                AND\n                dia.operation_interval_id = {$previousOperationIntervalID}\n                AND\n                dia.interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                dia.interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                AND\n                dia.ad_id != 0\n                AND\n                dia.zone_id != 0\n                AND\n                dia.ad_id = b.bannerid\n                AND\n                b.campaignid = c.campaignid\n                AND\n                c.priority > 0\n            GROUP BY\n                ad_id,\n                zone_id\n            ORDER BY\n                ad_id,\n                zone_id";
     $rc = $this->oDbh->query($query);
     while ($aRow = $rc->fetchRow()) {
         // Store the ad ID as being one that has delivered
         $aAds[$aRow['ad_id']] = $aRow['ad_id'];
         // Store the zone ID as one that had impressions in it
         $aZones[$aRow['zone_id']] = $aRow['zone_id'];
         // Store the ad IDs by zone ID
         $aZonesAds[$aRow['zone_id']][$aRow['ad_id']] = true;
         // Store the impressions delivered for the contract campaign creative/zone pair,
         // and that the past priority information for this contract campiang creative/zone
         // pair has not been found yet (it will be found later on)
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['impressions'] = $aRow['impressions'];
         $aPastDeliveryResult[$aRow['ad_id']][$aRow['zone_id']]['pastPriorityFound'] = false;
     }
     // Did any ads deliver last operation interval?
     if (!empty($aAds)) {
         // Is there past deliver data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // As all of the above contract capiang creative/zone combinations delivered impressions
             // in the previous operation interval, a priority value must have existed. However, the
             // priority value may *not* have come from the previous interval, as maintenance may not
             // have been run (although it should have ;-)
             // To be sure, interate backwards over past operation intervals (up to the earliest
             // existing record), obtaining the details of the impressions requested and the priority
             // values used for the above combinations
             $previousOperationIntervalIDLoop = $previousOperationIntervalID;
             $aDatesLoop = array();
             $aDatesLoop['start'] = new Date();
             $aDatesLoop['start']->copy($aDates['start']);
             $aDatesLoop['end'] = new Date();
             $aDatesLoop['end']->copy($aDates['end']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     OA::debug('    - Getting past details of contract campiang creative/zone pairs for OI starting at ' . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired\n                            FROM\n                            {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND\n                                zone_id IN (" . implode(', ', $aZones) . ")\n                                AND\n                                operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND\n                                operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND\n                                interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND\n                                interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aPastDeliveryResult in the call to
                     // _calculateAveragePastPriorityValues(), so that if this is the second (or greater)
                     // time this has been done then any contract campiang creative/zone pairs that have
                     // come up with details for a second (or greater) time (i.e. as a result of a priority
                     // value record from an earise operation interval as we iterate backwards in time) will
                     // NOT have its past priority info re-calculated with the wrong values
                     $this->_calculateAveragePastPriorityValues($aPastPriorityResult, $aResult, $oDate, $aPastDeliveryResult);
                     // Loop over the results, marking off the contract campiang banner/zone
                     // combinations in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aPastPriorityResult)) {
                         foreach ($aPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                 }
                 // Look over the past delivery array to see if there are any contract campaign creative/zone
                 // combinations that do not yet have the past prioritisation information
                 $foundAll = true;
                 if (!empty($aPastDeliveryResult)) {
                     foreach ($aPastDeliveryResult as $a => $aAd) {
                         $remove = true;
                         foreach ($aAd as $z => $aZone) {
                             if (!$aPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                 if ($foundAll) {
                                     // Need to go back in time to look for more past priority info
                                     $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                     $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                     if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                         // Haven't exceeded earliest priority info date, so okay
                                         // to go ahead with going back in time...
                                         $foundAll = false;
                                     }
                                 }
                                 $remove = false;
                             }
                             // Remove the contract campaign creative from the list of creatives to select
                             // from next round, and check if this was the last creative in the zone, and,
                             // if so, also remove the zone from the list of zones to select from
                             // next round
                             if ($remove) {
                                 unset($aAds[$a]);
                                 unset($aZonesAds[$z][$a]);
                                 if (count($aZonesAds[$z]) == 0) {
                                     unset($aZones[$z]);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aPastDeliveryResult)) {
             foreach ($aPastDeliveryResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aPastPriorityResult[$a][$z]['past_zone_traffic_fraction'], 'impressions' => $aPastDeliveryResult[$a][$z]['impressions']);
                 }
             }
         }
     }
     // Select the details of all contract campaign creative/zones that had required/requested impressions,
     // in the previous operation interval, but for which no impressions were delivered
     OA::debug('  - Getting details of contract campaign creative/zone pairs that did not deliver last OI (but should have)', PEAR_LOG_DEBUG);
     $table1 = $this->_getTablename('data_summary_ad_zone_assoc');
     $table2 = $this->_getTablename('data_intermediate_ad');
     $oneHourInterval = OA_Dal::quoteInterval(1, 'hour');
     // we have to do this complicated MINUS query (mysql doesn't support MINUS so we do a LEFT JOIN exclude not matching)
     // and we do two subqueries in order to use the INDEXes as expected
     // note the trick that we use range lookup on the date_time field as this is the one that is indexed
     $query = "\n            SELECT dsaza.*\n            FROM (\n                SELECT\n                    ad_id AS ad_id,\n                    zone_id AS zone_id,\n                    required_impressions AS required_impressions,\n                    requested_impressions AS requested_impressions,\n                    to_be_delivered AS to_be_delivered,\n                    priority_factor AS priority_factor,\n                    past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                    created AS created,\n                    expired AS expired\n                FROM\n                {$table1} AS dsaza\n                WHERE\n                    operation_interval = {$aConf['maintenance']['operationInterval']}\n                    AND\n                    operation_interval_id = {$previousOperationIntervalID}\n                    AND\n                    interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    ad_id != 0\n                    AND\n                    zone_id != 0\n                    AND\n                    required_impressions > 0\n                    AND\n                    requested_impressions > 0\n                ORDER BY\n                    ad_id,\n                    zone_id\n            ) as dsaza\n            LEFT JOIN\n            (\n            \tSELECT\n            \t\tad_id,\n            \t\tzone_id\n            \tFROM\n            \t{$table2} AS dia\n                WHERE\n                    operation_interval = {$aConf['maintenance']['operationInterval']}\n                    AND\n                    operation_interval_id = {$previousOperationIntervalID}\n                    AND\n                    interval_start = '" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    interval_end = '" . $aDates['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                    AND\n                    date_time > DATE_SUB('" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                    AND\n                    date_time < DATE_ADD('" . $aDates['start']->format('%Y-%m-%d %H:%M:%S') . "', {$oneHourInterval})\n                ORDER BY\n                    ad_id,\n                    zone_id\n            ) as dia\n            ON\n                dsaza.ad_id = dia.ad_id\n                AND\n                dsaza.zone_id = dia.zone_id\n            WHERE\n                dia.ad_id IS NULL\n                AND\n                dia.zone_id IS NULL\n            ";
     $rc = $this->oDbh->query($query);
     $aResult = $rc->fetchAll();
     $resultCount = count($aResult);
     OA::debug('    - Found ' . $resultCount . ' contract campaign creative/zone pairs that did not deliver last OI (but should have)', PEAR_LOG_DEBUG);
     if ($resultCount > 0) {
         // Calculate the past priority results, but without the optional parameter to
         // _calculateAveragePastPriorityValues(), as this is a single calculation on data
         // in the past OI, and no further looping back over time will occur
         OA::debug('  - Getting past details of the non-delivering contract campiang creative/zone pairs', PEAR_LOG_DEBUG);
         $this->_calculateAveragePastPriorityValues($aNonDeliveringPastPriorityResult, $aResult, $oDate);
         // Merge the past priority values into the final results array
         if (!empty($aNonDeliveringPastPriorityResult)) {
             foreach ($aNonDeliveringPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     if (empty($aFinalResult[$a][$z])) {
                         $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNonDeliveringPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNonDeliveringPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNonDeliveringPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNonDeliveringPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                     }
                 }
             }
         }
     }
     // Finally, now that all contract campaign creative/zone combinations that had required/requested
     // impressions in the previous operation interval and delivered/didn't deliver issues have been
     // dealt with, check to see if there are any contract campaign creative/zone combinations that are
     // linked to deliver in the current operation interval, which are not covered by the above
     OA::debug('  - Finding contract campaign creative/zone pairs set to deliver, but with no past data yet', PEAR_LOG_DEBUG);
     $aAds = array();
     $aZones = array();
     $aZonesAds = array();
     $aNotInLastOIPastDeliveryResult = array();
     $aNotInLastOIPastPriorityResult = array();
     if (is_array($aCurrentZones) && !empty($aCurrentZones)) {
         foreach ($aCurrentZones as $zoneId => $oZone) {
             // Ignore Zone ID 0, as data for this zone is not required (there will no be
             // priority compensation performed on this zone, the past data is not relevant)
             if ($oZone->id != 0) {
                 if (is_array($oZone->aAdverts) && !empty($oZone->aAdverts)) {
                     foreach ($oZone->aAdverts as $oAdvert) {
                         // Store that the past priority information for this contract campiagn creative/zone
                         // pair may not have yet been found
                         $aNotInLastOIPastDeliveryResult[$oAdvert->id][$zoneId]['pastPriorityFound'] = false;
                     }
                 }
             }
         }
     }
     // Remove those contract campiagn creative/zone pairs that have,
     // in fact, already had their past priority information found
     if (!empty($aFinalResult)) {
         foreach ($aFinalResult as $aResult) {
             if (isset($aResult['ad_id'])) {
                 unset($aNotInLastOIPastDeliveryResult[$aResult['ad_id']][$aResult['zone_id']]);
             }
         }
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aTestZone) {
             if (empty($aTestZone)) {
                 unset($aNotInLastOIPastDeliveryResult[$adKey]);
             }
         }
     }
     // Create the sets of required creatives and zones that need their past priority
     // information from older operation intervals found (exluding zone ID 0, as this
     // is not required)
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         foreach ($aNotInLastOIPastDeliveryResult as $adKey => $aData) {
             // Store the creative ID as being one that needs to deliver
             $aAds[$adKey] = $adKey;
             foreach ($aData as $zoneKey => $value) {
                 // Store the zone ID as one that has a creative that needs to deliver in it
                 $aZones[$zoneKey] = $zoneKey;
                 // Store the creative ID by zone ID
                 $aZonesAds[$zoneKey][$adKey] = true;
             }
         }
     }
     // Are there any contract campiagn creative/zone pairs that need data?
     if (!empty($aNotInLastOIPastDeliveryResult)) {
         // Is there past delivery data?
         if (isset($oEarliestPastPriorityRecordDate)) {
             // Loop over the previous operation intervals, starting with the one
             // *before* last, and find when (if possible) these contract campiagn
             // creative/zone pairs last *requested* to deliver; it doesn't matter if
             // they did deliver in that operation interval or not
             $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
             $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
             $foundAll = false;
             while (!$foundAll) {
                 if (!empty($aAds) && !empty($aZones)) {
                     OA::debug('    - Getting past details of contract campiagn creative/zone pairs which did not deliver last OI, for OI ' . 'starting at ' . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S'), PEAR_LOG_DEBUG);
                     $table = $this->_getTablename('data_summary_ad_zone_assoc');
                     $query = "\n                            SELECT\n                                ad_id AS ad_id,\n                                zone_id AS zone_id,\n                                required_impressions AS required_impressions,\n                                requested_impressions AS requested_impressions,\n                                to_be_delivered AS to_be_delivered,\n                                priority_factor AS priority_factor,\n                                past_zone_traffic_fraction AS past_zone_traffic_fraction,\n                                created AS created,\n                                expired AS expired,\n                                operation_interval AS operation_interval,\n                                operation_interval_id AS operation_interval_id,\n                                interval_start AS interval_start,\n                                interval_end AS interval_end\n                            FROM\n                            {$table}\n                            WHERE\n                                ad_id IN (" . implode(', ', $aAds) . ")\n                                AND\n                                zone_id IN (" . implode(', ', $aZones) . ")\n                                AND\n                                operation_interval = {$aConf['maintenance']['operationInterval']}\n                                AND\n                                operation_interval_id = {$previousOperationIntervalIDLoop}\n                                AND\n                                interval_start = '" . $aDatesLoop['start']->format('%Y-%m-%d %H:%M:%S') . "'\n                                AND\n                                interval_end = '" . $aDatesLoop['end']->format('%Y-%m-%d %H:%M:%S') . "'\n                            ORDER BY\n                                ad_id,\n                                zone_id";
                     $rc = $this->oDbh->query($query);
                     $aResult = $rc->fetchAll();
                     // Calculate the past priority results, using $aPastDeliveryResult in the call to
                     // _calculateAveragePastPriorityValues(), so that if this is the second (or greater)
                     // time this has been done then any contract campiang creative/zone pairs that have
                     // come up with details for a second (or greater) time (i.e. as a result of a priority
                     // value record from an earise operation interval as we iterate backwards in time) will
                     // NOT have its past priority info re-calculated with the wrong values
                     $this->_calculateAveragePastPriorityValues($aNotInLastOIPastPriorityResult, $aResult, $oDate, $aNotInLastOIPastDeliveryResult);
                     // Loop over the results, marking off the contract campiagn creative/zone
                     // combinations in the past delivery array as having had their past prioritisation
                     // information found and/or calculated
                     if (!empty($aNotInLastOIPastPriorityResult)) {
                         foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                             foreach ($aAd as $z => $aZone) {
                                 if ($aZone['pastPriorityFound']) {
                                     $aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound'] = true;
                                 }
                             }
                         }
                     }
                     // Look over the past delivery array to see if there are any contract campiagn creative/zone
                     // combinations that do not yet have the past prioritisation information
                     $foundAll = true;
                     if (!empty($aNotInLastOIPastDeliveryResult)) {
                         foreach ($aNotInLastOIPastDeliveryResult as $a => $aAd) {
                             $remove = true;
                             foreach ($aAd as $z => $aZone) {
                                 if (!$aNotInLastOIPastDeliveryResult[$a][$z]['pastPriorityFound']) {
                                     if ($foundAll) {
                                         // Need to go back in time to look for more past priority info
                                         $previousOperationIntervalIDLoop = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalIDLoop);
                                         $aDatesLoop = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDatesLoop['start']);
                                         if (!$aDatesLoop['start']->before($oEarliestPastPriorityRecordDate)) {
                                             // Haven't exceeded earliest priority info date, so okay
                                             // to go ahead with going back in time...
                                             $foundAll = false;
                                         }
                                     }
                                     $remove = false;
                                 }
                                 // Remove the creative from the list of creatives to select from next round,
                                 // and check if this was the last creative in the zone, and, if so,
                                 // also remove the zone from the list of zones to select from
                                 // next round
                                 if ($remove) {
                                     unset($aAds[$a]);
                                     unset($aZonesAds[$z][$a]);
                                     if (count($aZonesAds[$z]) == 0) {
                                         unset($aZones[$z]);
                                     }
                                 }
                             }
                         }
                     }
                 } else {
                     $foundAll = true;
                 }
             }
         }
         // Now that it is known when (if) the remaining creatives last requested to deliver,
         // determine how many impressions were delivered (if any) during the appropriate
         // operation intervals
         if (!empty($aNotInLastOIPastPriorityResult)) {
             $table = $this->_getTablename('data_intermediate_ad');
             $oneHourInterval = OA_Dal::quoteInterval(1, 'hour');
             $query = "\n                    SELECT\n                        SUM(impressions) AS impressions\n                    FROM\n                    {$table}\n                    WHERE\n                        operation_interval = ?\n                        AND\n                        operation_interval_id = ?\n                        AND\n                        date_time > DATE_SUB(?, " . $oneHourInterval . ")\n                        AND\n                        date_time < DATE_ADD(?, " . $oneHourInterval . ")\n                        AND\n                        interval_start = ?\n                        AND\n                        interval_end = ?\n                        AND\n                        ad_id = ?\n                        AND\n                        zone_id = ?";
             $aTypes = array('integer', 'integer', 'timestamp', 'timestamp', 'timestamp', 'timestamp', 'integer', 'integer');
             $stSelectSumImpressions = $this->oDbh->prepare($query, $aTypes, MDB2_PREPARE_RESULT);
             OA::debug('  - Looping over each zone linked to ' . count($aNotInLastOIPastPriorityResult) . ' ads');
             $countQueriesSumImp = 0;
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 OA::debug('    - Requesting sum of impressions for ad ID ' . $a . ' for ' . count($aAd) . ' zones ', PEAR_LOG_DEBUG);
                 foreach ($aAd as $z => $aZone) {
                     $aData = array($aNotInLastOIPastPriorityResult[$a][$z]['operation_interval'], $aNotInLastOIPastPriorityResult[$a][$z]['operation_interval_id'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_start'], $aNotInLastOIPastPriorityResult[$a][$z]['interval_end'], $a, $z);
                     $rsResult = $stSelectSumImpressions->execute($aData);
                     $aResult = $rsResult->fetchAll();
                     if (isset($aResult[0]['impressions'])) {
                         $aNotInLastOIPastPriorityResult[$a][$z]['impressions'] = $aResult[0]['impressions'];
                     }
                     $countQueriesSumImp++;
                 }
             }
             OA::debug('  - Finished querying impressions for ' . $countQueriesSumImp . ' ad-zones combinations');
         }
         // Merge the past priority and delivery values into the final results array
         if (!empty($aNotInLastOIPastPriorityResult)) {
             foreach ($aNotInLastOIPastPriorityResult as $a => $aAd) {
                 foreach ($aAd as $z => $aZone) {
                     if (empty($aFinalResult[$a][$z])) {
                         $aFinalResult[$a][$z] = array('ad_id' => $a, 'zone_id' => $z, 'required_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['required_impressions'], 'requested_impressions' => $aNotInLastOIPastPriorityResult[$a][$z]['requested_impressions'], 'to_be_delivered' => $aNotInLastOIPastPriorityResult[$a][$z]['to_be_delivered'], 'priority_factor' => $aNotInLastOIPastPriorityResult[$a][$z]['priority_factor'], 'past_zone_traffic_fraction' => $aNotInLastOIPastPriorityResult[$a][$z]['past_zone_traffic_fraction']);
                         if (isset($aNotInLastOIPastPriorityResult[$a][$z]['impressions'])) {
                             $aFinalResult[$a][$z]['impressions'] = $aNotInLastOIPastPriorityResult[$a][$z]['impressions'];
                         }
                     }
                 }
             }
         }
     }
     return $aFinalResult;
 }
 /**
  * A private method to calculate an equivalent "last time that maintenance
  * statistics was run" value from logged delivery data, if possible.
  *
  * Enables the MSE process to be kick-started for new installations, where
  * the MSE has not been run before; but without causing the MSE to run
  * until the installation is actually logging data.
  *
  * @access private
  * @param integer $type The update type that "occurred" - that is,
  *                      OX_DAL_MAINTENANCE_STATISTICS_UPDATE_OI if the required
  *                      calculated "update date" needs to be in terms of the
  *                      operation interval; or
  *                      OX_DAL_MAINTENANCE_STATISTICS_UPDATE_HOUR if the
  *                      required calculated "update date" needs to be in terms
  *                      of the hour.
  * @return Date A Date representing the end of the operation interval
  *              which is before the date found of the earliest known
  *              logged delivery data record. Returns null if no logged
  *              delivery data can be located.
  */
 function _getEarliestLoggedDeliveryData($type)
 {
     // Obtain all components from the deliveryLog plugin group
     $aDeliveryLogComponents = OX_Component::getComponents('deliveryLog');
     // Are there any components?
     if (empty($aDeliveryLogComponents)) {
         return null;
     }
     // Call the "getEarliestLoggedDataDate()" method on each
     // component, to find out what is the date of the earliest
     // logged data that the component knows about
     $aResult = OX_Component::callOnComponents($aDeliveryLogComponents, 'getEarliestLoggedDataDate');
     if ($aResults === false) {
         return null;
     }
     // Iterate over the results from above, and see if any of
     // the components returned valid dates, and if so, which
     // of the results is the earliest
     $oDate = null;
     foreach ($aResult as $oComponentDate) {
         if (is_a($oComponentDate, 'Date')) {
             // Logged data was located! Is this date earlier than
             // any previous "earliest" logged delivery data?
             if (is_null($oDate)) {
                 $oDate = new Date();
                 $oDate->copy($oComponentDate);
             } else {
                 if ($oComponentDate->before($oDate)) {
                     $oDate->copy($oComponentDate);
                 }
             }
         }
     }
     // Was a date found?
     if (is_null($oDate) || !is_a($oDate, 'Date')) {
         return null;
     }
     // Convert the located earliest logged data date into either the
     // end of the previous operation interval, or the end of the previous
     // hour, depending on the required type
     if ($type == OX_DAL_MAINTENANCE_STATISTICS_UPDATE_OI) {
         $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     } else {
         $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate, 60);
     }
     // Return the date
     return $aDates['end'];
 }
Beispiel #7
0
 /**
  * A method to get all zones that have, within the last week, Zone Impression
  * Forecast data in the data_summary_zone_impression_history table that is
  * based on the default forecast, from a given list of zone IDs.
  *
  * @param array $aZoneIDs An array of zone IDs.
  * @param PEAR::Date $oNowDate The current date/time.
  * @return mixed Either:
  *      - An array of zone IDs, or
  *      - A PEAR::Error.
  */
 function getRecentZones($aZoneIDs, $oNowDate)
 {
     $aResult = array();
     // Check parameters
     if (!is_array($aZoneIDs) || is_array($aZoneIDs) && count($aZoneIDs) == 0) {
         return $aResult;
     }
     foreach ($aZoneIDs as $zoneId) {
         if (!is_integer($zoneId) || $zoneId < 0) {
             return $aResult;
         }
     }
     if (!is_a($oNowDate, 'Date')) {
         return $aResult;
     }
     // Convert the "now" date into a date range of the last week
     $aUpperDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oNowDate);
     $oLowerDate = new Date();
     $oLowerDate->copy($aUpperDates['start']);
     $oLowerDate->subtractSeconds(SECONDS_PER_WEEK - OX_OperationInterval::secondsPerOperationInterval());
     // Select those zone IDs where data does exist
     $table = $this->_getTablename('data_summary_zone_impression_history');
     $query = "\n            SELECT DISTINCT\n                zone_id\n            FROM\n                {$table}\n            WHERE\n                zone_id IN (" . implode(', ', $aZoneIDs) . ")\n                AND\n                est = 1\n                AND\n                interval_start > " . $this->oDbh->quote($oLowerDate->format('%Y-%m-%d %H:%M:%S'), 'timestamp') . "\n                AND\n                interval_end <= " . $this->oDbh->quote($aUpperDates['start']->format('%Y-%m-%d %H:%M:%S'), 'timestamp');
     $rc = $this->oDbh->query($query);
     if (PEAR::isError($rc)) {
         return $rc;
     }
     // Add zones found to the result array
     while ($aRow = $rc->fetchRow()) {
         $aResult[] = $aRow['zone_id'];
     }
     return $aResult;
 }
Beispiel #8
0
 /**
  * @param $oDate
  * @param $campaignId
  * @return int Number of emails sent
  */
 function sendCampaignImpendingExpiryEmail($oDate, $campaignId)
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     global $date_format;
     $oPreference = new OA_Preferences();
     if (!isset($this->aAdminCache)) {
         // Get admin account ID
         $adminAccountId = OA_Dal_ApplicationVariables::get('admin_account_id');
         // Get admin prefs
         $adminPrefsNames = $this->_createPrefsListPerAccount(OA_ACCOUNT_ADMIN);
         $aAdminPrefs = $oPreference->loadAccountPreferences($adminAccountId, $adminPrefsNames, OA_ACCOUNT_ADMIN);
         // Get admin users
         $aAdminUsers = $this->getAdminUsersLinkedToAccount();
         // Store admin cache
         $this->aAdminCache = array($aAdminPrefs, $aAdminUsers);
     } else {
         // Retrieve admin cache
         list($aAdminPrefs, $aAdminUsers) = $this->aAdminCache;
     }
     $aPreviousOIDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aPreviousOIDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aPreviousOIDates['start']);
     $doCampaigns = OA_Dal::staticGetDO('campaigns', $campaignId);
     if (!$doCampaigns) {
         return 0;
     }
     $aCampaign = $doCampaigns->toArray();
     if (!isset($this->aClientCache[$aCampaign['clientid']])) {
         $doClients = OA_Dal::staticGetDO('clients', $aCampaign['clientid']);
         // Add advertiser linked users
         $aLinkedUsers['advertiser'] = $this->getUsersLinkedToAccount('clients', $aCampaign['clientid']);
         // Add advertiser prefs
         $advertiserPrefsNames = $this->_createPrefsListPerAccount(OA_ACCOUNT_ADVERTISER);
         $aPrefs['advertiser'] = $oPreference->loadAccountPreferences($doClients->account_id, $advertiserPrefsNames, OA_ACCOUNT_ADVERTISER);
         if (!isset($aAgencyCache[$doClients->agencyid])) {
             // Add manager linked users
             $doAgency = OA_Dal::staticGetDO('agency', $doClients->agencyid);
             $aLinkedUsers['manager'] = $this->getUsersLinkedToAccount('agency', $doClients->agencyid);
             // Add manager preferences
             $managerPrefsNames = $this->_createPrefsListPerAccount(OA_ACCOUNT_MANAGER);
             $aPrefs['manager'] = $oPreference->loadAccountPreferences($doAgency->account_id, $managerPrefsNames, OA_ACCOUNT_MANAGER);
             // Get agency "From" details
             $aAgencyFromDetails = $this->_getAgencyFromDetails($doAgency->agencyid);
             // Store in the agency cache
             $this->aAgencyCache = array($doClients->agencyid => array($aLinkedUsers['manager'], $aPrefs['manager'], $aAgencyFromDetails));
         } else {
             // Retrieve agency cache
             list($aLinkedUsers['manager'], $aPrefs['manager'], $aAgencyFromDetails) = $this->aAgencyCache[$doClients->agencyid];
         }
         // Add admin linked users and preferences
         $aLinkedUsers['admin'] = $aAdminUsers;
         $aPrefs['admin'] = $aAdminPrefs;
         // Create a linked user 'special' for the advertiser that will take the admin preferences for advertiser
         $aLinkedUsers['special']['advertiser'] = $doClients->toArray();
         $aLinkedUsers['special']['advertiser']['contact_name'] = $aLinkedUsers['special']['advertiser']['contact'];
         $aLinkedUsers['special']['advertiser']['email_address'] = $aLinkedUsers['special']['advertiser']['email'];
         $aLinkedUsers['special']['advertiser']['language'] = '';
         $aLinkedUsers['special']['advertiser']['user_id'] = 0;
         // Check that every user is not going to receive more than one email if they
         // are linked to more than one account
         $aLinkedUsers = $this->_deleteDuplicatedUser($aLinkedUsers);
         // Create the linked special user preferences from the admin preferences
         // the special user is the client that doesn't have preferences in the database
         $aPrefs['special'] = $aPrefs['admin'];
         $aPrefs['special']['warn_email_special'] = $aPrefs['special']['warn_email_advertiser'];
         $aPrefs['special']['warn_email_special_day_limit'] = $aPrefs['special']['warn_email_advertiser_day_limit'];
         $aPrefs['special']['warn_email_special_impression_limit'] = $aPrefs['special']['warn_email_advertiser_impression_limit'];
         // Store in the client cache
         $this->aClientCache = array($aCampaign['clientid'] => array($aLinkedUsers, $aPrefs, $aAgencyFromDetails));
     } else {
         // Retrieve client cache
         list($aLinkedUsers, $aPrefs, $aAgencyFromDetails) = $this->aClientCache[$aCampaign['clientid']];
     }
     $copiesSent = 0;
     foreach ($aLinkedUsers as $accountType => $aUsers) {
         if ($accountType == 'special' || $accountType == 'advertiser') {
             // Get the agency details and use them for emailing advertisers
             $aFromDetails = $aAgencyFromDetails;
         } else {
             // Use the Admin details
             $aFromDetails = '';
         }
         if ($aPrefs[$accountType]['warn_email_' . $accountType]) {
             // Does the account type want warnings when the impressions are low?
             if ($aPrefs[$accountType]['warn_email_' . $accountType . '_impression_limit'] > 0 && $aCampaign['views'] > 0) {
                 // Test to see if the placements impressions remaining are less than the limit
                 $dalCampaigns = OA_Dal::factoryDAL('campaigns');
                 $remainingImpressions = $dalCampaigns->getAdImpressionsLeft($aCampaign['campaignid']);
                 if ($remainingImpressions < $aPrefs[$accountType]['warn_email_' . $accountType . '_impression_limit']) {
                     // Yes, the placement will expire soon! But did the placement just reach
                     // the point where it is about to expire, or did it happen a while ago?
                     $previousRemainingImpressions = $dalCampaigns->getAdImpressionsLeft($aCampaign['campaignid'], $aPreviousOIDates['end']);
                     if ($previousRemainingImpressions >= $aPrefs[$accountType]['warn_email_' . $accountType . '_impression_limit']) {
                         // Yes! This is the operation interval that the boundary
                         // was crossed to the point where it's about to expire,
                         // so send that email, baby!
                         foreach ($aUsers as $aUser) {
                             $aEmail = $this->prepareCampaignImpendingExpiryEmail($aUser, $aCampaign['clientid'], $aCampaign['campaignid'], 'impressions', $aPrefs[$accountType]['warn_email_' . $accountType . '_impression_limit'], $accountType);
                             if ($aEmail !== false) {
                                 if ($this->sendMail($aEmail['subject'], $aEmail['contents'], $aUser['email_address'], $aUser['contact_name'], $aFromDetails)) {
                                     $copiesSent++;
                                     if ($aConf['email']['logOutgoing']) {
                                         phpAds_userlogSetUser(phpAds_userMaintenance);
                                         phpAds_userlogAdd(phpAds_actionWarningMailed, $aPlacement['campaignid'], "{$aEmail['subject']}\n\n\n                                                 {$aUser['contact_name']}({$aUser['email_address']})\n\n\n                                                 {$aEmail['contents']}");
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             // Does the account type want warnings when the days are low?
             if ($aPrefs[$accountType]['warn_email_' . $accountType . '_day_limit'] > 0 && !empty($aCampaign['expire_time'])) {
                 // Calculate the date that should be used to see if the warning needs to be sent
                 $warnSeconds = (int) ($aPrefs[$accountType]['warn_email_' . $accountType . '_day_limit'] + 1) * SECONDS_PER_DAY;
                 $oEndDate = new Date($aCampaign['expire_time']);
                 $oEndDate->setTZbyID('UTC');
                 $oTestDate = new Date();
                 $oTestDate->copy($oDate);
                 $oTestDate->addSeconds($warnSeconds);
                 // Test to see if the test date is after the placement's expiration date
                 if ($oTestDate->after($oEndDate)) {
                     // Yes, the placement will expire soon! But did the placement just reach
                     // the point where it is about to expire, or did it happen a while ago?
                     $oiSeconds = (int) $aConf['maintenance']['operationInterval'] * 60;
                     $oTestDate->subtractSeconds($oiSeconds);
                     if (!$oTestDate->after($oEndDate)) {
                         // Yes! This is the operation interval that the boundary
                         // was crossed to the point where it's about to expire,
                         // so send those emails, baby!
                         foreach ($aUsers as $aUser) {
                             $aEmail = $this->prepareCampaignImpendingExpiryEmail($aUser, $aCampaign['clientid'], $aCampaign['campaignid'], 'date', $oEndDate->format($date_format), $accountType);
                             if ($aEmail !== false) {
                                 if ($this->sendMail($aEmail['subject'], $aEmail['contents'], $aUser['email_address'], $aUser['contact_name'], $aFromDetails)) {
                                     $copiesSent++;
                                     if ($aConf['email']['logOutgoing']) {
                                         phpAds_userlogSetUser(phpAds_userMaintenance);
                                         phpAds_userlogAdd(phpAds_actionWarningMailed, $aPlacement['campaignid'], "{$aEmail['subject']}\n\n\n                                                 {$aUser['contact_name']}({$aUser['email_address']})\n\n\n                                                 {$aEmail['contents']}");
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Restore the default language strings
     Language_Loader::load('default');
     return $copiesSent;
 }
 /**
  * Method to test the getPreviousAdDeliveryInfo method.
  *
  * Requirements:
  * Test 1:   Test with no Date registered in the service locator, ensure false returned.
  * Test 2:   Test with a Date registered in the service locator, no data in the database,
  *           and ensure no data is returned.
  *
  * Test 3:   Test with ONLY impression data, but NOT in the previous OI, and ensure no
  *           data is returned.
  * Test 4:   Test with ONLY impression data, in the previous OI, and ensure that ONLY
  *           data relating to the impressions is returned.
  * Test 5:   Test with ONLY impression data, in the 2nd previous OI, and ensure that
  *           no data is returned.
  * Test 5a:  Re-test with ONLY impression data, in the 2nd previous OI, but pass in the
  *           ad/zone pair, and ensure that no data is returned.
  *
  * Test 6:   Test with ONLY prioritisation data, but NOT in the previous OI, and
  *           ensure no data is returned.
  * Test 7:   Test with ONLY prioritisation data, in the previous OI, and ensure that
  *           ONLY data relating to the prioritisation is returned.
  * Test 8:   Test with ONLY prioritisation data, in the 2nd previous OI, and ensure no
  *           data is returned.
  * Test 8a:  Re-test with ONLY prioritisation data, in the 2nd previous OI, but pass in
  *           the ad/zone pair, and ensure that ONLY data relating to the prioritisation
  *           is returned.
  *
  * Test 9:   Test with BOTH impressions data NOT in the previous OI, and prioritisation
  *           data NOT in the previous OI, and ensure no data is returned.
  * Test 10:  Test with BOTH impressions data NOT in the previous OI, and prioritisation
  *           data in the previous OI, and ensure ONLY data relating to the prioritisation
  *           is returned.
  * Test 11:  Test with BOTH impressions data NOT in the previous OI, and prioritisation
  *           data in the 2nd previous OI, and ensure no data is returned.
  * Test 11a: Re-test with BOTH impressions data NOT in the previous OI, and prioritisation
  *           data in the 2nd previous OI, but pass in the ad/zone pair, and ensure that
  *           ONLY data relating to the prioritisation is returned.
  *
  * Test 12:  Test with BOTH impressions data in the 2nd previous OI, and prioritisation
  *           data NOT in the previous OI, and ensure no data is returned.
  * Test 13:  Test with BOTH impressions data in the 2nd previous OI, and prioritisation
  *           data in the previous OI, and ensure ONLY data relating to the prioritisation
  *           is returned.
  * Test 14:  Test with BOTH impressions data in the 2nd previous OI, and prioritisation
  *           data in the 2nd previous OI, and ensure no data is returned.
  * Test 14a: Re-test with BOTH impressions data in the 2nd previous OI, and prioritisation
  *           data in the 2nd previous OI, but pass in the ad/zone pair, and ensure that
  *           all data is returned.
  *
  * Test 15:  Test with BOTH impressions data in the previous OI, and prioritisation
  *           data NOT in the previous OI, and ensure that ONLY data relating to the
  *           impressions is returned.
  * Test 16:  Test with BOTH impressions data in the previous OI, and prioritisation
  *           data in the previous OI, and ensure that all data is returned.
  * Test 17:  Test with BOTH impressions data in the previous OI, and prioritisation
  *           data in the 2nd previous OI, and ensure that all data is returned.
  * Test 17a: Re-test with BOTH impressions data in the previous OI, and prioritisation
  *           data in the 2nd previous OI, but pass in the ad/zone pair, and ensure that
  *           all data is returned.
  *
  * Test 18:  Perform a more realistic test, with data for the ads/zones in various
  *           past OIs, and including some ads with multiple prioritisation data
  *           per OI, as well as ads with no prioritisation data in some OIs, and
  *           ensure that the correct values are returned for each one. Test that:
  *           - Only ad/zones that delivered in the previous operation interval,
  *             or were requested to deliver in the previous operation interval,
  *             but didn't (i.e. not in other intervals) are returned in the
  *             results.
  *           - That prioritisation information where just ONE set of data exists
  *             is returned correctly.
  *           - That prioritisation information where multiple sets of INDENTICAL
  *             data exists is returned correctly.
  *           - That prioritisation information where multiple sets of DIFFERENT
  *             data exists is returned correctly.
  *           - That prioritisation information from older sets of data is
  *             returned correctly.
  * Test 18a: Re-test, but also include ad/zone pairs that are in/not in the above
  *           set of data, and ensure that these ad/zone pairs are also included
  *           in the results.
  */
 function testGetPreviousAdDeliveryInfo()
 {
     $conf = $GLOBALS['_MAX']['CONF'];
     $oDbh =& OA_DB::singleton();
     $oMaxDalMaintenance = new OA_Dal_Maintenance_Priority();
     $aEmptyZoneAdArray = array();
     $aAdParams = array('ad_id' => 1, 'active' => 't', 'type' => 'sql', 'weight' => 1);
     $oAd = new OA_Maintenance_Priority_Ad($aAdParams);
     $oZone = new OX_Maintenance_Priority_Zone(array('zoneid' => 1));
     $oZone->addAdvert($oAd);
     $aZoneAdArray = array($oZone->id => $oZone);
     // Test 1
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oServiceLocator->remove('now');
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertFalse($result);
     // Test 2
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     // Test 3
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $oNow = new Date();
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 4
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertNull($result[1][1]['required_impressions']);
     $this->assertNull($result[1][1]['requested_impressions']);
     $this->assertNull($result[1][1]['priority_factor']);
     $this->assertNull($result[1][1]['past_zone_traffic_fraction']);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 5, 5a
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 0);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 6
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0.1, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 7
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertNull($result[1][1]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 8, 8a
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertNull($result[1][1]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 9
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 10
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertNull($result[1][1]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 11, 11a
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertNull($result[1][1]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 12
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 13
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertNull($result[1][1]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 14, 14a
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 0);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 15
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $operationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertNull($result[1][1]['required_impressions']);
     $this->assertNull($result[1][1]['requested_impressions']);
     $this->assertNull($result[1][1]['priority_factor']);
     $this->assertNull($result[1][1]['past_zone_traffic_fraction']);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 16
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 17, 17a
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 1, 1, 1, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 1);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertEqual($result[1][1]['required_impressions'], 1);
     $this->assertEqual($result[1][1]['requested_impressions'], 1);
     $this->assertEqual($result[1][1]['priority_factor'], 0.5);
     $this->assertEqual($result[1][1]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 18
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 2, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $bannerId2 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 3, 2, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 4, 2, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $bannerId3 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId3, 0, 5, 5, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 100, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 2, 100, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 3, 200, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 4, 200, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId3, 0, 5, 500, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), 4, 0, 5, 500, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $oSpecialDate = new Date($aDates['end']);
     $oSpecialDate->addSeconds(1);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 2, 10, 10, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), 9, 9, 59, 59, 0, 95, 0.995, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 3, 30, 30, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), 0, $aDates['end']->format('%Y-%m-%d %H:30:00'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 3, 30, 30, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 4, 10, 10, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), 0, $aDates['end']->format('%Y-%m-%d %H:30:00'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 4, 20, 20, 0, 0.8, 0.5, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $oSpecialDate = new Date($aDates['end']);
     $oSpecialDate->addSeconds(1);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId3, 5, 200, 200, 0, 0.2, 0.95, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), 0, $aDates['end']->format('%Y-%m-%d %H:30:00'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId3, 5, 100, 100, 0, 0.4, 0.95, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aEmptyZoneAdArray);
     $this->assertEqual(count($result), 4);
     $this->assertEqual(count($result[1]), 2);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertNull($result[1][1]['required_impressions']);
     $this->assertNull($result[1][1]['requested_impressions']);
     $this->assertNull($result[1][1]['priority_factor']);
     $this->assertNull($result[1][1]['past_zone_traffic_fraction']);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $this->assertEqual($result[1][2]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][2]['zone_id'], 2);
     $this->assertEqual($result[1][2]['required_impressions'], 10);
     $this->assertEqual($result[1][2]['requested_impressions'], 10);
     $this->assertEqual($result[1][2]['priority_factor'], 0.5);
     $this->assertEqual($result[1][2]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][2]['impressions'], 1);
     $this->assertEqual(count($result[2]), 2);
     $this->assertEqual($result[2][3]['ad_id'], $bannerId2);
     $this->assertEqual($result[2][3]['zone_id'], 3);
     $this->assertEqual($result[2][3]['required_impressions'], 30);
     $this->assertEqual($result[2][3]['requested_impressions'], 30);
     $this->assertEqual($result[2][3]['priority_factor'], 0.4);
     $this->assertEqual($result[2][3]['past_zone_traffic_fraction'], 0.5);
     $this->assertEqual($result[2][3]['impressions'], 2);
     $this->assertEqual($result[2][4]['ad_id'], $bannerId2);
     $this->assertEqual($result[2][4]['zone_id'], 4);
     $this->assertEqual($result[2][4]['required_impressions'], 15);
     $this->assertEqual($result[2][4]['requested_impressions'], 15);
     $this->assertEqual($result[2][4]['priority_factor'], 0.6);
     $this->assertEqual($result[2][4]['past_zone_traffic_fraction'], 0.5);
     $this->assertEqual($result[2][4]['impressions'], 2);
     $this->assertEqual(count($result[3]), 1);
     $this->assertEqual($result[3][5]['ad_id'], $bannerId3);
     $this->assertEqual($result[3][5]['zone_id'], 5);
     $this->assertEqual($result[3][5]['required_impressions'], 150);
     $this->assertEqual($result[3][5]['requested_impressions'], 150);
     $this->assertEqual($result[3][5]['priority_factor'], 0.3);
     $this->assertEqual($result[3][5]['past_zone_traffic_fraction'], 0.95);
     $this->assertEqual($result[3][5]['impressions'], 5);
     $this->assertEqual(count($result[9]), 1);
     $this->assertEqual($result[9][9]['ad_id'], 9);
     $this->assertEqual($result[9][9]['zone_id'], 9);
     $this->assertEqual($result[9][9]['required_impressions'], 59);
     $this->assertEqual($result[9][9]['requested_impressions'], 59);
     $this->assertEqual($result[9][9]['priority_factor'], 95);
     $this->assertEqual($result[9][9]['past_zone_traffic_fraction'], 0.995);
     $this->assertNull($result[9][9]['impressions']);
     $oDate =& $oServiceLocator->get('now');
     DataGenerator::cleanUp();
     $oServiceLocator->register('now', $oDate);
     // Test 18a
     $oZone = new OX_Maintenance_Priority_Zone(array('zoneid' => 4));
     $aAdParams = array('ad_id' => 10, 'active' => 't', 'type' => 'sql', 'weight' => 1);
     $oAd = new OA_Maintenance_Priority_Ad($aAdParams);
     $oZone->addAdvert($oAd);
     $aAdParams = array('ad_id' => 11, 'active' => 't', 'type' => 'sql', 'weight' => 1);
     $oAd = new OA_Maintenance_Priority_Ad($aAdParams);
     $oZone->addAdvert($oAd);
     $aZoneAdArray = array($oZone->id => $oZone);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $bannerId1 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 2, 1, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $bannerId2 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 3, 2, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 4, 2, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $bannerId3 = $this->_insertCampaignBanner();
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId3, 0, 5, 5, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 1, 100, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId1, 0, 2, 100, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 3, 200, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId2, 0, 4, 200, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), $bannerId3, 0, 5, 500, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), 4, 0, 5, 500, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), 10, 0, 4, 1000, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     for ($i = 0; $i <= MINUTES_PER_WEEK / $conf['maintenance']['operationInterval']; $i++) {
         $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     }
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     for ($i = 0; $i <= MINUTES_PER_WEEK / $conf['maintenance']['operationInterval']; $i++) {
         $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     }
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $aDates['start']->format('%Y-%m-%d'), $aDates['start']->format('%H'), 11, 0, 4, 2000, $oNow->format('%Y-%m-%d %H:%M:%S'));
     $idDia = $this->_insertDataIntermediateAd($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $oSpecialDate = new Date($aDates['end']);
     $oSpecialDate->addSeconds(1);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId1, 2, 10, 10, 0, 0.5, 0.99, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), 9, 9, 59, 59, 0, 95, 0.995, $oNow->format('%Y-%m-%d %H:%M:%S'), 0);
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 3, 30, 30, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 3, 30, 30, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $aDates['end']->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 4, 10, 10, 0, 0.4, 0.5, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), 0, $aDates['end']->format('%Y-%m-%d %H:30:00'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId2, 4, 20, 20, 0, 0.8, 0.5, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $oSpecialDate = new Date($aDates['end']);
     $oSpecialDate->addSeconds(1);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId3, 5, 200, 200, 0, 0.2, 0.95, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), 0, $aDates['end']->format('%Y-%m-%d %H:30:00'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), $bannerId3, 5, 100, 100, 0, 0.4, 0.95, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), 10, 4, 1000, 1000, 0, 1, 0.9, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $operationIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oDate);
     $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($operationIntervalID);
     for ($i = 0; $i <= MINUTES_PER_WEEK / $conf['maintenance']['operationInterval']; $i++) {
         $previousOperationIntervalID = OX_OperationInterval::previousOperationIntervalID($previousOperationIntervalID);
     }
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oDate);
     for ($i = 0; $i <= MINUTES_PER_WEEK / $conf['maintenance']['operationInterval']; $i++) {
         $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     }
     $oSpecialDate = new Date($aDates['end']);
     $oSpecialDate->addSeconds(1);
     $aData = array($conf['maintenance']['operationInterval'], $previousOperationIntervalID, $aDates['start']->format('%Y-%m-%d %H:%M:%S'), $aDates['end']->format('%Y-%m-%d %H:%M:%S'), 11, 4, 2000, 2000, 0, 1, 0.9, $aDates['start']->format('%Y-%m-%d %H:30:00'), 0, $oSpecialDate->format('%Y-%m-%d %H:%M:%S'));
     $this->_insertDataSummaryAdZoneAssoc($aData);
     $result =& $oMaxDalMaintenance->getPreviousAdDeliveryInfo($aZoneAdArray);
     $this->assertEqual(count($result), 5);
     $this->assertEqual(count($result[1]), 2);
     $this->assertEqual($result[1][1]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][1]['zone_id'], 1);
     $this->assertNull($result[1][1]['required_impressions']);
     $this->assertNull($result[1][1]['requested_impressions']);
     $this->assertNull($result[1][1]['priority_factor']);
     $this->assertNull($result[1][1]['past_zone_traffic_fraction']);
     $this->assertEqual($result[1][1]['impressions'], 1);
     $this->assertEqual($result[1][2]['ad_id'], $bannerId1);
     $this->assertEqual($result[1][2]['zone_id'], 2);
     $this->assertEqual($result[1][2]['required_impressions'], 10);
     $this->assertEqual($result[1][2]['requested_impressions'], 10);
     $this->assertEqual($result[1][2]['priority_factor'], 0.5);
     $this->assertEqual($result[1][2]['past_zone_traffic_fraction'], 0.99);
     $this->assertEqual($result[1][2]['impressions'], 1);
     $this->assertEqual(count($result[2]), 2);
     $this->assertEqual($result[2][3]['ad_id'], $bannerId2);
     $this->assertEqual($result[2][3]['zone_id'], 3);
     $this->assertEqual($result[2][3]['required_impressions'], 30);
     $this->assertEqual($result[2][3]['requested_impressions'], 30);
     $this->assertEqual($result[2][3]['priority_factor'], 0.4);
     $this->assertEqual($result[2][3]['past_zone_traffic_fraction'], 0.5);
     $this->assertEqual($result[2][3]['impressions'], 2);
     $this->assertEqual($result[2][4]['ad_id'], $bannerId2);
     $this->assertEqual($result[2][4]['zone_id'], 4);
     $this->assertEqual($result[2][4]['required_impressions'], 15);
     $this->assertEqual($result[2][4]['requested_impressions'], 15);
     $this->assertEqual($result[2][4]['priority_factor'], 0.6);
     $this->assertEqual($result[2][4]['past_zone_traffic_fraction'], 0.5);
     $this->assertEqual($result[2][4]['impressions'], 2);
     $this->assertEqual(count($result[3]), 1);
     $this->assertEqual($result[3][5]['ad_id'], $bannerId3);
     $this->assertEqual($result[3][5]['zone_id'], 5);
     $this->assertEqual($result[3][5]['required_impressions'], 150);
     $this->assertEqual($result[3][5]['requested_impressions'], 150);
     $this->assertEqual($result[3][5]['priority_factor'], 0.3);
     $this->assertEqual($result[3][5]['past_zone_traffic_fraction'], 0.95);
     $this->assertEqual($result[3][5]['impressions'], 5);
     $this->assertEqual(count($result[9]), 1);
     $this->assertEqual($result[9][9]['ad_id'], 9);
     $this->assertEqual($result[9][9]['zone_id'], 9);
     $this->assertEqual($result[9][9]['required_impressions'], 59);
     $this->assertEqual($result[9][9]['requested_impressions'], 59);
     $this->assertEqual($result[9][9]['priority_factor'], 95);
     $this->assertEqual($result[9][9]['past_zone_traffic_fraction'], 0.995);
     $this->assertNull($result[9][9]['impressions']);
     $this->assertEqual(count($result[10]), 1);
     $this->assertEqual($result[10][4]['ad_id'], 10);
     $this->assertEqual($result[10][4]['zone_id'], 4);
     $this->assertEqual($result[10][4]['required_impressions'], 1000);
     $this->assertEqual($result[10][4]['requested_impressions'], 1000);
     $this->assertEqual($result[10][4]['priority_factor'], 1);
     $this->assertEqual($result[10][4]['past_zone_traffic_fraction'], 0.9);
     $this->assertEqual($result[10][4]['impressions'], 1000);
     TestEnv::restoreEnv();
 }
 /**
  * A method to test the getPreviousWeekZoneForcastImpressions() method.
  *
  * Test 1: Test with bad input, and ensure false is returned.
  * Test 2: Test with no date in the service locator, and ensure that
  *         false is returned.
  * Test 3: Test with no data, and ensure that an array with the default
  *         forecast for each zone is returned.
  * Test 4: Test with data, and ensure that an array with the correct
  *         forecasts is returned.
  */
 function testGetPreviousWeekZoneForcastImpressions()
 {
     $aConf = $GLOBALS['_MAX']['CONF'];
     $oDbh =& OA_DB::singleton();
     $oDal = new OA_Dal_Maintenance_Priority();
     // Test 1
     $aResult = $oDal->getPreviousWeekZoneForcastImpressions('foo');
     $this->assertFalse($aResult);
     // Test 2
     $oServiceLocator =& OA_ServiceLocator::instance();
     $oServiceLocator->remove('now');
     $aResult = $oDal->getPreviousWeekZoneForcastImpressions(1);
     $this->assertFalse($aResult);
     // Test 3
     $oDate = new Date();
     $oServiceLocator->register('now', $oDate);
     $aResult = $oDal->getPreviousWeekZoneForcastImpressions(1);
     $this->assertTrue(is_array($aResult));
     $this->assertEqual(count($aResult), OX_OperationInterval::operationIntervalsPerWeek());
     for ($operationIntervalID = 0; $operationIntervalID < OX_OperationInterval::operationIntervalsPerWeek(); $operationIntervalID++) {
         $expected = array('zone_id' => 1, 'forecast_impressions' => $oDal->getZoneForecastDefaultZoneImpressions(), 'operation_interval_id' => $operationIntervalID);
         $this->assertEqual($aResult[$operationIntervalID], $expected);
     }
     // Test 4
     // Insert impressions for the previous operation interval
     $aDates = OX_OperationInterval::convertDateToOperationIntervalStartAndEndDates($oDate);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $firstIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
     $startDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $endDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $doDIA = OA_Dal::factoryDO('data_intermediate_ad');
     $aDIAs = DataGenerator::generate($doDIA, 4);
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[0]);
     $startDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $endDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $doDIA->date_time = $startDate;
     $doDIA->interval_start = $startDate;
     $doDIA->interval_end = $endDate;
     $doDIA->operation_interval = $aConf['maintenance']['operationInterval'];
     $doDIA->operation_interval_id = $firstIntervalID;
     $doDIA->zone_id = 1;
     $doDIA->ad_id = 1;
     $doDIA->impressions = 4000;
     $doDIA->update();
     // Insert forcast for the (N - 2) OI
     // for two different ads in this OI
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($aDates['start']);
     $secondIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
     $startDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $endDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[1]);
     $doDIA->date_time = $startDate;
     $doDIA->interval_start = $startDate;
     $doDIA->interval_end = $endDate;
     $doDIA->operation_interval = $aConf['maintenance']['operationInterval'];
     $doDIA->operation_interval_id = $secondIntervalID;
     $doDIA->zone_id = 1;
     $doDIA->ad_id = 1;
     $doDIA->impressions = 4990;
     $doDIA->update();
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[2]);
     $doDIA->date_time = $startDate;
     $doDIA->interval_start = $startDate;
     $doDIA->interval_end = $endDate;
     $doDIA->operation_interval = $aConf['maintenance']['operationInterval'];
     $doDIA->operation_interval_id = $secondIntervalID;
     $doDIA->zone_id = 1;
     $doDIA->ad_id = 2;
     $doDIA->impressions = 10;
     $doDIA->update();
     // Insert forcast for the second previous operation interval, but
     // one week ago (so it should not be in the result set)
     $oNewDate = new Date();
     $oNewDate->copy($aDates['start']);
     $oNewDate->subtractSeconds(SECONDS_PER_WEEK);
     $aDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($oNewDate);
     $intervalID = OX_OperationInterval::convertDateToOperationIntervalID($aDates['start']);
     $startDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $endDate = $aDates['start']->format('%Y-%m-%d %H:%M:%S');
     $doDIA = OA_Dal::staticGetDO('data_intermediate_ad', $aDIAs[3]);
     $doDIA->date_time = $startDate;
     $doDIA->interval_start = $startDate;
     $doDIA->interval_end = $endDate;
     $doDIA->operation_interval = $aConf['maintenance']['operationInterval'];
     $doDIA->operation_interval_id = $intervalID;
     $doDIA->zone_id = 1;
     $doDIA->ad_id = 1;
     $doDIA->impressions = 1000;
     $doDIA->update();
     // What's the current OI?
     $currentIntervalID = OX_OperationInterval::convertDateToOperationIntervalID($oServiceLocator->get('now'));
     $aResult = $oDal->getPreviousWeekZoneForcastImpressions(1);
     $this->assertTrue(is_array($aResult));
     $this->assertEqual(count($aResult), OX_OperationInterval::operationIntervalsPerWeek());
     for ($operationIntervalID = 0; $operationIntervalID < OX_OperationInterval::operationIntervalsPerWeek(); $operationIntervalID++) {
         $this->assertTrue(is_array($aResult[$operationIntervalID]));
         $this->assertEqual(count($aResult[$operationIntervalID]), 3);
         $this->assertEqual($aResult[$operationIntervalID]['zone_id'], 1);
         if ($operationIntervalID == $firstIntervalID || $operationIntervalID == $currentIntervalID) {
             // Current and previous OI forecasts should be the same
             $this->assertEqual($aResult[$operationIntervalID]['forecast_impressions'], 4000);
         } elseif ($operationIntervalID == $secondIntervalID) {
             $this->assertEqual($aResult[$operationIntervalID]['forecast_impressions'], 5000);
         } else {
             $this->assertEqual($aResult[$operationIntervalID]['forecast_impressions'], 4500);
             // average between both known forecast
         }
         $this->assertEqual($aResult[$operationIntervalID]['operation_interval_id'], $operationIntervalID);
     }
     DataGenerator::cleanUp();
 }
 /**
  * A method to perform basic end-to-end integration testing of the Maintenance
  * Priority Engine classes for the Ad Server.
  *
  * Test 0: Test that no zone forecast or priority data exists to begin with.
  * Test 1: Run the MPE without any stats, and without the stats engine ever
  *         having been run before. Test that zone forecasts are updated
  *         with the appropriate values, and that the correct priorities are
  *         generated.
  * Test 2: Run the MPE without any stats, but with the stats engine having
  *         reported that it has run. Test that zone forecasts are updated
  *         with the appropriate values, and that the correct priorities are
  *         generated.
  * Test 3: Run the MPE again, as for Test 2, but with a later date used as
  *         for when the stats engine reported having run.
  */
 function testAdServer()
 {
     // Test 0: Ensure correct number of links in the ad_zone_assoc table
     $this->assertEqual($this->_azaRows(), 7);
     // 4 proper associations + 3 default with zone 0
     // Test 0: Ensure no links in the ad_zone_assoc table have priority > 0
     $this->assertEqual($this->_azaRows(true), 0);
     // Test 0: Ensure no links in the data_summary_ad_zone_assoc table have priority > 0
     $this->assertEqual($this->_dsazaRows(true), 0);
     // Test 0: Ensure no data in the log_maintenance_priority table
     $this->_assertLogMaintenance();
     // Test 1: Set "current" date for the MPE run
     $oDate = new Date('2005-06-15 13:01:01');
     $this->oServiceLocator->register('now', $oDate);
     // Test 1: Prepare the MPE object
     $oMaintenancePriority = new OA_Maintenance_Priority_AdServer();
     // Test 1: Store the date before the MPE runs
     $oTest1BeforeUpdateDate = new Date();
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     // Test 1: Run the MPE
     $oMaintenancePriority->updatePriorities();
     // Test 1: Store the date after the MPE runs
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     $oTest1AfterUpdateDate = new Date();
     // Test 1: Ensure correct number of links in the ad_zone_assoc table
     $this->assertEqual($this->_azaRows(), 7);
     // 4 proper associations + 3 default with zone 0
     // Test 1: Ensure correct number of links in the ad_zone_assoc table with priority > 0
     $this->assertEqual($this->_azaRows(true), 7);
     // Test 1: Ensure correct number of links in the data_summary_ad_zone_assoc table with priority >
     $this->assertEqual($this->_dsazaRows(true), 7);
     // Test 1: Ensure that the priorities in the ad_zone_assoc and data_summary_ad_zone_assoc
     // tables are set correctly
     $aTestOneZero = array();
     $aTestOneZero['ad_id'] = 1;
     $aTestOneZero['zone_id'] = 0;
     $aTestOneZero['priority'] = 11 / 200;
     // 200 is 10 (default forecast) / 0.05 (factor)
     $aTestOneZero['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestOneZero['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 11, 'requested_impressions' => 11, 'priority' => $aTestOneZero['priority'], 'priority_factor' => $aTestOneZero['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestOneZero);
     $aTestTwoZero = array();
     $aTestTwoZero['ad_id'] = 2;
     $aTestTwoZero['zone_id'] = 0;
     $aTestTwoZero['priority'] = 12 / 200;
     $aTestTwoZero['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestTwoZero['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 12, 'requested_impressions' => 12, 'priority' => $aTestTwoZero['priority'], 'priority_factor' => $aTestTwoZero['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestTwoZero);
     $aTestThreeZero = array();
     $aTestThreeZero['ad_id'] = 3;
     $aTestThreeZero['zone_id'] = 0;
     $aTestThreeZero['priority'] = 6 / 200;
     $aTestThreeZero['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestThreeZero['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 6, 'requested_impressions' => 6, 'priority' => $aTestThreeZero['priority'], 'priority_factor' => $aTestThreeZero['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestThreeZero);
     $aTestOneOne = array();
     $aTestOneOne['ad_id'] = 1;
     $aTestOneOne['zone_id'] = 1;
     $aTestOneOne['priority'] = 10 / 200;
     // Constant, only priority_factor increases
     $aTestOneOne['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestOneOne['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 11, 'requested_impressions' => 10, 'priority' => $aTestOneOne['priority'], 'priority_factor' => $aTestOneOne['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestOneOne);
     $aTestTwoThree = array();
     $aTestTwoThree['ad_id'] = 2;
     $aTestTwoThree['zone_id'] = 3;
     $aTestTwoThree['priority'] = 8 / 200;
     // Constant, only priority_factor increases
     $aTestTwoThree['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestTwoThree['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 12, 'requested_impressions' => 8, 'priority' => $aTestTwoThree['priority'], 'priority_factor' => $aTestTwoThree['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestTwoThree);
     $aTestThreeThree = array();
     $aTestThreeThree['ad_id'] = 3;
     $aTestThreeThree['zone_id'] = 3;
     $aTestThreeThree['priority'] = 2 / 200;
     // Constant, only priority_factor increases
     $aTestThreeThree['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestThreeThree['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 3, 'requested_impressions' => 2, 'priority' => $aTestThreeThree['priority'], 'priority_factor' => $aTestThreeThree['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestThreeThree);
     $aTestThreeFour = array();
     $aTestThreeFour['ad_id'] = 3;
     $aTestThreeFour['zone_id'] = 4;
     $aTestThreeFour['priority'] = 3 / 200;
     // Constant, only priority_factor increases
     $aTestThreeFour['priority_factor'] = 1;
     // Initial priority run, factor starts at 1
     $aTestThreeFour['history'][0] = array('operation_interval' => 60, 'operation_interval_id' => 85, 'interval_start' => '2005-06-15 13:00:00', 'interval_end' => '2005-06-15 13:59:59', 'required_impressions' => 3, 'requested_impressions' => 3, 'priority' => $aTestThreeFour['priority'], 'priority_factor' => $aTestThreeFour['priority_factor'], 'past_zone_traffic_fraction' => null);
     $this->_assertPriority($aTestThreeFour);
     // Test 1: Ensure that the values in the log_maintenance_priority table are correct
     $this->_assertLogMaintenance(2, $oTest1BeforeUpdateDate, $oTest1AfterUpdateDate, 60, DAL_PRIORITY_UPDATE_ECPM);
     // Insert data that indicates that the Maintenance Statistics Engine
     // has recently updated the available stats, but don't insert any
     // stats into the tables
     $this->oServiceLocator =& OA_ServiceLocator::instance();
     $startDate = new Date('2005-06-15 14:00:01');
     $this->oServiceLocator->register('now', $startDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->updateFinal = true;
     $aOiDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($startDate);
     $oMaintenanceStatistics->oUpdateIntermediateToDate = $aOiDates['end'];
     $oMaintenanceStatistics->oUpdateFinalToDate = $aOiDates['end'];
     $this->oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     $oLogCompletion = new OX_Maintenance_Statistics_Task_LogCompletion();
     $oLogCompletion->run();
     // Test 2: Set "previous" date for the MPE run
     $oPreviousDate = new Date('2005-06-15 13:01:01');
     $previousOperationIntervalID = $currentOperationIntervalID;
     // Test 2: Set "current" date for the MPE run
     $oDate = new Date('2005-06-15 14:01:01');
     $this->oServiceLocator->register('now', $oDate);
     // Test 2: Prepare the MPE object
     $oMaintenancePriority = new OA_Maintenance_Priority_AdServer();
     // Test 2: Store the date before the MPE runs
     $oTest2BeforeUpdateDate = new Date();
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     // Test 2: Run the MPE
     $oMaintenancePriority->updatePriorities();
     // Test 2: Store the date after the MPE runs
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     $oTest2AfterUpdateDate = new Date();
     // Test 2: Ensure correct number of links in the ad_zone_assoc table
     $this->assertEqual($this->_azaRows(), 7);
     // 4 proper associations + 3 default with zone 0
     // Test 2: Ensure correct number of links in the ad_zone_assoc table with priority > 0
     $this->assertEqual($this->_azaRows(true), 7);
     // Test 2: Ensure correct number of links in the data_summary_ad_zone_assoc table with priority > 0
     $this->assertEqual($this->_dsazaRows(true), 14);
     // Test 2: Ensure that the priorities in the ad_zone_assoc and data_summary_ad_zone_assoc
     // tables are set correctly
     $aTestOneZero['priority'] = 12 / 200;
     $aTestOneZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestOneZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 12, 'requested_impressions' => 12, 'priority' => $aTestOneZero['priority'], 'priority_factor' => $aTestOneZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestOneZero);
     $aTestTwoZero['priority'] = 12 / 200;
     $aTestTwoZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestTwoZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 12, 'requested_impressions' => 12, 'priority' => $aTestTwoZero['priority'], 'priority_factor' => $aTestTwoZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestTwoZero);
     $aTestThreeZero['priority'] = 6 / 200;
     $aTestThreeZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestThreeZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 6, 'requested_impressions' => 6, 'priority' => $aTestThreeZero['priority'], 'priority_factor' => $aTestThreeZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestThreeZero);
     $aTestOneOne['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestOneOne['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 12, 'requested_impressions' => 10, 'priority' => $aTestOneOne['priority'], 'priority_factor' => $aTestOneOne['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestOneOne);
     $aTestTwoThree['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestTwoThree['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 12, 'requested_impressions' => 8, 'priority' => $aTestTwoThree['priority'], 'priority_factor' => $aTestTwoThree['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestTwoThree);
     $aTestThreeThree['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestThreeThree['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 3, 'requested_impressions' => 2, 'priority' => $aTestThreeThree['priority'], 'priority_factor' => $aTestThreeThree['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestThreeThree);
     $aTestThreeFour['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestThreeFour['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 86, 'interval_start' => '2005-06-15 14:00:00', 'interval_end' => '2005-06-15 14:59:59', 'required_impressions' => 3, 'requested_impressions' => 3, 'priority' => $aTestThreeFour['priority'], 'priority_factor' => $aTestThreeFour['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestThreeFour);
     // Test 2: Ensure that the values in the log_maintenance_priority table are correct
     $this->_assertLogMaintenance(2, $oTest1BeforeUpdateDate, $oTest1AfterUpdateDate, 60, DAL_PRIORITY_UPDATE_ECPM);
     $this->_assertLogMaintenance(6, $oTest2BeforeUpdateDate, $oTest2AfterUpdateDate, 60, DAL_PRIORITY_UPDATE_ECPM);
     // Insert data that indicates that the Maintenance Statistics Engine
     // has recently updated the available stats
     $this->oServiceLocator =& OA_ServiceLocator::instance();
     $startDate = new Date('2005-06-19 00:00:01');
     $this->oServiceLocator->register('now', $startDate);
     $oMaintenanceStatistics = new OX_Maintenance_Statistics();
     $oMaintenanceStatistics->updateIntermediate = true;
     $oMaintenanceStatistics->updateFinal = true;
     $aOiDates = OX_OperationInterval::convertDateToPreviousOperationIntervalStartAndEndDates($startDate);
     $oMaintenanceStatistics->oUpdateIntermediateToDate = $aOiDates['end'];
     $oMaintenanceStatistics->oUpdateFinalToDate = $aOiDates['end'];
     $this->oServiceLocator->register('Maintenance_Statistics_Controller', $oMaintenanceStatistics);
     $oLogCompletion = new OX_Maintenance_Statistics_Task_LogCompletion();
     $oLogCompletion->run();
     // Insert some stats for an ad zone combination
     $doDIA = OA_DAL::factoryDO('data_intermediate_ad');
     $doDIA->ad_id = 3;
     $doDIA->zone_id = 3;
     $doDIA->impressions = 20;
     $doDIA->date_time = $aOiDates['start']->getDate();
     $doDIA->interval_start = $aOiDates['start']->getDate();
     $doDIA->interval_end = $aOiDates['end']->getDate();
     $doDIA->operation_interval = 60;
     $doDIA->operation_interval_id = OX_OperationInterval::convertDateToOperationIntervalID($aOiDates['start']);
     $doDIA->insert();
     // Test 3: Set "current" date for the MPE run
     $oDate = new Date('2005-06-19 00:01:01');
     $this->oServiceLocator->register('now', $oDate);
     // Test 3: Prepare the MPE object
     $oMaintenancePriority = new OA_Maintenance_Priority_AdServer();
     // Test 3: Store the date before the MPE runs
     $oTest3BeforeUpdateDate = new Date();
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     // Test 3: Run the MPE
     $oMaintenancePriority->updatePriorities();
     // Test 3: Store the date after the MPE runs
     sleep(1);
     // Ensure that next date is at least 1 second after above...
     $oTest3AfterUpdateDate = new Date();
     $oLastUpdatedTo1 = new Date('2005-06-15 14:00:00');
     $oNowUpdatedTo1 = new Date('2005-06-15 15:00:00');
     $oSpan = new Date_Span();
     $oLastUpdatedTo1Copy = new Date();
     $oLastUpdatedTo1Copy->copy($oLastUpdatedTo1);
     $oNowUpdatedTo1Copy = new Date();
     $oNowUpdatedTo1Copy->copy($oNowUpdatedTo1);
     $oSpan->setFromDateDiff($oLastUpdatedTo1Copy, $oNowUpdatedTo1Copy);
     $hours1 = $oSpan->toHours();
     $oLastUpdatedTo2 = new Date('2005-06-15 15:00:00');
     $oNowUpdatedTo2 = new Date('2005-06-19 01:00:00');
     $oSpan = new Date_Span();
     $oLastUpdatedTo2Copy = new Date();
     $oLastUpdatedTo2Copy->copy($oLastUpdatedTo2);
     $oNowUpdatedTo2Copy = new Date();
     $oNowUpdatedTo2Copy->copy($oNowUpdatedTo2);
     $oSpan->setFromDateDiff($oLastUpdatedTo2Copy, $oNowUpdatedTo2Copy);
     $hours2 = $oSpan->toHours();
     // Test 3: Ensure correct number of links in the ad_zone_assoc table
     $this->assertEqual($this->_azaRows(), 7);
     // 4 proper associations + 3 default with zone 0
     // Test 3: Ensure correct number of links in the ad_zone_assoc table with priority > 0
     $this->assertEqual($this->_azaRows(true), 7);
     // Test 3: Ensure correct number of links in the data_summary_ad_zone_assoc table with priority > 0
     $this->assertEqual($this->_dsazaRows(true), 21);
     // Test 3: Ensure that the priorities in the ad_zone_assoc and data_summary_ad_zone_assoc
     // tables are set correctly
     $aTestOneZero['priority'] = 5 / 200;
     $aTestOneZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestOneZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 5, 'requested_impressions' => 5, 'priority' => $aTestOneZero['priority'], 'priority_factor' => $aTestOneZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestOneZero);
     $aTestTwoZero['priority'] = 12 / 200;
     $aTestTwoZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestTwoZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 12, 'requested_impressions' => 12, 'priority' => $aTestTwoZero['priority'], 'priority_factor' => $aTestTwoZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestTwoZero);
     $aTestThreeZero['priority'] = 6 / 200;
     $aTestThreeZero['priority_factor'] = 1;
     // Remains at 1, no priority compensation in Zone ID 0
     $aTestThreeZero['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 6, 'requested_impressions' => 6, 'priority' => $aTestThreeZero['priority'], 'priority_factor' => $aTestThreeZero['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestThreeZero);
     $aTestOneOne['priority'] = 5 / 200;
     // Changed, skipped OIs
     $aTestOneOne['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestOneOne['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 5, 'requested_impressions' => 5, 'priority' => $aTestOneOne['priority'], 'priority_factor' => $aTestOneOne['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestOneOne);
     $aTestTwoThree['priority'] = 12 / 20;
     // Zone has had some impressions, we have a forecast now
     $aTestTwoThree['priority_factor'] = 10;
     // But this ad didn't deliver. Factor increased
     $aTestTwoThree['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 12, 'requested_impressions' => 12, 'priority' => $aTestTwoThree['priority'], 'priority_factor' => $aTestTwoThree['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestTwoThree);
     $aTestThreeThree['priority'] = 4 / 20;
     // Ad/Zone has delivered!
     $aTestThreeThree['priority_factor'] = 2 / 20;
     // Overdelivered quite a bit!
     $aTestThreeThree['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 4, 'requested_impressions' => 4, 'priority' => $aTestThreeThree['priority'], 'priority_factor' => $aTestThreeThree['priority_factor'], 'past_zone_traffic_fraction' => 1);
     $this->_assertPriority($aTestThreeThree);
     $aTestThreeFour['priority'] = 2 / 200;
     // Ad has delivered, but not in this zone
     $aTestThreeFour['priority_factor'] = 1;
     // Remains at 1, zone was not active
     $aTestThreeFour['history'][1] = array('operation_interval' => 60, 'operation_interval_id' => 0, 'interval_start' => '2005-06-19 00:00:00', 'interval_end' => '2005-06-19 00:59:59', 'required_impressions' => 2, 'requested_impressions' => 2, 'priority' => $aTestThreeFour['priority'], 'priority_factor' => $aTestThreeFour['priority_factor'], 'past_zone_traffic_fraction' => 0);
     $this->_assertPriority($aTestThreeFour);
     // Test 3: Ensure that the values in the log_maintenance_priority table are correct
     $this->_assertLogMaintenance(2, $oTest1BeforeUpdateDate, $oTest1AfterUpdateDate, 60, DAL_PRIORITY_UPDATE_ECPM);
     $this->_assertLogMaintenance(6, $oTest2BeforeUpdateDate, $oTest2AfterUpdateDate, 60, DAL_PRIORITY_UPDATE_ECPM);
 }